rename
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Mon, 23 Mar 2009 14:37:43 +0100
changeset 4364579bbfe8bb65
parent 4363 55ccad74d7cc
child 4365 f71fd5bfc4ad
rename
bindings/python/ns3_module_olsr.py
src/helper/olsr-helper.cc
src/routing/olsr/olsr-agent-impl.cc
src/routing/olsr/olsr-agent-impl.h
src/routing/olsr/olsr-routing-protocol.cc
src/routing/olsr/olsr-routing-protocol.h
src/routing/olsr/wscript
utils/print-introspected-doxygen.cc
     1.1 --- a/bindings/python/ns3_module_olsr.py	Mon Mar 23 14:29:31 2009 +0100
     1.2 +++ b/bindings/python/ns3_module_olsr.py	Mon Mar 23 14:37:43 2009 +0100
     1.3 @@ -51,8 +51,6 @@
     1.4  def register_types_ns3_olsr(module):
     1.5      root_module = module.get_root()
     1.6      
     1.7 -    ## olsr-agent-impl.h: ns3::olsr::AgentImpl [class]
     1.8 -    module.add_class('AgentImpl', parent=root_module['ns3::Ipv4RoutingProtocol'])
     1.9      ## olsr-repositories.h: ns3::olsr::DuplicateTuple [struct]
    1.10      module.add_class('DuplicateTuple')
    1.11      ## olsr-repositories.h: ns3::olsr::IfaceAssocTuple [struct]
    1.12 @@ -83,7 +81,9 @@
    1.13      module.add_enum('Status', ['STATUS_NOT_SYM', 'STATUS_SYM'], outer_class=root_module['ns3::olsr::NeighborTuple'])
    1.14      ## olsr-header.h: ns3::olsr::PacketHeader [class]
    1.15      module.add_class('PacketHeader', parent=root_module['ns3::Header'])
    1.16 -    ## olsr-agent-impl.h: ns3::olsr::RoutingTableEntry [struct]
    1.17 +    ## olsr-routing-protocol.h: ns3::olsr::RoutingProtocol [class]
    1.18 +    module.add_class('RoutingProtocol', parent=root_module['ns3::Ipv4RoutingProtocol'])
    1.19 +    ## olsr-routing-protocol.h: ns3::olsr::RoutingTableEntry [struct]
    1.20      module.add_class('RoutingTableEntry')
    1.21      ## olsr-repositories.h: ns3::olsr::TopologyTuple [struct]
    1.22      module.add_class('TopologyTuple')
    1.23 @@ -94,7 +94,6 @@
    1.24  
    1.25  def register_methods(root_module):
    1.26      register_Ns3OlsrState_methods(root_module, root_module['ns3::OlsrState'])
    1.27 -    register_Ns3OlsrAgentImpl_methods(root_module, root_module['ns3::olsr::AgentImpl'])
    1.28      register_Ns3OlsrDuplicateTuple_methods(root_module, root_module['ns3::olsr::DuplicateTuple'])
    1.29      register_Ns3OlsrIfaceAssocTuple_methods(root_module, root_module['ns3::olsr::IfaceAssocTuple'])
    1.30      register_Ns3OlsrLinkTuple_methods(root_module, root_module['ns3::olsr::LinkTuple'])
    1.31 @@ -108,6 +107,7 @@
    1.32      register_Ns3OlsrMprSelectorTuple_methods(root_module, root_module['ns3::olsr::MprSelectorTuple'])
    1.33      register_Ns3OlsrNeighborTuple_methods(root_module, root_module['ns3::olsr::NeighborTuple'])
    1.34      register_Ns3OlsrPacketHeader_methods(root_module, root_module['ns3::olsr::PacketHeader'])
    1.35 +    register_Ns3OlsrRoutingProtocol_methods(root_module, root_module['ns3::olsr::RoutingProtocol'])
    1.36      register_Ns3OlsrRoutingTableEntry_methods(root_module, root_module['ns3::olsr::RoutingTableEntry'])
    1.37      register_Ns3OlsrTopologyTuple_methods(root_module, root_module['ns3::olsr::TopologyTuple'])
    1.38      register_Ns3OlsrTwoHopNeighborTuple_methods(root_module, root_module['ns3::olsr::TwoHopNeighborTuple'])
    1.39 @@ -306,45 +306,6 @@
    1.40                     is_const=True)
    1.41      return
    1.42  
    1.43 -def register_Ns3OlsrAgentImpl_methods(root_module, cls):
    1.44 -    ## olsr-agent-impl.h: ns3::olsr::AgentImpl::AgentImpl(ns3::olsr::AgentImpl const & arg0) [copy constructor]
    1.45 -    cls.add_constructor([param('ns3::olsr::AgentImpl const &', 'arg0')])
    1.46 -    ## olsr-agent-impl.h: static ns3::TypeId ns3::olsr::AgentImpl::GetTypeId() [member function]
    1.47 -    cls.add_method('GetTypeId', 
    1.48 -                   'ns3::TypeId', 
    1.49 -                   [], 
    1.50 -                   is_static=True)
    1.51 -    ## olsr-agent-impl.h: ns3::olsr::AgentImpl::AgentImpl() [constructor]
    1.52 -    cls.add_constructor([])
    1.53 -    ## olsr-agent-impl.h: void ns3::olsr::AgentImpl::SetNode(ns3::Ptr<ns3::Node> node) [member function]
    1.54 -    cls.add_method('SetNode', 
    1.55 -                   'void', 
    1.56 -                   [param('ns3::Ptr< ns3::Node >', 'node')])
    1.57 -    ## olsr-agent-impl.h: void ns3::olsr::AgentImpl::Start() [member function]
    1.58 -    cls.add_method('Start', 
    1.59 -                   'void', 
    1.60 -                   [])
    1.61 -    ## olsr-agent-impl.h: void ns3::olsr::AgentImpl::SetMainInterface(uint32_t interface) [member function]
    1.62 -    cls.add_method('SetMainInterface', 
    1.63 -                   'void', 
    1.64 -                   [param('uint32_t', 'interface')])
    1.65 -    ## olsr-agent-impl.h: bool ns3::olsr::AgentImpl::RequestRoute(uint32_t ifIndex, ns3::Ipv4Header const & ipHeader, ns3::Ptr<ns3::Packet> packet, ns3::Callback<void,bool,const ns3::Ipv4Route&,ns3::Ptr<ns3::Packet>,const ns3::Ipv4Header&,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> routeReply) [member function]
    1.66 -    cls.add_method('RequestRoute', 
    1.67 -                   'bool', 
    1.68 -                   [param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header const &', 'ipHeader'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, ns3::Ipv4Route const &, ns3::Ptr< ns3::Packet >, ns3::Ipv4Header const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'routeReply')], 
    1.69 -                   visibility='private', is_virtual=True)
    1.70 -    ## olsr-agent-impl.h: bool ns3::olsr::AgentImpl::RequestIfIndex(ns3::Ipv4Address destination, uint32_t & ifIndex) [member function]
    1.71 -    cls.add_method('RequestIfIndex', 
    1.72 -                   'bool', 
    1.73 -                   [param('ns3::Ipv4Address', 'destination'), param('uint32_t &', 'ifIndex')], 
    1.74 -                   visibility='private', is_virtual=True)
    1.75 -    ## olsr-agent-impl.h: void ns3::olsr::AgentImpl::DoDispose() [member function]
    1.76 -    cls.add_method('DoDispose', 
    1.77 -                   'void', 
    1.78 -                   [], 
    1.79 -                   visibility='private', is_virtual=True)
    1.80 -    return
    1.81 -
    1.82  def register_Ns3OlsrDuplicateTuple_methods(root_module, cls):
    1.83      cls.add_binary_comparison_operator('==')
    1.84      ## olsr-repositories.h: ns3::olsr::DuplicateTuple::DuplicateTuple() [constructor]
    1.85 @@ -757,18 +718,57 @@
    1.86                     [param('uint16_t', 'seqnum')])
    1.87      return
    1.88  
    1.89 +def register_Ns3OlsrRoutingProtocol_methods(root_module, cls):
    1.90 +    ## olsr-routing-protocol.h: ns3::olsr::RoutingProtocol::RoutingProtocol(ns3::olsr::RoutingProtocol const & arg0) [copy constructor]
    1.91 +    cls.add_constructor([param('ns3::olsr::RoutingProtocol const &', 'arg0')])
    1.92 +    ## olsr-routing-protocol.h: static ns3::TypeId ns3::olsr::RoutingProtocol::GetTypeId() [member function]
    1.93 +    cls.add_method('GetTypeId', 
    1.94 +                   'ns3::TypeId', 
    1.95 +                   [], 
    1.96 +                   is_static=True)
    1.97 +    ## olsr-routing-protocol.h: ns3::olsr::RoutingProtocol::RoutingProtocol() [constructor]
    1.98 +    cls.add_constructor([])
    1.99 +    ## olsr-routing-protocol.h: void ns3::olsr::RoutingProtocol::SetNode(ns3::Ptr<ns3::Node> node) [member function]
   1.100 +    cls.add_method('SetNode', 
   1.101 +                   'void', 
   1.102 +                   [param('ns3::Ptr< ns3::Node >', 'node')])
   1.103 +    ## olsr-routing-protocol.h: void ns3::olsr::RoutingProtocol::Start() [member function]
   1.104 +    cls.add_method('Start', 
   1.105 +                   'void', 
   1.106 +                   [])
   1.107 +    ## olsr-routing-protocol.h: void ns3::olsr::RoutingProtocol::SetMainInterface(uint32_t interface) [member function]
   1.108 +    cls.add_method('SetMainInterface', 
   1.109 +                   'void', 
   1.110 +                   [param('uint32_t', 'interface')])
   1.111 +    ## olsr-routing-protocol.h: bool ns3::olsr::RoutingProtocol::RequestRoute(uint32_t ifIndex, ns3::Ipv4Header const & ipHeader, ns3::Ptr<ns3::Packet> packet, ns3::Callback<void,bool,const ns3::Ipv4Route&,ns3::Ptr<ns3::Packet>,const ns3::Ipv4Header&,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> routeReply) [member function]
   1.112 +    cls.add_method('RequestRoute', 
   1.113 +                   'bool', 
   1.114 +                   [param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header const &', 'ipHeader'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, ns3::Ipv4Route const &, ns3::Ptr< ns3::Packet >, ns3::Ipv4Header const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'routeReply')], 
   1.115 +                   visibility='private', is_virtual=True)
   1.116 +    ## olsr-routing-protocol.h: bool ns3::olsr::RoutingProtocol::RequestIfIndex(ns3::Ipv4Address destination, uint32_t & ifIndex) [member function]
   1.117 +    cls.add_method('RequestIfIndex', 
   1.118 +                   'bool', 
   1.119 +                   [param('ns3::Ipv4Address', 'destination'), param('uint32_t &', 'ifIndex')], 
   1.120 +                   visibility='private', is_virtual=True)
   1.121 +    ## olsr-routing-protocol.h: void ns3::olsr::RoutingProtocol::DoDispose() [member function]
   1.122 +    cls.add_method('DoDispose', 
   1.123 +                   'void', 
   1.124 +                   [], 
   1.125 +                   visibility='private', is_virtual=True)
   1.126 +    return
   1.127 +
   1.128  def register_Ns3OlsrRoutingTableEntry_methods(root_module, cls):
   1.129 -    ## olsr-agent-impl.h: ns3::olsr::RoutingTableEntry::destAddr [variable]
   1.130 +    ## olsr-routing-protocol.h: ns3::olsr::RoutingTableEntry::destAddr [variable]
   1.131      cls.add_instance_attribute('destAddr', 'ns3::Ipv4Address', is_const=False)
   1.132 -    ## olsr-agent-impl.h: ns3::olsr::RoutingTableEntry::nextAddr [variable]
   1.133 +    ## olsr-routing-protocol.h: ns3::olsr::RoutingTableEntry::nextAddr [variable]
   1.134      cls.add_instance_attribute('nextAddr', 'ns3::Ipv4Address', is_const=False)
   1.135 -    ## olsr-agent-impl.h: ns3::olsr::RoutingTableEntry::interface [variable]
   1.136 +    ## olsr-routing-protocol.h: ns3::olsr::RoutingTableEntry::interface [variable]
   1.137      cls.add_instance_attribute('interface', 'uint32_t', is_const=False)
   1.138 -    ## olsr-agent-impl.h: ns3::olsr::RoutingTableEntry::distance [variable]
   1.139 +    ## olsr-routing-protocol.h: ns3::olsr::RoutingTableEntry::distance [variable]
   1.140      cls.add_instance_attribute('distance', 'uint32_t', is_const=False)
   1.141 -    ## olsr-agent-impl.h: ns3::olsr::RoutingTableEntry::RoutingTableEntry(ns3::olsr::RoutingTableEntry const & arg0) [copy constructor]
   1.142 +    ## olsr-routing-protocol.h: ns3::olsr::RoutingTableEntry::RoutingTableEntry(ns3::olsr::RoutingTableEntry const & arg0) [copy constructor]
   1.143      cls.add_constructor([param('ns3::olsr::RoutingTableEntry const &', 'arg0')])
   1.144 -    ## olsr-agent-impl.h: ns3::olsr::RoutingTableEntry::RoutingTableEntry() [constructor]
   1.145 +    ## olsr-routing-protocol.h: ns3::olsr::RoutingTableEntry::RoutingTableEntry() [constructor]
   1.146      cls.add_constructor([])
   1.147      return
   1.148  
     2.1 --- a/src/helper/olsr-helper.cc	Mon Mar 23 14:29:31 2009 +0100
     2.2 +++ b/src/helper/olsr-helper.cc	Mon Mar 23 14:37:43 2009 +0100
     2.3 @@ -18,7 +18,7 @@
     2.4   * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
     2.5   */
     2.6  #include "olsr-helper.h"
     2.7 -#include "ns3/olsr-agent-impl.h"
     2.8 +#include "ns3/olsr-routing-protocol.h"
     2.9  #include "ns3/node-list.h"
    2.10  #include "ns3/names.h"
    2.11  
    2.12 @@ -26,7 +26,7 @@
    2.13  
    2.14  OlsrHelper::OlsrHelper ()
    2.15  {
    2.16 -  m_agentFactory.SetTypeId ("ns3::olsr::AgentImpl");
    2.17 +  m_agentFactory.SetTypeId ("ns3::olsr::RoutingProtocol");
    2.18  }
    2.19  
    2.20  void 
    2.21 @@ -63,13 +63,13 @@
    2.22  void 
    2.23  OlsrHelper::Install (Ptr<Node> node)
    2.24  {
    2.25 -  if (node->GetObject<olsr::AgentImpl> () != 0)
    2.26 +  if (node->GetObject<olsr::RoutingProtocol> () != 0)
    2.27      {
    2.28        NS_FATAL_ERROR ("OlsrHelper::Install(): Aggregating "
    2.29 -         "an Olsr Agent to a node with an existing Olsr Agent");
    2.30 +         "an Olsr Agent to a node with an existing Olsr RoutingProtocol");
    2.31        return;
    2.32      }
    2.33 -  Ptr<olsr::AgentImpl> agent = m_agentFactory.Create<olsr::AgentImpl> ();
    2.34 +  Ptr<olsr::RoutingProtocol> agent = m_agentFactory.Create<olsr::RoutingProtocol> ();
    2.35    node->AggregateObject (agent);
    2.36    Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
    2.37    ipv4->AddRoutingProtocol (agent, 10);
     3.1 --- a/src/routing/olsr/olsr-agent-impl.cc	Mon Mar 23 14:29:31 2009 +0100
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,2681 +0,0 @@
     3.4 -/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     3.5 -/*
     3.6 - * Copyright (c) 2004 Francisco J. Ros 
     3.7 - * Copyright (c) 2007 INESC Porto
     3.8 - *
     3.9 - * This program is free software; you can redistribute it and/or modify
    3.10 - * it under the terms of the GNU General Public License version 2 as
    3.11 - * published by the Free Software Foundation;
    3.12 - *
    3.13 - * This program is distributed in the hope that it will be useful,
    3.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.16 - * GNU General Public License for more details.
    3.17 - *
    3.18 - * You should have received a copy of the GNU General Public License
    3.19 - * along with this program; if not, write to the Free Software
    3.20 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.21 - *
    3.22 - * Authors: Francisco J. Ros  <fjrm@dif.um.es>
    3.23 - *          Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
    3.24 - */
    3.25 -
    3.26 -
    3.27 -///
    3.28 -/// \file	OLSR.cc
    3.29 -/// \brief	Implementation of OLSR agent and related classes.
    3.30 -///
    3.31 -/// This is the main file of this software because %OLSR's behaviour is
    3.32 -/// implemented here.
    3.33 -///
    3.34 -
    3.35 -#define NS_LOG_APPEND_CONTEXT                                   \
    3.36 -  if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
    3.37 -
    3.38 -
    3.39 -#include "olsr-agent-impl.h"
    3.40 -#include "ns3/socket-factory.h"
    3.41 -#include "ns3/udp-socket-factory.h"
    3.42 -#include "ns3/simulator.h"
    3.43 -#include "ns3/log.h"
    3.44 -#include "ns3/random-variable.h"
    3.45 -#include "ns3/inet-socket-address.h"
    3.46 -#include "ns3/boolean.h"
    3.47 -#include "ns3/uinteger.h"
    3.48 -#include "ns3/enum.h"
    3.49 -#include "ns3/trace-source-accessor.h"
    3.50 -#include "ns3/ipv4-header.h"
    3.51 -
    3.52 -/********** Useful macros **********/
    3.53 -
    3.54 -///
    3.55 -/// \brief Gets the delay between a given time and the current time.
    3.56 -///
    3.57 -/// If given time is previous to the current one, then this macro returns
    3.58 -/// a number close to 0. This is used for scheduling events at a certain moment.
    3.59 -///
    3.60 -#define DELAY(time) (((time) < (Simulator::Now ())) ? Seconds (0.000001) : \
    3.61 -                     (time - Simulator::Now () + Seconds (0.000001)))
    3.62 -
    3.63 -
    3.64 -
    3.65 -///
    3.66 -/// \brief Period at which a node must cite every link and every neighbor.
    3.67 -///
    3.68 -/// We only use this value in order to define OLSR_NEIGHB_HOLD_TIME.
    3.69 -///
    3.70 -#define OLSR_REFRESH_INTERVAL	Seconds (2)
    3.71 -
    3.72 -
    3.73 -/********** Holding times **********/
    3.74 -
    3.75 -/// Neighbor holding time.
    3.76 -#define OLSR_NEIGHB_HOLD_TIME	(Scalar (3) * OLSR_REFRESH_INTERVAL)
    3.77 -/// Top holding time.
    3.78 -#define OLSR_TOP_HOLD_TIME	(Scalar (3) * m_tcInterval)
    3.79 -/// Dup holding time.
    3.80 -#define OLSR_DUP_HOLD_TIME	Seconds (30)
    3.81 -/// MID holding time.
    3.82 -#define OLSR_MID_HOLD_TIME	(Scalar (3) * m_midInterval)
    3.83 -
    3.84 -
    3.85 -/********** Link types **********/
    3.86 -
    3.87 -/// Unspecified link type.
    3.88 -#define OLSR_UNSPEC_LINK	0
    3.89 -/// Asymmetric link type.
    3.90 -#define OLSR_ASYM_LINK		1
    3.91 -/// Symmetric link type.
    3.92 -#define OLSR_SYM_LINK		2
    3.93 -/// Lost link type.
    3.94 -#define OLSR_LOST_LINK		3
    3.95 -
    3.96 -/********** Neighbor types **********/
    3.97 -
    3.98 -/// Not neighbor type.
    3.99 -#define OLSR_NOT_NEIGH		0
   3.100 -/// Symmetric neighbor type.
   3.101 -#define OLSR_SYM_NEIGH		1
   3.102 -/// Asymmetric neighbor type.
   3.103 -#define OLSR_MPR_NEIGH		2
   3.104 -
   3.105 -
   3.106 -/********** Willingness **********/
   3.107 -
   3.108 -/// Willingness for forwarding packets from other nodes: never.
   3.109 -#define OLSR_WILL_NEVER		0
   3.110 -/// Willingness for forwarding packets from other nodes: low.
   3.111 -#define OLSR_WILL_LOW		1
   3.112 -/// Willingness for forwarding packets from other nodes: medium.
   3.113 -#define OLSR_WILL_DEFAULT	3
   3.114 -/// Willingness for forwarding packets from other nodes: high.
   3.115 -#define OLSR_WILL_HIGH		6
   3.116 -/// Willingness for forwarding packets from other nodes: always.
   3.117 -#define OLSR_WILL_ALWAYS	7
   3.118 -
   3.119 -
   3.120 -/********** Miscellaneous constants **********/
   3.121 -
   3.122 -/// Maximum allowed jitter.
   3.123 -#define OLSR_MAXJITTER		(m_helloInterval.GetSeconds () / 4)
   3.124 -/// Maximum allowed sequence number.
   3.125 -#define OLSR_MAX_SEQ_NUM	65535
   3.126 -/// Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission.
   3.127 -#define JITTER (Seconds (UniformVariable().GetValue (0, OLSR_MAXJITTER)))
   3.128 -
   3.129 -
   3.130 -#define OLSR_PORT_NUMBER 698
   3.131 -/// Maximum number of messages per packet.
   3.132 -#define OLSR_MAX_MSGS		64
   3.133 -
   3.134 -/// Maximum number of hellos per message (4 possible link types * 3 possible nb types).
   3.135 -#define OLSR_MAX_HELLOS		12
   3.136 -
   3.137 -/// Maximum number of addresses advertised on a message.
   3.138 -#define OLSR_MAX_ADDRS		64
   3.139 -
   3.140 -
   3.141 -namespace ns3 {
   3.142 -namespace olsr {
   3.143 -
   3.144 -NS_LOG_COMPONENT_DEFINE ("OlsrAgent");
   3.145 -
   3.146 -
   3.147 -/********** OLSR class **********/
   3.148 -
   3.149 -NS_OBJECT_ENSURE_REGISTERED (AgentImpl);
   3.150 -
   3.151 -TypeId 
   3.152 -AgentImpl::GetTypeId (void)
   3.153 -{
   3.154 -  static TypeId tid = TypeId ("ns3::olsr::AgentImpl")
   3.155 -    .SetParent<Ipv4RoutingProtocol> ()
   3.156 -    .AddConstructor<AgentImpl> ()
   3.157 -    .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
   3.158 -                   TimeValue (Seconds (2)),
   3.159 -                   MakeTimeAccessor (&AgentImpl::m_helloInterval),
   3.160 -                   MakeTimeChecker ())
   3.161 -    .AddAttribute ("TcInterval", "TC messages emission interval.",
   3.162 -                   TimeValue (Seconds (5)),
   3.163 -                   MakeTimeAccessor (&AgentImpl::m_tcInterval),
   3.164 -                   MakeTimeChecker ())
   3.165 -    .AddAttribute ("MidInterval", "MID messages emission interval.  Normally it is equal to TcInterval.",
   3.166 -                   TimeValue (Seconds (5)),
   3.167 -                   MakeTimeAccessor (&AgentImpl::m_midInterval),
   3.168 -                   MakeTimeChecker ())
   3.169 -    .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.",
   3.170 -                   EnumValue (OLSR_WILL_DEFAULT),
   3.171 -                   MakeEnumAccessor (&AgentImpl::m_willingness),
   3.172 -                   MakeEnumChecker (OLSR_WILL_NEVER, "never",
   3.173 -                                    OLSR_WILL_LOW, "low",
   3.174 -                                    OLSR_WILL_DEFAULT, "default",
   3.175 -                                    OLSR_WILL_HIGH, "high",
   3.176 -                                    OLSR_WILL_ALWAYS, "always"))
   3.177 -    .AddTraceSource ("Rx", "Receive OLSR packet.",
   3.178 -                     MakeTraceSourceAccessor (&AgentImpl::m_rxPacketTrace))
   3.179 -    .AddTraceSource ("Tx", "Send OLSR packet.",
   3.180 -                     MakeTraceSourceAccessor (&AgentImpl::m_txPacketTrace))
   3.181 -    .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.",
   3.182 -		     MakeTraceSourceAccessor (&AgentImpl::m_routingTableChanged))
   3.183 -    ;
   3.184 -  return tid;
   3.185 -}
   3.186 -
   3.187 -
   3.188 -AgentImpl::AgentImpl ()
   3.189 -  :
   3.190 -  m_helloTimer (Timer::CANCEL_ON_DESTROY),
   3.191 -  m_tcTimer (Timer::CANCEL_ON_DESTROY),
   3.192 -  m_midTimer (Timer::CANCEL_ON_DESTROY)
   3.193 -{}
   3.194 -
   3.195 -AgentImpl::~AgentImpl ()
   3.196 -{}
   3.197 -
   3.198 -void
   3.199 -AgentImpl::SetNode (Ptr<Node> node)
   3.200 -{
   3.201 -  NS_LOG_DEBUG ("Created olsr::AgentImpl");
   3.202 -  m_helloTimer.SetFunction (&AgentImpl::HelloTimerExpire, this);
   3.203 -  m_tcTimer.SetFunction (&AgentImpl::TcTimerExpire, this);
   3.204 -  m_midTimer.SetFunction (&AgentImpl::MidTimerExpire, this);
   3.205 -  m_queuedMessagesTimer.SetFunction (&AgentImpl::SendQueuedMessages, this);
   3.206 -
   3.207 -  m_packetSequenceNumber = OLSR_MAX_SEQ_NUM;
   3.208 -  m_messageSequenceNumber = OLSR_MAX_SEQ_NUM;
   3.209 -  m_ansn = OLSR_MAX_SEQ_NUM;
   3.210 -
   3.211 -  m_linkTupleTimerFirstTime = true;
   3.212 -
   3.213 -  m_ipv4 = node->GetObject<Ipv4> ();
   3.214 -  NS_ASSERT (m_ipv4);
   3.215 -}
   3.216 -
   3.217 -void AgentImpl::DoDispose ()
   3.218 -{
   3.219 -  m_ipv4 = 0;
   3.220 -
   3.221 -  for (std::map< Ptr<Socket>, Ipv4Address >::iterator iter = m_socketAddresses.begin ();
   3.222 -       iter != m_socketAddresses.end (); iter++)
   3.223 -    {
   3.224 -      iter->first->Close ();
   3.225 -    }
   3.226 -  m_socketAddresses.clear ();
   3.227 -
   3.228 -  Ipv4RoutingProtocol::DoDispose ();
   3.229 -}
   3.230 -
   3.231 -void AgentImpl::Start ()
   3.232 -{
   3.233 -  if (m_mainAddress == Ipv4Address ())
   3.234 -    {
   3.235 -      Ipv4Address loopback ("127.0.0.1");
   3.236 -      for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
   3.237 -        {
   3.238 -          Ipv4Address addr = m_ipv4->GetAddress (i);
   3.239 -          if (addr != loopback)
   3.240 -            {
   3.241 -              m_mainAddress = addr;
   3.242 -              break;
   3.243 -            }
   3.244 -        }
   3.245 -
   3.246 -      NS_ASSERT (m_mainAddress != Ipv4Address ());
   3.247 -    }
   3.248 -
   3.249 -  NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
   3.250 -
   3.251 -  Ipv4Address loopback ("127.0.0.1");
   3.252 -  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
   3.253 -    {
   3.254 -      Ipv4Address addr = m_ipv4->GetAddress (i);
   3.255 -      if (addr == loopback)
   3.256 -        continue;
   3.257 -
   3.258 -      if (addr != m_mainAddress)
   3.259 -        {
   3.260 -          // Create never expiring interface association tuple entries for our
   3.261 -          // own network interfaces, so that GetMainAddress () works to
   3.262 -          // translate the node's own interface addresses into the main address.
   3.263 -          IfaceAssocTuple tuple;
   3.264 -          tuple.ifaceAddr = addr;
   3.265 -          tuple.mainAddr = m_mainAddress;
   3.266 -          AddIfaceAssocTuple (tuple);
   3.267 -          NS_ASSERT (GetMainAddress (addr) == m_mainAddress);
   3.268 -        }
   3.269 -
   3.270 -      // Create a socket to listen only on this interface
   3.271 -      Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (), 
   3.272 -        UdpSocketFactory::GetTypeId()); 
   3.273 -      socket->SetRecvCallback (MakeCallback (&AgentImpl::RecvOlsr,  this));
   3.274 -      if (socket->Bind (InetSocketAddress (addr, OLSR_PORT_NUMBER)))
   3.275 -        {
   3.276 -          NS_FATAL_ERROR ("Failed to bind() OLSR receive socket");
   3.277 -        }
   3.278 -      socket->Connect (InetSocketAddress (Ipv4Address (0xffffffff), OLSR_PORT_NUMBER));
   3.279 -      m_socketAddresses[socket] = addr;
   3.280 -    }
   3.281 -
   3.282 -  HelloTimerExpire ();
   3.283 -  TcTimerExpire ();
   3.284 -  MidTimerExpire ();
   3.285 -
   3.286 -  NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
   3.287 -}
   3.288 -
   3.289 -void AgentImpl::SetMainInterface (uint32_t interface)
   3.290 -{
   3.291 -  m_mainAddress = m_ipv4->GetAddress (interface);
   3.292 -}
   3.293 -
   3.294 -
   3.295 -//
   3.296 -// \brief Processes an incoming %OLSR packet following RFC 3626 specification.
   3.297 -void
   3.298 -AgentImpl::RecvOlsr (Ptr<Socket> socket)
   3.299 -{
   3.300 -  Ptr<Packet> receivedPacket;
   3.301 -  Address sourceAddress;
   3.302 -  receivedPacket = socket->RecvFrom (sourceAddress);
   3.303 -
   3.304 -  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
   3.305 -  Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
   3.306 -  Ipv4Address receiverIfaceAddr = m_socketAddresses[socket];
   3.307 -  NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
   3.308 -  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
   3.309 -                << senderIfaceAddr << " to " << receiverIfaceAddr);
   3.310 -  
   3.311 -  // All routing messages are sent from and to port RT_PORT,
   3.312 -  // so we check it.
   3.313 -  NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER);
   3.314 -  
   3.315 -  Ptr<Packet> packet = receivedPacket;
   3.316 -
   3.317 -  olsr::PacketHeader olsrPacketHeader;
   3.318 -  packet->RemoveHeader (olsrPacketHeader);
   3.319 -  NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ());
   3.320 -  uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize ();
   3.321 -
   3.322 -  MessageList messages;
   3.323 -  
   3.324 -  while (sizeLeft)
   3.325 -    {
   3.326 -      MessageHeader messageHeader;
   3.327 -      if (packet->RemoveHeader (messageHeader) == 0)
   3.328 -        NS_ASSERT (false);
   3.329 -      
   3.330 -      sizeLeft -= messageHeader.GetSerializedSize ();
   3.331 -
   3.332 -      NS_LOG_DEBUG ("Olsr Msg received with type "
   3.333 -                << std::dec << int (messageHeader.GetMessageType ())
   3.334 -                << " TTL=" << int (messageHeader.GetTimeToLive ())
   3.335 -                << " origAddr=" << messageHeader.GetOriginatorAddress ());
   3.336 -      messages.push_back (messageHeader);
   3.337 -    }
   3.338 -
   3.339 -  m_rxPacketTrace (olsrPacketHeader, messages);
   3.340 -
   3.341 -  for (MessageList::const_iterator messageIter = messages.begin ();
   3.342 -       messageIter != messages.end (); messageIter++)
   3.343 -    {
   3.344 -      const MessageHeader &messageHeader = *messageIter;
   3.345 -      // If ttl is less than or equal to zero, or
   3.346 -      // the receiver is the same as the originator,
   3.347 -      // the message must be silently dropped
   3.348 -      if (messageHeader.GetTimeToLive () == 0
   3.349 -          || messageHeader.GetOriginatorAddress () == m_mainAddress)
   3.350 -        {
   3.351 -          packet->RemoveAtStart (messageHeader.GetSerializedSize ()
   3.352 -                                 - messageHeader.GetSerializedSize ());
   3.353 -          continue;
   3.354 -        }
   3.355 -
   3.356 -      // If the message has been processed it must not be processed again
   3.357 -      bool do_forwarding = true;
   3.358 -      DuplicateTuple *duplicated = m_state.FindDuplicateTuple
   3.359 -        (messageHeader.GetOriginatorAddress (),
   3.360 -         messageHeader.GetMessageSequenceNumber ());
   3.361 -
   3.362 -      // Get main address of the peer, which may be different from the packet source address
   3.363 -//       const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ());
   3.364 -//       Ipv4Address peerMainAddress;
   3.365 -//       if (ifaceAssoc != NULL)
   3.366 -//         {
   3.367 -//           peerMainAddress = ifaceAssoc->mainAddr;
   3.368 -//         }
   3.369 -//       else
   3.370 -//         {
   3.371 -//           peerMainAddress = inetSourceAddr.GetIpv4 () ;
   3.372 -//         }
   3.373 -      
   3.374 -      if (duplicated == NULL)
   3.375 -        {
   3.376 -          switch (messageHeader.GetMessageType ())
   3.377 -            {
   3.378 -            case olsr::MessageHeader::HELLO_MESSAGE:
   3.379 -              NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
   3.380 -                            << "s OLSR node " << m_mainAddress
   3.381 -                            << " received HELLO message of size " << messageHeader.GetSerializedSize ());
   3.382 -              ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr);
   3.383 -              break;
   3.384 -
   3.385 -            case olsr::MessageHeader::TC_MESSAGE:
   3.386 -              NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
   3.387 -                            << "s OLSR node " << m_mainAddress
   3.388 -                            << " received TC message of size " << messageHeader.GetSerializedSize ());
   3.389 -              ProcessTc (messageHeader, senderIfaceAddr);
   3.390 -              break;
   3.391 -
   3.392 -            case olsr::MessageHeader::MID_MESSAGE:
   3.393 -              NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
   3.394 -                            << "s OLSR node " << m_mainAddress
   3.395 -                            <<  " received MID message of size " << messageHeader.GetSerializedSize ());
   3.396 -              ProcessMid (messageHeader, senderIfaceAddr);
   3.397 -              break;
   3.398 -
   3.399 -            default:
   3.400 -              NS_LOG_DEBUG ("OLSR message type " <<
   3.401 -                        int (messageHeader.GetMessageType ()) <<
   3.402 -                        " not implemented");
   3.403 -            }
   3.404 -        }
   3.405 -      else
   3.406 -        {
   3.407 -          NS_LOG_DEBUG ("OLSR message is duplicated, not reading it.");
   3.408 -      
   3.409 -          // If the message has been considered for forwarding, it should
   3.410 -          // not be retransmitted again
   3.411 -          for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin ();
   3.412 -               it != duplicated->ifaceList.end(); it++)
   3.413 -            {
   3.414 -              if (*it == receiverIfaceAddr)
   3.415 -                {
   3.416 -                  do_forwarding = false;
   3.417 -                  break;
   3.418 -                }
   3.419 -            }
   3.420 -        }
   3.421 -      
   3.422 -      if (do_forwarding)
   3.423 -        {
   3.424 -          // HELLO messages are never forwarded.
   3.425 -          // TC and MID messages are forwarded using the default algorithm.
   3.426 -          // Remaining messages are also forwarded using the default algorithm.
   3.427 -          if (messageHeader.GetMessageType ()  != olsr::MessageHeader::HELLO_MESSAGE)
   3.428 -            {
   3.429 -              ForwardDefault (messageHeader, duplicated,
   3.430 -                              receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
   3.431 -            }
   3.432 -        }
   3.433 -	
   3.434 -    }
   3.435 -
   3.436 -  // After processing all OLSR messages, we must recompute the routing table
   3.437 -  RoutingTableComputation ();
   3.438 -}
   3.439 -
   3.440 -///
   3.441 -/// \brief This auxiliary function (defined in RFC 3626) is used for calculating the MPR Set.
   3.442 -///
   3.443 -/// \param tuple the neighbor tuple which has the main address of the node we are going to calculate its degree to.
   3.444 -/// \return the degree of the node.
   3.445 -///
   3.446 -int
   3.447 -AgentImpl::Degree (NeighborTuple const &tuple)
   3.448 -{
   3.449 -  int degree = 0;
   3.450 -  for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin ();
   3.451 -       it != m_state.GetTwoHopNeighbors ().end (); it++)
   3.452 -    {
   3.453 -      TwoHopNeighborTuple const &nb2hop_tuple = *it;
   3.454 -      if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
   3.455 -        {
   3.456 -          const NeighborTuple *nb_tuple =
   3.457 -            m_state.FindNeighborTuple (nb2hop_tuple.neighborMainAddr);
   3.458 -          if (nb_tuple == NULL)
   3.459 -            degree++;
   3.460 -        }
   3.461 -    }
   3.462 -  return degree;
   3.463 -}
   3.464 -
   3.465 -///
   3.466 -/// \brief Computates MPR set of a node following RFC 3626 hints.
   3.467 -///
   3.468 -void
   3.469 -AgentImpl::MprComputation()
   3.470 -{
   3.471 -  NS_LOG_FUNCTION (this);
   3.472 -  
   3.473 -  // MPR computation should be done for each interface. See section 8.3.1
   3.474 -  // (RFC 3626) for details.
   3.475 -  MprSet mprSet;
   3.476 -	
   3.477 -  
   3.478 -  // N is the subset of neighbors of the node, which are
   3.479 -  // neighbor "of the interface I"
   3.480 -  NeighborSet N;
   3.481 -  for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin();
   3.482 -       neighbor != m_state.GetNeighbors ().end (); neighbor++)
   3.483 -    {
   3.484 -      if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
   3.485 -        {
   3.486 -          N.push_back (*neighbor);
   3.487 -        }
   3.488 -    }
   3.489 -	
   3.490 -  // N2 is the set of 2-hop neighbors reachable from "the interface
   3.491 -  // I", excluding:
   3.492 -  // (i)   the nodes only reachable by members of N with willingness WILL_NEVER
   3.493 -  // (ii)  the node performing the computation
   3.494 -  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
   3.495 -  //       link to this node on some interface.
   3.496 -  TwoHopNeighborSet N2;
   3.497 -  for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin ();
   3.498 -       twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++)
   3.499 -    {
   3.500 -      // excluding:
   3.501 -      // (ii)  the node performing the computation
   3.502 -      if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
   3.503 -        {
   3.504 -          continue;
   3.505 -        }
   3.506 -
   3.507 -      //  excluding:
   3.508 -      // (i)   the nodes only reachable by members of N with willingness WILL_NEVER      
   3.509 -      bool ok = false;
   3.510 -      for (NeighborSet::const_iterator neigh = N.begin ();
   3.511 -           neigh != N.end (); neigh++)
   3.512 -        {
   3.513 -          if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
   3.514 -            {
   3.515 -              if (neigh->willingness == OLSR_WILL_NEVER)
   3.516 -                {
   3.517 -                  ok = false;
   3.518 -                  break;
   3.519 -                }
   3.520 -              else
   3.521 -                {
   3.522 -                  ok = true;
   3.523 -                  break;
   3.524 -                }
   3.525 -            }
   3.526 -        }
   3.527 -      if (!ok)
   3.528 -        {
   3.529 -          continue;
   3.530 -        }
   3.531 -      
   3.532 -      // excluding:
   3.533 -      // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
   3.534 -      //       link to this node on some interface.
   3.535 -      for (NeighborSet::const_iterator neigh = N.begin ();
   3.536 -           neigh != N.end (); neigh++)
   3.537 -        {
   3.538 -          if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
   3.539 -            {
   3.540 -              ok = false;
   3.541 -              break;
   3.542 -            }
   3.543 -        }
   3.544 -
   3.545 -      if (ok)
   3.546 -        {
   3.547 -          N2.push_back (*twoHopNeigh);
   3.548 -        }
   3.549 -    }
   3.550 -
   3.551 -  NS_LOG_DEBUG ("Size of N2: " << N2.size ());  
   3.552 -
   3.553 -  // 1. Start with an MPR set made of all members of N with
   3.554 -  // N_willingness equal to WILL_ALWAYS
   3.555 -  for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
   3.556 -    {
   3.557 -      if (neighbor->willingness == OLSR_WILL_ALWAYS)
   3.558 -        {
   3.559 -          mprSet.insert (neighbor->neighborMainAddr);
   3.560 -          // (not in RFC but I think is needed: remove the 2-hop
   3.561 -          // neighbors reachable by the MPR from N2)
   3.562 -          for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
   3.563 -               twoHopNeigh != N2.end (); )
   3.564 -            {
   3.565 -              if (twoHopNeigh->neighborMainAddr == neighbor->neighborMainAddr)
   3.566 -                {
   3.567 -                  twoHopNeigh = N2.erase (twoHopNeigh);
   3.568 -                }
   3.569 -              else
   3.570 -                {
   3.571 -                  twoHopNeigh++;
   3.572 -                }
   3.573 -            }
   3.574 -        }
   3.575 -    }
   3.576 -  
   3.577 -  // 2. Calculate D(y), where y is a member of N, for all nodes in N.
   3.578 -  // (we do this later)
   3.579 -	
   3.580 -  // 3. Add to the MPR set those nodes in N, which are the *only*
   3.581 -  // nodes to provide reachability to a node in N2.
   3.582 -  std::set<Ipv4Address> coveredTwoHopNeighbors;
   3.583 -  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
   3.584 -    {
   3.585 -      NeighborSet::const_iterator onlyNeighbor = N.end ();
   3.586 -      
   3.587 -      for (NeighborSet::const_iterator neighbor = N.begin ();
   3.588 -           neighbor != N.end (); neighbor++)
   3.589 -        {
   3.590 -          if (neighbor->neighborMainAddr == twoHopNeigh->neighborMainAddr)
   3.591 -            {
   3.592 -              if (onlyNeighbor == N.end ())
   3.593 -                {
   3.594 -                  onlyNeighbor = neighbor;
   3.595 -                }
   3.596 -              else
   3.597 -                {
   3.598 -                  onlyNeighbor = N.end ();
   3.599 -                  break;
   3.600 -                }
   3.601 -            }
   3.602 -        }
   3.603 -      if (onlyNeighbor != N.end ())
   3.604 -        {
   3.605 -          mprSet.insert (onlyNeighbor->neighborMainAddr);
   3.606 -          coveredTwoHopNeighbors.insert (twoHopNeigh->twoHopNeighborAddr);
   3.607 -        }
   3.608 -    }
   3.609 -  // Remove the nodes from N2 which are now covered by a node in the MPR set.
   3.610 -  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
   3.611 -       twoHopNeigh != N2.end (); )
   3.612 -    {
   3.613 -      if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
   3.614 -        {
   3.615 -          twoHopNeigh = N2.erase (twoHopNeigh);
   3.616 -        }
   3.617 -      else
   3.618 -        {
   3.619 -          twoHopNeigh++;
   3.620 -        }
   3.621 -    }
   3.622 -	
   3.623 -  // 4. While there exist nodes in N2 which are not covered by at
   3.624 -  // least one node in the MPR set:
   3.625 -  while (N2.begin () != N2.end ())
   3.626 -    {
   3.627 -      // 4.1. For each node in N, calculate the reachability, i.e., the
   3.628 -      // number of nodes in N2 which are not yet covered by at
   3.629 -      // least one node in the MPR set, and which are reachable
   3.630 -      // through this 1-hop neighbor
   3.631 -      std::map<int, std::vector<const NeighborTuple *> > reachability;
   3.632 -      std::set<int> rs;
   3.633 -      for (NeighborSet::iterator it = N.begin(); it != N.end(); it++)
   3.634 -        {
   3.635 -          NeighborTuple const &nb_tuple = *it;
   3.636 -          int r = 0;
   3.637 -          for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++)
   3.638 -            {
   3.639 -              TwoHopNeighborTuple const &nb2hop_tuple = *it2;
   3.640 -              if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
   3.641 -                r++;
   3.642 -            }
   3.643 -          rs.insert (r);
   3.644 -          reachability[r].push_back (&nb_tuple);
   3.645 -        }
   3.646 -      
   3.647 -      // 4.2. Select as a MPR the node with highest N_willingness among
   3.648 -      // the nodes in N with non-zero reachability. In case of
   3.649 -      // multiple choice select the node which provides
   3.650 -      // reachability to the maximum number of nodes in N2. In
   3.651 -      // case of multiple nodes providing the same amount of
   3.652 -      // reachability, select the node as MPR whose D(y) is
   3.653 -      // greater. Remove the nodes from N2 which are now covered
   3.654 -      // by a node in the MPR set.
   3.655 -      NeighborTuple const *max = NULL;
   3.656 -      int max_r = 0;
   3.657 -      for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++)
   3.658 -        {
   3.659 -          int r = *it;
   3.660 -          if (r == 0)
   3.661 -            {
   3.662 -              continue;
   3.663 -            }
   3.664 -          for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin ();
   3.665 -               it2 != reachability[r].end (); it2++)
   3.666 -            {
   3.667 -              const NeighborTuple *nb_tuple = *it2;
   3.668 -              if (max == NULL || nb_tuple->willingness > max->willingness)
   3.669 -                {
   3.670 -                  max = nb_tuple;
   3.671 -                  max_r = r;
   3.672 -                }
   3.673 -              else if (nb_tuple->willingness == max->willingness)
   3.674 -                {
   3.675 -                  if (r > max_r)
   3.676 -                    {
   3.677 -                      max = nb_tuple;
   3.678 -                      max_r = r;
   3.679 -                    }
   3.680 -                  else if (r == max_r)
   3.681 -                    {
   3.682 -                      if (Degree (*nb_tuple) > Degree (*max))
   3.683 -                        {
   3.684 -                          max = nb_tuple;
   3.685 -                          max_r = r;
   3.686 -                        }
   3.687 -                    }
   3.688 -                }
   3.689 -            }
   3.690 -        }
   3.691 -
   3.692 -      if (max != NULL)
   3.693 -        {
   3.694 -          mprSet.insert (max->neighborMainAddr);
   3.695 -          for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
   3.696 -               twoHopNeigh != N2.end (); )
   3.697 -            {
   3.698 -              if (twoHopNeigh->neighborMainAddr == max->neighborMainAddr)
   3.699 -                {
   3.700 -                  twoHopNeigh = N2.erase (twoHopNeigh);
   3.701 -                }
   3.702 -              else
   3.703 -                {
   3.704 -                  twoHopNeigh++;
   3.705 -                }
   3.706 -            }
   3.707 -        }
   3.708 -    }
   3.709 -
   3.710 -#ifdef NS3_LOG_ENABLE
   3.711 -  {
   3.712 -    std::ostringstream os;
   3.713 -    os << "[";
   3.714 -    for (MprSet::const_iterator iter = mprSet.begin ();
   3.715 -         iter != mprSet.end (); iter++)
   3.716 -      {
   3.717 -        MprSet::const_iterator next = iter;
   3.718 -        next++;
   3.719 -        os << *iter;
   3.720 -        if (next != mprSet.end ())
   3.721 -          os << ", ";
   3.722 -      }
   3.723 -    os << "]";
   3.724 -    NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
   3.725 -  }
   3.726 -#endif
   3.727 -
   3.728 -  m_state.SetMprSet (mprSet);
   3.729 -}
   3.730 -
   3.731 -///
   3.732 -/// \brief Gets the main address associated with a given interface address.
   3.733 -///
   3.734 -/// \param iface_addr the interface address.
   3.735 -/// \return the corresponding main address.
   3.736 -///
   3.737 -Ipv4Address
   3.738 -AgentImpl::GetMainAddress (Ipv4Address iface_addr) const
   3.739 -{
   3.740 -  const IfaceAssocTuple *tuple =
   3.741 -    m_state.FindIfaceAssocTuple (iface_addr);
   3.742 -  
   3.743 -  if (tuple != NULL)
   3.744 -    return tuple->mainAddr;
   3.745 -  else
   3.746 -    return iface_addr;
   3.747 -}
   3.748 -
   3.749 -///
   3.750 -/// \brief Creates the routing table of the node following RFC 3626 hints.
   3.751 -///
   3.752 -void
   3.753 -AgentImpl::RoutingTableComputation ()
   3.754 -{
   3.755 -  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " s: Node " << m_mainAddress
   3.756 -                << ": RoutingTableComputation begin...");
   3.757 -
   3.758 -  // 1. All the entries from the routing table are removed.
   3.759 -  Clear ();
   3.760 -	
   3.761 -  // 2. The new routing entries are added starting with the
   3.762 -  // symmetric neighbors (h=1) as the destination nodes.
   3.763 -  const NeighborSet &neighborSet = m_state.GetNeighbors ();
   3.764 -  for (NeighborSet::const_iterator it = neighborSet.begin ();
   3.765 -       it != neighborSet.end(); it++)
   3.766 -    {
   3.767 -      NeighborTuple const &nb_tuple = *it;
   3.768 -      NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple);
   3.769 -      if (nb_tuple.status == NeighborTuple::STATUS_SYM)
   3.770 -        {
   3.771 -          bool nb_main_addr = false;
   3.772 -          const LinkTuple *lt = NULL;
   3.773 -          const LinkSet &linkSet = m_state.GetLinks ();
   3.774 -          for (LinkSet::const_iterator it2 = linkSet.begin();
   3.775 -               it2 != linkSet.end(); it2++)
   3.776 -            {
   3.777 -              LinkTuple const &link_tuple = *it2;
   3.778 -              NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple
   3.779 -                            << (link_tuple.time >= Simulator::Now ()? "" : " (expired)"));
   3.780 -              if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr)
   3.781 -                  && link_tuple.time >= Simulator::Now ())
   3.782 -                {
   3.783 -                  NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr
   3.784 -                                << " => adding routing table entry to neighbor");
   3.785 -                  lt = &link_tuple;
   3.786 -                  AddEntry (link_tuple.neighborIfaceAddr,
   3.787 -                            link_tuple.neighborIfaceAddr,
   3.788 -                            link_tuple.localIfaceAddr,
   3.789 -                            1);
   3.790 -                  if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
   3.791 -                    {
   3.792 -                      nb_main_addr = true;
   3.793 -                    }
   3.794 -                }
   3.795 -              else
   3.796 -                {
   3.797 -                  NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr)
   3.798 -                                << "; neighborMainAddr =  " << nb_tuple.neighborMainAddr
   3.799 -                                << "; expired=" << int (link_tuple.time < Simulator::Now ())
   3.800 -                                << " => IGNORE");
   3.801 -                }
   3.802 -            }
   3.803 -
   3.804 -          // If, in the above, no R_dest_addr is equal to the main
   3.805 -          // address of the neighbor, then another new routing entry
   3.806 -          // with MUST be added, with:
   3.807 -          //      R_dest_addr  = main address of the neighbor;
   3.808 -          //      R_next_addr  = L_neighbor_iface_addr of one of the
   3.809 -          //                     associated link tuple with L_time >= current time;
   3.810 -          //      R_dist       = 1;
   3.811 -          //      R_iface_addr = L_local_iface_addr of the
   3.812 -          //                     associated link tuple.
   3.813 -          if (!nb_main_addr && lt != NULL)
   3.814 -            {
   3.815 -              NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor "
   3.816 -                            "=> adding additional routing entry");
   3.817 -              AddEntry(nb_tuple.neighborMainAddr,
   3.818 -                       lt->neighborIfaceAddr,
   3.819 -                       lt->localIfaceAddr,
   3.820 -                       1);
   3.821 -            }
   3.822 -        }
   3.823 -    }
   3.824 -  
   3.825 -  //  3. for each node in N2, i.e., a 2-hop neighbor which is not a
   3.826 -  //  neighbor node or the node itself, and such that there exist at
   3.827 -  //  least one entry in the 2-hop neighbor set where
   3.828 -  //  N_neighbor_main_addr correspond to a neighbor node with
   3.829 -  //  willingness different of WILL_NEVER,
   3.830 -  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
   3.831 -  for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin ();
   3.832 -       it != twoHopNeighbors.end (); it++)
   3.833 -    {
   3.834 -      TwoHopNeighborTuple const &nb2hop_tuple = *it;
   3.835 -
   3.836 -      NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
   3.837 -
   3.838 -      // a 2-hop neighbor which is not a neighbor node or the node itself
   3.839 -      if (m_state.FindNeighborTuple (nb2hop_tuple.twoHopNeighborAddr))
   3.840 -        {
   3.841 -          NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped.");
   3.842 -          continue;
   3.843 -        }
   3.844 -
   3.845 -      if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
   3.846 -        {
   3.847 -          NS_LOG_LOGIC ("Two-hop neighbor is self; skipped.");
   3.848 -          continue;
   3.849 -        }
   3.850 -
   3.851 -      // ...and such that there exist at least one entry in the 2-hop
   3.852 -      // neighbor set where N_neighbor_main_addr correspond to a
   3.853 -      // neighbor node with willingness different of WILL_NEVER...
   3.854 -      bool nb2hopOk = false;
   3.855 -      for (NeighborSet::const_iterator neighbor = neighborSet.begin ();
   3.856 -           neighbor != neighborSet.end(); neighbor++)
   3.857 -        {
   3.858 -          if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr
   3.859 -              && neighbor->willingness != OLSR_WILL_NEVER)
   3.860 -            {
   3.861 -              nb2hopOk = true;
   3.862 -              break;
   3.863 -            }
   3.864 -        }
   3.865 -      if (!nb2hopOk)
   3.866 -        {
   3.867 -          NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor "
   3.868 -                        << nb2hop_tuple.twoHopNeighborAddr
   3.869 -                        << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr
   3.870 -                        << ", which was not found in the Neighbor Set.");
   3.871 -          continue;
   3.872 -        }
   3.873 -      
   3.874 -      // one selects one 2-hop tuple and creates one entry in the routing table with:
   3.875 -      //                R_dest_addr  =  the main address of the 2-hop neighbor;
   3.876 -      //                R_next_addr  = the R_next_addr of the entry in the
   3.877 -      //                               routing table with:
   3.878 -      //                                   R_dest_addr == N_neighbor_main_addr
   3.879 -      //                                                  of the 2-hop tuple;
   3.880 -      //                R_dist       = 2;
   3.881 -      //                R_iface_addr = the R_iface_addr of the entry in the
   3.882 -      //                               routing table with:
   3.883 -      //                                   R_dest_addr == N_neighbor_main_addr
   3.884 -      //                                                  of the 2-hop tuple;
   3.885 -      RoutingTableEntry entry;
   3.886 -      bool foundEntry = Lookup (nb2hop_tuple.neighborMainAddr, entry);
   3.887 -      if (foundEntry)
   3.888 -        {
   3.889 -          NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor.");
   3.890 -          AddEntry (nb2hop_tuple.twoHopNeighborAddr,
   3.891 -                                    entry.nextAddr,
   3.892 -                                    entry.interface,
   3.893 -                                    2);
   3.894 -        }
   3.895 -      else
   3.896 -        {
   3.897 -          NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor ("
   3.898 -                        << nb2hop_tuple.twoHopNeighborAddr
   3.899 -                        << " not found in the routing table)");
   3.900 -        }
   3.901 -    }
   3.902 -  
   3.903 -  for (uint32_t h = 2; ; h++)
   3.904 -    {
   3.905 -      bool added = false;
   3.906 -		
   3.907 -      // 3.1. For each topology entry in the topology table, if its
   3.908 -      // T_dest_addr does not correspond to R_dest_addr of any
   3.909 -      // route entry in the routing table AND its T_last_addr
   3.910 -      // corresponds to R_dest_addr of a route entry whose R_dist
   3.911 -      // is equal to h, then a new route entry MUST be recorded in
   3.912 -      // the routing table (if it does not already exist)
   3.913 -      const TopologySet &topology = m_state.GetTopologySet ();
   3.914 -      for (TopologySet::const_iterator it = topology.begin ();
   3.915 -           it != topology.end (); it++)
   3.916 -        {
   3.917 -          const TopologyTuple &topology_tuple = *it;
   3.918 -          NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple);
   3.919 -
   3.920 -          RoutingTableEntry destAddrEntry, lastAddrEntry;
   3.921 -          bool have_destAddrEntry = Lookup (topology_tuple.destAddr, destAddrEntry);
   3.922 -          bool have_lastAddrEntry = Lookup (topology_tuple.lastAddr, lastAddrEntry);
   3.923 -          if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
   3.924 -            {
   3.925 -              NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple.");
   3.926 -              // then a new route entry MUST be recorded in
   3.927 -              //                the routing table (if it does not already exist) where:
   3.928 -              //                     R_dest_addr  = T_dest_addr;
   3.929 -              //                     R_next_addr  = R_next_addr of the recorded
   3.930 -              //                                    route entry where:
   3.931 -              //                                    R_dest_addr == T_last_addr
   3.932 -              //                     R_dist       = h+1; and
   3.933 -              //                     R_iface_addr = R_iface_addr of the recorded
   3.934 -              //                                    route entry where:
   3.935 -              //                                       R_dest_addr == T_last_addr.
   3.936 -              AddEntry (topology_tuple.destAddr,
   3.937 -                        lastAddrEntry.nextAddr,
   3.938 -                        lastAddrEntry.interface,
   3.939 -                        h + 1);
   3.940 -              added = true;
   3.941 -            }
   3.942 -          else
   3.943 -            {
   3.944 -              NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: "
   3.945 -                            "have_destAddrEntry=" << have_destAddrEntry
   3.946 -                            << " have_lastAddrEntry=" << have_lastAddrEntry
   3.947 -                            << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance
   3.948 -                            << " (h=" << h << ")");
   3.949 -            }
   3.950 -        }
   3.951 -      
   3.952 -      if (!added)
   3.953 -        break;
   3.954 -    }
   3.955 -
   3.956 -  // 4. For each entry in the multiple interface association base
   3.957 -  // where there exists a routing entry such that:
   3.958 -  //	R_dest_addr  == I_main_addr  (of the multiple interface association entry)
   3.959 -  // AND there is no routing entry such that:
   3.960 -  //	R_dest_addr  == I_iface_addr
   3.961 -  const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
   3.962 -  for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
   3.963 -       it != ifaceAssocSet.end (); it++)
   3.964 -    {
   3.965 -      IfaceAssocTuple const &tuple = *it;
   3.966 -      RoutingTableEntry entry1, entry2;
   3.967 -      bool have_entry1 = Lookup (tuple.mainAddr, entry1);
   3.968 -      bool have_entry2 = Lookup (tuple.ifaceAddr, entry2);
   3.969 -      if (have_entry1 && !have_entry2)
   3.970 -        {
   3.971 -          // then a route entry is created in the routing table with:
   3.972 -          //       R_dest_addr  =  I_iface_addr (of the multiple interface
   3.973 -          //                                     association entry)
   3.974 -          //       R_next_addr  =  R_next_addr  (of the recorded route entry)
   3.975 -          //       R_dist       =  R_dist       (of the recorded route entry)
   3.976 -          //       R_iface_addr =  R_iface_addr (of the recorded route entry).
   3.977 -          AddEntry (tuple.ifaceAddr,
   3.978 -                    entry1.nextAddr,
   3.979 -                    entry1.interface,
   3.980 -                    entry1.distance);
   3.981 -        }
   3.982 -    }
   3.983 -
   3.984 -  NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
   3.985 -  m_routingTableChanged (GetSize ());
   3.986 -}
   3.987 -
   3.988 -
   3.989 -///
   3.990 -/// \brief Processes a HELLO message following RFC 3626 specification.
   3.991 -///
   3.992 -/// Link sensing and population of the Neighbor Set, 2-hop Neighbor Set and MPR
   3.993 -/// Selector Set are performed.
   3.994 -///
   3.995 -/// \param msg the %OLSR message which contains the HELLO message.
   3.996 -/// \param receiver_iface the address of the interface where the message was received from.
   3.997 -/// \param sender_iface the address of the interface where the message was sent from.
   3.998 -///
   3.999 -void
  3.1000 -AgentImpl::ProcessHello (const olsr::MessageHeader &msg,
  3.1001 -                         const Ipv4Address &receiverIface,
  3.1002 -                         const Ipv4Address &senderIface)
  3.1003 -{
  3.1004 -  const olsr::MessageHeader::Hello &hello = msg.GetHello ();
  3.1005 -
  3.1006 -  LinkSensing (msg, hello, receiverIface, senderIface);
  3.1007 -
  3.1008 -#ifdef NS3_LOG_ENABLE
  3.1009 -  {
  3.1010 -    const LinkSet &links = m_state.GetLinks ();
  3.1011 -    NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  3.1012 -                  << "s ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
  3.1013 -    for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++)
  3.1014 -      {
  3.1015 -        NS_LOG_DEBUG(*link);
  3.1016 -      }
  3.1017 -    NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress);
  3.1018 -
  3.1019 -    const NeighborSet &neighbors = m_state.GetNeighbors ();
  3.1020 -    NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  3.1021 -                  << "s ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
  3.1022 -    for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
  3.1023 -      {
  3.1024 -        NS_LOG_DEBUG(*neighbor);
  3.1025 -      }
  3.1026 -    NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
  3.1027 -  }
  3.1028 -#endif
  3.1029 -
  3.1030 -  PopulateNeighborSet (msg, hello);
  3.1031 -  PopulateTwoHopNeighborSet (msg, hello);
  3.1032 -
  3.1033 -#ifdef NS3_LOG_ENABLE
  3.1034 -  {
  3.1035 -    const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
  3.1036 -    NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  3.1037 -                  << "s ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
  3.1038 -    for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin ();
  3.1039 -         tuple != twoHopNeighbors.end (); tuple++)
  3.1040 -      {
  3.1041 -        NS_LOG_DEBUG(*tuple);
  3.1042 -      }
  3.1043 -    NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
  3.1044 -  }
  3.1045 -#endif
  3.1046 -
  3.1047 -  MprComputation ();
  3.1048 -  PopulateMprSelectorSet (msg, hello);
  3.1049 -}
  3.1050 -
  3.1051 -///
  3.1052 -/// \brief Processes a TC message following RFC 3626 specification.
  3.1053 -///
  3.1054 -/// The Topology Set is updated (if needed) with the information of
  3.1055 -/// the received TC message.
  3.1056 -///
  3.1057 -/// \param msg the %OLSR message which contains the TC message.
  3.1058 -/// \param sender_iface the address of the interface where the message was sent from.
  3.1059 -///
  3.1060 -void
  3.1061 -AgentImpl::ProcessTc (const olsr::MessageHeader &msg,
  3.1062 -                      const Ipv4Address &senderIface)
  3.1063 -{
  3.1064 -  const olsr::MessageHeader::Tc &tc = msg.GetTc ();
  3.1065 -  Time now = Simulator::Now ();
  3.1066 -	
  3.1067 -  // 1. If the sender interface of this message is not in the symmetric
  3.1068 -  // 1-hop neighborhood of this node, the message MUST be discarded.
  3.1069 -  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
  3.1070 -  if (link_tuple == NULL)
  3.1071 -    return;
  3.1072 -	
  3.1073 -  // 2. If there exist some tuple in the topology set where:
  3.1074 -  // 	T_last_addr == originator address AND
  3.1075 -  // 	T_seq       >  ANSN,
  3.1076 -  // then further processing of this TC message MUST NOT be
  3.1077 -  // performed.
  3.1078 -  const TopologyTuple *topologyTuple =
  3.1079 -    m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.ansn);
  3.1080 -  if (topologyTuple != NULL)
  3.1081 -    return;
  3.1082 -	
  3.1083 -  // 3. All tuples in the topology set where:
  3.1084 -  //	T_last_addr == originator address AND
  3.1085 -  //	T_seq       <  ANSN
  3.1086 -  // MUST be removed from the topology set.
  3.1087 -  m_state.EraseOlderTopologyTuples (msg.GetOriginatorAddress (), tc.ansn);
  3.1088 -
  3.1089 -  // 4. For each of the advertised neighbor main address received in
  3.1090 -  // the TC message:
  3.1091 -  for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin ();
  3.1092 -       i != tc.neighborAddresses.end (); i++)
  3.1093 -    {
  3.1094 -      const Ipv4Address &addr = *i;
  3.1095 -      // 4.1. If there exist some tuple in the topology set where:
  3.1096 -      // 	T_dest_addr == advertised neighbor main address, AND
  3.1097 -      // 	T_last_addr == originator address,
  3.1098 -      // then the holding time of that tuple MUST be set to:
  3.1099 -      // 	T_time      =  current time + validity time.
  3.1100 -      TopologyTuple *topologyTuple =
  3.1101 -        m_state.FindTopologyTuple (addr, msg.GetOriginatorAddress ());
  3.1102 -
  3.1103 -      if (topologyTuple != NULL)
  3.1104 -        {
  3.1105 -          topologyTuple->expirationTime = now + msg.GetVTime ();
  3.1106 -        }
  3.1107 -      else
  3.1108 -        {
  3.1109 -          // 4.2. Otherwise, a new tuple MUST be recorded in the topology
  3.1110 -          // set where:
  3.1111 -          //	T_dest_addr = advertised neighbor main address,
  3.1112 -          //	T_last_addr = originator address,
  3.1113 -          //	T_seq       = ANSN,
  3.1114 -          //	T_time      = current time + validity time.
  3.1115 -          TopologyTuple topologyTuple;;
  3.1116 -          topologyTuple.destAddr = addr;
  3.1117 -          topologyTuple.lastAddr = msg.GetOriginatorAddress ();
  3.1118 -          topologyTuple.sequenceNumber = tc.ansn;
  3.1119 -          topologyTuple.expirationTime = now + msg.GetVTime ();
  3.1120 -          AddTopologyTuple (topologyTuple);
  3.1121 -
  3.1122 -          // Schedules topology tuple deletion
  3.1123 -          m_events.Track (Simulator::Schedule (DELAY (topologyTuple.expirationTime),
  3.1124 -                                               &AgentImpl::TopologyTupleTimerExpire,
  3.1125 -                                               this,
  3.1126 -                                               topologyTuple.destAddr,
  3.1127 -                                               topologyTuple.lastAddr));
  3.1128 -        }
  3.1129 -    }
  3.1130 -
  3.1131 -#ifdef NS3_LOG_ENABLE
  3.1132 -  {
  3.1133 -    const TopologySet &topology = m_state.GetTopologySet ();
  3.1134 -    NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  3.1135 -                  << "s ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
  3.1136 -    for (TopologySet::const_iterator tuple = topology.begin ();
  3.1137 -         tuple != topology.end (); tuple++)
  3.1138 -      {
  3.1139 -        NS_LOG_DEBUG (*tuple);
  3.1140 -      }
  3.1141 -    NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
  3.1142 -  }
  3.1143 -#endif
  3.1144 -}
  3.1145 -
  3.1146 -///
  3.1147 -/// \brief Processes a MID message following RFC 3626 specification.
  3.1148 -///
  3.1149 -/// The Interface Association Set is updated (if needed) with the information
  3.1150 -/// of the received MID message.
  3.1151 -///
  3.1152 -/// \param msg the %OLSR message which contains the MID message.
  3.1153 -/// \param sender_iface the address of the interface where the message was sent from.
  3.1154 -///
  3.1155 -void
  3.1156 -AgentImpl::ProcessMid (const olsr::MessageHeader &msg,
  3.1157 -                       const Ipv4Address &senderIface)
  3.1158 -{
  3.1159 -  const olsr::MessageHeader::Mid &mid = msg.GetMid ();
  3.1160 -  Time now = Simulator::Now ();
  3.1161 -  
  3.1162 -  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
  3.1163 -  // 1. If the sender interface of this message is not in the symmetric
  3.1164 -  // 1-hop neighborhood of this node, the message MUST be discarded.
  3.1165 -  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
  3.1166 -  if (linkTuple == NULL)
  3.1167 -    {
  3.1168 -      NS_LOG_LOGIC ("Node " << m_mainAddress <<
  3.1169 -                    ": the sender interface of this message is not in the "
  3.1170 -                    "symmetric 1-hop neighborhood of this node,"
  3.1171 -                    " the message MUST be discarded.");
  3.1172 -      return;
  3.1173 -    }
  3.1174 -	
  3.1175 -  // 2. For each interface address listed in the MID message
  3.1176 -  for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
  3.1177 -       i != mid.interfaceAddresses.end (); i++)
  3.1178 -    {
  3.1179 -      bool updated = false;
  3.1180 -      IfaceAssocSet &ifaceAssoc = m_state.GetIfaceAssocSetMutable ();
  3.1181 -      for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin();
  3.1182 -           tuple != ifaceAssoc.end(); tuple++)
  3.1183 -        {
  3.1184 -          if (tuple->ifaceAddr == *i
  3.1185 -              && tuple->mainAddr == msg.GetOriginatorAddress ())
  3.1186 -            {
  3.1187 -              NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple);
  3.1188 -              tuple->time = now + msg.GetVTime ();
  3.1189 -              updated = true;
  3.1190 -            }
  3.1191 -        }
  3.1192 -      if (!updated)
  3.1193 -        {
  3.1194 -          IfaceAssocTuple tuple;
  3.1195 -          tuple.ifaceAddr = *i;
  3.1196 -          tuple.mainAddr = msg.GetOriginatorAddress ();
  3.1197 -          tuple.time = now + msg.GetVTime ();
  3.1198 -          AddIfaceAssocTuple (tuple);
  3.1199 -          NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple);
  3.1200 -          // Schedules iface association tuple deletion
  3.1201 -          Simulator::Schedule (DELAY (tuple.time),
  3.1202 -                               &AgentImpl::IfaceAssocTupleTimerExpire, this, tuple.ifaceAddr);
  3.1203 -        }
  3.1204 -    }
  3.1205 -
  3.1206 -  // 3. (not part of the RFC) iterate over all NeighborTuple's and
  3.1207 -  // TwoHopNeighborTuples, update the neighbor addresses taking into account
  3.1208 -  // the new MID information.
  3.1209 -  NeighborSet &neighbors = m_state.GetNeighbors ();
  3.1210 -  for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end(); neighbor++)
  3.1211 -    {
  3.1212 -      neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr);
  3.1213 -    }
  3.1214 -
  3.1215 -  TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
  3.1216 -  for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin ();
  3.1217 -       twoHopNeighbor != twoHopNeighbors.end(); twoHopNeighbor++)
  3.1218 -    {
  3.1219 -      twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr);
  3.1220 -      twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr);
  3.1221 -    }
  3.1222 -  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
  3.1223 -}
  3.1224 -
  3.1225 -
  3.1226 -///
  3.1227 -/// \brief OLSR's default forwarding algorithm.
  3.1228 -///
  3.1229 -/// See RFC 3626 for details.
  3.1230 -///
  3.1231 -/// \param p the %OLSR packet which has been received.
  3.1232 -/// \param msg the %OLSR message which must be forwarded.
  3.1233 -/// \param dup_tuple NULL if the message has never been considered for forwarding,
  3.1234 -/// or a duplicate tuple in other case.
  3.1235 -/// \param local_iface the address of the interface where the message was received from.
  3.1236 -///
  3.1237 -void
  3.1238 -AgentImpl::ForwardDefault (olsr::MessageHeader olsrMessage,
  3.1239 -                               DuplicateTuple *duplicated,
  3.1240 -                               const Ipv4Address &localIface,
  3.1241 -                               const Ipv4Address &senderAddress)
  3.1242 -{
  3.1243 -  Time now = Simulator::Now ();
  3.1244 -  
  3.1245 -  // If the sender interface address is not in the symmetric
  3.1246 -  // 1-hop neighborhood the message must not be forwarded
  3.1247 -  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
  3.1248 -  if (linkTuple == NULL)
  3.1249 -    return;
  3.1250 -
  3.1251 -  // If the message has already been considered for forwarding,
  3.1252 -  // it must not be retransmitted again
  3.1253 -  if (duplicated != NULL && duplicated->retransmitted)
  3.1254 -    {
  3.1255 -      NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received"
  3.1256 -                    " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
  3.1257 -      return;
  3.1258 -    }
  3.1259 -	
  3.1260 -  // If the sender interface address is an interface address
  3.1261 -  // of a MPR selector of this node and ttl is greater than 1,
  3.1262 -  // the message must be retransmitted
  3.1263 -  bool retransmitted = false;
  3.1264 -  if (olsrMessage.GetTimeToLive () > 1)
  3.1265 -    {
  3.1266 -      const MprSelectorTuple *mprselTuple =
  3.1267 -        m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
  3.1268 -      if (mprselTuple != NULL)
  3.1269 -        {
  3.1270 -          olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1);
  3.1271 -          olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1);
  3.1272 -          // We have to introduce a random delay to avoid
  3.1273 -          // synchronization with neighbors.
  3.1274 -          QueueMessage (olsrMessage, JITTER);
  3.1275 -          retransmitted = true;
  3.1276 -        }
  3.1277 -    }
  3.1278 -	
  3.1279 -  // Update duplicate tuple...
  3.1280 -  if (duplicated != NULL)
  3.1281 -    {
  3.1282 -      duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
  3.1283 -      duplicated->retransmitted = retransmitted;
  3.1284 -      duplicated->ifaceList.push_back (localIface);
  3.1285 -    }
  3.1286 -  // ...or create a new one
  3.1287 -  else
  3.1288 -    {
  3.1289 -      DuplicateTuple newDup;
  3.1290 -      newDup.address = olsrMessage.GetOriginatorAddress ();
  3.1291 -      newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber ();
  3.1292 -      newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
  3.1293 -      newDup.retransmitted = retransmitted;
  3.1294 -      newDup.ifaceList.push_back (localIface);
  3.1295 -      AddDuplicateTuple (newDup);
  3.1296 -      // Schedule dup tuple deletion
  3.1297 -      Simulator::Schedule (OLSR_DUP_HOLD_TIME,
  3.1298 -                           &AgentImpl::DupTupleTimerExpire, this,
  3.1299 -                           newDup.address, newDup.sequenceNumber);
  3.1300 -    }
  3.1301 -}
  3.1302 -
  3.1303 -///
  3.1304 -/// \brief Enques an %OLSR message which will be sent with a delay of (0, delay].
  3.1305 -///
  3.1306 -/// This buffering system is used in order to piggyback several %OLSR messages in
  3.1307 -/// a same %OLSR packet.
  3.1308 -///
  3.1309 -/// \param msg the %OLSR message which must be sent.
  3.1310 -/// \param delay maximum delay the %OLSR message is going to be buffered.
  3.1311 -///
  3.1312 -void
  3.1313 -AgentImpl::QueueMessage (const olsr::MessageHeader &message, Time delay)
  3.1314 -{
  3.1315 -  m_queuedMessages.push_back (message);
  3.1316 -  if (not m_queuedMessagesTimer.IsRunning ())
  3.1317 -    {
  3.1318 -      m_queuedMessagesTimer.SetDelay (delay);
  3.1319 -      m_queuedMessagesTimer.Schedule ();
  3.1320 -    }
  3.1321 -}
  3.1322 -
  3.1323 -void
  3.1324 -AgentImpl::SendPacket (Ptr<Packet> packet, 
  3.1325 -                       const MessageList &containedMessages)
  3.1326 -{
  3.1327 -  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet");
  3.1328 -
  3.1329 -  // Add a header
  3.1330 -  olsr::PacketHeader header;
  3.1331 -  header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ());
  3.1332 -  header.SetPacketSequenceNumber (GetPacketSequenceNumber ());
  3.1333 -  packet->AddHeader (header);
  3.1334 -
  3.1335 -  // Trace it
  3.1336 -  m_txPacketTrace (header, containedMessages);
  3.1337 -
  3.1338 -  // Send it
  3.1339 -  m_socketAddresses.begin ()->first->Send (packet);
  3.1340 -}
  3.1341 -
  3.1342 -///
  3.1343 -/// \brief Creates as many %OLSR packets as needed in order to send all buffered
  3.1344 -/// %OLSR messages.
  3.1345 -///
  3.1346 -/// Maximum number of messages which can be contained in an %OLSR packet is
  3.1347 -/// dictated by OLSR_MAX_MSGS constant.
  3.1348 -///
  3.1349 -void
  3.1350 -AgentImpl::SendQueuedMessages ()
  3.1351 -{
  3.1352 -  Ptr<Packet> packet = Create<Packet> ();
  3.1353 -  int numMessages = 0;
  3.1354 -
  3.1355 -  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages");
  3.1356 -
  3.1357 -  MessageList msglist;
  3.1358 -
  3.1359 -  for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin ();
  3.1360 -       message != m_queuedMessages.end ();
  3.1361 -       message++)
  3.1362 -    {
  3.1363 -      Ptr<Packet> p = Create<Packet> ();
  3.1364 -      p->AddHeader (*message);
  3.1365 -      packet->AddAtEnd (p);
  3.1366 -      msglist.push_back (*message);
  3.1367 -      if (++numMessages == OLSR_MAX_MSGS)
  3.1368 -        {
  3.1369 -          SendPacket (packet, msglist);
  3.1370 -          msglist.clear ();
  3.1371 -          // Reset variables for next packet
  3.1372 -          numMessages = 0;
  3.1373 -          packet = Create<Packet> ();
  3.1374 -        }
  3.1375 -    }
  3.1376 -
  3.1377 -  if (packet->GetSize ())
  3.1378 -    {
  3.1379 -      SendPacket (packet, msglist);
  3.1380 -    }
  3.1381 -
  3.1382 -  m_queuedMessages.clear ();
  3.1383 -}
  3.1384 -
  3.1385 -///
  3.1386 -/// \brief Creates a new %OLSR HELLO message which is buffered for being sent later on.
  3.1387 -///
  3.1388 -void
  3.1389 -AgentImpl::SendHello ()
  3.1390 -{
  3.1391 -  NS_LOG_FUNCTION (this);
  3.1392 -  
  3.1393 -  olsr::MessageHeader msg;
  3.1394 -  Time now = Simulator::Now ();
  3.1395 -
  3.1396 -  msg.SetVTime (OLSR_NEIGHB_HOLD_TIME);
  3.1397 -  msg.SetOriginatorAddress (m_mainAddress);
  3.1398 -  msg.SetTimeToLive (1);
  3.1399 -  msg.SetHopCount (0);
  3.1400 -  msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
  3.1401 -  olsr::MessageHeader::Hello &hello = msg.GetHello ();
  3.1402 -
  3.1403 -  hello.SetHTime (Scalar (3) * m_helloInterval);
  3.1404 -  hello.willingness = m_willingness;
  3.1405 -
  3.1406 -  std::vector<olsr::MessageHeader::Hello::LinkMessage>
  3.1407 -    &linkMessages = hello.linkMessages;
  3.1408 -	
  3.1409 -  const LinkSet &links = m_state.GetLinks ();
  3.1410 -  for (LinkSet::const_iterator link_tuple = links.begin ();
  3.1411 -       link_tuple != links.end (); link_tuple++)
  3.1412 -    {
  3.1413 -      if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress
  3.1414 -            && link_tuple->time >= now))
  3.1415 -        {
  3.1416 -          continue;
  3.1417 -        }
  3.1418 -
  3.1419 -      uint8_t link_type, nb_type = 0xff;
  3.1420 -			
  3.1421 -      // Establishes link type
  3.1422 -      if (link_tuple->symTime >= now)
  3.1423 -        {
  3.1424 -          link_type = OLSR_SYM_LINK;
  3.1425 -        }
  3.1426 -      else if (link_tuple->asymTime >= now)
  3.1427 -        {
  3.1428 -          link_type = OLSR_ASYM_LINK;
  3.1429 -        }
  3.1430 -      else
  3.1431 -        {
  3.1432 -          link_type = OLSR_LOST_LINK;
  3.1433 -        }
  3.1434 -      // Establishes neighbor type.
  3.1435 -      if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
  3.1436 -        {
  3.1437 -          nb_type = OLSR_MPR_NEIGH;
  3.1438 -          NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
  3.1439 -                        << " to be MPR_NEIGH.");
  3.1440 -        }
  3.1441 -      else
  3.1442 -        {
  3.1443 -          bool ok = false;
  3.1444 -          for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin ();
  3.1445 -               nb_tuple != m_state.GetNeighbors ().end ();
  3.1446 -               nb_tuple++)
  3.1447 -            {
  3.1448 -              if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr))
  3.1449 -                {
  3.1450 -                  if (nb_tuple->status == NeighborTuple::STATUS_SYM)
  3.1451 -                    {
  3.1452 -                      NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
  3.1453 -                                    << " to be SYM_NEIGH.");
  3.1454 -                      nb_type = OLSR_SYM_NEIGH;
  3.1455 -                    }
  3.1456 -                  else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
  3.1457 -                    {
  3.1458 -                      nb_type = OLSR_NOT_NEIGH;
  3.1459 -                      NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
  3.1460 -                                    << " to be NOT_NEIGH.");
  3.1461 -                    }
  3.1462 -                  else
  3.1463 -                    {
  3.1464 -                      NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n");
  3.1465 -                    }
  3.1466 -                  ok = true;
  3.1467 -                  break;
  3.1468 -                }
  3.1469 -            }
  3.1470 -          if (!ok)
  3.1471 -            {
  3.1472 -              NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
  3.1473 -              continue;
  3.1474 -            }
  3.1475 -        }
  3.1476 -
  3.1477 -      olsr::MessageHeader::Hello::LinkMessage linkMessage;
  3.1478 -      linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f);
  3.1479 -      linkMessage.neighborInterfaceAddresses.push_back
  3.1480 -        (link_tuple->neighborIfaceAddr);
  3.1481 -
  3.1482 -      std::vector<Ipv4Address> interfaces =
  3.1483 -        m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr);
  3.1484 -
  3.1485 -      linkMessage.neighborInterfaceAddresses.insert
  3.1486 -        (linkMessage.neighborInterfaceAddresses.end (),
  3.1487 -         interfaces.begin (), interfaces.end ());
  3.1488 -
  3.1489 -      linkMessages.push_back (linkMessage);
  3.1490 -    }
  3.1491 -  NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ())
  3.1492 -                << " (with " << int (linkMessages.size ()) << " link messages)");
  3.1493 -  QueueMessage (msg, JITTER);
  3.1494 -}
  3.1495 -
  3.1496 -///
  3.1497 -/// \brief Creates a new %OLSR TC message which is buffered for being sent later on.
  3.1498 -///
  3.1499 -void
  3.1500 -AgentImpl::SendTc ()
  3.1501 -{
  3.1502 -  NS_LOG_FUNCTION (this);
  3.1503 -  
  3.1504 -  olsr::MessageHeader msg;
  3.1505 -
  3.1506 -  msg.SetVTime (OLSR_TOP_HOLD_TIME);
  3.1507 -  msg.SetOriginatorAddress (m_mainAddress);
  3.1508 -  msg.SetTimeToLive (255);
  3.1509 -  msg.SetHopCount (0);
  3.1510 -  msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
  3.1511 -  
  3.1512 -  olsr::MessageHeader::Tc &tc = msg.GetTc ();
  3.1513 -  tc.ansn = m_ansn;
  3.1514 -  for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin();
  3.1515 -       mprsel_tuple != m_state.GetMprSelectors ().end(); mprsel_tuple++)
  3.1516 -    {
  3.1517 -      tc.neighborAddresses.push_back (mprsel_tuple->mainAddr);
  3.1518 -    }
  3.1519 -  QueueMessage (msg, JITTER);
  3.1520 -}
  3.1521 -
  3.1522 -///
  3.1523 -/// \brief Creates a new %OLSR MID message which is buffered for being sent later on.
  3.1524 -///
  3.1525 -void
  3.1526 -AgentImpl::SendMid ()
  3.1527 -{
  3.1528 -  olsr::MessageHeader msg;
  3.1529 -  olsr::MessageHeader::Mid &mid = msg.GetMid ();
  3.1530 -
  3.1531 -  // A node which has only a single interface address participating in
  3.1532 -  // the MANET (i.e., running OLSR), MUST NOT generate any MID
  3.1533 -  // message.
  3.1534 -
  3.1535 -  // A node with several interfaces, where only one is participating
  3.1536 -  // in the MANET and running OLSR (e.g., a node is connected to a
  3.1537 -  // wired network as well as to a MANET) MUST NOT generate any MID
  3.1538 -  // messages.
  3.1539 -
  3.1540 -  // A node with several interfaces, where more than one is
  3.1541 -  // participating in the MANET and running OLSR MUST generate MID
  3.1542 -  // messages as specified.
  3.1543 -
  3.1544 -  // [ Note: assuming here that all interfaces participate in the
  3.1545 -  // MANET; later we may want to make this configurable. ]
  3.1546 -
  3.1547 -  Ipv4Address loopback ("127.0.0.1");
  3.1548 -  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
  3.1549 -    {
  3.1550 -      Ipv4Address addr = m_ipv4->GetAddress (i);
  3.1551 -      if (addr != m_mainAddress && addr != loopback)
  3.1552 -        mid.interfaceAddresses.push_back (addr);
  3.1553 -    }
  3.1554 -  if (mid.interfaceAddresses.size () == 0)
  3.1555 -    return;
  3.1556 -  
  3.1557 -  msg.SetVTime (OLSR_MID_HOLD_TIME);
  3.1558 -  msg.SetOriginatorAddress (m_mainAddress);
  3.1559 -  msg.SetTimeToLive (255);
  3.1560 -  msg.SetHopCount (0);
  3.1561 -  msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
  3.1562 -
  3.1563 -  QueueMessage (msg, JITTER);
  3.1564 -}
  3.1565 -
  3.1566 -///
  3.1567 -/// \brief	Updates Link Set according to a new received HELLO message (following RFC 3626
  3.1568 -///		specification). Neighbor Set is also updated if needed.
  3.1569 -void
  3.1570 -AgentImpl::LinkSensing (const olsr::MessageHeader &msg,
  3.1571 -                        const olsr::MessageHeader::Hello &hello,
  3.1572 -                        const Ipv4Address &receiverIface,
  3.1573 -                        const Ipv4Address &senderIface)
  3.1574 -{
  3.1575 -  Time now = Simulator::Now ();
  3.1576 -  bool updated = false;
  3.1577 -  bool created = false;
  3.1578 -  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
  3.1579 -                << ": LinkSensing(receiverIface=" << receiverIface
  3.1580 -                << ", senderIface=" << senderIface << ") BEGIN");
  3.1581 -	
  3.1582 -  NS_ASSERT (msg.GetVTime () > Seconds (0));
  3.1583 -  LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
  3.1584 -  if (link_tuple == NULL)
  3.1585 -    {
  3.1586 -      LinkTuple newLinkTuple;
  3.1587 -      // We have to create a new tuple
  3.1588 -      newLinkTuple.neighborIfaceAddr = senderIface;
  3.1589 -      newLinkTuple.localIfaceAddr = receiverIface;
  3.1590 -      newLinkTuple.symTime = now - Seconds (1);
  3.1591 -      newLinkTuple.time = now + msg.GetVTime ();
  3.1592 -      link_tuple = &m_state.InsertLinkTuple (newLinkTuple);
  3.1593 -      created = true;
  3.1594 -      NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one");
  3.1595 -    }
  3.1596 -  else
  3.1597 -    {
  3.1598 -      NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
  3.1599 -      updated = true;
  3.1600 -    }
  3.1601 -	
  3.1602 -  link_tuple->asymTime = now + msg.GetVTime ();
  3.1603 -  for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
  3.1604 -         hello.linkMessages.begin ();
  3.1605 -       linkMessage != hello.linkMessages.end ();
  3.1606 -       linkMessage++)
  3.1607 -    {
  3.1608 -      int lt = linkMessage->linkCode & 0x03; // Link Type
  3.1609 -      int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type
  3.1610 -
  3.1611 -#ifdef NS3_LOG_ENABLE
  3.1612 -      const char *linkTypeName;
  3.1613 -      switch (lt)
  3.1614 -        {
  3.1615 -        case OLSR_UNSPEC_LINK: linkTypeName = "UNSPEC_LINK"; break;
  3.1616 -        case OLSR_ASYM_LINK: linkTypeName = "ASYM_LINK"; break;
  3.1617 -        case OLSR_SYM_LINK: linkTypeName = "SYM_LINK"; break;
  3.1618 -        case OLSR_LOST_LINK: linkTypeName = "LOST_LINK"; break;
  3.1619 -        default: linkTypeName = "(invalid value!)";
  3.1620 -        }
  3.1621 -
  3.1622 -      const char *neighborTypeName;
  3.1623 -      switch (nt)
  3.1624 -        {
  3.1625 -        case OLSR_NOT_NEIGH: neighborTypeName = "NOT_NEIGH"; break;
  3.1626 -        case OLSR_SYM_NEIGH: neighborTypeName = "SYM_NEIGH"; break;
  3.1627 -        case OLSR_MPR_NEIGH: neighborTypeName = "MPR_NEIGH"; break;
  3.1628 -        default: neighborTypeName = "(invalid value!)";
  3.1629 -        }
  3.1630 -
  3.1631 -      NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type "
  3.1632 -                    << lt << " (" << linkTypeName
  3.1633 -                    << ") and Neighbor Type " << nt
  3.1634 -                    << " (" << neighborTypeName << ")");
  3.1635 -#endif
  3.1636 -
  3.1637 -      // We must not process invalid advertised links
  3.1638 -      if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) ||
  3.1639 -          (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH
  3.1640 -           && nt != OLSR_NOT_NEIGH))
  3.1641 -        {
  3.1642 -          NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING");
  3.1643 -          continue;
  3.1644 -        }
  3.1645 -      
  3.1646 -      for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr =
  3.1647 -             linkMessage->neighborInterfaceAddresses.begin ();
  3.1648 -           neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end ();
  3.1649 -           neighIfaceAddr++)
  3.1650 -        {
  3.1651 -          NS_LOG_DEBUG ("   -> Neighbor: " << *neighIfaceAddr);
  3.1652 -          if (*neighIfaceAddr == receiverIface)
  3.1653 -            {
  3.1654 -              if (lt == OLSR_LOST_LINK)
  3.1655 -                {
  3.1656 -                  NS_LOG_LOGIC ("link is LOST => expiring it");
  3.1657 -                  link_tuple->symTime = now - Seconds (1);
  3.1658 -                  updated = true;
  3.1659 -                }
  3.1660 -              else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK)
  3.1661 -                {
  3.1662 -                  NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now"
  3.1663 -                                " (symTime being increased to " << now + msg.GetVTime ());
  3.1664 -                  link_tuple->symTime = now + msg.GetVTime ();
  3.1665 -                  link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
  3.1666 -                  updated = true;
  3.1667 -                }
  3.1668 -              else
  3.1669 -                {
  3.1670 -                  NS_FATAL_ERROR ("bad link type");
  3.1671 -                }
  3.1672 -              break;
  3.1673 -            }
  3.1674 -          else
  3.1675 -            {
  3.1676 -              NS_LOG_DEBUG ("     \\-> *neighIfaceAddr (" << *neighIfaceAddr
  3.1677 -                            << " != receiverIface (" << receiverIface << ") => IGNORING!");
  3.1678 -            }
  3.1679 -        }
  3.1680 -      NS_LOG_DEBUG ("Link tuple updated: " << int (updated));
  3.1681 -    }
  3.1682 -  link_tuple->time = std::max(link_tuple->time, link_tuple->asymTime);
  3.1683 -
  3.1684 -  if (updated)
  3.1685 -    {
  3.1686 -      LinkTupleUpdated (*link_tuple, hello.willingness);
  3.1687 -    }
  3.1688 -
  3.1689 -  // Schedules link tuple deletion
  3.1690 -  if (created && link_tuple != NULL)
  3.1691 -    {
  3.1692 -      LinkTupleAdded (*link_tuple, hello.willingness);
  3.1693 -      m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
  3.1694 -                                           &AgentImpl::LinkTupleTimerExpire, this,
  3.1695 -                                           link_tuple->neighborIfaceAddr));
  3.1696 -    }
  3.1697 -  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
  3.1698 -                << ": LinkSensing END");
  3.1699 -}
  3.1700 -
  3.1701 -///
  3.1702 -/// \brief	Updates the Neighbor Set according to the information contained in a new received
  3.1703 -///		HELLO message (following RFC 3626).
  3.1704 -void
  3.1705 -AgentImpl::PopulateNeighborSet (const olsr::MessageHeader &msg,
  3.1706 -                                const olsr::MessageHeader::Hello &hello)
  3.1707 -{
  3.1708 -  NeighborTuple *nb_tuple = m_state.FindNeighborTuple (msg.GetOriginatorAddress ());
  3.1709 -  if (nb_tuple != NULL)
  3.1710 -    {
  3.1711 -      nb_tuple->willingness = hello.willingness;
  3.1712 -    }
  3.1713 -}
  3.1714 -
  3.1715 -
  3.1716 -///
  3.1717 -/// \brief	Updates the 2-hop Neighbor Set according to the information contained in a new
  3.1718 -///		received HELLO message (following RFC 3626).
  3.1719 -void
  3.1720 -AgentImpl::PopulateTwoHopNeighborSet (const olsr::MessageHeader &msg,
  3.1721 -                                      const olsr::MessageHeader::Hello &hello)
  3.1722 -{
  3.1723 -  Time now = Simulator::Now ();
  3.1724 -
  3.1725 -  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
  3.1726 -	
  3.1727 -  for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
  3.1728 -       link_tuple != m_state.GetLinks ().end (); link_tuple++)
  3.1729 -    {
  3.1730 -      NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple);
  3.1731 -      if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ())
  3.1732 -        {
  3.1733 -          NS_LOG_LOGIC ("Link tuple ignored: "
  3.1734 -                        "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
  3.1735 -          NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): "
  3.1736 -                        << GetMainAddress (link_tuple->neighborIfaceAddr)
  3.1737 -                        << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ());
  3.1738 -          continue;
  3.1739 -        }
  3.1740 -
  3.1741 -      if (link_tuple->symTime < now)
  3.1742 -        {
  3.1743 -          NS_LOG_LOGIC ("Link tuple ignored: expired.");
  3.1744 -          continue;
  3.1745 -        }
  3.1746 -
  3.1747 -      typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
  3.1748 -      for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
  3.1749 -           linkMessage != hello.linkMessages.end (); linkMessage++)
  3.1750 -        {
  3.1751 -          int neighborType = (linkMessage->linkCode >> 2) & 0x3;
  3.1752 -#ifdef NS3_LOG_ENABLE
  3.1753 -          const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" };
  3.1754 -          const char *neighborTypeName = ((neighborType < 3)?
  3.1755 -                                          neighborTypeNames[neighborType]
  3.1756 -                                          : "(invalid value)");
  3.1757 -          NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType="
  3.1758 -                        << neighborType << " (" << neighborTypeName << ")");
  3.1759 -#endif
  3.1760 -
  3.1761 -          for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter =
  3.1762 -                 linkMessage->neighborInterfaceAddresses.begin ();
  3.1763 -               nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end ();
  3.1764 -               nb2hop_addr_iter++)
  3.1765 -            {
  3.1766 -              Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter);
  3.1767 -              NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: "
  3.1768 -                            << *nb2hop_addr_iter
  3.1769 -                            << " (main address is " << nb2hop_addr << ")");
  3.1770 -              if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH)
  3.1771 -                {
  3.1772 -                  // If the main address of the 2-hop neighbor address == main address
  3.1773 -                  // of the receiving node, silently discard the 2-hop
  3.1774 -                  // neighbor address.
  3.1775 -                  if (nb2hop_addr == m_routingAgentAddr)
  3.1776 -                    {
  3.1777 -                      NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)");
  3.1778 -                      continue;
  3.1779 -                    }
  3.1780 -
  3.1781 -                  // Otherwise, a 2-hop tuple is created
  3.1782 -                  TwoHopNeighborTuple *nb2hop_tuple =
  3.1783 -                    m_state.FindTwoHopNeighborTuple (msg.GetOriginatorAddress (), nb2hop_addr);
  3.1784 -                  NS_LOG_LOGIC ("Adding the 2-hop neighbor"
  3.1785 -                                << (nb2hop_tuple? " (refreshing existing entry)" : ""));
  3.1786 -                  if (nb2hop_tuple == NULL)
  3.1787 -                    {
  3.1788 -                      TwoHopNeighborTuple new_nb2hop_tuple;
  3.1789 -                      new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress ();
  3.1790 -                      new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
  3.1791 -                      new_nb2hop_tuple.expirationTime = now + msg.GetVTime ();
  3.1792 -                      AddTwoHopNeighborTuple (new_nb2hop_tuple);
  3.1793 -                      // Schedules nb2hop tuple deletion
  3.1794 -                      m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime),
  3.1795 -                                                           &AgentImpl::Nb2hopTupleTimerExpire, this,
  3.1796 -                                                           new_nb2hop_tuple.neighborMainAddr,
  3.1797 -                                                           new_nb2hop_tuple.twoHopNeighborAddr));
  3.1798 -                    }
  3.1799 -                  else
  3.1800 -                    {
  3.1801 -                      nb2hop_tuple->expirationTime = now + msg.GetVTime ();
  3.1802 -                    }
  3.1803 -                }
  3.1804 -              else if (neighborType == OLSR_NOT_NEIGH)
  3.1805 -                {
  3.1806 -                  // For each 2-hop node listed in the HELLO message
  3.1807 -                  // with Neighbor Type equal to NOT_NEIGH all 2-hop
  3.1808 -                  // tuples where: N_neighbor_main_addr == Originator
  3.1809 -                  // Address AND N_2hop_addr == main address of the
  3.1810 -                  // 2-hop neighbor are deleted.
  3.1811 -                  NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
  3.1812 -                  m_state.EraseTwoHopNeighborTuples (msg.GetOriginatorAddress (), nb2hop_addr);
  3.1813 -                }
  3.1814 -              else
  3.1815 -                {
  3.1816 -                  NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad"
  3.1817 -                                " neighbor type value: " << neighborType);
  3.1818 -                }
  3.1819 -            }
  3.1820 -        }
  3.1821 -    }
  3.1822 -
  3.1823 -  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
  3.1824 -}
  3.1825 -
  3.1826 -
  3.1827 -
  3.1828 -///
  3.1829 -/// \brief	Updates the MPR Selector Set according to the information contained in a new
  3.1830 -///		received HELLO message (following RFC 3626).
  3.1831 -void
  3.1832 -AgentImpl::PopulateMprSelectorSet (const olsr::MessageHeader &msg,
  3.1833 -                                       const olsr::MessageHeader::Hello &hello)
  3.1834 -{
  3.1835 -  NS_LOG_FUNCTION (this);
  3.1836 -  
  3.1837 -  Time now = Simulator::Now ();
  3.1838 -	
  3.1839 -  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
  3.1840 -  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
  3.1841 -       linkMessage != hello.linkMessages.end ();
  3.1842 -       linkMessage++)
  3.1843 -    {
  3.1844 -      int nt = linkMessage->linkCode >> 2;
  3.1845 -      if (nt == OLSR_MPR_NEIGH)
  3.1846 -        {
  3.1847 -          NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
  3.1848 -          
  3.1849 -          for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
  3.1850 -                 linkMessage->neighborInterfaceAddresses.begin ();
  3.1851 -               nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
  3.1852 -               nb_iface_addr++)
  3.1853 -            {
  3.1854 -              if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
  3.1855 -                {
  3.1856 -                  NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
  3.1857 -                  
  3.1858 -                  // We must create a new entry into the mpr selector set
  3.1859 -                  MprSelectorTuple *existing_mprsel_tuple =
  3.1860 -                    m_state.FindMprSelectorTuple (msg.GetOriginatorAddress ());
  3.1861 -                  if (existing_mprsel_tuple == NULL)
  3.1862 -                    {
  3.1863 -                      MprSelectorTuple mprsel_tuple;
  3.1864 -
  3.1865 -                      mprsel_tuple.mainAddr = msg.GetOriginatorAddress ();
  3.1866 -                      mprsel_tuple.expirationTime = now + msg.GetVTime ();
  3.1867 -                      AddMprSelectorTuple (mprsel_tuple);
  3.1868 -
  3.1869 -                      // Schedules mpr selector tuple deletion
  3.1870 -                      m_events.Track (Simulator::Schedule
  3.1871 -                                      (DELAY (mprsel_tuple.expirationTime),
  3.1872 -                                       &AgentImpl::MprSelTupleTimerExpire, this,
  3.1873 -                                       mprsel_tuple.mainAddr));
  3.1874 -                    }
  3.1875 -                  else
  3.1876 -                    {
  3.1877 -                      existing_mprsel_tuple->expirationTime = now + msg.GetVTime ();
  3.1878 -                    }
  3.1879 -                }
  3.1880 -            }
  3.1881 -        }
  3.1882 -    }
  3.1883 -  NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
  3.1884 -}
  3.1885 -
  3.1886 -
  3.1887 -#if 0
  3.1888 -///
  3.1889 -/// \brief	Drops a given packet because it couldn't be delivered to the corresponding
  3.1890 -///		destination by the MAC layer. This may cause a neighbor loss, and appropiate
  3.1891 -///		actions are then taken.
  3.1892 -///
  3.1893 -/// \param p the packet which couldn't be delivered by the MAC layer.
  3.1894 -///
  3.1895 -void
  3.1896 -OLSR::mac_failed(Ptr<Packet> p) {
  3.1897 -	double now		= Simulator::Now ();
  3.1898 -	struct hdr_ip* ih	= HDR_IP(p);
  3.1899 -	struct hdr_cmn* ch	= HDR_CMN(p);
  3.1900 -	
  3.1901 -	debug("%f: Node %d MAC Layer detects a breakage on link to %d\n",
  3.1902 -		now,
  3.1903 -		OLSR::node_id(ra_addr()),
  3.1904 -		OLSR::node_id(ch->next_hop()));
  3.1905 -	
  3.1906 -	if ((u_int32_t)ih->daddr() == IP_BROADCAST) {
  3.1907 -		drop(p, DROP_RTR_MAC_CALLBACK);
  3.1908 -		return;
  3.1909 -	}
  3.1910 -	
  3.1911 -	OLSR_link_tuple* link_tuple = state_.find_link_tuple(ch->next_hop());
  3.1912 -	if (link_tuple != NULL) {
  3.1913 -		link_tuple->lost_time()	= now + OLSR_NEIGHB_HOLD_TIME;
  3.1914 -		link_tuple->time()	= now + OLSR_NEIGHB_HOLD_TIME;
  3.1915 -		nb_loss(link_tuple);
  3.1916 -	}
  3.1917 -	drop(p, DROP_RTR_MAC_CALLBACK);
  3.1918 -}
  3.1919 -#endif
  3.1920 -
  3.1921 -
  3.1922 -
  3.1923 -
  3.1924 -///
  3.1925 -/// \brief Performs all actions needed when a neighbor loss occurs.
  3.1926 -///
  3.1927 -/// Neighbor Set, 2-hop Neighbor Set, MPR Set and MPR Selector Set are updated.
  3.1928 -///
  3.1929 -/// \param tuple link tuple with the information of the link to the neighbor which has been lost.
  3.1930 -///
  3.1931 -void
  3.1932 -AgentImpl::NeighborLoss (const LinkTuple &tuple)
  3.1933 -{
  3.1934 -  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  3.1935 -                << "s: OLSR Node " << m_mainAddress
  3.1936 -                << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
  3.1937 -  LinkTupleUpdated (tuple, OLSR_WILL_DEFAULT);
  3.1938 -  m_state.EraseTwoHopNeighborTuples (GetMainAddress (tuple.neighborIfaceAddr));
  3.1939 -  m_state.EraseMprSelectorTuples (GetMainAddress (tuple.neighborIfaceAddr));
  3.1940 -  
  3.1941 -  MprComputation ();
  3.1942 -  RoutingTableComputation ();
  3.1943 -}
  3.1944 -
  3.1945 -///
  3.1946 -/// \brief Adds a duplicate tuple to the Duplicate Set.
  3.1947 -///
  3.1948 -/// \param tuple the duplicate tuple to be added.
  3.1949 -///
  3.1950 -void
  3.1951 -AgentImpl::AddDuplicateTuple (const DuplicateTuple &tuple)
  3.1952 -{
  3.1953 -	/*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
  3.1954 -		Simulator::Now (),
  3.1955 -		OLSR::node_id(ra_addr()),
  3.1956 -		OLSR::node_id(tuple->addr()),
  3.1957 -		tuple->seq_num());*/
  3.1958 -  m_state.InsertDuplicateTuple (tuple);
  3.1959 -}
  3.1960 -
  3.1961 -///
  3.1962 -/// \brief Removes a duplicate tuple from the Duplicate Set.
  3.1963 -///
  3.1964 -/// \param tuple the duplicate tuple to be removed.
  3.1965 -///
  3.1966 -void
  3.1967 -AgentImpl::RemoveDuplicateTuple (const DuplicateTuple &tuple)
  3.1968 -{
  3.1969 -  /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
  3.1970 -    Simulator::Now (),
  3.1971 -    OLSR::node_id(ra_addr()),
  3.1972 -    OLSR::node_id(tuple->addr()),
  3.1973 -    tuple->seq_num());*/
  3.1974 -  m_state.EraseDuplicateTuple (tuple);
  3.1975 -}
  3.1976 -
  3.1977 -void
  3.1978 -AgentImpl::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness)
  3.1979 -{
  3.1980 -  // Creates associated neighbor tuple
  3.1981 -  NeighborTuple nb_tuple;
  3.1982 -  nb_tuple.neighborMainAddr = GetMainAddress (tuple.neighborIfaceAddr);
  3.1983 -  nb_tuple.willingness = willingness;
  3.1984 -
  3.1985 -  if (tuple.symTime >= Simulator::Now ())
  3.1986 -    {
  3.1987 -      nb_tuple.status = NeighborTuple::STATUS_SYM;
  3.1988 -    }
  3.1989 -  else
  3.1990 -    {
  3.1991 -      nb_tuple.status = NeighborTuple::STATUS_NOT_SYM;
  3.1992 -    }
  3.1993 -
  3.1994 -  AddNeighborTuple (nb_tuple);
  3.1995 -}
  3.1996 -
  3.1997 -///
  3.1998 -/// \brief Removes a link tuple from the Link Set.
  3.1999 -///
  3.2000 -/// \param tuple the link tuple to be removed.
  3.2001 -///
  3.2002 -void
  3.2003 -AgentImpl::RemoveLinkTuple (const LinkTuple &tuple)
  3.2004 -{
  3.2005 -  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  3.2006 -                << "s: OLSR Node " << m_mainAddress
  3.2007 -                << " LinkTuple " << tuple << " REMOVED.");
  3.2008 -
  3.2009 -  m_state.EraseLinkTuple (tuple);
  3.2010 -  m_state.EraseNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
  3.2011 -
  3.2012 -}
  3.2013 -
  3.2014 -///
  3.2015 -/// \brief	This function is invoked when a link tuple is updated. Its aim is to
  3.2016 -///		also update the corresponding neighbor tuple if it is needed.
  3.2017 -///
  3.2018 -/// \param tuple the link tuple which has been updated.
  3.2019 -///
  3.2020 -void
  3.2021 -AgentImpl::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
  3.2022 -{
  3.2023 -  // Each time a link tuple changes, the associated neighbor tuple must be recomputed
  3.2024 -
  3.2025 -  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  3.2026 -                << "s: OLSR Node " << m_mainAddress
  3.2027 -                << " LinkTuple " << tuple << " UPDATED.");
  3.2028 -
  3.2029 -  NeighborTuple *nb_tuple =
  3.2030 -    m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
  3.2031 -  
  3.2032 -  if (nb_tuple == NULL)
  3.2033 -    {
  3.2034 -      LinkTupleAdded (tuple, willingness);
  3.2035 -      nb_tuple = m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
  3.2036 -    }
  3.2037 -
  3.2038 -  if (nb_tuple != NULL)
  3.2039 -    {
  3.2040 -#ifdef NS3_LOG_ENABLE
  3.2041 -      int statusBefore = nb_tuple->status;
  3.2042 -#endif
  3.2043 -      if (tuple.symTime >= Simulator::Now ())
  3.2044 -        {
  3.2045 -          nb_tuple->status = NeighborTuple::STATUS_SYM;
  3.2046 -          NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_SYM; changed:"
  3.2047 -                        << int (statusBefore != nb_tuple->status));
  3.2048 -        }
  3.2049 -      else
  3.2050 -        {
  3.2051 -          nb_tuple->status = NeighborTuple::STATUS_NOT_SYM;
  3.2052 -          NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_NOT_SYM; changed:"
  3.2053 -                        << int (statusBefore != nb_tuple->status));
  3.2054 -        }
  3.2055 -    }
  3.2056 -  else
  3.2057 -    {
  3.2058 -      NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!");
  3.2059 -    }
  3.2060 -}
  3.2061 -
  3.2062 -///
  3.2063 -/// \brief Adds a neighbor tuple to the Neighbor Set.
  3.2064 -///
  3.2065 -/// \param tuple the neighbor tuple to be added.
  3.2066 -///
  3.2067 -void
  3.2068 -AgentImpl::AddNeighborTuple (const NeighborTuple &tuple)
  3.2069 -{
  3.2070 -//   debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n",
  3.2071 -//         Simulator::Now (),
  3.2072 -//         OLSR::node_id(ra_addr()),
  3.2073 -//         OLSR::node_id(tuple->neighborMainAddr),
  3.2074 -//         ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
  3.2075 -  
  3.2076 -  m_state.InsertNeighborTuple (tuple);
  3.2077 -  IncrementAnsn ();
  3.2078 -}
  3.2079 -
  3.2080 -///
  3.2081 -/// \brief Removes a neighbor tuple from the Neighbor Set.
  3.2082 -///
  3.2083 -/// \param tuple the neighbor tuple to be removed.
  3.2084 -///
  3.2085 -void
  3.2086 -AgentImpl::RemoveNeighborTuple (const NeighborTuple &tuple)
  3.2087 -{
  3.2088 -//   debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n",
  3.2089 -//         Simulator::Now (),
  3.2090 -//         OLSR::node_id(ra_addr()),
  3.2091 -//         OLSR::node_id(tuple->neighborMainAddr),
  3.2092 -//         ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
  3.2093 -	
  3.2094 -  m_state.EraseNeighborTuple (tuple);
  3.2095 -  IncrementAnsn ();
  3.2096 -}
  3.2097 -
  3.2098 -///
  3.2099 -/// \brief Adds a 2-hop neighbor tuple to the 2-hop Neighbor Set.
  3.2100 -///
  3.2101 -/// \param tuple the 2-hop neighbor tuple to be added.
  3.2102 -///
  3.2103 -void
  3.2104 -AgentImpl::AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
  3.2105 -{
  3.2106 -//   debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
  3.2107 -//         Simulator::Now (),
  3.2108 -//         OLSR::node_id(ra_addr()),
  3.2109 -//         OLSR::node_id(tuple->neighborMainAddr),
  3.2110 -//         OLSR::node_id(tuple->twoHopNeighborAddr));
  3.2111 -  
  3.2112 -  m_state.InsertTwoHopNeighborTuple (tuple);
  3.2113 -}
  3.2114 -
  3.2115 -///
  3.2116 -/// \brief Removes a 2-hop neighbor tuple from the 2-hop Neighbor Set.
  3.2117 -///
  3.2118 -/// \param tuple the 2-hop neighbor tuple to be removed.
  3.2119 -///
  3.2120 -void
  3.2121 -AgentImpl::RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
  3.2122 -{
  3.2123 -//   debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
  3.2124 -//         Simulator::Now (),
  3.2125 -//         OLSR::node_id(ra_addr()),
  3.2126 -//         OLSR::node_id(tuple->neighborMainAddr),
  3.2127 -//         OLSR::node_id(tuple->twoHopNeighborAddr));
  3.2128 -
  3.2129 -  m_state.EraseTwoHopNeighborTuple (tuple);
  3.2130 -}
  3.2131 -
  3.2132 -void
  3.2133 -AgentImpl::IncrementAnsn ()
  3.2134 -{
  3.2135 -  m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1);
  3.2136 -}
  3.2137 -
  3.2138 -///
  3.2139 -/// \brief Adds an MPR selector tuple to the MPR Selector Set.
  3.2140 -///
  3.2141 -/// Advertised Neighbor Sequence Number (ANSN) is also updated.
  3.2142 -///
  3.2143 -/// \param tuple the MPR selector tuple to be added.
  3.2144 -///
  3.2145 -void
  3.2146 -AgentImpl::AddMprSelectorTuple (const MprSelectorTuple  &tuple)
  3.2147 -{
  3.2148 -//   debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n",
  3.2149 -//         Simulator::Now (),
  3.2150 -//         OLSR::node_id(ra_addr()),
  3.2151 -//         OLSR::node_id(tuple->main_addr()));
  3.2152 -  
  3.2153 -  m_state.InsertMprSelectorTuple (tuple);
  3.2154 -  IncrementAnsn ();
  3.2155 -}
  3.2156 -
  3.2157 -///
  3.2158 -/// \brief Removes an MPR selector tuple from the MPR Selector Set.
  3.2159 -///
  3.2160 -/// Advertised Neighbor Sequence Number (ANSN) is also updated.
  3.2161 -///
  3.2162 -/// \param tuple the MPR selector tuple to be removed.
  3.2163 -///
  3.2164 -void
  3.2165 -AgentImpl::RemoveMprSelectorTuple (const MprSelectorTuple &tuple)
  3.2166 -{
  3.2167 -//   debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n",
  3.2168 -//         Simulator::Now (),
  3.2169 -//         OLSR::node_id(ra_addr()),
  3.2170 -//         OLSR::node_id(tuple->main_addr()));
  3.2171 -  
  3.2172 -  m_state.EraseMprSelectorTuple (tuple);
  3.2173 -  IncrementAnsn ();
  3.2174 -}
  3.2175 -
  3.2176 -///
  3.2177 -/// \brief Adds a topology tuple to the Topology Set.
  3.2178 -///
  3.2179 -/// \param tuple the topology tuple to be added.
  3.2180 -///
  3.2181 -void
  3.2182 -AgentImpl::AddTopologyTuple (const TopologyTuple &tuple)
  3.2183 -{
  3.2184 -//   debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
  3.2185 -//         Simulator::Now (),
  3.2186 -//         OLSR::node_id(ra_addr()),
  3.2187 -//         OLSR::node_id(tuple->dest_addr()),
  3.2188 -//         OLSR::node_id(tuple->last_addr()),
  3.2189 -//         tuple->seq());
  3.2190 -
  3.2191 -  m_state.InsertTopologyTuple(tuple);
  3.2192 -}
  3.2193 -
  3.2194 -///
  3.2195 -/// \brief Removes a topology tuple from the Topology Set.
  3.2196 -///
  3.2197 -/// \param tuple the topology tuple to be removed.
  3.2198 -///
  3.2199 -void
  3.2200 -AgentImpl::RemoveTopologyTuple (const TopologyTuple &tuple)
  3.2201 -{
  3.2202 -//   debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
  3.2203 -//         Simulator::Now (),
  3.2204 -//         OLSR::node_id(ra_addr()),
  3.2205 -//         OLSR::node_id(tuple->dest_addr()),
  3.2206 -//         OLSR::node_id(tuple->last_addr()),
  3.2207 -//         tuple->seq());
  3.2208 -
  3.2209 -  m_state.EraseTopologyTuple (tuple);
  3.2210 -}
  3.2211 -
  3.2212 -///
  3.2213 -/// \brief Adds an interface association tuple to the Interface Association Set.
  3.2214 -///
  3.2215 -/// \param tuple the interface association tuple to be added.
  3.2216 -///
  3.2217 -void
  3.2218 -AgentImpl::AddIfaceAssocTuple (const IfaceAssocTuple &tuple)
  3.2219 -{
  3.2220 -//   debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n",
  3.2221 -//         Simulator::Now (),
  3.2222 -//         OLSR::node_id(ra_addr()),
  3.2223 -//         OLSR::node_id(tuple->main_addr()),
  3.2224 -//         OLSR::node_id(tuple->iface_addr()));
  3.2225 -
  3.2226 -  m_state.InsertIfaceAssocTuple (tuple);
  3.2227 -}
  3.2228 -
  3.2229 -///
  3.2230 -/// \brief Removes an interface association tuple from the Interface Association Set.
  3.2231 -///
  3.2232 -/// \param tuple the interface association tuple to be removed.
  3.2233 -///
  3.2234 -void
  3.2235 -AgentImpl::RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple)
  3.2236 -{
  3.2237 -//   debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n",
  3.2238 -//         Simulator::Now (),
  3.2239 -//         OLSR::node_id(ra_addr()),
  3.2240 -//         OLSR::node_id(tuple->main_addr()),
  3.2241 -//         OLSR::node_id(tuple->iface_addr()));
  3.2242 -
  3.2243 -  m_state.EraseIfaceAssocTuple (tuple);
  3.2244 -}
  3.2245 -
  3.2246 -
  3.2247 -uint16_t AgentImpl::GetPacketSequenceNumber ()
  3.2248 -{
  3.2249 -  m_packetSequenceNumber = (m_packetSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1);
  3.2250 -  return m_packetSequenceNumber;
  3.2251 -}
  3.2252 -
  3.2253 -/// Increments message sequence number and returns the new value.
  3.2254 -uint16_t AgentImpl::GetMessageSequenceNumber ()
  3.2255 -{
  3.2256 -  m_messageSequenceNumber = (m_messageSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1);
  3.2257 -  return m_messageSequenceNumber;
  3.2258 -}
  3.2259 -
  3.2260 -
  3.2261 -///
  3.2262 -/// \brief Sends a HELLO message and reschedules the HELLO timer.
  3.2263 -/// \param e The event which has expired.
  3.2264 -///
  3.2265 -void
  3.2266 -AgentImpl::HelloTimerExpire ()
  3.2267 -{
  3.2268 -  SendHello ();
  3.2269 -  m_helloTimer.Schedule (m_helloInterval);
  3.2270 -}
  3.2271 -
  3.2272 -///
  3.2273 -/// \brief Sends a TC message (if there exists any MPR selector) and reschedules the TC timer.
  3.2274 -/// \param e The event which has expired.
  3.2275 -///
  3.2276 -void
  3.2277 -AgentImpl::TcTimerExpire ()
  3.2278 -{
  3.2279 -  if (m_state.GetMprSelectors ().size () > 0)
  3.2280 -    {
  3.2281 -      SendTc ();
  3.2282 -    }
  3.2283 -  else
  3.2284 -    {
  3.2285 -      NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR.");
  3.2286 -    }
  3.2287 -  m_tcTimer.Schedule (m_tcInterval);
  3.2288 -}
  3.2289 -
  3.2290 -///
  3.2291 -/// \brief Sends a MID message (if the node has more than one interface) and resets the MID timer.
  3.2292 -/// \warning Currently it does nothing because there is no support for multiple interfaces.
  3.2293 -/// \param e The event which has expired.
  3.2294 -///
  3.2295 -void
  3.2296 -AgentImpl::MidTimerExpire ()
  3.2297 -{
  3.2298 -  SendMid ();
  3.2299 -  m_midTimer.Schedule (m_midInterval);
  3.2300 -}
  3.2301 -
  3.2302 -///
  3.2303 -/// \brief Removes tuple if expired. Else timer is rescheduled to expire at tuple.expirationTime.
  3.2304 -///
  3.2305 -/// The task of actually removing the tuple is left to the OLSR agent.
  3.2306 -///
  3.2307 -/// \param tuple The tuple which has expired.
  3.2308 -///
  3.2309 -void
  3.2310 -AgentImpl::DupTupleTimerExpire (Ipv4Address address, uint16_t sequenceNumber)
  3.2311 -{
  3.2312 -  DuplicateTuple *tuple =
  3.2313 -    m_state.FindDuplicateTuple (address, sequenceNumber);
  3.2314 -  if (tuple == NULL)
  3.2315 -    {
  3.2316 -      return;
  3.2317 -    }
  3.2318 -  if (tuple->expirationTime < Simulator::Now ())
  3.2319 -    {
  3.2320 -      RemoveDuplicateTuple (*tuple);
  3.2321 -    }
  3.2322 -  else
  3.2323 -    {
  3.2324 -      m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  3.2325 -                                           &AgentImpl::DupTupleTimerExpire, this,
  3.2326 -                                           address, sequenceNumber));
  3.2327 -    }
  3.2328 -}
  3.2329 -
  3.2330 -///
  3.2331 -/// \brief Removes tuple_ if expired. Else if symmetric time
  3.2332 -/// has expired then it is assumed a neighbor loss and agent_->nb_loss()
  3.2333 -/// is called. In this case the timer is rescheduled to expire at
  3.2334 -/// tuple_->time(). Otherwise the timer is rescheduled to expire at
  3.2335 -/// the minimum between tuple_->time() and tuple_->sym_time().
  3.2336 -///
  3.2337 -/// The task of actually removing the tuple is left to the OLSR agent.
  3.2338 -///
  3.2339 -/// \param e The event which has expired.
  3.2340 -///
  3.2341 -void
  3.2342 -AgentImpl::LinkTupleTimerExpire (Ipv4Address neighborIfaceAddr)
  3.2343 -{
  3.2344 -  Time now = Simulator::Now ();
  3.2345 -
  3.2346 -  // the tuple parameter may be a stale copy; get a newer version from m_state
  3.2347 -  LinkTuple *tuple = m_state.FindLinkTuple (neighborIfaceAddr);
  3.2348 -  if (tuple == NULL)
  3.2349 -    {
  3.2350 -      return;
  3.2351 -    }
  3.2352 -  if (tuple->time < now)
  3.2353 -    {
  3.2354 -      RemoveLinkTuple (*tuple);
  3.2355 -    }
  3.2356 -  else if (tuple->symTime < now)
  3.2357 -    {
  3.2358 -      if (m_linkTupleTimerFirstTime)
  3.2359 -        m_linkTupleTimerFirstTime = false;
  3.2360 -      else
  3.2361 -        NeighborLoss (*tuple);
  3.2362 -
  3.2363 -      m_events.Track (Simulator::Schedule (DELAY (tuple->time),
  3.2364 -                                           &AgentImpl::LinkTupleTimerExpire, this,
  3.2365 -                                           neighborIfaceAddr));
  3.2366 -    }
  3.2367 -  else
  3.2368 -    {
  3.2369 -      m_events.Track (Simulator::Schedule (DELAY (std::min (tuple->time, tuple->symTime)),
  3.2370 -                                           &AgentImpl::LinkTupleTimerExpire, this,
  3.2371 -                                           neighborIfaceAddr));
  3.2372 -    }
  3.2373 -}
  3.2374 -
  3.2375 -///
  3.2376 -/// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
  3.2377 -///
  3.2378 -/// The task of actually removing the tuple is left to the OLSR agent.
  3.2379 -///
  3.2380 -/// \param e The event which has expired.
  3.2381 -///
  3.2382 -void
  3.2383 -AgentImpl::Nb2hopTupleTimerExpire (Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr)
  3.2384 -{
  3.2385 -  TwoHopNeighborTuple *tuple;
  3.2386 -  tuple = m_state.FindTwoHopNeighborTuple (neighborMainAddr, twoHopNeighborAddr);
  3.2387 -  if (tuple == NULL)
  3.2388 -    {
  3.2389 -      return;
  3.2390 -    }
  3.2391 -  if (tuple->expirationTime < Simulator::Now ())
  3.2392 -    {
  3.2393 -      RemoveTwoHopNeighborTuple (*tuple);
  3.2394 -    }
  3.2395 -  else
  3.2396 -    {
  3.2397 -      m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  3.2398 -                                           &AgentImpl::Nb2hopTupleTimerExpire,
  3.2399 -                                           this, neighborMainAddr, twoHopNeighborAddr));
  3.2400 -    }
  3.2401 -}
  3.2402 -
  3.2403 -///
  3.2404 -/// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
  3.2405 -///
  3.2406 -/// The task of actually removing the tuple is left to the OLSR agent.
  3.2407 -///
  3.2408 -/// \param e The event which has expired.
  3.2409 -///
  3.2410 -void
  3.2411 -AgentImpl::MprSelTupleTimerExpire (Ipv4Address mainAddr)
  3.2412 -{
  3.2413 -  MprSelectorTuple *tuple = m_state.FindMprSelectorTuple (mainAddr);
  3.2414 -  if (tuple == NULL)
  3.2415 -    {
  3.2416 -      return;
  3.2417 -    }
  3.2418 -  if (tuple->expirationTime < Simulator::Now ())
  3.2419 -    {
  3.2420 -      RemoveMprSelectorTuple (*tuple);
  3.2421 -    }
  3.2422 -  else
  3.2423 -    {
  3.2424 -      m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  3.2425 -                                           &AgentImpl::MprSelTupleTimerExpire,
  3.2426 -                                           this, mainAddr));
  3.2427 -    }
  3.2428 -}
  3.2429 -
  3.2430 -///
  3.2431 -/// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
  3.2432 -///
  3.2433 -/// The task of actually removing the tuple is left to the OLSR agent.
  3.2434 -///
  3.2435 -/// \param e The event which has expired.
  3.2436 -///
  3.2437 -void
  3.2438 -AgentImpl::TopologyTupleTimerExpire (Ipv4Address destAddr, Ipv4Address lastAddr)
  3.2439 -{
  3.2440 -  TopologyTuple *tuple = m_state.FindTopologyTuple (destAddr, lastAddr);
  3.2441 -  if (tuple == NULL)
  3.2442 -    {
  3.2443 -      return;
  3.2444 -    }
  3.2445 -  if (tuple->expirationTime < Simulator::Now ())
  3.2446 -    {
  3.2447 -      RemoveTopologyTuple (*tuple);
  3.2448 -    }
  3.2449 -  else
  3.2450 -    {
  3.2451 -      m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  3.2452 -                                           &AgentImpl::TopologyTupleTimerExpire,
  3.2453 -                                           this, tuple->destAddr, tuple->lastAddr));
  3.2454 -    }
  3.2455 -}
  3.2456 -
  3.2457 -///
  3.2458 -/// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time().
  3.2459 -/// \warning Actually this is never invoked because there is no support for multiple interfaces.
  3.2460 -/// \param e The event which has expired.
  3.2461 -///
  3.2462 -void
  3.2463 -AgentImpl::IfaceAssocTupleTimerExpire (Ipv4Address ifaceAddr)
  3.2464 -{
  3.2465 -  IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (ifaceAddr);
  3.2466 -  if (tuple == NULL)
  3.2467 -    {
  3.2468 -      return;
  3.2469 -    }
  3.2470 -  if (tuple->time < Simulator::Now ())
  3.2471 -    {
  3.2472 -      RemoveIfaceAssocTuple (*tuple);
  3.2473 -    }
  3.2474 -  else
  3.2475 -    {
  3.2476 -      m_events.Track (Simulator::Schedule (DELAY (tuple->time),
  3.2477 -                                           &AgentImpl::IfaceAssocTupleTimerExpire,
  3.2478 -                                           this, ifaceAddr));
  3.2479 -    }
  3.2480 -}
  3.2481 -
  3.2482 -///
  3.2483 -/// \brief Clears the routing table and frees the memory assigned to each one of its entries.
  3.2484 -///
  3.2485 -void
  3.2486 -AgentImpl::Clear ()
  3.2487 -{
  3.2488 -  NS_LOG_FUNCTION_NOARGS ();
  3.2489 -  m_table.clear ();
  3.2490 -}
  3.2491 -
  3.2492 -///
  3.2493 -/// \brief Deletes the entry whose destination address is given.
  3.2494 -/// \param dest	address of the destination node.
  3.2495 -///
  3.2496 -void
  3.2497 -AgentImpl::RemoveEntry (Ipv4Address const &dest)
  3.2498 -{
  3.2499 -  m_table.erase (dest);
  3.2500 -}
  3.2501 -
  3.2502 -///
  3.2503 -/// \brief Looks up an entry for the specified destination address.
  3.2504 -/// \param dest	destination address.
  3.2505 -/// \param outEntry output parameter to hold the routing entry result, if fuond
  3.2506 -/// \return	true if found, false if not found
  3.2507 -///
  3.2508 -bool
  3.2509 -AgentImpl::Lookup (Ipv4Address const &dest,
  3.2510 -                      RoutingTableEntry &outEntry) const
  3.2511 -{
  3.2512 -  // Get the iterator at "dest" position
  3.2513 -  std::map<Ipv4Address, RoutingTableEntry>::const_iterator it =
  3.2514 -    m_table.find (dest);
  3.2515 -  // If there is no route to "dest", return NULL
  3.2516 -  if (it == m_table.end ())
  3.2517 -    return false;
  3.2518 -  outEntry = it->second;
  3.2519 -  return true;
  3.2520 -}
  3.2521 -
  3.2522 -///
  3.2523 -/// \brief	Finds the appropiate entry which must be used in order to forward
  3.2524 -///		a data packet to a next hop (given a destination).
  3.2525 -///
  3.2526 -/// Imagine a routing table like this: [A,B] [B,C] [C,C]; being each pair of the
  3.2527 -/// form [dest addr,next-hop addr]. In this case, if this function is invoked with
  3.2528 -/// [A,B] then pair [C,C] is returned because C is the next hop that must be used
  3.2529 -/// to forward a data packet destined to A. That is, C is a neighbor of this node,
  3.2530 -/// but B isn't. This function finds the appropiate neighbor for forwarding a packet.
  3.2531 -///
  3.2532 -/// \param entry	the routing table entry which indicates the destination node
  3.2533 -///			we are interested in.
  3.2534 -/// \return		the appropiate routing table entry which indicates the next
  3.2535 -///			hop which must be used for forwarding a data packet, or NULL
  3.2536 -///			if there is no such entry.
  3.2537 -///
  3.2538 -bool
  3.2539 -AgentImpl::FindSendEntry (RoutingTableEntry const &entry,
  3.2540 -                             RoutingTableEntry &outEntry) const
  3.2541 -{
  3.2542 -  outEntry = entry;
  3.2543 -  while (outEntry.destAddr != outEntry.nextAddr)
  3.2544 -    {
  3.2545 -      if (not Lookup(outEntry.nextAddr, outEntry))
  3.2546 -        return false;
  3.2547 -    }
  3.2548 -  return true;
  3.2549 -}
  3.2550 -
  3.2551 -
  3.2552 -bool
  3.2553 -AgentImpl::RequestRoute (uint32_t ifIndex,
  3.2554 -                            const Ipv4Header &ipHeader,
  3.2555 -                            Ptr<Packet> packet,
  3.2556 -                            RouteReplyCallback routeReply)
  3.2557 -{
  3.2558 -  RoutingTableEntry entry1, entry2;
  3.2559 -  if (Lookup (ipHeader.GetDestination (), entry1))
  3.2560 -    {
  3.2561 -      bool foundSendEntry = FindSendEntry (entry1, entry2);
  3.2562 -      if (!foundSendEntry)
  3.2563 -        NS_FATAL_ERROR ("FindSendEntry failure");
  3.2564 -
  3.2565 -      Ipv4Route route = Ipv4Route::CreateHostRouteTo
  3.2566 -        (ipHeader.GetDestination (), entry2.nextAddr, entry2.interface);
  3.2567 -
  3.2568 -      NS_LOG_DEBUG ("Olsr node " << m_mainAddress
  3.2569 -                    << ": RouteRequest for dest=" << ipHeader.GetDestination ()
  3.2570 -                    << " --> nestHop=" << entry2.nextAddr
  3.2571 -                    << " interface=" << entry2.interface);
  3.2572 -      
  3.2573 -      routeReply (true, route, packet, ipHeader);
  3.2574 -      return true;
  3.2575 -    }
  3.2576 -  else
  3.2577 -    {
  3.2578 -#ifdef NS3_LOG_ENABLE
  3.2579 -      NS_LOG_DEBUG ("Olsr node " << m_mainAddress
  3.2580 -                    << ": RouteRequest for dest=" << ipHeader.GetDestination ()
  3.2581 -                    << " --> NOT FOUND; ** Dumping routing table...");
  3.2582 -      for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
  3.2583 -           iter != m_table.end (); iter++)
  3.2584 -        {
  3.2585 -          NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
  3.2586 -                        << " via interface " << iter->second.interface);
  3.2587 -        }
  3.2588 -
  3.2589 -      NS_LOG_DEBUG ("** Routing table dump end.");
  3.2590 -#endif
  3.2591 -      return false;
  3.2592 -    }
  3.2593 -}
  3.2594 -
  3.2595 -bool
  3.2596 -AgentImpl::RequestIfIndex (Ipv4Address destination,
  3.2597 -                              uint32_t& ifIndex)
  3.2598 -{
  3.2599 -  RoutingTableEntry entry1, entry2;
  3.2600 -  if (Lookup (destination, entry1))
  3.2601 -    {
  3.2602 -      bool foundSendEntry = FindSendEntry (entry1, entry2);
  3.2603 -      if (!foundSendEntry)
  3.2604 -        NS_FATAL_ERROR ("FindSendEntry failure");
  3.2605 -      ifIndex = entry2.interface;
  3.2606 -      return true;
  3.2607 -    }
  3.2608 -  else
  3.2609 -    {
  3.2610 -      return false;
  3.2611 -    }
  3.2612 -}
  3.2613 -
  3.2614 -
  3.2615 -///
  3.2616 -/// \brief Adds a new entry into the routing table.
  3.2617 -///
  3.2618 -/// If an entry for the given destination existed, it is deleted and freed.
  3.2619 -///
  3.2620 -/// \param dest		address of the destination node.
  3.2621 -/// \param next		address of the next hop node.
  3.2622 -/// \param iface	address of the local interface.
  3.2623 -/// \param dist		distance to the destination node.
  3.2624 -///
  3.2625 -void
  3.2626 -AgentImpl::AddEntry (Ipv4Address const &dest,
  3.2627 -                        Ipv4Address const &next,
  3.2628 -                        uint32_t interface,
  3.2629 -                        uint32_t distance)
  3.2630 -{
  3.2631 -  NS_LOG_FUNCTION (this << dest << next << interface << distance << m_mainAddress);
  3.2632 -
  3.2633 -  NS_ASSERT (distance > 0);
  3.2634 -
  3.2635 -  // Creates a new rt entry with specified values
  3.2636 -  RoutingTableEntry &entry = m_table[dest];
  3.2637 -
  3.2638 -  entry.destAddr = dest;
  3.2639 -  entry.nextAddr = next;
  3.2640 -  entry.interface = interface;
  3.2641 -  entry.distance = distance;
  3.2642 -}
  3.2643 -
  3.2644 -void
  3.2645 -AgentImpl::AddEntry (Ipv4Address const &dest,
  3.2646 -                        Ipv4Address const &next,
  3.2647 -                        Ipv4Address const &interfaceAddress,
  3.2648 -                        uint32_t distance)
  3.2649 -{
  3.2650 -  NS_LOG_FUNCTION (this << dest << next << interfaceAddress << distance << m_mainAddress);
  3.2651 -
  3.2652 -  NS_ASSERT (distance > 0);
  3.2653 -  NS_ASSERT (m_ipv4);
  3.2654 -
  3.2655 -  RoutingTableEntry entry;
  3.2656 -  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
  3.2657 -    {
  3.2658 -      if (m_ipv4->GetAddress (i) == interfaceAddress)
  3.2659 -        {
  3.2660 -          AddEntry (dest, next, i, distance);
  3.2661 -          return;
  3.2662 -        }
  3.2663 -    }
  3.2664 -  NS_ASSERT (false); // should not be reached
  3.2665 -  AddEntry (dest, next, 0, distance);
  3.2666 -}
  3.2667 -
  3.2668 -
  3.2669 -std::vector<RoutingTableEntry>
  3.2670 -AgentImpl::GetEntries () const
  3.2671 -{
  3.2672 -  std::vector<RoutingTableEntry> retval;
  3.2673 -  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
  3.2674 -       iter != m_table.end (); iter++)
  3.2675 -    {
  3.2676 -      retval.push_back (iter->second);
  3.2677 -    }
  3.2678 -  return retval;
  3.2679 -}
  3.2680 -
  3.2681 -
  3.2682 -}} // namespace olsr, ns3
  3.2683 -
  3.2684 -
     4.1 --- a/src/routing/olsr/olsr-agent-impl.h	Mon Mar 23 14:29:31 2009 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,236 +0,0 @@
     4.4 -/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     4.5 -/*
     4.6 - * Copyright (c) 2004 Francisco J. Ros 
     4.7 - * Copyright (c) 2007 INESC Porto
     4.8 - *
     4.9 - * This program is free software; you can redistribute it and/or modify
    4.10 - * it under the terms of the GNU General Public License version 2 as
    4.11 - * published by the Free Software Foundation;
    4.12 - *
    4.13 - * This program is distributed in the hope that it will be useful,
    4.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.16 - * GNU General Public License for more details.
    4.17 - *
    4.18 - * You should have received a copy of the GNU General Public License
    4.19 - * along with this program; if not, write to the Free Software
    4.20 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.21 - *
    4.22 - * Authors: Francisco J. Ros  <fjrm@dif.um.es>
    4.23 - *          Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
    4.24 - */
    4.25 -
    4.26 -
    4.27 -#ifndef __OLSR_AGENT_IMPL_H__
    4.28 -#define __OLSR_AGENT_IMPL_H__
    4.29 -
    4.30 -#include "olsr-header.h"
    4.31 -#include "olsr-state.h"
    4.32 -#include "olsr-repositories.h"
    4.33 -
    4.34 -#include "ns3/object.h"
    4.35 -#include "ns3/packet.h"
    4.36 -#include "ns3/node.h"
    4.37 -#include "ns3/socket.h"
    4.38 -#include "ns3/event-garbage-collector.h"
    4.39 -#include "ns3/timer.h"
    4.40 -#include "ns3/traced-callback.h"
    4.41 -#include "ns3/ipv4.h"
    4.42 -
    4.43 -#include <vector>
    4.44 -#include <map>
    4.45 -
    4.46 -
    4.47 -namespace ns3 {
    4.48 -namespace olsr {
    4.49 -
    4.50 -
    4.51 -/// An %OLSR's routing table entry.
    4.52 -struct RoutingTableEntry
    4.53 -{
    4.54 -  Ipv4Address destAddr;	///< Address of the destination node.
    4.55 -  Ipv4Address nextAddr;	///< Address of the next hop.
    4.56 -  uint32_t interface; ///< Interface index
    4.57 -  uint32_t distance; ///< Distance in hops to the destination.
    4.58 -
    4.59 -  RoutingTableEntry () : // default values
    4.60 -    destAddr (), nextAddr (),
    4.61 -    interface (0), distance (0) {};
    4.62 -};
    4.63 -
    4.64 -
    4.65 -class AgentImpl : public Ipv4RoutingProtocol
    4.66 -{
    4.67 -public:
    4.68 -  static TypeId GetTypeId (void);
    4.69 -
    4.70 -  AgentImpl ();
    4.71 -  virtual ~AgentImpl ();
    4.72 -
    4.73 -  void SetNode (Ptr<Node> node);
    4.74 -
    4.75 -  void Start ();
    4.76 -  void SetMainInterface (uint32_t interface);
    4.77 -
    4.78 -private:
    4.79 -  std::map<Ipv4Address, RoutingTableEntry> m_table; ///< Data structure for the routing table.
    4.80 -
    4.81 -  EventGarbageCollector m_events;
    4.82 -
    4.83 -  /// Address of the routing agent.
    4.84 -  Ipv4Address m_routingAgentAddr;
    4.85 -	
    4.86 -  /// Packets sequence number counter.
    4.87 -  uint16_t m_packetSequenceNumber;
    4.88 -  /// Messages sequence number counter.
    4.89 -  uint16_t m_messageSequenceNumber;
    4.90 -  /// Advertised Neighbor Set sequence number.
    4.91 -  uint16_t m_ansn;
    4.92 -  
    4.93 -  /// HELLO messages' emission interval.
    4.94 -  Time m_helloInterval;
    4.95 -  /// TC messages' emission interval.
    4.96 -  Time m_tcInterval;
    4.97 -  /// MID messages' emission interval.
    4.98 -  Time m_midInterval;
    4.99 -  /// Willingness for forwarding packets on behalf of other nodes.
   4.100 -  uint8_t m_willingness;
   4.101 -	
   4.102 -  /// Internal state with all needed data structs.
   4.103 -  OlsrState m_state;
   4.104 -
   4.105 -  Ptr<Ipv4> m_ipv4;
   4.106 -	
   4.107 -private:
   4.108 -
   4.109 -  void Clear ();
   4.110 -  uint32_t GetSize () const { return m_table.size (); }
   4.111 -  std::vector<RoutingTableEntry> GetEntries () const;
   4.112 -  void RemoveEntry (const Ipv4Address &dest);
   4.113 -  void AddEntry (const Ipv4Address &dest,
   4.114 -                 const Ipv4Address &next,
   4.115 -                 uint32_t interface,
   4.116 -                 uint32_t distance);
   4.117 -  void AddEntry (const Ipv4Address &dest,
   4.118 -                 const Ipv4Address &next,
   4.119 -                 const Ipv4Address &interfaceAddress,
   4.120 -                 uint32_t distance);
   4.121 -  bool Lookup (const Ipv4Address &dest,
   4.122 -               RoutingTableEntry &outEntry) const;
   4.123 -  bool FindSendEntry (const RoutingTableEntry &entry,
   4.124 -                      RoutingTableEntry &outEntry) const;
   4.125 -
   4.126 -  // From Ipv4RoutingProtocol
   4.127 -  virtual bool RequestRoute (uint32_t ifIndex,
   4.128 -                             const Ipv4Header &ipHeader,
   4.129 -                             Ptr<Packet> packet,
   4.130 -                             RouteReplyCallback routeReply);
   4.131 -  virtual bool RequestIfIndex (Ipv4Address destination, 
   4.132 -                               uint32_t& ifIndex);
   4.133 -
   4.134 -
   4.135 -  void DoDispose ();
   4.136 -
   4.137 -  void SendPacket (Ptr<Packet> packet, const MessageList &containedMessages);
   4.138 -	
   4.139 -  /// Increments packet sequence number and returns the new value.
   4.140 -  inline uint16_t GetPacketSequenceNumber ();
   4.141 -  /// Increments message sequence number and returns the new value.
   4.142 -  inline uint16_t GetMessageSequenceNumber ();
   4.143 -	
   4.144 -  void RecvOlsr (Ptr<Socket> socket);
   4.145 -
   4.146 -  void MprComputation ();
   4.147 -  void RoutingTableComputation ();
   4.148 -  Ipv4Address GetMainAddress (Ipv4Address iface_addr) const;
   4.149 -
   4.150 -  // Timer handlers
   4.151 -  Timer m_helloTimer;
   4.152 -  void HelloTimerExpire ();
   4.153 -  
   4.154 -  Timer m_tcTimer;
   4.155 -  void TcTimerExpire ();
   4.156 -
   4.157 -  Timer m_midTimer;
   4.158 -  void MidTimerExpire ();
   4.159 -
   4.160 -  void DupTupleTimerExpire (Ipv4Address address, uint16_t sequenceNumber);
   4.161 -  bool m_linkTupleTimerFirstTime;
   4.162 -  void LinkTupleTimerExpire (Ipv4Address neighborIfaceAddr);
   4.163 -  void Nb2hopTupleTimerExpire (Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr);
   4.164 -  void MprSelTupleTimerExpire (Ipv4Address mainAddr);
   4.165 -  void TopologyTupleTimerExpire (Ipv4Address destAddr, Ipv4Address lastAddr);
   4.166 -  void IfaceAssocTupleTimerExpire (Ipv4Address ifaceAddr);
   4.167 -
   4.168 -  void IncrementAnsn ();
   4.169 -
   4.170 -  /// A list of pending messages which are buffered awaiting for being sent.
   4.171 -  olsr::MessageList m_queuedMessages;
   4.172 -  Timer m_queuedMessagesTimer; // timer for throttling outgoing messages
   4.173 -
   4.174 -  void ForwardDefault (olsr::MessageHeader olsrMessage,
   4.175 -                       DuplicateTuple *duplicated,
   4.176 -                       const Ipv4Address &localIface,
   4.177 -                       const Ipv4Address &senderAddress);
   4.178 -  void QueueMessage (const olsr::MessageHeader &message, Time delay);
   4.179 -  void SendQueuedMessages ();
   4.180 -  void SendHello ();
   4.181 -  void SendTc ();
   4.182 -  void SendMid ();
   4.183 -
   4.184 -  void NeighborLoss (const LinkTuple &tuple);
   4.185 -  void AddDuplicateTuple (const DuplicateTuple &tuple);
   4.186 -  void RemoveDuplicateTuple (const DuplicateTuple &tuple);
   4.187 -  void LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness);
   4.188 -  void RemoveLinkTuple (const LinkTuple &tuple);
   4.189 -  void LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness);
   4.190 -  void AddNeighborTuple (const NeighborTuple &tuple);
   4.191 -  void RemoveNeighborTuple (const NeighborTuple &tuple);
   4.192 -  void AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple);
   4.193 -  void RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple);
   4.194 -  void AddMprSelectorTuple (const MprSelectorTuple  &tuple);
   4.195 -  void RemoveMprSelectorTuple (const MprSelectorTuple &tuple);
   4.196 -  void AddTopologyTuple (const TopologyTuple &tuple);
   4.197 -  void RemoveTopologyTuple (const TopologyTuple &tuple);
   4.198 -  void AddIfaceAssocTuple (const IfaceAssocTuple &tuple);
   4.199 -  void RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple);
   4.200 -
   4.201 -  void ProcessHello (const olsr::MessageHeader &msg,
   4.202 -                     const Ipv4Address &receiverIface,
   4.203 -                     const Ipv4Address &senderIface);
   4.204 -  void ProcessTc (const olsr::MessageHeader &msg,
   4.205 -                  const Ipv4Address &senderIface);
   4.206 -  void ProcessMid (const olsr::MessageHeader &msg,
   4.207 -                   const Ipv4Address &senderIface);
   4.208 -
   4.209 -  void LinkSensing (const olsr::MessageHeader &msg,
   4.210 -                    const olsr::MessageHeader::Hello &hello,
   4.211 -                    const Ipv4Address &receiverIface,
   4.212 -                    const Ipv4Address &sender_iface);
   4.213 -  void PopulateNeighborSet (const olsr::MessageHeader &msg,
   4.214 -                            const olsr::MessageHeader::Hello &hello);
   4.215 -  void PopulateTwoHopNeighborSet (const olsr::MessageHeader &msg,
   4.216 -                                  const olsr::MessageHeader::Hello &hello);
   4.217 -  void PopulateMprSelectorSet (const olsr::MessageHeader &msg,
   4.218 -                               const olsr::MessageHeader::Hello &hello);
   4.219 -
   4.220 -  int Degree (NeighborTuple const &tuple);
   4.221 -
   4.222 -  Ipv4Address m_mainAddress;
   4.223 -
   4.224 -  // One socket per interface, each bound to that interface's address
   4.225 -  // (reason: for OLSR Link Sensing we need to know on which interface
   4.226 -  // HELLO messages arrive)
   4.227 -  std::map< Ptr<Socket>, Ipv4Address > m_socketAddresses;
   4.228 -
   4.229 -  TracedCallback <const PacketHeader &,
   4.230 -                  const MessageList &> m_rxPacketTrace;
   4.231 -  TracedCallback <const PacketHeader &,
   4.232 -                  const MessageList &> m_txPacketTrace;
   4.233 -  TracedCallback <uint32_t> m_routingTableChanged;
   4.234 -
   4.235 -};
   4.236 -
   4.237 -}} // namespace ns3
   4.238 -
   4.239 -#endif
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/routing/olsr/olsr-routing-protocol.cc	Mon Mar 23 14:37:43 2009 +0100
     5.3 @@ -0,0 +1,2681 @@
     5.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     5.5 +/*
     5.6 + * Copyright (c) 2004 Francisco J. Ros 
     5.7 + * Copyright (c) 2007 INESC Porto
     5.8 + *
     5.9 + * This program is free software; you can redistribute it and/or modify
    5.10 + * it under the terms of the GNU General Public License version 2 as
    5.11 + * published by the Free Software Foundation;
    5.12 + *
    5.13 + * This program is distributed in the hope that it will be useful,
    5.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.16 + * GNU General Public License for more details.
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License
    5.19 + * along with this program; if not, write to the Free Software
    5.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.21 + *
    5.22 + * Authors: Francisco J. Ros  <fjrm@dif.um.es>
    5.23 + *          Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
    5.24 + */
    5.25 +
    5.26 +
    5.27 +///
    5.28 +/// \file	OLSR.cc
    5.29 +/// \brief	Implementation of OLSR agent and related classes.
    5.30 +///
    5.31 +/// This is the main file of this software because %OLSR's behaviour is
    5.32 +/// implemented here.
    5.33 +///
    5.34 +
    5.35 +#define NS_LOG_APPEND_CONTEXT                                   \
    5.36 +  if (GetObject<Node> ()) { std::clog << "[node " << GetObject<Node> ()->GetId () << "] "; }
    5.37 +
    5.38 +
    5.39 +#include "olsr-routing-protocol.h"
    5.40 +#include "ns3/socket-factory.h"
    5.41 +#include "ns3/udp-socket-factory.h"
    5.42 +#include "ns3/simulator.h"
    5.43 +#include "ns3/log.h"
    5.44 +#include "ns3/random-variable.h"
    5.45 +#include "ns3/inet-socket-address.h"
    5.46 +#include "ns3/boolean.h"
    5.47 +#include "ns3/uinteger.h"
    5.48 +#include "ns3/enum.h"
    5.49 +#include "ns3/trace-source-accessor.h"
    5.50 +#include "ns3/ipv4-header.h"
    5.51 +
    5.52 +/********** Useful macros **********/
    5.53 +
    5.54 +///
    5.55 +/// \brief Gets the delay between a given time and the current time.
    5.56 +///
    5.57 +/// If given time is previous to the current one, then this macro returns
    5.58 +/// a number close to 0. This is used for scheduling events at a certain moment.
    5.59 +///
    5.60 +#define DELAY(time) (((time) < (Simulator::Now ())) ? Seconds (0.000001) : \
    5.61 +                     (time - Simulator::Now () + Seconds (0.000001)))
    5.62 +
    5.63 +
    5.64 +
    5.65 +///
    5.66 +/// \brief Period at which a node must cite every link and every neighbor.
    5.67 +///
    5.68 +/// We only use this value in order to define OLSR_NEIGHB_HOLD_TIME.
    5.69 +///
    5.70 +#define OLSR_REFRESH_INTERVAL	Seconds (2)
    5.71 +
    5.72 +
    5.73 +/********** Holding times **********/
    5.74 +
    5.75 +/// Neighbor holding time.
    5.76 +#define OLSR_NEIGHB_HOLD_TIME	(Scalar (3) * OLSR_REFRESH_INTERVAL)
    5.77 +/// Top holding time.
    5.78 +#define OLSR_TOP_HOLD_TIME	(Scalar (3) * m_tcInterval)
    5.79 +/// Dup holding time.
    5.80 +#define OLSR_DUP_HOLD_TIME	Seconds (30)
    5.81 +/// MID holding time.
    5.82 +#define OLSR_MID_HOLD_TIME	(Scalar (3) * m_midInterval)
    5.83 +
    5.84 +
    5.85 +/********** Link types **********/
    5.86 +
    5.87 +/// Unspecified link type.
    5.88 +#define OLSR_UNSPEC_LINK	0
    5.89 +/// Asymmetric link type.
    5.90 +#define OLSR_ASYM_LINK		1
    5.91 +/// Symmetric link type.
    5.92 +#define OLSR_SYM_LINK		2
    5.93 +/// Lost link type.
    5.94 +#define OLSR_LOST_LINK		3
    5.95 +
    5.96 +/********** Neighbor types **********/
    5.97 +
    5.98 +/// Not neighbor type.
    5.99 +#define OLSR_NOT_NEIGH		0
   5.100 +/// Symmetric neighbor type.
   5.101 +#define OLSR_SYM_NEIGH		1
   5.102 +/// Asymmetric neighbor type.
   5.103 +#define OLSR_MPR_NEIGH		2
   5.104 +
   5.105 +
   5.106 +/********** Willingness **********/
   5.107 +
   5.108 +/// Willingness for forwarding packets from other nodes: never.
   5.109 +#define OLSR_WILL_NEVER		0
   5.110 +/// Willingness for forwarding packets from other nodes: low.
   5.111 +#define OLSR_WILL_LOW		1
   5.112 +/// Willingness for forwarding packets from other nodes: medium.
   5.113 +#define OLSR_WILL_DEFAULT	3
   5.114 +/// Willingness for forwarding packets from other nodes: high.
   5.115 +#define OLSR_WILL_HIGH		6
   5.116 +/// Willingness for forwarding packets from other nodes: always.
   5.117 +#define OLSR_WILL_ALWAYS	7
   5.118 +
   5.119 +
   5.120 +/********** Miscellaneous constants **********/
   5.121 +
   5.122 +/// Maximum allowed jitter.
   5.123 +#define OLSR_MAXJITTER		(m_helloInterval.GetSeconds () / 4)
   5.124 +/// Maximum allowed sequence number.
   5.125 +#define OLSR_MAX_SEQ_NUM	65535
   5.126 +/// Random number between [0-OLSR_MAXJITTER] used to jitter OLSR packet transmission.
   5.127 +#define JITTER (Seconds (UniformVariable().GetValue (0, OLSR_MAXJITTER)))
   5.128 +
   5.129 +
   5.130 +#define OLSR_PORT_NUMBER 698
   5.131 +/// Maximum number of messages per packet.
   5.132 +#define OLSR_MAX_MSGS		64
   5.133 +
   5.134 +/// Maximum number of hellos per message (4 possible link types * 3 possible nb types).
   5.135 +#define OLSR_MAX_HELLOS		12
   5.136 +
   5.137 +/// Maximum number of addresses advertised on a message.
   5.138 +#define OLSR_MAX_ADDRS		64
   5.139 +
   5.140 +
   5.141 +namespace ns3 {
   5.142 +namespace olsr {
   5.143 +
   5.144 +NS_LOG_COMPONENT_DEFINE ("OlsrAgent");
   5.145 +
   5.146 +
   5.147 +/********** OLSR class **********/
   5.148 +
   5.149 +NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
   5.150 +
   5.151 +TypeId 
   5.152 +RoutingProtocol::GetTypeId (void)
   5.153 +{
   5.154 +  static TypeId tid = TypeId ("ns3::olsr::RoutingProtocol")
   5.155 +    .SetParent<Ipv4RoutingProtocol> ()
   5.156 +    .AddConstructor<RoutingProtocol> ()
   5.157 +    .AddAttribute ("HelloInterval", "HELLO messages emission interval.",
   5.158 +                   TimeValue (Seconds (2)),
   5.159 +                   MakeTimeAccessor (&RoutingProtocol::m_helloInterval),
   5.160 +                   MakeTimeChecker ())
   5.161 +    .AddAttribute ("TcInterval", "TC messages emission interval.",
   5.162 +                   TimeValue (Seconds (5)),
   5.163 +                   MakeTimeAccessor (&RoutingProtocol::m_tcInterval),
   5.164 +                   MakeTimeChecker ())
   5.165 +    .AddAttribute ("MidInterval", "MID messages emission interval.  Normally it is equal to TcInterval.",
   5.166 +                   TimeValue (Seconds (5)),
   5.167 +                   MakeTimeAccessor (&RoutingProtocol::m_midInterval),
   5.168 +                   MakeTimeChecker ())
   5.169 +    .AddAttribute ("Willingness", "Willingness of a node to carry and forward traffic for other nodes.",
   5.170 +                   EnumValue (OLSR_WILL_DEFAULT),
   5.171 +                   MakeEnumAccessor (&RoutingProtocol::m_willingness),
   5.172 +                   MakeEnumChecker (OLSR_WILL_NEVER, "never",
   5.173 +                                    OLSR_WILL_LOW, "low",
   5.174 +                                    OLSR_WILL_DEFAULT, "default",
   5.175 +                                    OLSR_WILL_HIGH, "high",
   5.176 +                                    OLSR_WILL_ALWAYS, "always"))
   5.177 +    .AddTraceSource ("Rx", "Receive OLSR packet.",
   5.178 +                     MakeTraceSourceAccessor (&RoutingProtocol::m_rxPacketTrace))
   5.179 +    .AddTraceSource ("Tx", "Send OLSR packet.",
   5.180 +                     MakeTraceSourceAccessor (&RoutingProtocol::m_txPacketTrace))
   5.181 +    .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.",
   5.182 +		     MakeTraceSourceAccessor (&RoutingProtocol::m_routingTableChanged))
   5.183 +    ;
   5.184 +  return tid;
   5.185 +}
   5.186 +
   5.187 +
   5.188 +RoutingProtocol::RoutingProtocol ()
   5.189 +  :
   5.190 +  m_helloTimer (Timer::CANCEL_ON_DESTROY),
   5.191 +  m_tcTimer (Timer::CANCEL_ON_DESTROY),
   5.192 +  m_midTimer (Timer::CANCEL_ON_DESTROY)
   5.193 +{}
   5.194 +
   5.195 +RoutingProtocol::~RoutingProtocol ()
   5.196 +{}
   5.197 +
   5.198 +void
   5.199 +RoutingProtocol::SetNode (Ptr<Node> node)
   5.200 +{
   5.201 +  NS_LOG_DEBUG ("Created olsr::RoutingProtocol");
   5.202 +  m_helloTimer.SetFunction (&RoutingProtocol::HelloTimerExpire, this);
   5.203 +  m_tcTimer.SetFunction (&RoutingProtocol::TcTimerExpire, this);
   5.204 +  m_midTimer.SetFunction (&RoutingProtocol::MidTimerExpire, this);
   5.205 +  m_queuedMessagesTimer.SetFunction (&RoutingProtocol::SendQueuedMessages, this);
   5.206 +
   5.207 +  m_packetSequenceNumber = OLSR_MAX_SEQ_NUM;
   5.208 +  m_messageSequenceNumber = OLSR_MAX_SEQ_NUM;
   5.209 +  m_ansn = OLSR_MAX_SEQ_NUM;
   5.210 +
   5.211 +  m_linkTupleTimerFirstTime = true;
   5.212 +
   5.213 +  m_ipv4 = node->GetObject<Ipv4> ();
   5.214 +  NS_ASSERT (m_ipv4);
   5.215 +}
   5.216 +
   5.217 +void RoutingProtocol::DoDispose ()
   5.218 +{
   5.219 +  m_ipv4 = 0;
   5.220 +
   5.221 +  for (std::map< Ptr<Socket>, Ipv4Address >::iterator iter = m_socketAddresses.begin ();
   5.222 +       iter != m_socketAddresses.end (); iter++)
   5.223 +    {
   5.224 +      iter->first->Close ();
   5.225 +    }
   5.226 +  m_socketAddresses.clear ();
   5.227 +
   5.228 +  Ipv4RoutingProtocol::DoDispose ();
   5.229 +}
   5.230 +
   5.231 +void RoutingProtocol::Start ()
   5.232 +{
   5.233 +  if (m_mainAddress == Ipv4Address ())
   5.234 +    {
   5.235 +      Ipv4Address loopback ("127.0.0.1");
   5.236 +      for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
   5.237 +        {
   5.238 +          Ipv4Address addr = m_ipv4->GetAddress (i);
   5.239 +          if (addr != loopback)
   5.240 +            {
   5.241 +              m_mainAddress = addr;
   5.242 +              break;
   5.243 +            }
   5.244 +        }
   5.245 +
   5.246 +      NS_ASSERT (m_mainAddress != Ipv4Address ());
   5.247 +    }
   5.248 +
   5.249 +  NS_LOG_DEBUG ("Starting OLSR on node " << m_mainAddress);
   5.250 +
   5.251 +  Ipv4Address loopback ("127.0.0.1");
   5.252 +  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
   5.253 +    {
   5.254 +      Ipv4Address addr = m_ipv4->GetAddress (i);
   5.255 +      if (addr == loopback)
   5.256 +        continue;
   5.257 +
   5.258 +      if (addr != m_mainAddress)
   5.259 +        {
   5.260 +          // Create never expiring interface association tuple entries for our
   5.261 +          // own network interfaces, so that GetMainAddress () works to
   5.262 +          // translate the node's own interface addresses into the main address.
   5.263 +          IfaceAssocTuple tuple;
   5.264 +          tuple.ifaceAddr = addr;
   5.265 +          tuple.mainAddr = m_mainAddress;
   5.266 +          AddIfaceAssocTuple (tuple);
   5.267 +          NS_ASSERT (GetMainAddress (addr) == m_mainAddress);
   5.268 +        }
   5.269 +
   5.270 +      // Create a socket to listen only on this interface
   5.271 +      Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (), 
   5.272 +        UdpSocketFactory::GetTypeId()); 
   5.273 +      socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvOlsr,  this));
   5.274 +      if (socket->Bind (InetSocketAddress (addr, OLSR_PORT_NUMBER)))
   5.275 +        {
   5.276 +          NS_FATAL_ERROR ("Failed to bind() OLSR receive socket");
   5.277 +        }
   5.278 +      socket->Connect (InetSocketAddress (Ipv4Address (0xffffffff), OLSR_PORT_NUMBER));
   5.279 +      m_socketAddresses[socket] = addr;
   5.280 +    }
   5.281 +
   5.282 +  HelloTimerExpire ();
   5.283 +  TcTimerExpire ();
   5.284 +  MidTimerExpire ();
   5.285 +
   5.286 +  NS_LOG_DEBUG ("OLSR on node " << m_mainAddress << " started");
   5.287 +}
   5.288 +
   5.289 +void RoutingProtocol::SetMainInterface (uint32_t interface)
   5.290 +{
   5.291 +  m_mainAddress = m_ipv4->GetAddress (interface);
   5.292 +}
   5.293 +
   5.294 +
   5.295 +//
   5.296 +// \brief Processes an incoming %OLSR packet following RFC 3626 specification.
   5.297 +void
   5.298 +RoutingProtocol::RecvOlsr (Ptr<Socket> socket)
   5.299 +{
   5.300 +  Ptr<Packet> receivedPacket;
   5.301 +  Address sourceAddress;
   5.302 +  receivedPacket = socket->RecvFrom (sourceAddress);
   5.303 +
   5.304 +  InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
   5.305 +  Ipv4Address senderIfaceAddr = inetSourceAddr.GetIpv4 ();
   5.306 +  Ipv4Address receiverIfaceAddr = m_socketAddresses[socket];
   5.307 +  NS_ASSERT (receiverIfaceAddr != Ipv4Address ());
   5.308 +  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " received a OLSR packet from "
   5.309 +                << senderIfaceAddr << " to " << receiverIfaceAddr);
   5.310 +  
   5.311 +  // All routing messages are sent from and to port RT_PORT,
   5.312 +  // so we check it.
   5.313 +  NS_ASSERT (inetSourceAddr.GetPort () == OLSR_PORT_NUMBER);
   5.314 +  
   5.315 +  Ptr<Packet> packet = receivedPacket;
   5.316 +
   5.317 +  olsr::PacketHeader olsrPacketHeader;
   5.318 +  packet->RemoveHeader (olsrPacketHeader);
   5.319 +  NS_ASSERT (olsrPacketHeader.GetPacketLength () >= olsrPacketHeader.GetSerializedSize ());
   5.320 +  uint32_t sizeLeft = olsrPacketHeader.GetPacketLength () - olsrPacketHeader.GetSerializedSize ();
   5.321 +
   5.322 +  MessageList messages;
   5.323 +  
   5.324 +  while (sizeLeft)
   5.325 +    {
   5.326 +      MessageHeader messageHeader;
   5.327 +      if (packet->RemoveHeader (messageHeader) == 0)
   5.328 +        NS_ASSERT (false);
   5.329 +      
   5.330 +      sizeLeft -= messageHeader.GetSerializedSize ();
   5.331 +
   5.332 +      NS_LOG_DEBUG ("Olsr Msg received with type "
   5.333 +                << std::dec << int (messageHeader.GetMessageType ())
   5.334 +                << " TTL=" << int (messageHeader.GetTimeToLive ())
   5.335 +                << " origAddr=" << messageHeader.GetOriginatorAddress ());
   5.336 +      messages.push_back (messageHeader);
   5.337 +    }
   5.338 +
   5.339 +  m_rxPacketTrace (olsrPacketHeader, messages);
   5.340 +
   5.341 +  for (MessageList::const_iterator messageIter = messages.begin ();
   5.342 +       messageIter != messages.end (); messageIter++)
   5.343 +    {
   5.344 +      const MessageHeader &messageHeader = *messageIter;
   5.345 +      // If ttl is less than or equal to zero, or
   5.346 +      // the receiver is the same as the originator,
   5.347 +      // the message must be silently dropped
   5.348 +      if (messageHeader.GetTimeToLive () == 0
   5.349 +          || messageHeader.GetOriginatorAddress () == m_mainAddress)
   5.350 +        {
   5.351 +          packet->RemoveAtStart (messageHeader.GetSerializedSize ()
   5.352 +                                 - messageHeader.GetSerializedSize ());
   5.353 +          continue;
   5.354 +        }
   5.355 +
   5.356 +      // If the message has been processed it must not be processed again
   5.357 +      bool do_forwarding = true;
   5.358 +      DuplicateTuple *duplicated = m_state.FindDuplicateTuple
   5.359 +        (messageHeader.GetOriginatorAddress (),
   5.360 +         messageHeader.GetMessageSequenceNumber ());
   5.361 +
   5.362 +      // Get main address of the peer, which may be different from the packet source address
   5.363 +//       const IfaceAssocTuple *ifaceAssoc = m_state.FindIfaceAssocTuple (inetSourceAddr.GetIpv4 ());
   5.364 +//       Ipv4Address peerMainAddress;
   5.365 +//       if (ifaceAssoc != NULL)
   5.366 +//         {
   5.367 +//           peerMainAddress = ifaceAssoc->mainAddr;
   5.368 +//         }
   5.369 +//       else
   5.370 +//         {
   5.371 +//           peerMainAddress = inetSourceAddr.GetIpv4 () ;
   5.372 +//         }
   5.373 +      
   5.374 +      if (duplicated == NULL)
   5.375 +        {
   5.376 +          switch (messageHeader.GetMessageType ())
   5.377 +            {
   5.378 +            case olsr::MessageHeader::HELLO_MESSAGE:
   5.379 +              NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
   5.380 +                            << "s OLSR node " << m_mainAddress
   5.381 +                            << " received HELLO message of size " << messageHeader.GetSerializedSize ());
   5.382 +              ProcessHello (messageHeader, receiverIfaceAddr, senderIfaceAddr);
   5.383 +              break;
   5.384 +
   5.385 +            case olsr::MessageHeader::TC_MESSAGE:
   5.386 +              NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
   5.387 +                            << "s OLSR node " << m_mainAddress
   5.388 +                            << " received TC message of size " << messageHeader.GetSerializedSize ());
   5.389 +              ProcessTc (messageHeader, senderIfaceAddr);
   5.390 +              break;
   5.391 +
   5.392 +            case olsr::MessageHeader::MID_MESSAGE:
   5.393 +              NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
   5.394 +                            << "s OLSR node " << m_mainAddress
   5.395 +                            <<  " received MID message of size " << messageHeader.GetSerializedSize ());
   5.396 +              ProcessMid (messageHeader, senderIfaceAddr);
   5.397 +              break;
   5.398 +
   5.399 +            default:
   5.400 +              NS_LOG_DEBUG ("OLSR message type " <<
   5.401 +                        int (messageHeader.GetMessageType ()) <<
   5.402 +                        " not implemented");
   5.403 +            }
   5.404 +        }
   5.405 +      else
   5.406 +        {
   5.407 +          NS_LOG_DEBUG ("OLSR message is duplicated, not reading it.");
   5.408 +      
   5.409 +          // If the message has been considered for forwarding, it should
   5.410 +          // not be retransmitted again
   5.411 +          for (std::vector<Ipv4Address>::const_iterator it = duplicated->ifaceList.begin ();
   5.412 +               it != duplicated->ifaceList.end(); it++)
   5.413 +            {
   5.414 +              if (*it == receiverIfaceAddr)
   5.415 +                {
   5.416 +                  do_forwarding = false;
   5.417 +                  break;
   5.418 +                }
   5.419 +            }
   5.420 +        }
   5.421 +      
   5.422 +      if (do_forwarding)
   5.423 +        {
   5.424 +          // HELLO messages are never forwarded.
   5.425 +          // TC and MID messages are forwarded using the default algorithm.
   5.426 +          // Remaining messages are also forwarded using the default algorithm.
   5.427 +          if (messageHeader.GetMessageType ()  != olsr::MessageHeader::HELLO_MESSAGE)
   5.428 +            {
   5.429 +              ForwardDefault (messageHeader, duplicated,
   5.430 +                              receiverIfaceAddr, inetSourceAddr.GetIpv4 ());
   5.431 +            }
   5.432 +        }
   5.433 +	
   5.434 +    }
   5.435 +
   5.436 +  // After processing all OLSR messages, we must recompute the routing table
   5.437 +  RoutingTableComputation ();
   5.438 +}
   5.439 +
   5.440 +///
   5.441 +/// \brief This auxiliary function (defined in RFC 3626) is used for calculating the MPR Set.
   5.442 +///
   5.443 +/// \param tuple the neighbor tuple which has the main address of the node we are going to calculate its degree to.
   5.444 +/// \return the degree of the node.
   5.445 +///
   5.446 +int
   5.447 +RoutingProtocol::Degree (NeighborTuple const &tuple)
   5.448 +{
   5.449 +  int degree = 0;
   5.450 +  for (TwoHopNeighborSet::const_iterator it = m_state.GetTwoHopNeighbors ().begin ();
   5.451 +       it != m_state.GetTwoHopNeighbors ().end (); it++)
   5.452 +    {
   5.453 +      TwoHopNeighborTuple const &nb2hop_tuple = *it;
   5.454 +      if (nb2hop_tuple.neighborMainAddr == tuple.neighborMainAddr)
   5.455 +        {
   5.456 +          const NeighborTuple *nb_tuple =
   5.457 +            m_state.FindNeighborTuple (nb2hop_tuple.neighborMainAddr);
   5.458 +          if (nb_tuple == NULL)
   5.459 +            degree++;
   5.460 +        }
   5.461 +    }
   5.462 +  return degree;
   5.463 +}
   5.464 +
   5.465 +///
   5.466 +/// \brief Computates MPR set of a node following RFC 3626 hints.
   5.467 +///
   5.468 +void
   5.469 +RoutingProtocol::MprComputation()
   5.470 +{
   5.471 +  NS_LOG_FUNCTION (this);
   5.472 +  
   5.473 +  // MPR computation should be done for each interface. See section 8.3.1
   5.474 +  // (RFC 3626) for details.
   5.475 +  MprSet mprSet;
   5.476 +	
   5.477 +  
   5.478 +  // N is the subset of neighbors of the node, which are
   5.479 +  // neighbor "of the interface I"
   5.480 +  NeighborSet N;
   5.481 +  for (NeighborSet::const_iterator neighbor = m_state.GetNeighbors ().begin();
   5.482 +       neighbor != m_state.GetNeighbors ().end (); neighbor++)
   5.483 +    {
   5.484 +      if (neighbor->status == NeighborTuple::STATUS_SYM) // I think that we need this check
   5.485 +        {
   5.486 +          N.push_back (*neighbor);
   5.487 +        }
   5.488 +    }
   5.489 +	
   5.490 +  // N2 is the set of 2-hop neighbors reachable from "the interface
   5.491 +  // I", excluding:
   5.492 +  // (i)   the nodes only reachable by members of N with willingness WILL_NEVER
   5.493 +  // (ii)  the node performing the computation
   5.494 +  // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
   5.495 +  //       link to this node on some interface.
   5.496 +  TwoHopNeighborSet N2;
   5.497 +  for (TwoHopNeighborSet::const_iterator twoHopNeigh = m_state.GetTwoHopNeighbors ().begin ();
   5.498 +       twoHopNeigh != m_state.GetTwoHopNeighbors ().end (); twoHopNeigh++)
   5.499 +    {
   5.500 +      // excluding:
   5.501 +      // (ii)  the node performing the computation
   5.502 +      if (twoHopNeigh->twoHopNeighborAddr == m_mainAddress)
   5.503 +        {
   5.504 +          continue;
   5.505 +        }
   5.506 +
   5.507 +      //  excluding:
   5.508 +      // (i)   the nodes only reachable by members of N with willingness WILL_NEVER      
   5.509 +      bool ok = false;
   5.510 +      for (NeighborSet::const_iterator neigh = N.begin ();
   5.511 +           neigh != N.end (); neigh++)
   5.512 +        {
   5.513 +          if (neigh->neighborMainAddr == twoHopNeigh->neighborMainAddr)
   5.514 +            {
   5.515 +              if (neigh->willingness == OLSR_WILL_NEVER)
   5.516 +                {
   5.517 +                  ok = false;
   5.518 +                  break;
   5.519 +                }
   5.520 +              else
   5.521 +                {
   5.522 +                  ok = true;
   5.523 +                  break;
   5.524 +                }
   5.525 +            }
   5.526 +        }
   5.527 +      if (!ok)
   5.528 +        {
   5.529 +          continue;
   5.530 +        }
   5.531 +      
   5.532 +      // excluding:
   5.533 +      // (iii) all the symmetric neighbors: the nodes for which there exists a symmetric
   5.534 +      //       link to this node on some interface.
   5.535 +      for (NeighborSet::const_iterator neigh = N.begin ();
   5.536 +           neigh != N.end (); neigh++)
   5.537 +        {
   5.538 +          if (neigh->neighborMainAddr == twoHopNeigh->twoHopNeighborAddr)
   5.539 +            {
   5.540 +              ok = false;
   5.541 +              break;
   5.542 +            }
   5.543 +        }
   5.544 +
   5.545 +      if (ok)
   5.546 +        {
   5.547 +          N2.push_back (*twoHopNeigh);
   5.548 +        }
   5.549 +    }
   5.550 +
   5.551 +  NS_LOG_DEBUG ("Size of N2: " << N2.size ());  
   5.552 +
   5.553 +  // 1. Start with an MPR set made of all members of N with
   5.554 +  // N_willingness equal to WILL_ALWAYS
   5.555 +  for (NeighborSet::const_iterator neighbor = N.begin (); neighbor != N.end (); neighbor++)
   5.556 +    {
   5.557 +      if (neighbor->willingness == OLSR_WILL_ALWAYS)
   5.558 +        {
   5.559 +          mprSet.insert (neighbor->neighborMainAddr);
   5.560 +          // (not in RFC but I think is needed: remove the 2-hop
   5.561 +          // neighbors reachable by the MPR from N2)
   5.562 +          for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
   5.563 +               twoHopNeigh != N2.end (); )
   5.564 +            {
   5.565 +              if (twoHopNeigh->neighborMainAddr == neighbor->neighborMainAddr)
   5.566 +                {
   5.567 +                  twoHopNeigh = N2.erase (twoHopNeigh);
   5.568 +                }
   5.569 +              else
   5.570 +                {
   5.571 +                  twoHopNeigh++;
   5.572 +                }
   5.573 +            }
   5.574 +        }
   5.575 +    }
   5.576 +  
   5.577 +  // 2. Calculate D(y), where y is a member of N, for all nodes in N.
   5.578 +  // (we do this later)
   5.579 +	
   5.580 +  // 3. Add to the MPR set those nodes in N, which are the *only*
   5.581 +  // nodes to provide reachability to a node in N2.
   5.582 +  std::set<Ipv4Address> coveredTwoHopNeighbors;
   5.583 +  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin (); twoHopNeigh != N2.end (); twoHopNeigh++)
   5.584 +    {
   5.585 +      NeighborSet::const_iterator onlyNeighbor = N.end ();
   5.586 +      
   5.587 +      for (NeighborSet::const_iterator neighbor = N.begin ();
   5.588 +           neighbor != N.end (); neighbor++)
   5.589 +        {
   5.590 +          if (neighbor->neighborMainAddr == twoHopNeigh->neighborMainAddr)
   5.591 +            {
   5.592 +              if (onlyNeighbor == N.end ())
   5.593 +                {
   5.594 +                  onlyNeighbor = neighbor;
   5.595 +                }
   5.596 +              else
   5.597 +                {
   5.598 +                  onlyNeighbor = N.end ();
   5.599 +                  break;
   5.600 +                }
   5.601 +            }
   5.602 +        }
   5.603 +      if (onlyNeighbor != N.end ())
   5.604 +        {
   5.605 +          mprSet.insert (onlyNeighbor->neighborMainAddr);
   5.606 +          coveredTwoHopNeighbors.insert (twoHopNeigh->twoHopNeighborAddr);
   5.607 +        }
   5.608 +    }
   5.609 +  // Remove the nodes from N2 which are now covered by a node in the MPR set.
   5.610 +  for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
   5.611 +       twoHopNeigh != N2.end (); )
   5.612 +    {
   5.613 +      if (coveredTwoHopNeighbors.find (twoHopNeigh->twoHopNeighborAddr) != coveredTwoHopNeighbors.end ())
   5.614 +        {
   5.615 +          twoHopNeigh = N2.erase (twoHopNeigh);
   5.616 +        }
   5.617 +      else
   5.618 +        {
   5.619 +          twoHopNeigh++;
   5.620 +        }
   5.621 +    }
   5.622 +	
   5.623 +  // 4. While there exist nodes in N2 which are not covered by at
   5.624 +  // least one node in the MPR set:
   5.625 +  while (N2.begin () != N2.end ())
   5.626 +    {
   5.627 +      // 4.1. For each node in N, calculate the reachability, i.e., the
   5.628 +      // number of nodes in N2 which are not yet covered by at
   5.629 +      // least one node in the MPR set, and which are reachable
   5.630 +      // through this 1-hop neighbor
   5.631 +      std::map<int, std::vector<const NeighborTuple *> > reachability;
   5.632 +      std::set<int> rs;
   5.633 +      for (NeighborSet::iterator it = N.begin(); it != N.end(); it++)
   5.634 +        {
   5.635 +          NeighborTuple const &nb_tuple = *it;
   5.636 +          int r = 0;
   5.637 +          for (TwoHopNeighborSet::iterator it2 = N2.begin (); it2 != N2.end (); it2++)
   5.638 +            {
   5.639 +              TwoHopNeighborTuple const &nb2hop_tuple = *it2;
   5.640 +              if (nb_tuple.neighborMainAddr == nb2hop_tuple.neighborMainAddr)
   5.641 +                r++;
   5.642 +            }
   5.643 +          rs.insert (r);
   5.644 +          reachability[r].push_back (&nb_tuple);
   5.645 +        }
   5.646 +      
   5.647 +      // 4.2. Select as a MPR the node with highest N_willingness among
   5.648 +      // the nodes in N with non-zero reachability. In case of
   5.649 +      // multiple choice select the node which provides
   5.650 +      // reachability to the maximum number of nodes in N2. In
   5.651 +      // case of multiple nodes providing the same amount of
   5.652 +      // reachability, select the node as MPR whose D(y) is
   5.653 +      // greater. Remove the nodes from N2 which are now covered
   5.654 +      // by a node in the MPR set.
   5.655 +      NeighborTuple const *max = NULL;
   5.656 +      int max_r = 0;
   5.657 +      for (std::set<int>::iterator it = rs.begin (); it != rs.end (); it++)
   5.658 +        {
   5.659 +          int r = *it;
   5.660 +          if (r == 0)
   5.661 +            {
   5.662 +              continue;
   5.663 +            }
   5.664 +          for (std::vector<const NeighborTuple *>::iterator it2 = reachability[r].begin ();
   5.665 +               it2 != reachability[r].end (); it2++)
   5.666 +            {
   5.667 +              const NeighborTuple *nb_tuple = *it2;
   5.668 +              if (max == NULL || nb_tuple->willingness > max->willingness)
   5.669 +                {
   5.670 +                  max = nb_tuple;
   5.671 +                  max_r = r;
   5.672 +                }
   5.673 +              else if (nb_tuple->willingness == max->willingness)
   5.674 +                {
   5.675 +                  if (r > max_r)
   5.676 +                    {
   5.677 +                      max = nb_tuple;
   5.678 +                      max_r = r;
   5.679 +                    }
   5.680 +                  else if (r == max_r)
   5.681 +                    {
   5.682 +                      if (Degree (*nb_tuple) > Degree (*max))
   5.683 +                        {
   5.684 +                          max = nb_tuple;
   5.685 +                          max_r = r;
   5.686 +                        }
   5.687 +                    }
   5.688 +                }
   5.689 +            }
   5.690 +        }
   5.691 +
   5.692 +      if (max != NULL)
   5.693 +        {
   5.694 +          mprSet.insert (max->neighborMainAddr);
   5.695 +          for (TwoHopNeighborSet::iterator twoHopNeigh = N2.begin ();
   5.696 +               twoHopNeigh != N2.end (); )
   5.697 +            {
   5.698 +              if (twoHopNeigh->neighborMainAddr == max->neighborMainAddr)
   5.699 +                {
   5.700 +                  twoHopNeigh = N2.erase (twoHopNeigh);
   5.701 +                }
   5.702 +              else
   5.703 +                {
   5.704 +                  twoHopNeigh++;
   5.705 +                }
   5.706 +            }
   5.707 +        }
   5.708 +    }
   5.709 +
   5.710 +#ifdef NS3_LOG_ENABLE
   5.711 +  {
   5.712 +    std::ostringstream os;
   5.713 +    os << "[";
   5.714 +    for (MprSet::const_iterator iter = mprSet.begin ();
   5.715 +         iter != mprSet.end (); iter++)
   5.716 +      {
   5.717 +        MprSet::const_iterator next = iter;
   5.718 +        next++;
   5.719 +        os << *iter;
   5.720 +        if (next != mprSet.end ())
   5.721 +          os << ", ";
   5.722 +      }
   5.723 +    os << "]";
   5.724 +    NS_LOG_DEBUG ("Computed MPR set for node " << m_mainAddress << ": " << os.str ());
   5.725 +  }
   5.726 +#endif
   5.727 +
   5.728 +  m_state.SetMprSet (mprSet);
   5.729 +}
   5.730 +
   5.731 +///
   5.732 +/// \brief Gets the main address associated with a given interface address.
   5.733 +///
   5.734 +/// \param iface_addr the interface address.
   5.735 +/// \return the corresponding main address.
   5.736 +///
   5.737 +Ipv4Address
   5.738 +RoutingProtocol::GetMainAddress (Ipv4Address iface_addr) const
   5.739 +{
   5.740 +  const IfaceAssocTuple *tuple =
   5.741 +    m_state.FindIfaceAssocTuple (iface_addr);
   5.742 +  
   5.743 +  if (tuple != NULL)
   5.744 +    return tuple->mainAddr;
   5.745 +  else
   5.746 +    return iface_addr;
   5.747 +}
   5.748 +
   5.749 +///
   5.750 +/// \brief Creates the routing table of the node following RFC 3626 hints.
   5.751 +///
   5.752 +void
   5.753 +RoutingProtocol::RoutingTableComputation ()
   5.754 +{
   5.755 +  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " s: Node " << m_mainAddress
   5.756 +                << ": RoutingTableComputation begin...");
   5.757 +
   5.758 +  // 1. All the entries from the routing table are removed.
   5.759 +  Clear ();
   5.760 +	
   5.761 +  // 2. The new routing entries are added starting with the
   5.762 +  // symmetric neighbors (h=1) as the destination nodes.
   5.763 +  const NeighborSet &neighborSet = m_state.GetNeighbors ();
   5.764 +  for (NeighborSet::const_iterator it = neighborSet.begin ();
   5.765 +       it != neighborSet.end(); it++)
   5.766 +    {
   5.767 +      NeighborTuple const &nb_tuple = *it;
   5.768 +      NS_LOG_DEBUG ("Looking at neighbor tuple: " << nb_tuple);
   5.769 +      if (nb_tuple.status == NeighborTuple::STATUS_SYM)
   5.770 +        {
   5.771 +          bool nb_main_addr = false;
   5.772 +          const LinkTuple *lt = NULL;
   5.773 +          const LinkSet &linkSet = m_state.GetLinks ();
   5.774 +          for (LinkSet::const_iterator it2 = linkSet.begin();
   5.775 +               it2 != linkSet.end(); it2++)
   5.776 +            {
   5.777 +              LinkTuple const &link_tuple = *it2;
   5.778 +              NS_LOG_DEBUG ("Looking at link tuple: " << link_tuple
   5.779 +                            << (link_tuple.time >= Simulator::Now ()? "" : " (expired)"));
   5.780 +              if ((GetMainAddress (link_tuple.neighborIfaceAddr) == nb_tuple.neighborMainAddr)
   5.781 +                  && link_tuple.time >= Simulator::Now ())
   5.782 +                {
   5.783 +                  NS_LOG_LOGIC ("Link tuple matches neighbor " << nb_tuple.neighborMainAddr
   5.784 +                                << " => adding routing table entry to neighbor");
   5.785 +                  lt = &link_tuple;
   5.786 +                  AddEntry (link_tuple.neighborIfaceAddr,
   5.787 +                            link_tuple.neighborIfaceAddr,
   5.788 +                            link_tuple.localIfaceAddr,
   5.789 +                            1);
   5.790 +                  if (link_tuple.neighborIfaceAddr == nb_tuple.neighborMainAddr)
   5.791 +                    {
   5.792 +                      nb_main_addr = true;
   5.793 +                    }
   5.794 +                }
   5.795 +              else
   5.796 +                {
   5.797 +                  NS_LOG_LOGIC ("Link tuple: linkMainAddress= " << GetMainAddress (link_tuple.neighborIfaceAddr)
   5.798 +                                << "; neighborMainAddr =  " << nb_tuple.neighborMainAddr
   5.799 +                                << "; expired=" << int (link_tuple.time < Simulator::Now ())
   5.800 +                                << " => IGNORE");
   5.801 +                }
   5.802 +            }
   5.803 +
   5.804 +          // If, in the above, no R_dest_addr is equal to the main
   5.805 +          // address of the neighbor, then another new routing entry
   5.806 +          // with MUST be added, with:
   5.807 +          //      R_dest_addr  = main address of the neighbor;
   5.808 +          //      R_next_addr  = L_neighbor_iface_addr of one of the
   5.809 +          //                     associated link tuple with L_time >= current time;
   5.810 +          //      R_dist       = 1;
   5.811 +          //      R_iface_addr = L_local_iface_addr of the
   5.812 +          //                     associated link tuple.
   5.813 +          if (!nb_main_addr && lt != NULL)
   5.814 +            {
   5.815 +              NS_LOG_LOGIC ("no R_dest_addr is equal to the main address of the neighbor "
   5.816 +                            "=> adding additional routing entry");
   5.817 +              AddEntry(nb_tuple.neighborMainAddr,
   5.818 +                       lt->neighborIfaceAddr,
   5.819 +                       lt->localIfaceAddr,
   5.820 +                       1);
   5.821 +            }
   5.822 +        }
   5.823 +    }
   5.824 +  
   5.825 +  //  3. for each node in N2, i.e., a 2-hop neighbor which is not a
   5.826 +  //  neighbor node or the node itself, and such that there exist at
   5.827 +  //  least one entry in the 2-hop neighbor set where
   5.828 +  //  N_neighbor_main_addr correspond to a neighbor node with
   5.829 +  //  willingness different of WILL_NEVER,
   5.830 +  const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
   5.831 +  for (TwoHopNeighborSet::const_iterator it = twoHopNeighbors.begin ();
   5.832 +       it != twoHopNeighbors.end (); it++)
   5.833 +    {
   5.834 +      TwoHopNeighborTuple const &nb2hop_tuple = *it;
   5.835 +
   5.836 +      NS_LOG_LOGIC ("Looking at two-hop neighbor tuple: " << nb2hop_tuple);
   5.837 +
   5.838 +      // a 2-hop neighbor which is not a neighbor node or the node itself
   5.839 +      if (m_state.FindNeighborTuple (nb2hop_tuple.twoHopNeighborAddr))
   5.840 +        {
   5.841 +          NS_LOG_LOGIC ("Two-hop neighbor tuple is also neighbor; skipped.");
   5.842 +          continue;
   5.843 +        }
   5.844 +
   5.845 +      if (nb2hop_tuple.twoHopNeighborAddr == m_mainAddress)
   5.846 +        {
   5.847 +          NS_LOG_LOGIC ("Two-hop neighbor is self; skipped.");
   5.848 +          continue;
   5.849 +        }
   5.850 +
   5.851 +      // ...and such that there exist at least one entry in the 2-hop
   5.852 +      // neighbor set where N_neighbor_main_addr correspond to a
   5.853 +      // neighbor node with willingness different of WILL_NEVER...
   5.854 +      bool nb2hopOk = false;
   5.855 +      for (NeighborSet::const_iterator neighbor = neighborSet.begin ();
   5.856 +           neighbor != neighborSet.end(); neighbor++)
   5.857 +        {
   5.858 +          if (neighbor->neighborMainAddr == nb2hop_tuple.neighborMainAddr
   5.859 +              && neighbor->willingness != OLSR_WILL_NEVER)
   5.860 +            {
   5.861 +              nb2hopOk = true;
   5.862 +              break;
   5.863 +            }
   5.864 +        }
   5.865 +      if (!nb2hopOk)
   5.866 +        {
   5.867 +          NS_LOG_LOGIC ("Two-hop neighbor tuple skipped: 2-hop neighbor "
   5.868 +                        << nb2hop_tuple.twoHopNeighborAddr
   5.869 +                        << " is attached to neighbor " << nb2hop_tuple.neighborMainAddr
   5.870 +                        << ", which was not found in the Neighbor Set.");
   5.871 +          continue;
   5.872 +        }
   5.873 +      
   5.874 +      // one selects one 2-hop tuple and creates one entry in the routing table with:
   5.875 +      //                R_dest_addr  =  the main address of the 2-hop neighbor;
   5.876 +      //                R_next_addr  = the R_next_addr of the entry in the
   5.877 +      //                               routing table with:
   5.878 +      //                                   R_dest_addr == N_neighbor_main_addr
   5.879 +      //                                                  of the 2-hop tuple;
   5.880 +      //                R_dist       = 2;
   5.881 +      //                R_iface_addr = the R_iface_addr of the entry in the
   5.882 +      //                               routing table with:
   5.883 +      //                                   R_dest_addr == N_neighbor_main_addr
   5.884 +      //                                                  of the 2-hop tuple;
   5.885 +      RoutingTableEntry entry;
   5.886 +      bool foundEntry = Lookup (nb2hop_tuple.neighborMainAddr, entry);
   5.887 +      if (foundEntry)
   5.888 +        {
   5.889 +          NS_LOG_LOGIC ("Adding routing entry for two-hop neighbor.");
   5.890 +          AddEntry (nb2hop_tuple.twoHopNeighborAddr,
   5.891 +                                    entry.nextAddr,
   5.892 +                                    entry.interface,
   5.893 +                                    2);
   5.894 +        }
   5.895 +      else
   5.896 +        {
   5.897 +          NS_LOG_LOGIC ("NOT adding routing entry for two-hop neighbor ("
   5.898 +                        << nb2hop_tuple.twoHopNeighborAddr
   5.899 +                        << " not found in the routing table)");
   5.900 +        }
   5.901 +    }
   5.902 +  
   5.903 +  for (uint32_t h = 2; ; h++)
   5.904 +    {
   5.905 +      bool added = false;
   5.906 +		
   5.907 +      // 3.1. For each topology entry in the topology table, if its
   5.908 +      // T_dest_addr does not correspond to R_dest_addr of any
   5.909 +      // route entry in the routing table AND its T_last_addr
   5.910 +      // corresponds to R_dest_addr of a route entry whose R_dist
   5.911 +      // is equal to h, then a new route entry MUST be recorded in
   5.912 +      // the routing table (if it does not already exist)
   5.913 +      const TopologySet &topology = m_state.GetTopologySet ();
   5.914 +      for (TopologySet::const_iterator it = topology.begin ();
   5.915 +           it != topology.end (); it++)
   5.916 +        {
   5.917 +          const TopologyTuple &topology_tuple = *it;
   5.918 +          NS_LOG_LOGIC ("Looking at topology tuple: " << topology_tuple);
   5.919 +
   5.920 +          RoutingTableEntry destAddrEntry, lastAddrEntry;
   5.921 +          bool have_destAddrEntry = Lookup (topology_tuple.destAddr, destAddrEntry);
   5.922 +          bool have_lastAddrEntry = Lookup (topology_tuple.lastAddr, lastAddrEntry);
   5.923 +          if (!have_destAddrEntry && have_lastAddrEntry && lastAddrEntry.distance == h)
   5.924 +            {
   5.925 +              NS_LOG_LOGIC ("Adding routing table entry based on the topology tuple.");
   5.926 +              // then a new route entry MUST be recorded in
   5.927 +              //                the routing table (if it does not already exist) where:
   5.928 +              //                     R_dest_addr  = T_dest_addr;
   5.929 +              //                     R_next_addr  = R_next_addr of the recorded
   5.930 +              //                                    route entry where:
   5.931 +              //                                    R_dest_addr == T_last_addr
   5.932 +              //                     R_dist       = h+1; and
   5.933 +              //                     R_iface_addr = R_iface_addr of the recorded
   5.934 +              //                                    route entry where:
   5.935 +              //                                       R_dest_addr == T_last_addr.
   5.936 +              AddEntry (topology_tuple.destAddr,
   5.937 +                        lastAddrEntry.nextAddr,
   5.938 +                        lastAddrEntry.interface,
   5.939 +                        h + 1);
   5.940 +              added = true;
   5.941 +            }
   5.942 +          else
   5.943 +            {
   5.944 +              NS_LOG_LOGIC ("NOT adding routing table entry based on the topology tuple: "
   5.945 +                            "have_destAddrEntry=" << have_destAddrEntry
   5.946 +                            << " have_lastAddrEntry=" << have_lastAddrEntry
   5.947 +                            << " lastAddrEntry.distance=" << (int) lastAddrEntry.distance
   5.948 +                            << " (h=" << h << ")");
   5.949 +            }
   5.950 +        }
   5.951 +      
   5.952 +      if (!added)
   5.953 +        break;
   5.954 +    }
   5.955 +
   5.956 +  // 4. For each entry in the multiple interface association base
   5.957 +  // where there exists a routing entry such that:
   5.958 +  //	R_dest_addr  == I_main_addr  (of the multiple interface association entry)
   5.959 +  // AND there is no routing entry such that:
   5.960 +  //	R_dest_addr  == I_iface_addr
   5.961 +  const IfaceAssocSet &ifaceAssocSet = m_state.GetIfaceAssocSet ();
   5.962 +  for (IfaceAssocSet::const_iterator it = ifaceAssocSet.begin ();
   5.963 +       it != ifaceAssocSet.end (); it++)
   5.964 +    {
   5.965 +      IfaceAssocTuple const &tuple = *it;
   5.966 +      RoutingTableEntry entry1, entry2;
   5.967 +      bool have_entry1 = Lookup (tuple.mainAddr, entry1);
   5.968 +      bool have_entry2 = Lookup (tuple.ifaceAddr, entry2);
   5.969 +      if (have_entry1 && !have_entry2)
   5.970 +        {
   5.971 +          // then a route entry is created in the routing table with:
   5.972 +          //       R_dest_addr  =  I_iface_addr (of the multiple interface
   5.973 +          //                                     association entry)
   5.974 +          //       R_next_addr  =  R_next_addr  (of the recorded route entry)
   5.975 +          //       R_dist       =  R_dist       (of the recorded route entry)
   5.976 +          //       R_iface_addr =  R_iface_addr (of the recorded route entry).
   5.977 +          AddEntry (tuple.ifaceAddr,
   5.978 +                    entry1.nextAddr,
   5.979 +                    entry1.interface,
   5.980 +                    entry1.distance);
   5.981 +        }
   5.982 +    }
   5.983 +
   5.984 +  NS_LOG_DEBUG ("Node " << m_mainAddress << ": RoutingTableComputation end.");
   5.985 +  m_routingTableChanged (GetSize ());
   5.986 +}
   5.987 +
   5.988 +
   5.989 +///
   5.990 +/// \brief Processes a HELLO message following RFC 3626 specification.
   5.991 +///
   5.992 +/// Link sensing and population of the Neighbor Set, 2-hop Neighbor Set and MPR
   5.993 +/// Selector Set are performed.
   5.994 +///
   5.995 +/// \param msg the %OLSR message which contains the HELLO message.
   5.996 +/// \param receiver_iface the address of the interface where the message was received from.
   5.997 +/// \param sender_iface the address of the interface where the message was sent from.
   5.998 +///
   5.999 +void
  5.1000 +RoutingProtocol::ProcessHello (const olsr::MessageHeader &msg,
  5.1001 +                         const Ipv4Address &receiverIface,
  5.1002 +                         const Ipv4Address &senderIface)
  5.1003 +{
  5.1004 +  const olsr::MessageHeader::Hello &hello = msg.GetHello ();
  5.1005 +
  5.1006 +  LinkSensing (msg, hello, receiverIface, senderIface);
  5.1007 +
  5.1008 +#ifdef NS3_LOG_ENABLE
  5.1009 +  {
  5.1010 +    const LinkSet &links = m_state.GetLinks ();
  5.1011 +    NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  5.1012 +                  << "s ** BEGIN dump Link Set for OLSR Node " << m_mainAddress);
  5.1013 +    for (LinkSet::const_iterator link = links.begin (); link != links.end (); link++)
  5.1014 +      {
  5.1015 +        NS_LOG_DEBUG(*link);
  5.1016 +      }
  5.1017 +    NS_LOG_DEBUG ("** END dump Link Set for OLSR Node " << m_mainAddress);
  5.1018 +
  5.1019 +    const NeighborSet &neighbors = m_state.GetNeighbors ();
  5.1020 +    NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  5.1021 +                  << "s ** BEGIN dump Neighbor Set for OLSR Node " << m_mainAddress);
  5.1022 +    for (NeighborSet::const_iterator neighbor = neighbors.begin (); neighbor != neighbors.end (); neighbor++)
  5.1023 +      {
  5.1024 +        NS_LOG_DEBUG(*neighbor);
  5.1025 +      }
  5.1026 +    NS_LOG_DEBUG ("** END dump Neighbor Set for OLSR Node " << m_mainAddress);
  5.1027 +  }
  5.1028 +#endif
  5.1029 +
  5.1030 +  PopulateNeighborSet (msg, hello);
  5.1031 +  PopulateTwoHopNeighborSet (msg, hello);
  5.1032 +
  5.1033 +#ifdef NS3_LOG_ENABLE
  5.1034 +  {
  5.1035 +    const TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
  5.1036 +    NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  5.1037 +                  << "s ** BEGIN dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
  5.1038 +    for (TwoHopNeighborSet::const_iterator tuple = twoHopNeighbors.begin ();
  5.1039 +         tuple != twoHopNeighbors.end (); tuple++)
  5.1040 +      {
  5.1041 +        NS_LOG_DEBUG(*tuple);
  5.1042 +      }
  5.1043 +    NS_LOG_DEBUG ("** END dump TwoHopNeighbor Set for OLSR Node " << m_mainAddress);
  5.1044 +  }
  5.1045 +#endif
  5.1046 +
  5.1047 +  MprComputation ();
  5.1048 +  PopulateMprSelectorSet (msg, hello);
  5.1049 +}
  5.1050 +
  5.1051 +///
  5.1052 +/// \brief Processes a TC message following RFC 3626 specification.
  5.1053 +///
  5.1054 +/// The Topology Set is updated (if needed) with the information of
  5.1055 +/// the received TC message.
  5.1056 +///
  5.1057 +/// \param msg the %OLSR message which contains the TC message.
  5.1058 +/// \param sender_iface the address of the interface where the message was sent from.
  5.1059 +///
  5.1060 +void
  5.1061 +RoutingProtocol::ProcessTc (const olsr::MessageHeader &msg,
  5.1062 +                      const Ipv4Address &senderIface)
  5.1063 +{
  5.1064 +  const olsr::MessageHeader::Tc &tc = msg.GetTc ();
  5.1065 +  Time now = Simulator::Now ();
  5.1066 +	
  5.1067 +  // 1. If the sender interface of this message is not in the symmetric
  5.1068 +  // 1-hop neighborhood of this node, the message MUST be discarded.
  5.1069 +  const LinkTuple *link_tuple = m_state.FindSymLinkTuple (senderIface, now);
  5.1070 +  if (link_tuple == NULL)
  5.1071 +    return;
  5.1072 +	
  5.1073 +  // 2. If there exist some tuple in the topology set where:
  5.1074 +  // 	T_last_addr == originator address AND
  5.1075 +  // 	T_seq       >  ANSN,
  5.1076 +  // then further processing of this TC message MUST NOT be
  5.1077 +  // performed.
  5.1078 +  const TopologyTuple *topologyTuple =
  5.1079 +    m_state.FindNewerTopologyTuple (msg.GetOriginatorAddress (), tc.ansn);
  5.1080 +  if (topologyTuple != NULL)
  5.1081 +    return;
  5.1082 +	
  5.1083 +  // 3. All tuples in the topology set where:
  5.1084 +  //	T_last_addr == originator address AND
  5.1085 +  //	T_seq       <  ANSN
  5.1086 +  // MUST be removed from the topology set.
  5.1087 +  m_state.EraseOlderTopologyTuples (msg.GetOriginatorAddress (), tc.ansn);
  5.1088 +
  5.1089 +  // 4. For each of the advertised neighbor main address received in
  5.1090 +  // the TC message:
  5.1091 +  for (std::vector<Ipv4Address>::const_iterator i = tc.neighborAddresses.begin ();
  5.1092 +       i != tc.neighborAddresses.end (); i++)
  5.1093 +    {
  5.1094 +      const Ipv4Address &addr = *i;
  5.1095 +      // 4.1. If there exist some tuple in the topology set where:
  5.1096 +      // 	T_dest_addr == advertised neighbor main address, AND
  5.1097 +      // 	T_last_addr == originator address,
  5.1098 +      // then the holding time of that tuple MUST be set to:
  5.1099 +      // 	T_time      =  current time + validity time.
  5.1100 +      TopologyTuple *topologyTuple =
  5.1101 +        m_state.FindTopologyTuple (addr, msg.GetOriginatorAddress ());
  5.1102 +
  5.1103 +      if (topologyTuple != NULL)
  5.1104 +        {
  5.1105 +          topologyTuple->expirationTime = now + msg.GetVTime ();
  5.1106 +        }
  5.1107 +      else
  5.1108 +        {
  5.1109 +          // 4.2. Otherwise, a new tuple MUST be recorded in the topology
  5.1110 +          // set where:
  5.1111 +          //	T_dest_addr = advertised neighbor main address,
  5.1112 +          //	T_last_addr = originator address,
  5.1113 +          //	T_seq       = ANSN,
  5.1114 +          //	T_time      = current time + validity time.
  5.1115 +          TopologyTuple topologyTuple;;
  5.1116 +          topologyTuple.destAddr = addr;
  5.1117 +          topologyTuple.lastAddr = msg.GetOriginatorAddress ();
  5.1118 +          topologyTuple.sequenceNumber = tc.ansn;
  5.1119 +          topologyTuple.expirationTime = now + msg.GetVTime ();
  5.1120 +          AddTopologyTuple (topologyTuple);
  5.1121 +
  5.1122 +          // Schedules topology tuple deletion
  5.1123 +          m_events.Track (Simulator::Schedule (DELAY (topologyTuple.expirationTime),
  5.1124 +                                               &RoutingProtocol::TopologyTupleTimerExpire,
  5.1125 +                                               this,
  5.1126 +                                               topologyTuple.destAddr,
  5.1127 +                                               topologyTuple.lastAddr));
  5.1128 +        }
  5.1129 +    }
  5.1130 +
  5.1131 +#ifdef NS3_LOG_ENABLE
  5.1132 +  {
  5.1133 +    const TopologySet &topology = m_state.GetTopologySet ();
  5.1134 +    NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  5.1135 +                  << "s ** BEGIN dump TopologySet for OLSR Node " << m_mainAddress);
  5.1136 +    for (TopologySet::const_iterator tuple = topology.begin ();
  5.1137 +         tuple != topology.end (); tuple++)
  5.1138 +      {
  5.1139 +        NS_LOG_DEBUG (*tuple);
  5.1140 +      }
  5.1141 +    NS_LOG_DEBUG ("** END dump TopologySet Set for OLSR Node " << m_mainAddress);
  5.1142 +  }
  5.1143 +#endif
  5.1144 +}
  5.1145 +
  5.1146 +///
  5.1147 +/// \brief Processes a MID message following RFC 3626 specification.
  5.1148 +///
  5.1149 +/// The Interface Association Set is updated (if needed) with the information
  5.1150 +/// of the received MID message.
  5.1151 +///
  5.1152 +/// \param msg the %OLSR message which contains the MID message.
  5.1153 +/// \param sender_iface the address of the interface where the message was sent from.
  5.1154 +///
  5.1155 +void
  5.1156 +RoutingProtocol::ProcessMid (const olsr::MessageHeader &msg,
  5.1157 +                       const Ipv4Address &senderIface)
  5.1158 +{
  5.1159 +  const olsr::MessageHeader::Mid &mid = msg.GetMid ();
  5.1160 +  Time now = Simulator::Now ();
  5.1161 +  
  5.1162 +  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface);
  5.1163 +  // 1. If the sender interface of this message is not in the symmetric
  5.1164 +  // 1-hop neighborhood of this node, the message MUST be discarded.
  5.1165 +  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderIface, now);
  5.1166 +  if (linkTuple == NULL)
  5.1167 +    {
  5.1168 +      NS_LOG_LOGIC ("Node " << m_mainAddress <<
  5.1169 +                    ": the sender interface of this message is not in the "
  5.1170 +                    "symmetric 1-hop neighborhood of this node,"
  5.1171 +                    " the message MUST be discarded.");
  5.1172 +      return;
  5.1173 +    }
  5.1174 +	
  5.1175 +  // 2. For each interface address listed in the MID message
  5.1176 +  for (std::vector<Ipv4Address>::const_iterator i = mid.interfaceAddresses.begin ();
  5.1177 +       i != mid.interfaceAddresses.end (); i++)
  5.1178 +    {
  5.1179 +      bool updated = false;
  5.1180 +      IfaceAssocSet &ifaceAssoc = m_state.GetIfaceAssocSetMutable ();
  5.1181 +      for (IfaceAssocSet::iterator tuple = ifaceAssoc.begin();
  5.1182 +           tuple != ifaceAssoc.end(); tuple++)
  5.1183 +        {
  5.1184 +          if (tuple->ifaceAddr == *i
  5.1185 +              && tuple->mainAddr == msg.GetOriginatorAddress ())
  5.1186 +            {
  5.1187 +              NS_LOG_LOGIC ("IfaceAssoc updated: " << *tuple);
  5.1188 +              tuple->time = now + msg.GetVTime ();
  5.1189 +              updated = true;
  5.1190 +            }
  5.1191 +        }
  5.1192 +      if (!updated)
  5.1193 +        {
  5.1194 +          IfaceAssocTuple tuple;
  5.1195 +          tuple.ifaceAddr = *i;
  5.1196 +          tuple.mainAddr = msg.GetOriginatorAddress ();
  5.1197 +          tuple.time = now + msg.GetVTime ();
  5.1198 +          AddIfaceAssocTuple (tuple);
  5.1199 +          NS_LOG_LOGIC ("New IfaceAssoc added: " << tuple);
  5.1200 +          // Schedules iface association tuple deletion
  5.1201 +          Simulator::Schedule (DELAY (tuple.time),
  5.1202 +                               &RoutingProtocol::IfaceAssocTupleTimerExpire, this, tuple.ifaceAddr);
  5.1203 +        }
  5.1204 +    }
  5.1205 +
  5.1206 +  // 3. (not part of the RFC) iterate over all NeighborTuple's and
  5.1207 +  // TwoHopNeighborTuples, update the neighbor addresses taking into account
  5.1208 +  // the new MID information.
  5.1209 +  NeighborSet &neighbors = m_state.GetNeighbors ();
  5.1210 +  for (NeighborSet::iterator neighbor = neighbors.begin (); neighbor != neighbors.end(); neighbor++)
  5.1211 +    {
  5.1212 +      neighbor->neighborMainAddr = GetMainAddress (neighbor->neighborMainAddr);
  5.1213 +    }
  5.1214 +
  5.1215 +  TwoHopNeighborSet &twoHopNeighbors = m_state.GetTwoHopNeighbors ();
  5.1216 +  for (TwoHopNeighborSet::iterator twoHopNeighbor = twoHopNeighbors.begin ();
  5.1217 +       twoHopNeighbor != twoHopNeighbors.end(); twoHopNeighbor++)
  5.1218 +    {
  5.1219 +      twoHopNeighbor->neighborMainAddr = GetMainAddress (twoHopNeighbor->neighborMainAddr);
  5.1220 +      twoHopNeighbor->twoHopNeighborAddr = GetMainAddress (twoHopNeighbor->twoHopNeighborAddr);
  5.1221 +    }
  5.1222 +  NS_LOG_DEBUG ("Node " << m_mainAddress << " ProcessMid from " << senderIface << " -> END.");
  5.1223 +}
  5.1224 +
  5.1225 +
  5.1226 +///
  5.1227 +/// \brief OLSR's default forwarding algorithm.
  5.1228 +///
  5.1229 +/// See RFC 3626 for details.
  5.1230 +///
  5.1231 +/// \param p the %OLSR packet which has been received.
  5.1232 +/// \param msg the %OLSR message which must be forwarded.
  5.1233 +/// \param dup_tuple NULL if the message has never been considered for forwarding,
  5.1234 +/// or a duplicate tuple in other case.
  5.1235 +/// \param local_iface the address of the interface where the message was received from.
  5.1236 +///
  5.1237 +void
  5.1238 +RoutingProtocol::ForwardDefault (olsr::MessageHeader olsrMessage,
  5.1239 +                               DuplicateTuple *duplicated,
  5.1240 +                               const Ipv4Address &localIface,
  5.1241 +                               const Ipv4Address &senderAddress)
  5.1242 +{
  5.1243 +  Time now = Simulator::Now ();
  5.1244 +  
  5.1245 +  // If the sender interface address is not in the symmetric
  5.1246 +  // 1-hop neighborhood the message must not be forwarded
  5.1247 +  const LinkTuple *linkTuple = m_state.FindSymLinkTuple (senderAddress, now);
  5.1248 +  if (linkTuple == NULL)
  5.1249 +    return;
  5.1250 +
  5.1251 +  // If the message has already been considered for forwarding,
  5.1252 +  // it must not be retransmitted again
  5.1253 +  if (duplicated != NULL && duplicated->retransmitted)
  5.1254 +    {
  5.1255 +      NS_LOG_LOGIC (Simulator::Now () << "Node " << m_mainAddress << " does not forward a message received"
  5.1256 +                    " from " << olsrMessage.GetOriginatorAddress () << " because it is duplicated");
  5.1257 +      return;
  5.1258 +    }
  5.1259 +	
  5.1260 +  // If the sender interface address is an interface address
  5.1261 +  // of a MPR selector of this node and ttl is greater than 1,
  5.1262 +  // the message must be retransmitted
  5.1263 +  bool retransmitted = false;
  5.1264 +  if (olsrMessage.GetTimeToLive () > 1)
  5.1265 +    {
  5.1266 +      const MprSelectorTuple *mprselTuple =
  5.1267 +        m_state.FindMprSelectorTuple (GetMainAddress (senderAddress));
  5.1268 +      if (mprselTuple != NULL)
  5.1269 +        {
  5.1270 +          olsrMessage.SetTimeToLive (olsrMessage.GetTimeToLive () - 1);
  5.1271 +          olsrMessage.SetHopCount (olsrMessage.GetHopCount () + 1);
  5.1272 +          // We have to introduce a random delay to avoid
  5.1273 +          // synchronization with neighbors.
  5.1274 +          QueueMessage (olsrMessage, JITTER);
  5.1275 +          retransmitted = true;
  5.1276 +        }
  5.1277 +    }
  5.1278 +	
  5.1279 +  // Update duplicate tuple...
  5.1280 +  if (duplicated != NULL)
  5.1281 +    {
  5.1282 +      duplicated->expirationTime = now + OLSR_DUP_HOLD_TIME;
  5.1283 +      duplicated->retransmitted = retransmitted;
  5.1284 +      duplicated->ifaceList.push_back (localIface);
  5.1285 +    }
  5.1286 +  // ...or create a new one
  5.1287 +  else
  5.1288 +    {
  5.1289 +      DuplicateTuple newDup;
  5.1290 +      newDup.address = olsrMessage.GetOriginatorAddress ();
  5.1291 +      newDup.sequenceNumber = olsrMessage.GetMessageSequenceNumber ();
  5.1292 +      newDup.expirationTime = now + OLSR_DUP_HOLD_TIME;
  5.1293 +      newDup.retransmitted = retransmitted;
  5.1294 +      newDup.ifaceList.push_back (localIface);
  5.1295 +      AddDuplicateTuple (newDup);
  5.1296 +      // Schedule dup tuple deletion
  5.1297 +      Simulator::Schedule (OLSR_DUP_HOLD_TIME,
  5.1298 +                           &RoutingProtocol::DupTupleTimerExpire, this,
  5.1299 +                           newDup.address, newDup.sequenceNumber);
  5.1300 +    }
  5.1301 +}
  5.1302 +
  5.1303 +///
  5.1304 +/// \brief Enques an %OLSR message which will be sent with a delay of (0, delay].
  5.1305 +///
  5.1306 +/// This buffering system is used in order to piggyback several %OLSR messages in
  5.1307 +/// a same %OLSR packet.
  5.1308 +///
  5.1309 +/// \param msg the %OLSR message which must be sent.
  5.1310 +/// \param delay maximum delay the %OLSR message is going to be buffered.
  5.1311 +///
  5.1312 +void
  5.1313 +RoutingProtocol::QueueMessage (const olsr::MessageHeader &message, Time delay)
  5.1314 +{
  5.1315 +  m_queuedMessages.push_back (message);
  5.1316 +  if (not m_queuedMessagesTimer.IsRunning ())
  5.1317 +    {
  5.1318 +      m_queuedMessagesTimer.SetDelay (delay);
  5.1319 +      m_queuedMessagesTimer.Schedule ();
  5.1320 +    }
  5.1321 +}
  5.1322 +
  5.1323 +void
  5.1324 +RoutingProtocol::SendPacket (Ptr<Packet> packet, 
  5.1325 +                       const MessageList &containedMessages)
  5.1326 +{
  5.1327 +  NS_LOG_DEBUG ("OLSR node " << m_mainAddress << " sending a OLSR packet");
  5.1328 +
  5.1329 +  // Add a header
  5.1330 +  olsr::PacketHeader header;
  5.1331 +  header.SetPacketLength (header.GetSerializedSize () + packet->GetSize ());
  5.1332 +  header.SetPacketSequenceNumber (GetPacketSequenceNumber ());
  5.1333 +  packet->AddHeader (header);
  5.1334 +
  5.1335 +  // Trace it
  5.1336 +  m_txPacketTrace (header, containedMessages);
  5.1337 +
  5.1338 +  // Send it
  5.1339 +  m_socketAddresses.begin ()->first->Send (packet);
  5.1340 +}
  5.1341 +
  5.1342 +///
  5.1343 +/// \brief Creates as many %OLSR packets as needed in order to send all buffered
  5.1344 +/// %OLSR messages.
  5.1345 +///
  5.1346 +/// Maximum number of messages which can be contained in an %OLSR packet is
  5.1347 +/// dictated by OLSR_MAX_MSGS constant.
  5.1348 +///
  5.1349 +void
  5.1350 +RoutingProtocol::SendQueuedMessages ()
  5.1351 +{
  5.1352 +  Ptr<Packet> packet = Create<Packet> ();
  5.1353 +  int numMessages = 0;
  5.1354 +
  5.1355 +  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": SendQueuedMessages");
  5.1356 +
  5.1357 +  MessageList msglist;
  5.1358 +
  5.1359 +  for (std::vector<olsr::MessageHeader>::const_iterator message = m_queuedMessages.begin ();
  5.1360 +       message != m_queuedMessages.end ();
  5.1361 +       message++)
  5.1362 +    {
  5.1363 +      Ptr<Packet> p = Create<Packet> ();
  5.1364 +      p->AddHeader (*message);
  5.1365 +      packet->AddAtEnd (p);
  5.1366 +      msglist.push_back (*message);
  5.1367 +      if (++numMessages == OLSR_MAX_MSGS)
  5.1368 +        {
  5.1369 +          SendPacket (packet, msglist);
  5.1370 +          msglist.clear ();
  5.1371 +          // Reset variables for next packet
  5.1372 +          numMessages = 0;
  5.1373 +          packet = Create<Packet> ();
  5.1374 +        }
  5.1375 +    }
  5.1376 +
  5.1377 +  if (packet->GetSize ())
  5.1378 +    {
  5.1379 +      SendPacket (packet, msglist);
  5.1380 +    }
  5.1381 +
  5.1382 +  m_queuedMessages.clear ();
  5.1383 +}
  5.1384 +
  5.1385 +///
  5.1386 +/// \brief Creates a new %OLSR HELLO message which is buffered for being sent later on.
  5.1387 +///
  5.1388 +void
  5.1389 +RoutingProtocol::SendHello ()
  5.1390 +{
  5.1391 +  NS_LOG_FUNCTION (this);
  5.1392 +  
  5.1393 +  olsr::MessageHeader msg;
  5.1394 +  Time now = Simulator::Now ();
  5.1395 +
  5.1396 +  msg.SetVTime (OLSR_NEIGHB_HOLD_TIME);
  5.1397 +  msg.SetOriginatorAddress (m_mainAddress);
  5.1398 +  msg.SetTimeToLive (1);
  5.1399 +  msg.SetHopCount (0);
  5.1400 +  msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
  5.1401 +  olsr::MessageHeader::Hello &hello = msg.GetHello ();
  5.1402 +
  5.1403 +  hello.SetHTime (Scalar (3) * m_helloInterval);
  5.1404 +  hello.willingness = m_willingness;
  5.1405 +
  5.1406 +  std::vector<olsr::MessageHeader::Hello::LinkMessage>
  5.1407 +    &linkMessages = hello.linkMessages;
  5.1408 +	
  5.1409 +  const LinkSet &links = m_state.GetLinks ();
  5.1410 +  for (LinkSet::const_iterator link_tuple = links.begin ();
  5.1411 +       link_tuple != links.end (); link_tuple++)
  5.1412 +    {
  5.1413 +      if (!(GetMainAddress (link_tuple->localIfaceAddr) == m_mainAddress
  5.1414 +            && link_tuple->time >= now))
  5.1415 +        {
  5.1416 +          continue;
  5.1417 +        }
  5.1418 +
  5.1419 +      uint8_t link_type, nb_type = 0xff;
  5.1420 +			
  5.1421 +      // Establishes link type
  5.1422 +      if (link_tuple->symTime >= now)
  5.1423 +        {
  5.1424 +          link_type = OLSR_SYM_LINK;
  5.1425 +        }
  5.1426 +      else if (link_tuple->asymTime >= now)
  5.1427 +        {
  5.1428 +          link_type = OLSR_ASYM_LINK;
  5.1429 +        }
  5.1430 +      else
  5.1431 +        {
  5.1432 +          link_type = OLSR_LOST_LINK;
  5.1433 +        }
  5.1434 +      // Establishes neighbor type.
  5.1435 +      if (m_state.FindMprAddress (GetMainAddress (link_tuple->neighborIfaceAddr)))
  5.1436 +        {
  5.1437 +          nb_type = OLSR_MPR_NEIGH;
  5.1438 +          NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
  5.1439 +                        << " to be MPR_NEIGH.");
  5.1440 +        }
  5.1441 +      else
  5.1442 +        {
  5.1443 +          bool ok = false;
  5.1444 +          for (NeighborSet::const_iterator nb_tuple = m_state.GetNeighbors ().begin ();
  5.1445 +               nb_tuple != m_state.GetNeighbors ().end ();
  5.1446 +               nb_tuple++)
  5.1447 +            {
  5.1448 +              if (nb_tuple->neighborMainAddr == GetMainAddress (link_tuple->neighborIfaceAddr))
  5.1449 +                {
  5.1450 +                  if (nb_tuple->status == NeighborTuple::STATUS_SYM)
  5.1451 +                    {
  5.1452 +                      NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
  5.1453 +                                    << " to be SYM_NEIGH.");
  5.1454 +                      nb_type = OLSR_SYM_NEIGH;
  5.1455 +                    }
  5.1456 +                  else if (nb_tuple->status == NeighborTuple::STATUS_NOT_SYM)
  5.1457 +                    {
  5.1458 +                      nb_type = OLSR_NOT_NEIGH;
  5.1459 +                      NS_LOG_DEBUG ("I consider neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr)
  5.1460 +                                    << " to be NOT_NEIGH.");
  5.1461 +                    }
  5.1462 +                  else
  5.1463 +                    {
  5.1464 +                      NS_FATAL_ERROR ("There is a neighbor tuple with an unknown status!\n");
  5.1465 +                    }
  5.1466 +                  ok = true;
  5.1467 +                  break;
  5.1468 +                }
  5.1469 +            }
  5.1470 +          if (!ok)
  5.1471 +            {
  5.1472 +              NS_LOG_WARN ("I don't know the neighbor " << GetMainAddress (link_tuple->neighborIfaceAddr) << "!!!");
  5.1473 +              continue;
  5.1474 +            }
  5.1475 +        }
  5.1476 +
  5.1477 +      olsr::MessageHeader::Hello::LinkMessage linkMessage;
  5.1478 +      linkMessage.linkCode = (link_type & 0x03) | ((nb_type << 2) & 0x0f);
  5.1479 +      linkMessage.neighborInterfaceAddresses.push_back
  5.1480 +        (link_tuple->neighborIfaceAddr);
  5.1481 +
  5.1482 +      std::vector<Ipv4Address> interfaces =
  5.1483 +        m_state.FindNeighborInterfaces (link_tuple->neighborIfaceAddr);
  5.1484 +
  5.1485 +      linkMessage.neighborInterfaceAddresses.insert
  5.1486 +        (linkMessage.neighborInterfaceAddresses.end (),
  5.1487 +         interfaces.begin (), interfaces.end ());
  5.1488 +
  5.1489 +      linkMessages.push_back (linkMessage);
  5.1490 +    }
  5.1491 +  NS_LOG_DEBUG ("OLSR HELLO message size: " << int (msg.GetSerializedSize ())
  5.1492 +                << " (with " << int (linkMessages.size ()) << " link messages)");
  5.1493 +  QueueMessage (msg, JITTER);
  5.1494 +}
  5.1495 +
  5.1496 +///
  5.1497 +/// \brief Creates a new %OLSR TC message which is buffered for being sent later on.
  5.1498 +///
  5.1499 +void
  5.1500 +RoutingProtocol::SendTc ()
  5.1501 +{
  5.1502 +  NS_LOG_FUNCTION (this);
  5.1503 +  
  5.1504 +  olsr::MessageHeader msg;
  5.1505 +
  5.1506 +  msg.SetVTime (OLSR_TOP_HOLD_TIME);
  5.1507 +  msg.SetOriginatorAddress (m_mainAddress);
  5.1508 +  msg.SetTimeToLive (255);
  5.1509 +  msg.SetHopCount (0);
  5.1510 +  msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
  5.1511 +  
  5.1512 +  olsr::MessageHeader::Tc &tc = msg.GetTc ();
  5.1513 +  tc.ansn = m_ansn;
  5.1514 +  for (MprSelectorSet::const_iterator mprsel_tuple = m_state.GetMprSelectors ().begin();
  5.1515 +       mprsel_tuple != m_state.GetMprSelectors ().end(); mprsel_tuple++)
  5.1516 +    {
  5.1517 +      tc.neighborAddresses.push_back (mprsel_tuple->mainAddr);
  5.1518 +    }
  5.1519 +  QueueMessage (msg, JITTER);
  5.1520 +}
  5.1521 +
  5.1522 +///
  5.1523 +/// \brief Creates a new %OLSR MID message which is buffered for being sent later on.
  5.1524 +///
  5.1525 +void
  5.1526 +RoutingProtocol::SendMid ()
  5.1527 +{
  5.1528 +  olsr::MessageHeader msg;
  5.1529 +  olsr::MessageHeader::Mid &mid = msg.GetMid ();
  5.1530 +
  5.1531 +  // A node which has only a single interface address participating in
  5.1532 +  // the MANET (i.e., running OLSR), MUST NOT generate any MID
  5.1533 +  // message.
  5.1534 +
  5.1535 +  // A node with several interfaces, where only one is participating
  5.1536 +  // in the MANET and running OLSR (e.g., a node is connected to a
  5.1537 +  // wired network as well as to a MANET) MUST NOT generate any MID
  5.1538 +  // messages.
  5.1539 +
  5.1540 +  // A node with several interfaces, where more than one is
  5.1541 +  // participating in the MANET and running OLSR MUST generate MID
  5.1542 +  // messages as specified.
  5.1543 +
  5.1544 +  // [ Note: assuming here that all interfaces participate in the
  5.1545 +  // MANET; later we may want to make this configurable. ]
  5.1546 +
  5.1547 +  Ipv4Address loopback ("127.0.0.1");
  5.1548 +  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
  5.1549 +    {
  5.1550 +      Ipv4Address addr = m_ipv4->GetAddress (i);
  5.1551 +      if (addr != m_mainAddress && addr != loopback)
  5.1552 +        mid.interfaceAddresses.push_back (addr);
  5.1553 +    }
  5.1554 +  if (mid.interfaceAddresses.size () == 0)
  5.1555 +    return;
  5.1556 +  
  5.1557 +  msg.SetVTime (OLSR_MID_HOLD_TIME);
  5.1558 +  msg.SetOriginatorAddress (m_mainAddress);
  5.1559 +  msg.SetTimeToLive (255);
  5.1560 +  msg.SetHopCount (0);
  5.1561 +  msg.SetMessageSequenceNumber (GetMessageSequenceNumber ());
  5.1562 +
  5.1563 +  QueueMessage (msg, JITTER);
  5.1564 +}
  5.1565 +
  5.1566 +///
  5.1567 +/// \brief	Updates Link Set according to a new received HELLO message (following RFC 3626
  5.1568 +///		specification). Neighbor Set is also updated if needed.
  5.1569 +void
  5.1570 +RoutingProtocol::LinkSensing (const olsr::MessageHeader &msg,
  5.1571 +                        const olsr::MessageHeader::Hello &hello,
  5.1572 +                        const Ipv4Address &receiverIface,
  5.1573 +                        const Ipv4Address &senderIface)
  5.1574 +{
  5.1575 +  Time now = Simulator::Now ();
  5.1576 +  bool updated = false;
  5.1577 +  bool created = false;
  5.1578 +  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
  5.1579 +                << ": LinkSensing(receiverIface=" << receiverIface
  5.1580 +                << ", senderIface=" << senderIface << ") BEGIN");
  5.1581 +	
  5.1582 +  NS_ASSERT (msg.GetVTime () > Seconds (0));
  5.1583 +  LinkTuple *link_tuple = m_state.FindLinkTuple (senderIface);
  5.1584 +  if (link_tuple == NULL)
  5.1585 +    {
  5.1586 +      LinkTuple newLinkTuple;
  5.1587 +      // We have to create a new tuple
  5.1588 +      newLinkTuple.neighborIfaceAddr = senderIface;
  5.1589 +      newLinkTuple.localIfaceAddr = receiverIface;
  5.1590 +      newLinkTuple.symTime = now - Seconds (1);
  5.1591 +      newLinkTuple.time = now + msg.GetVTime ();
  5.1592 +      link_tuple = &m_state.InsertLinkTuple (newLinkTuple);
  5.1593 +      created = true;
  5.1594 +      NS_LOG_LOGIC ("Existing link tuple did not exist => creating new one");
  5.1595 +    }
  5.1596 +  else
  5.1597 +    {
  5.1598 +      NS_LOG_LOGIC ("Existing link tuple already exists => will update it");
  5.1599 +      updated = true;
  5.1600 +    }
  5.1601 +	
  5.1602 +  link_tuple->asymTime = now + msg.GetVTime ();
  5.1603 +  for (std::vector<olsr::MessageHeader::Hello::LinkMessage>::const_iterator linkMessage =
  5.1604 +         hello.linkMessages.begin ();
  5.1605 +       linkMessage != hello.linkMessages.end ();
  5.1606 +       linkMessage++)
  5.1607 +    {
  5.1608 +      int lt = linkMessage->linkCode & 0x03; // Link Type
  5.1609 +      int nt = (linkMessage->linkCode >> 2) & 0x03; // Neighbor Type
  5.1610 +
  5.1611 +#ifdef NS3_LOG_ENABLE
  5.1612 +      const char *linkTypeName;
  5.1613 +      switch (lt)
  5.1614 +        {
  5.1615 +        case OLSR_UNSPEC_LINK: linkTypeName = "UNSPEC_LINK"; break;
  5.1616 +        case OLSR_ASYM_LINK: linkTypeName = "ASYM_LINK"; break;
  5.1617 +        case OLSR_SYM_LINK: linkTypeName = "SYM_LINK"; break;
  5.1618 +        case OLSR_LOST_LINK: linkTypeName = "LOST_LINK"; break;
  5.1619 +        default: linkTypeName = "(invalid value!)";
  5.1620 +        }
  5.1621 +
  5.1622 +      const char *neighborTypeName;
  5.1623 +      switch (nt)
  5.1624 +        {
  5.1625 +        case OLSR_NOT_NEIGH: neighborTypeName = "NOT_NEIGH"; break;
  5.1626 +        case OLSR_SYM_NEIGH: neighborTypeName = "SYM_NEIGH"; break;
  5.1627 +        case OLSR_MPR_NEIGH: neighborTypeName = "MPR_NEIGH"; break;
  5.1628 +        default: neighborTypeName = "(invalid value!)";
  5.1629 +        }
  5.1630 +
  5.1631 +      NS_LOG_DEBUG ("Looking at HELLO link messages with Link Type "
  5.1632 +                    << lt << " (" << linkTypeName
  5.1633 +                    << ") and Neighbor Type " << nt
  5.1634 +                    << " (" << neighborTypeName << ")");
  5.1635 +#endif
  5.1636 +
  5.1637 +      // We must not process invalid advertised links
  5.1638 +      if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) ||
  5.1639 +          (nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH
  5.1640 +           && nt != OLSR_NOT_NEIGH))
  5.1641 +        {
  5.1642 +          NS_LOG_LOGIC ("HELLO link code is invalid => IGNORING");
  5.1643 +          continue;
  5.1644 +        }
  5.1645 +      
  5.1646 +      for (std::vector<Ipv4Address>::const_iterator neighIfaceAddr =
  5.1647 +             linkMessage->neighborInterfaceAddresses.begin ();
  5.1648 +           neighIfaceAddr != linkMessage->neighborInterfaceAddresses.end ();
  5.1649 +           neighIfaceAddr++)
  5.1650 +        {
  5.1651 +          NS_LOG_DEBUG ("   -> Neighbor: " << *neighIfaceAddr);
  5.1652 +          if (*neighIfaceAddr == receiverIface)
  5.1653 +            {
  5.1654 +              if (lt == OLSR_LOST_LINK)
  5.1655 +                {
  5.1656 +                  NS_LOG_LOGIC ("link is LOST => expiring it");
  5.1657 +                  link_tuple->symTime = now - Seconds (1);
  5.1658 +                  updated = true;
  5.1659 +                }
  5.1660 +              else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK)
  5.1661 +                {
  5.1662 +                  NS_LOG_DEBUG (*link_tuple << ": link is SYM or ASYM => should become SYM now"
  5.1663 +                                " (symTime being increased to " << now + msg.GetVTime ());
  5.1664 +                  link_tuple->symTime = now + msg.GetVTime ();
  5.1665 +                  link_tuple->time = link_tuple->symTime + OLSR_NEIGHB_HOLD_TIME;
  5.1666 +                  updated = true;
  5.1667 +                }
  5.1668 +              else
  5.1669 +                {
  5.1670 +                  NS_FATAL_ERROR ("bad link type");
  5.1671 +                }
  5.1672 +              break;
  5.1673 +            }
  5.1674 +          else
  5.1675 +            {
  5.1676 +              NS_LOG_DEBUG ("     \\-> *neighIfaceAddr (" << *neighIfaceAddr
  5.1677 +                            << " != receiverIface (" << receiverIface << ") => IGNORING!");
  5.1678 +            }
  5.1679 +        }
  5.1680 +      NS_LOG_DEBUG ("Link tuple updated: " << int (updated));
  5.1681 +    }
  5.1682 +  link_tuple->time = std::max(link_tuple->time, link_tuple->asymTime);
  5.1683 +
  5.1684 +  if (updated)
  5.1685 +    {
  5.1686 +      LinkTupleUpdated (*link_tuple, hello.willingness);
  5.1687 +    }
  5.1688 +
  5.1689 +  // Schedules link tuple deletion
  5.1690 +  if (created && link_tuple != NULL)
  5.1691 +    {
  5.1692 +      LinkTupleAdded (*link_tuple, hello.willingness);
  5.1693 +      m_events.Track (Simulator::Schedule (DELAY (std::min (link_tuple->time, link_tuple->symTime)),
  5.1694 +                                           &RoutingProtocol::LinkTupleTimerExpire, this,
  5.1695 +                                           link_tuple->neighborIfaceAddr));
  5.1696 +    }
  5.1697 +  NS_LOG_DEBUG ("@" << now.GetSeconds () << ": Olsr node " << m_mainAddress
  5.1698 +                << ": LinkSensing END");
  5.1699 +}
  5.1700 +
  5.1701 +///
  5.1702 +/// \brief	Updates the Neighbor Set according to the information contained in a new received
  5.1703 +///		HELLO message (following RFC 3626).
  5.1704 +void
  5.1705 +RoutingProtocol::PopulateNeighborSet (const olsr::MessageHeader &msg,
  5.1706 +                                const olsr::MessageHeader::Hello &hello)
  5.1707 +{
  5.1708 +  NeighborTuple *nb_tuple = m_state.FindNeighborTuple (msg.GetOriginatorAddress ());
  5.1709 +  if (nb_tuple != NULL)
  5.1710 +    {
  5.1711 +      nb_tuple->willingness = hello.willingness;
  5.1712 +    }
  5.1713 +}
  5.1714 +
  5.1715 +
  5.1716 +///
  5.1717 +/// \brief	Updates the 2-hop Neighbor Set according to the information contained in a new
  5.1718 +///		received HELLO message (following RFC 3626).
  5.1719 +void
  5.1720 +RoutingProtocol::PopulateTwoHopNeighborSet (const olsr::MessageHeader &msg,
  5.1721 +                                      const olsr::MessageHeader::Hello &hello)
  5.1722 +{
  5.1723 +  Time now = Simulator::Now ();
  5.1724 +
  5.1725 +  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet BEGIN");
  5.1726 +	
  5.1727 +  for (LinkSet::const_iterator link_tuple = m_state.GetLinks ().begin ();
  5.1728 +       link_tuple != m_state.GetLinks ().end (); link_tuple++)
  5.1729 +    {
  5.1730 +      NS_LOG_LOGIC ("Looking at link tuple: " << *link_tuple);
  5.1731 +      if (GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ())
  5.1732 +        {
  5.1733 +          NS_LOG_LOGIC ("Link tuple ignored: "
  5.1734 +                        "GetMainAddress (link_tuple->neighborIfaceAddr) != msg.GetOriginatorAddress ()");
  5.1735 +          NS_LOG_LOGIC ("(GetMainAddress(" << link_tuple->neighborIfaceAddr << "): "
  5.1736 +                        << GetMainAddress (link_tuple->neighborIfaceAddr)
  5.1737 +                        << "; msg.GetOriginatorAddress (): " << msg.GetOriginatorAddress ());
  5.1738 +          continue;
  5.1739 +        }
  5.1740 +
  5.1741 +      if (link_tuple->symTime < now)
  5.1742 +        {
  5.1743 +          NS_LOG_LOGIC ("Link tuple ignored: expired.");
  5.1744 +          continue;
  5.1745 +        }
  5.1746 +
  5.1747 +      typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
  5.1748 +      for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
  5.1749 +           linkMessage != hello.linkMessages.end (); linkMessage++)
  5.1750 +        {
  5.1751 +          int neighborType = (linkMessage->linkCode >> 2) & 0x3;
  5.1752 +#ifdef NS3_LOG_ENABLE
  5.1753 +          const char *neighborTypeNames[3] = { "NOT_NEIGH", "SYM_NEIGH", "MPR_NEIGH" };
  5.1754 +          const char *neighborTypeName = ((neighborType < 3)?
  5.1755 +                                          neighborTypeNames[neighborType]
  5.1756 +                                          : "(invalid value)");
  5.1757 +          NS_LOG_DEBUG ("Looking at Link Message from HELLO message: neighborType="
  5.1758 +                        << neighborType << " (" << neighborTypeName << ")");
  5.1759 +#endif
  5.1760 +
  5.1761 +          for (std::vector<Ipv4Address>::const_iterator nb2hop_addr_iter =
  5.1762 +                 linkMessage->neighborInterfaceAddresses.begin ();
  5.1763 +               nb2hop_addr_iter != linkMessage->neighborInterfaceAddresses.end ();
  5.1764 +               nb2hop_addr_iter++)
  5.1765 +            {
  5.1766 +              Ipv4Address nb2hop_addr = GetMainAddress (*nb2hop_addr_iter);
  5.1767 +              NS_LOG_DEBUG ("Looking at 2-hop neighbor address from HELLO message: "
  5.1768 +                            << *nb2hop_addr_iter
  5.1769 +                            << " (main address is " << nb2hop_addr << ")");
  5.1770 +              if (neighborType == OLSR_SYM_NEIGH || neighborType == OLSR_MPR_NEIGH)
  5.1771 +                {
  5.1772 +                  // If the main address of the 2-hop neighbor address == main address
  5.1773 +                  // of the receiving node, silently discard the 2-hop
  5.1774 +                  // neighbor address.
  5.1775 +                  if (nb2hop_addr == m_routingAgentAddr)
  5.1776 +                    {
  5.1777 +                      NS_LOG_LOGIC ("Ignoring 2-hop neighbor (it is the node itself)");
  5.1778 +                      continue;
  5.1779 +                    }
  5.1780 +
  5.1781 +                  // Otherwise, a 2-hop tuple is created
  5.1782 +                  TwoHopNeighborTuple *nb2hop_tuple =
  5.1783 +                    m_state.FindTwoHopNeighborTuple (msg.GetOriginatorAddress (), nb2hop_addr);
  5.1784 +                  NS_LOG_LOGIC ("Adding the 2-hop neighbor"
  5.1785 +                                << (nb2hop_tuple? " (refreshing existing entry)" : ""));
  5.1786 +                  if (nb2hop_tuple == NULL)
  5.1787 +                    {
  5.1788 +                      TwoHopNeighborTuple new_nb2hop_tuple;
  5.1789 +                      new_nb2hop_tuple.neighborMainAddr = msg.GetOriginatorAddress ();
  5.1790 +                      new_nb2hop_tuple.twoHopNeighborAddr = nb2hop_addr;
  5.1791 +                      new_nb2hop_tuple.expirationTime = now + msg.GetVTime ();
  5.1792 +                      AddTwoHopNeighborTuple (new_nb2hop_tuple);
  5.1793 +                      // Schedules nb2hop tuple deletion
  5.1794 +                      m_events.Track (Simulator::Schedule (DELAY (new_nb2hop_tuple.expirationTime),
  5.1795 +                                                           &RoutingProtocol::Nb2hopTupleTimerExpire, this,
  5.1796 +                                                           new_nb2hop_tuple.neighborMainAddr,
  5.1797 +                                                           new_nb2hop_tuple.twoHopNeighborAddr));
  5.1798 +                    }
  5.1799 +                  else
  5.1800 +                    {
  5.1801 +                      nb2hop_tuple->expirationTime = now + msg.GetVTime ();
  5.1802 +                    }
  5.1803 +                }
  5.1804 +              else if (neighborType == OLSR_NOT_NEIGH)
  5.1805 +                {
  5.1806 +                  // For each 2-hop node listed in the HELLO message
  5.1807 +                  // with Neighbor Type equal to NOT_NEIGH all 2-hop
  5.1808 +                  // tuples where: N_neighbor_main_addr == Originator
  5.1809 +                  // Address AND N_2hop_addr == main address of the
  5.1810 +                  // 2-hop neighbor are deleted.
  5.1811 +                  NS_LOG_LOGIC ("2-hop neighbor is NOT_NEIGH => deleting matching 2-hop neighbor state");
  5.1812 +                  m_state.EraseTwoHopNeighborTuples (msg.GetOriginatorAddress (), nb2hop_addr);
  5.1813 +                }
  5.1814 +              else
  5.1815 +                {
  5.1816 +                  NS_LOG_LOGIC ("*** WARNING *** Ignoring link message (inside HELLO) with bad"
  5.1817 +                                " neighbor type value: " << neighborType);
  5.1818 +                }
  5.1819 +            }
  5.1820 +        }
  5.1821 +    }
  5.1822 +
  5.1823 +  NS_LOG_DEBUG ("Olsr node " << m_mainAddress << ": PopulateTwoHopNeighborSet END");
  5.1824 +}
  5.1825 +
  5.1826 +
  5.1827 +
  5.1828 +///
  5.1829 +/// \brief	Updates the MPR Selector Set according to the information contained in a new
  5.1830 +///		received HELLO message (following RFC 3626).
  5.1831 +void
  5.1832 +RoutingProtocol::PopulateMprSelectorSet (const olsr::MessageHeader &msg,
  5.1833 +                                       const olsr::MessageHeader::Hello &hello)
  5.1834 +{
  5.1835 +  NS_LOG_FUNCTION (this);
  5.1836 +  
  5.1837 +  Time now = Simulator::Now ();
  5.1838 +	
  5.1839 +  typedef std::vector<olsr::MessageHeader::Hello::LinkMessage> LinkMessageVec;
  5.1840 +  for (LinkMessageVec::const_iterator linkMessage = hello.linkMessages.begin ();
  5.1841 +       linkMessage != hello.linkMessages.end ();
  5.1842 +       linkMessage++)
  5.1843 +    {
  5.1844 +      int nt = linkMessage->linkCode >> 2;
  5.1845 +      if (nt == OLSR_MPR_NEIGH)
  5.1846 +        {
  5.1847 +          NS_LOG_DEBUG ("Processing a link message with neighbor type MPR_NEIGH");
  5.1848 +          
  5.1849 +          for (std::vector<Ipv4Address>::const_iterator nb_iface_addr =
  5.1850 +                 linkMessage->neighborInterfaceAddresses.begin ();
  5.1851 +               nb_iface_addr != linkMessage->neighborInterfaceAddresses.end ();
  5.1852 +               nb_iface_addr++)
  5.1853 +            {
  5.1854 +              if (GetMainAddress (*nb_iface_addr) == m_mainAddress)
  5.1855 +                {
  5.1856 +                  NS_LOG_DEBUG ("Adding entry to mpr selector set for neighbor " << *nb_iface_addr);
  5.1857 +                  
  5.1858 +                  // We must create a new entry into the mpr selector set
  5.1859 +                  MprSelectorTuple *existing_mprsel_tuple =
  5.1860 +                    m_state.FindMprSelectorTuple (msg.GetOriginatorAddress ());
  5.1861 +                  if (existing_mprsel_tuple == NULL)
  5.1862 +                    {
  5.1863 +                      MprSelectorTuple mprsel_tuple;
  5.1864 +
  5.1865 +                      mprsel_tuple.mainAddr = msg.GetOriginatorAddress ();
  5.1866 +                      mprsel_tuple.expirationTime = now + msg.GetVTime ();
  5.1867 +                      AddMprSelectorTuple (mprsel_tuple);
  5.1868 +
  5.1869 +                      // Schedules mpr selector tuple deletion
  5.1870 +                      m_events.Track (Simulator::Schedule
  5.1871 +                                      (DELAY (mprsel_tuple.expirationTime),
  5.1872 +                                       &RoutingProtocol::MprSelTupleTimerExpire, this,
  5.1873 +                                       mprsel_tuple.mainAddr));
  5.1874 +                    }
  5.1875 +                  else
  5.1876 +                    {
  5.1877 +                      existing_mprsel_tuple->expirationTime = now + msg.GetVTime ();
  5.1878 +                    }
  5.1879 +                }
  5.1880 +            }
  5.1881 +        }
  5.1882 +    }
  5.1883 +  NS_LOG_DEBUG ("Computed MPR selector set for node " << m_mainAddress << ": " << m_state.PrintMprSelectorSet ());
  5.1884 +}
  5.1885 +
  5.1886 +
  5.1887 +#if 0
  5.1888 +///
  5.1889 +/// \brief	Drops a given packet because it couldn't be delivered to the corresponding
  5.1890 +///		destination by the MAC layer. This may cause a neighbor loss, and appropiate
  5.1891 +///		actions are then taken.
  5.1892 +///
  5.1893 +/// \param p the packet which couldn't be delivered by the MAC layer.
  5.1894 +///
  5.1895 +void
  5.1896 +OLSR::mac_failed(Ptr<Packet> p) {
  5.1897 +	double now		= Simulator::Now ();
  5.1898 +	struct hdr_ip* ih	= HDR_IP(p);
  5.1899 +	struct hdr_cmn* ch	= HDR_CMN(p);
  5.1900 +	
  5.1901 +	debug("%f: Node %d MAC Layer detects a breakage on link to %d\n",
  5.1902 +		now,
  5.1903 +		OLSR::node_id(ra_addr()),
  5.1904 +		OLSR::node_id(ch->next_hop()));
  5.1905 +	
  5.1906 +	if ((u_int32_t)ih->daddr() == IP_BROADCAST) {
  5.1907 +		drop(p, DROP_RTR_MAC_CALLBACK);
  5.1908 +		return;
  5.1909 +	}
  5.1910 +	
  5.1911 +	OLSR_link_tuple* link_tuple = state_.find_link_tuple(ch->next_hop());
  5.1912 +	if (link_tuple != NULL) {
  5.1913 +		link_tuple->lost_time()	= now + OLSR_NEIGHB_HOLD_TIME;
  5.1914 +		link_tuple->time()	= now + OLSR_NEIGHB_HOLD_TIME;
  5.1915 +		nb_loss(link_tuple);
  5.1916 +	}
  5.1917 +	drop(p, DROP_RTR_MAC_CALLBACK);
  5.1918 +}
  5.1919 +#endif
  5.1920 +
  5.1921 +
  5.1922 +
  5.1923 +
  5.1924 +///
  5.1925 +/// \brief Performs all actions needed when a neighbor loss occurs.
  5.1926 +///
  5.1927 +/// Neighbor Set, 2-hop Neighbor Set, MPR Set and MPR Selector Set are updated.
  5.1928 +///
  5.1929 +/// \param tuple link tuple with the information of the link to the neighbor which has been lost.
  5.1930 +///
  5.1931 +void
  5.1932 +RoutingProtocol::NeighborLoss (const LinkTuple &tuple)
  5.1933 +{
  5.1934 +  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  5.1935 +                << "s: OLSR Node " << m_mainAddress
  5.1936 +                << " LinkTuple " << tuple.neighborIfaceAddr << " -> neighbor loss.");
  5.1937 +  LinkTupleUpdated (tuple, OLSR_WILL_DEFAULT);
  5.1938 +  m_state.EraseTwoHopNeighborTuples (GetMainAddress (tuple.neighborIfaceAddr));
  5.1939 +  m_state.EraseMprSelectorTuples (GetMainAddress (tuple.neighborIfaceAddr));
  5.1940 +  
  5.1941 +  MprComputation ();
  5.1942 +  RoutingTableComputation ();
  5.1943 +}
  5.1944 +
  5.1945 +///
  5.1946 +/// \brief Adds a duplicate tuple to the Duplicate Set.
  5.1947 +///
  5.1948 +/// \param tuple the duplicate tuple to be added.
  5.1949 +///
  5.1950 +void
  5.1951 +RoutingProtocol::AddDuplicateTuple (const DuplicateTuple &tuple)
  5.1952 +{
  5.1953 +	/*debug("%f: Node %d adds dup tuple: addr = %d seq_num = %d\n",
  5.1954 +		Simulator::Now (),
  5.1955 +		OLSR::node_id(ra_addr()),
  5.1956 +		OLSR::node_id(tuple->addr()),
  5.1957 +		tuple->seq_num());*/
  5.1958 +  m_state.InsertDuplicateTuple (tuple);
  5.1959 +}
  5.1960 +
  5.1961 +///
  5.1962 +/// \brief Removes a duplicate tuple from the Duplicate Set.
  5.1963 +///
  5.1964 +/// \param tuple the duplicate tuple to be removed.
  5.1965 +///
  5.1966 +void
  5.1967 +RoutingProtocol::RemoveDuplicateTuple (const DuplicateTuple &tuple)
  5.1968 +{
  5.1969 +  /*debug("%f: Node %d removes dup tuple: addr = %d seq_num = %d\n",
  5.1970 +    Simulator::Now (),
  5.1971 +    OLSR::node_id(ra_addr()),
  5.1972 +    OLSR::node_id(tuple->addr()),
  5.1973 +    tuple->seq_num());*/
  5.1974 +  m_state.EraseDuplicateTuple (tuple);
  5.1975 +}
  5.1976 +
  5.1977 +void
  5.1978 +RoutingProtocol::LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness)
  5.1979 +{
  5.1980 +  // Creates associated neighbor tuple
  5.1981 +  NeighborTuple nb_tuple;
  5.1982 +  nb_tuple.neighborMainAddr = GetMainAddress (tuple.neighborIfaceAddr);
  5.1983 +  nb_tuple.willingness = willingness;
  5.1984 +
  5.1985 +  if (tuple.symTime >= Simulator::Now ())
  5.1986 +    {
  5.1987 +      nb_tuple.status = NeighborTuple::STATUS_SYM;
  5.1988 +    }
  5.1989 +  else
  5.1990 +    {
  5.1991 +      nb_tuple.status = NeighborTuple::STATUS_NOT_SYM;
  5.1992 +    }
  5.1993 +
  5.1994 +  AddNeighborTuple (nb_tuple);
  5.1995 +}
  5.1996 +
  5.1997 +///
  5.1998 +/// \brief Removes a link tuple from the Link Set.
  5.1999 +///
  5.2000 +/// \param tuple the link tuple to be removed.
  5.2001 +///
  5.2002 +void
  5.2003 +RoutingProtocol::RemoveLinkTuple (const LinkTuple &tuple)
  5.2004 +{
  5.2005 +  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  5.2006 +                << "s: OLSR Node " << m_mainAddress
  5.2007 +                << " LinkTuple " << tuple << " REMOVED.");
  5.2008 +
  5.2009 +  m_state.EraseLinkTuple (tuple);
  5.2010 +  m_state.EraseNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
  5.2011 +
  5.2012 +}
  5.2013 +
  5.2014 +///
  5.2015 +/// \brief	This function is invoked when a link tuple is updated. Its aim is to
  5.2016 +///		also update the corresponding neighbor tuple if it is needed.
  5.2017 +///
  5.2018 +/// \param tuple the link tuple which has been updated.
  5.2019 +///
  5.2020 +void
  5.2021 +RoutingProtocol::LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness)
  5.2022 +{
  5.2023 +  // Each time a link tuple changes, the associated neighbor tuple must be recomputed
  5.2024 +
  5.2025 +  NS_LOG_DEBUG (Simulator::Now ().GetSeconds ()
  5.2026 +                << "s: OLSR Node " << m_mainAddress
  5.2027 +                << " LinkTuple " << tuple << " UPDATED.");
  5.2028 +
  5.2029 +  NeighborTuple *nb_tuple =
  5.2030 +    m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
  5.2031 +  
  5.2032 +  if (nb_tuple == NULL)
  5.2033 +    {
  5.2034 +      LinkTupleAdded (tuple, willingness);
  5.2035 +      nb_tuple = m_state.FindNeighborTuple (GetMainAddress (tuple.neighborIfaceAddr));
  5.2036 +    }
  5.2037 +
  5.2038 +  if (nb_tuple != NULL)
  5.2039 +    {
  5.2040 +#ifdef NS3_LOG_ENABLE
  5.2041 +      int statusBefore = nb_tuple->status;
  5.2042 +#endif
  5.2043 +      if (tuple.symTime >= Simulator::Now ())
  5.2044 +        {
  5.2045 +          nb_tuple->status = NeighborTuple::STATUS_SYM;
  5.2046 +          NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_SYM; changed:"
  5.2047 +                        << int (statusBefore != nb_tuple->status));
  5.2048 +        }
  5.2049 +      else
  5.2050 +        {
  5.2051 +          nb_tuple->status = NeighborTuple::STATUS_NOT_SYM;
  5.2052 +          NS_LOG_DEBUG (*nb_tuple << "->status = STATUS_NOT_SYM; changed:"
  5.2053 +                        << int (statusBefore != nb_tuple->status));
  5.2054 +        }
  5.2055 +    }
  5.2056 +  else
  5.2057 +    {
  5.2058 +      NS_LOG_WARN ("ERROR! Wanted to update a NeighborTuple but none was found!");
  5.2059 +    }
  5.2060 +}
  5.2061 +
  5.2062 +///
  5.2063 +/// \brief Adds a neighbor tuple to the Neighbor Set.
  5.2064 +///
  5.2065 +/// \param tuple the neighbor tuple to be added.
  5.2066 +///
  5.2067 +void
  5.2068 +RoutingProtocol::AddNeighborTuple (const NeighborTuple &tuple)
  5.2069 +{
  5.2070 +//   debug("%f: Node %d adds neighbor tuple: nb_addr = %d status = %s\n",
  5.2071 +//         Simulator::Now (),
  5.2072 +//         OLSR::node_id(ra_addr()),
  5.2073 +//         OLSR::node_id(tuple->neighborMainAddr),
  5.2074 +//         ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
  5.2075 +  
  5.2076 +  m_state.InsertNeighborTuple (tuple);
  5.2077 +  IncrementAnsn ();
  5.2078 +}
  5.2079 +
  5.2080 +///
  5.2081 +/// \brief Removes a neighbor tuple from the Neighbor Set.
  5.2082 +///
  5.2083 +/// \param tuple the neighbor tuple to be removed.
  5.2084 +///
  5.2085 +void
  5.2086 +RoutingProtocol::RemoveNeighborTuple (const NeighborTuple &tuple)
  5.2087 +{
  5.2088 +//   debug("%f: Node %d removes neighbor tuple: nb_addr = %d status = %s\n",
  5.2089 +//         Simulator::Now (),
  5.2090 +//         OLSR::node_id(ra_addr()),
  5.2091 +//         OLSR::node_id(tuple->neighborMainAddr),
  5.2092 +//         ((tuple->status() == OLSR_STATUS_SYM) ? "sym" : "not_sym"));
  5.2093 +	
  5.2094 +  m_state.EraseNeighborTuple (tuple);
  5.2095 +  IncrementAnsn ();
  5.2096 +}
  5.2097 +
  5.2098 +///
  5.2099 +/// \brief Adds a 2-hop neighbor tuple to the 2-hop Neighbor Set.
  5.2100 +///
  5.2101 +/// \param tuple the 2-hop neighbor tuple to be added.
  5.2102 +///
  5.2103 +void
  5.2104 +RoutingProtocol::AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
  5.2105 +{
  5.2106 +//   debug("%f: Node %d adds 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
  5.2107 +//         Simulator::Now (),
  5.2108 +//         OLSR::node_id(ra_addr()),
  5.2109 +//         OLSR::node_id(tuple->neighborMainAddr),
  5.2110 +//         OLSR::node_id(tuple->twoHopNeighborAddr));
  5.2111 +  
  5.2112 +  m_state.InsertTwoHopNeighborTuple (tuple);
  5.2113 +}
  5.2114 +
  5.2115 +///
  5.2116 +/// \brief Removes a 2-hop neighbor tuple from the 2-hop Neighbor Set.
  5.2117 +///
  5.2118 +/// \param tuple the 2-hop neighbor tuple to be removed.
  5.2119 +///
  5.2120 +void
  5.2121 +RoutingProtocol::RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
  5.2122 +{
  5.2123 +//   debug("%f: Node %d removes 2-hop neighbor tuple: nb_addr = %d nb2hop_addr = %d\n",
  5.2124 +//         Simulator::Now (),
  5.2125 +//         OLSR::node_id(ra_addr()),
  5.2126 +//         OLSR::node_id(tuple->neighborMainAddr),
  5.2127 +//         OLSR::node_id(tuple->twoHopNeighborAddr));
  5.2128 +
  5.2129 +  m_state.EraseTwoHopNeighborTuple (tuple);
  5.2130 +}
  5.2131 +
  5.2132 +void
  5.2133 +RoutingProtocol::IncrementAnsn ()
  5.2134 +{
  5.2135 +  m_ansn = (m_ansn + 1) % (OLSR_MAX_SEQ_NUM + 1);
  5.2136 +}
  5.2137 +
  5.2138 +///
  5.2139 +/// \brief Adds an MPR selector tuple to the MPR Selector Set.
  5.2140 +///
  5.2141 +/// Advertised Neighbor Sequence Number (ANSN) is also updated.
  5.2142 +///
  5.2143 +/// \param tuple the MPR selector tuple to be added.
  5.2144 +///
  5.2145 +void
  5.2146 +RoutingProtocol::AddMprSelectorTuple (const MprSelectorTuple  &tuple)
  5.2147 +{
  5.2148 +//   debug("%f: Node %d adds MPR selector tuple: nb_addr = %d\n",
  5.2149 +//         Simulator::Now (),
  5.2150 +//         OLSR::node_id(ra_addr()),
  5.2151 +//         OLSR::node_id(tuple->main_addr()));
  5.2152 +  
  5.2153 +  m_state.InsertMprSelectorTuple (tuple);
  5.2154 +  IncrementAnsn ();
  5.2155 +}
  5.2156 +
  5.2157 +///
  5.2158 +/// \brief Removes an MPR selector tuple from the MPR Selector Set.
  5.2159 +///
  5.2160 +/// Advertised Neighbor Sequence Number (ANSN) is also updated.
  5.2161 +///
  5.2162 +/// \param tuple the MPR selector tuple to be removed.
  5.2163 +///
  5.2164 +void
  5.2165 +RoutingProtocol::RemoveMprSelectorTuple (const MprSelectorTuple &tuple)
  5.2166 +{
  5.2167 +//   debug("%f: Node %d removes MPR selector tuple: nb_addr = %d\n",
  5.2168 +//         Simulator::Now (),
  5.2169 +//         OLSR::node_id(ra_addr()),
  5.2170 +//         OLSR::node_id(tuple->main_addr()));
  5.2171 +  
  5.2172 +  m_state.EraseMprSelectorTuple (tuple);
  5.2173 +  IncrementAnsn ();
  5.2174 +}
  5.2175 +
  5.2176 +///
  5.2177 +/// \brief Adds a topology tuple to the Topology Set.
  5.2178 +///
  5.2179 +/// \param tuple the topology tuple to be added.
  5.2180 +///
  5.2181 +void
  5.2182 +RoutingProtocol::AddTopologyTuple (const TopologyTuple &tuple)
  5.2183 +{
  5.2184 +//   debug("%f: Node %d adds topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
  5.2185 +//         Simulator::Now (),
  5.2186 +//         OLSR::node_id(ra_addr()),
  5.2187 +//         OLSR::node_id(tuple->dest_addr()),
  5.2188 +//         OLSR::node_id(tuple->last_addr()),
  5.2189 +//         tuple->seq());
  5.2190 +
  5.2191 +  m_state.InsertTopologyTuple(tuple);
  5.2192 +}
  5.2193 +
  5.2194 +///
  5.2195 +/// \brief Removes a topology tuple from the Topology Set.
  5.2196 +///
  5.2197 +/// \param tuple the topology tuple to be removed.
  5.2198 +///
  5.2199 +void
  5.2200 +RoutingProtocol::RemoveTopologyTuple (const TopologyTuple &tuple)
  5.2201 +{
  5.2202 +//   debug("%f: Node %d removes topology tuple: dest_addr = %d last_addr = %d seq = %d\n",
  5.2203 +//         Simulator::Now (),
  5.2204 +//         OLSR::node_id(ra_addr()),
  5.2205 +//         OLSR::node_id(tuple->dest_addr()),
  5.2206 +//         OLSR::node_id(tuple->last_addr()),
  5.2207 +//         tuple->seq());
  5.2208 +
  5.2209 +  m_state.EraseTopologyTuple (tuple);
  5.2210 +}
  5.2211 +
  5.2212 +///
  5.2213 +/// \brief Adds an interface association tuple to the Interface Association Set.
  5.2214 +///
  5.2215 +/// \param tuple the interface association tuple to be added.
  5.2216 +///
  5.2217 +void
  5.2218 +RoutingProtocol::AddIfaceAssocTuple (const IfaceAssocTuple &tuple)
  5.2219 +{
  5.2220 +//   debug("%f: Node %d adds iface association tuple: main_addr = %d iface_addr = %d\n",
  5.2221 +//         Simulator::Now (),
  5.2222 +//         OLSR::node_id(ra_addr()),
  5.2223 +//         OLSR::node_id(tuple->main_addr()),
  5.2224 +//         OLSR::node_id(tuple->iface_addr()));
  5.2225 +
  5.2226 +  m_state.InsertIfaceAssocTuple (tuple);
  5.2227 +}
  5.2228 +
  5.2229 +///
  5.2230 +/// \brief Removes an interface association tuple from the Interface Association Set.
  5.2231 +///
  5.2232 +/// \param tuple the interface association tuple to be removed.
  5.2233 +///
  5.2234 +void
  5.2235 +RoutingProtocol::RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple)
  5.2236 +{
  5.2237 +//   debug("%f: Node %d removes iface association tuple: main_addr = %d iface_addr = %d\n",
  5.2238 +//         Simulator::Now (),
  5.2239 +//         OLSR::node_id(ra_addr()),
  5.2240 +//         OLSR::node_id(tuple->main_addr()),
  5.2241 +//         OLSR::node_id(tuple->iface_addr()));
  5.2242 +
  5.2243 +  m_state.EraseIfaceAssocTuple (tuple);
  5.2244 +}
  5.2245 +
  5.2246 +
  5.2247 +uint16_t RoutingProtocol::GetPacketSequenceNumber ()
  5.2248 +{
  5.2249 +  m_packetSequenceNumber = (m_packetSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1);
  5.2250 +  return m_packetSequenceNumber;
  5.2251 +}
  5.2252 +
  5.2253 +/// Increments message sequence number and returns the new value.
  5.2254 +uint16_t RoutingProtocol::GetMessageSequenceNumber ()
  5.2255 +{
  5.2256 +  m_messageSequenceNumber = (m_messageSequenceNumber + 1) % (OLSR_MAX_SEQ_NUM + 1);
  5.2257 +  return m_messageSequenceNumber;
  5.2258 +}
  5.2259 +
  5.2260 +
  5.2261 +///
  5.2262 +/// \brief Sends a HELLO message and reschedules the HELLO timer.
  5.2263 +/// \param e The event which has expired.
  5.2264 +///
  5.2265 +void
  5.2266 +RoutingProtocol::HelloTimerExpire ()
  5.2267 +{
  5.2268 +  SendHello ();
  5.2269 +  m_helloTimer.Schedule (m_helloInterval);
  5.2270 +}
  5.2271 +
  5.2272 +///
  5.2273 +/// \brief Sends a TC message (if there exists any MPR selector) and reschedules the TC timer.
  5.2274 +/// \param e The event which has expired.
  5.2275 +///
  5.2276 +void
  5.2277 +RoutingProtocol::TcTimerExpire ()
  5.2278 +{
  5.2279 +  if (m_state.GetMprSelectors ().size () > 0)
  5.2280 +    {
  5.2281 +      SendTc ();
  5.2282 +    }
  5.2283 +  else
  5.2284 +    {
  5.2285 +      NS_LOG_DEBUG ("Not sending any TC, no one selected me as MPR.");
  5.2286 +    }
  5.2287 +  m_tcTimer.Schedule (m_tcInterval);
  5.2288 +}
  5.2289 +
  5.2290 +///
  5.2291 +/// \brief Sends a MID message (if the node has more than one interface) and resets the MID timer.
  5.2292 +/// \warning Currently it does nothing because there is no support for multiple interfaces.
  5.2293 +/// \param e The event which has expired.
  5.2294 +///
  5.2295 +void
  5.2296 +RoutingProtocol::MidTimerExpire ()
  5.2297 +{
  5.2298 +  SendMid ();
  5.2299 +  m_midTimer.Schedule (m_midInterval);
  5.2300 +}
  5.2301 +
  5.2302 +///
  5.2303 +/// \brief Removes tuple if expired. Else timer is rescheduled to expire at tuple.expirationTime.
  5.2304 +///
  5.2305 +/// The task of actually removing the tuple is left to the OLSR agent.
  5.2306 +///
  5.2307 +/// \param tuple The tuple which has expired.
  5.2308 +///
  5.2309 +void
  5.2310 +RoutingProtocol::DupTupleTimerExpire (Ipv4Address address, uint16_t sequenceNumber)
  5.2311 +{
  5.2312 +  DuplicateTuple *tuple =
  5.2313 +    m_state.FindDuplicateTuple (address, sequenceNumber);
  5.2314 +  if (tuple == NULL)
  5.2315 +    {
  5.2316 +      return;
  5.2317 +    }
  5.2318 +  if (tuple->expirationTime < Simulator::Now ())
  5.2319 +    {
  5.2320 +      RemoveDuplicateTuple (*tuple);
  5.2321 +    }
  5.2322 +  else
  5.2323 +    {
  5.2324 +      m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  5.2325 +                                           &RoutingProtocol::DupTupleTimerExpire, this,
  5.2326 +                                           address, sequenceNumber));
  5.2327 +    }
  5.2328 +}
  5.2329 +
  5.2330 +///
  5.2331 +/// \brief Removes tuple_ if expired. Else if symmetric time
  5.2332 +/// has expired then it is assumed a neighbor loss and agent_->nb_loss()
  5.2333 +/// is called. In this case the timer is rescheduled to expire at
  5.2334 +/// tuple_->time(). Otherwise the timer is rescheduled to expire at
  5.2335 +/// the minimum between tuple_->time() and tuple_->sym_time().
  5.2336 +///
  5.2337 +/// The task of actually removing the tuple is left to the OLSR agent.
  5.2338 +///
  5.2339 +/// \param e The event which has expired.
  5.2340 +///
  5.2341 +void
  5.2342 +RoutingProtocol::LinkTupleTimerExpire (Ipv4Address neighborIfaceAddr)
  5.2343 +{
  5.2344 +  Time now = Simulator::Now ();
  5.2345 +
  5.2346 +  // the tuple parameter may be a stale copy; get a newer version from m_state
  5.2347 +  LinkTuple *tuple = m_state.FindLinkTuple (neighborIfaceAddr);
  5.2348 +  if (tuple == NULL)
  5.2349 +    {
  5.2350 +      return;
  5.2351 +    }
  5.2352 +  if (tuple->time < now)
  5.2353 +    {
  5.2354 +      RemoveLinkTuple (*tuple);
  5.2355 +    }
  5.2356 +  else if (tuple->symTime < now)
  5.2357 +    {
  5.2358 +      if (m_linkTupleTimerFirstTime)
  5.2359 +        m_linkTupleTimerFirstTime = false;
  5.2360 +      else
  5.2361 +        NeighborLoss (*tuple);
  5.2362 +
  5.2363 +      m_events.Track (Simulator::Schedule (DELAY (tuple->time),
  5.2364 +                                           &RoutingProtocol::LinkTupleTimerExpire, this,
  5.2365 +                                           neighborIfaceAddr));
  5.2366 +    }
  5.2367 +  else
  5.2368 +    {
  5.2369 +      m_events.Track (Simulator::Schedule (DELAY (std::min (tuple->time, tuple->symTime)),
  5.2370 +                                           &RoutingProtocol::LinkTupleTimerExpire, this,
  5.2371 +                                           neighborIfaceAddr));
  5.2372 +    }
  5.2373 +}
  5.2374 +
  5.2375 +///
  5.2376 +/// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
  5.2377 +///
  5.2378 +/// The task of actually removing the tuple is left to the OLSR agent.
  5.2379 +///
  5.2380 +/// \param e The event which has expired.
  5.2381 +///
  5.2382 +void
  5.2383 +RoutingProtocol::Nb2hopTupleTimerExpire (Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr)
  5.2384 +{
  5.2385 +  TwoHopNeighborTuple *tuple;
  5.2386 +  tuple = m_state.FindTwoHopNeighborTuple (neighborMainAddr, twoHopNeighborAddr);
  5.2387 +  if (tuple == NULL)
  5.2388 +    {
  5.2389 +      return;
  5.2390 +    }
  5.2391 +  if (tuple->expirationTime < Simulator::Now ())
  5.2392 +    {
  5.2393 +      RemoveTwoHopNeighborTuple (*tuple);
  5.2394 +    }
  5.2395 +  else
  5.2396 +    {
  5.2397 +      m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  5.2398 +                                           &RoutingProtocol::Nb2hopTupleTimerExpire,
  5.2399 +                                           this, neighborMainAddr, twoHopNeighborAddr));
  5.2400 +    }
  5.2401 +}
  5.2402 +
  5.2403 +///
  5.2404 +/// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
  5.2405 +///
  5.2406 +/// The task of actually removing the tuple is left to the OLSR agent.
  5.2407 +///
  5.2408 +/// \param e The event which has expired.
  5.2409 +///
  5.2410 +void
  5.2411 +RoutingProtocol::MprSelTupleTimerExpire (Ipv4Address mainAddr)
  5.2412 +{
  5.2413 +  MprSelectorTuple *tuple = m_state.FindMprSelectorTuple (mainAddr);
  5.2414 +  if (tuple == NULL)
  5.2415 +    {
  5.2416 +      return;
  5.2417 +    }
  5.2418 +  if (tuple->expirationTime < Simulator::Now ())
  5.2419 +    {
  5.2420 +      RemoveMprSelectorTuple (*tuple);
  5.2421 +    }
  5.2422 +  else
  5.2423 +    {
  5.2424 +      m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  5.2425 +                                           &RoutingProtocol::MprSelTupleTimerExpire,
  5.2426 +                                           this, mainAddr));
  5.2427 +    }
  5.2428 +}
  5.2429 +
  5.2430 +///
  5.2431 +/// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().
  5.2432 +///
  5.2433 +/// The task of actually removing the tuple is left to the OLSR agent.
  5.2434 +///
  5.2435 +/// \param e The event which has expired.
  5.2436 +///
  5.2437 +void
  5.2438 +RoutingProtocol::TopologyTupleTimerExpire (Ipv4Address destAddr, Ipv4Address lastAddr)
  5.2439 +{
  5.2440 +  TopologyTuple *tuple = m_state.FindTopologyTuple (destAddr, lastAddr);
  5.2441 +  if (tuple == NULL)
  5.2442 +    {
  5.2443 +      return;
  5.2444 +    }
  5.2445 +  if (tuple->expirationTime < Simulator::Now ())
  5.2446 +    {
  5.2447 +      RemoveTopologyTuple (*tuple);
  5.2448 +    }
  5.2449 +  else
  5.2450 +    {
  5.2451 +      m_events.Track (Simulator::Schedule (DELAY (tuple->expirationTime),
  5.2452 +                                           &RoutingProtocol::TopologyTupleTimerExpire,
  5.2453 +                                           this, tuple->destAddr, tuple->lastAddr));
  5.2454 +    }
  5.2455 +}
  5.2456 +
  5.2457 +///
  5.2458 +/// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time().
  5.2459 +/// \warning Actually this is never invoked because there is no support for multiple interfaces.
  5.2460 +/// \param e The event which has expired.
  5.2461 +///
  5.2462 +void
  5.2463 +RoutingProtocol::IfaceAssocTupleTimerExpire (Ipv4Address ifaceAddr)
  5.2464 +{
  5.2465 +  IfaceAssocTuple *tuple = m_state.FindIfaceAssocTuple (ifaceAddr);
  5.2466 +  if (tuple == NULL)
  5.2467 +    {
  5.2468 +      return;
  5.2469 +    }
  5.2470 +  if (tuple->time < Simulator::Now ())
  5.2471 +    {
  5.2472 +      RemoveIfaceAssocTuple (*tuple);
  5.2473 +    }
  5.2474 +  else
  5.2475 +    {
  5.2476 +      m_events.Track (Simulator::Schedule (DELAY (tuple->time),
  5.2477 +                                           &RoutingProtocol::IfaceAssocTupleTimerExpire,
  5.2478 +                                           this, ifaceAddr));
  5.2479 +    }
  5.2480 +}
  5.2481 +
  5.2482 +///
  5.2483 +/// \brief Clears the routing table and frees the memory assigned to each one of its entries.
  5.2484 +///
  5.2485 +void
  5.2486 +RoutingProtocol::Clear ()
  5.2487 +{
  5.2488 +  NS_LOG_FUNCTION_NOARGS ();
  5.2489 +  m_table.clear ();
  5.2490 +}
  5.2491 +
  5.2492 +///
  5.2493 +/// \brief Deletes the entry whose destination address is given.
  5.2494 +/// \param dest	address of the destination node.
  5.2495 +///
  5.2496 +void
  5.2497 +RoutingProtocol::RemoveEntry (Ipv4Address const &dest)
  5.2498 +{
  5.2499 +  m_table.erase (dest);
  5.2500 +}
  5.2501 +
  5.2502 +///
  5.2503 +/// \brief Looks up an entry for the specified destination address.
  5.2504 +/// \param dest	destination address.
  5.2505 +/// \param outEntry output parameter to hold the routing entry result, if fuond
  5.2506 +/// \return	true if found, false if not found
  5.2507 +///
  5.2508 +bool
  5.2509 +RoutingProtocol::Lookup (Ipv4Address const &dest,
  5.2510 +                      RoutingTableEntry &outEntry) const
  5.2511 +{
  5.2512 +  // Get the iterator at "dest" position
  5.2513 +  std::map<Ipv4Address, RoutingTableEntry>::const_iterator it =
  5.2514 +    m_table.find (dest);
  5.2515 +  // If there is no route to "dest", return NULL
  5.2516 +  if (it == m_table.end ())
  5.2517 +    return false;
  5.2518 +  outEntry = it->second;
  5.2519 +  return true;
  5.2520 +}
  5.2521 +
  5.2522 +///
  5.2523 +/// \brief	Finds the appropiate entry which must be used in order to forward
  5.2524 +///		a data packet to a next hop (given a destination).
  5.2525 +///
  5.2526 +/// Imagine a routing table like this: [A,B] [B,C] [C,C]; being each pair of the
  5.2527 +/// form [dest addr,next-hop addr]. In this case, if this function is invoked with
  5.2528 +/// [A,B] then pair [C,C] is returned because C is the next hop that must be used
  5.2529 +/// to forward a data packet destined to A. That is, C is a neighbor of this node,
  5.2530 +/// but B isn't. This function finds the appropiate neighbor for forwarding a packet.
  5.2531 +///
  5.2532 +/// \param entry	the routing table entry which indicates the destination node
  5.2533 +///			we are interested in.
  5.2534 +/// \return		the appropiate routing table entry which indicates the next
  5.2535 +///			hop which must be used for forwarding a data packet, or NULL
  5.2536 +///			if there is no such entry.
  5.2537 +///
  5.2538 +bool
  5.2539 +RoutingProtocol::FindSendEntry (RoutingTableEntry const &entry,
  5.2540 +                             RoutingTableEntry &outEntry) const
  5.2541 +{
  5.2542 +  outEntry = entry;
  5.2543 +  while (outEntry.destAddr != outEntry.nextAddr)
  5.2544 +    {
  5.2545 +      if (not Lookup(outEntry.nextAddr, outEntry))
  5.2546 +        return false;
  5.2547 +    }
  5.2548 +  return true;
  5.2549 +}
  5.2550 +
  5.2551 +
  5.2552 +bool
  5.2553 +RoutingProtocol::RequestRoute (uint32_t ifIndex,
  5.2554 +                            const Ipv4Header &ipHeader,
  5.2555 +                            Ptr<Packet> packet,
  5.2556 +                            RouteReplyCallback routeReply)
  5.2557 +{
  5.2558 +  RoutingTableEntry entry1, entry2;
  5.2559 +  if (Lookup (ipHeader.GetDestination (), entry1))
  5.2560 +    {
  5.2561 +      bool foundSendEntry = FindSendEntry (entry1, entry2);
  5.2562 +      if (!foundSendEntry)
  5.2563 +        NS_FATAL_ERROR ("FindSendEntry failure");
  5.2564 +
  5.2565 +      Ipv4Route route = Ipv4Route::CreateHostRouteTo
  5.2566 +        (ipHeader.GetDestination (), entry2.nextAddr, entry2.interface);
  5.2567 +
  5.2568 +      NS_LOG_DEBUG ("Olsr node " << m_mainAddress
  5.2569 +                    << ": RouteRequest for dest=" << ipHeader.GetDestination ()
  5.2570 +                    << " --> nestHop=" << entry2.nextAddr
  5.2571 +                    << " interface=" << entry2.interface);
  5.2572 +      
  5.2573 +      routeReply (true, route, packet, ipHeader);
  5.2574 +      return true;
  5.2575 +    }
  5.2576 +  else
  5.2577 +    {
  5.2578 +#ifdef NS3_LOG_ENABLE
  5.2579 +      NS_LOG_DEBUG ("Olsr node " << m_mainAddress
  5.2580 +                    << ": RouteRequest for dest=" << ipHeader.GetDestination ()
  5.2581 +                    << " --> NOT FOUND; ** Dumping routing table...");
  5.2582 +      for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
  5.2583 +           iter != m_table.end (); iter++)
  5.2584 +        {
  5.2585 +          NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
  5.2586 +                        << " via interface " << iter->second.interface);
  5.2587 +        }
  5.2588 +
  5.2589 +      NS_LOG_DEBUG ("** Routing table dump end.");
  5.2590 +#endif
  5.2591 +      return false;
  5.2592 +    }
  5.2593 +}
  5.2594 +
  5.2595 +bool
  5.2596 +RoutingProtocol::RequestIfIndex (Ipv4Address destination,
  5.2597 +                              uint32_t& ifIndex)
  5.2598 +{
  5.2599 +  RoutingTableEntry entry1, entry2;
  5.2600 +  if (Lookup (destination, entry1))
  5.2601 +    {
  5.2602 +      bool foundSendEntry = FindSendEntry (entry1, entry2);
  5.2603 +      if (!foundSendEntry)
  5.2604 +        NS_FATAL_ERROR ("FindSendEntry failure");
  5.2605 +      ifIndex = entry2.interface;
  5.2606 +      return true;
  5.2607 +    }
  5.2608 +  else
  5.2609 +    {
  5.2610 +      return false;
  5.2611 +    }
  5.2612 +}
  5.2613 +
  5.2614 +
  5.2615 +///
  5.2616 +/// \brief Adds a new entry into the routing table.
  5.2617 +///
  5.2618 +/// If an entry for the given destination existed, it is deleted and freed.
  5.2619 +///
  5.2620 +/// \param dest		address of the destination node.
  5.2621 +/// \param next		address of the next hop node.
  5.2622 +/// \param iface	address of the local interface.
  5.2623 +/// \param dist		distance to the destination node.
  5.2624 +///
  5.2625 +void
  5.2626 +RoutingProtocol::AddEntry (Ipv4Address const &dest,
  5.2627 +                        Ipv4Address const &next,
  5.2628 +                        uint32_t interface,
  5.2629 +                        uint32_t distance)
  5.2630 +{
  5.2631 +  NS_LOG_FUNCTION (this << dest << next << interface << distance << m_mainAddress);
  5.2632 +
  5.2633 +  NS_ASSERT (distance > 0);
  5.2634 +
  5.2635 +  // Creates a new rt entry with specified values
  5.2636 +  RoutingTableEntry &entry = m_table[dest];
  5.2637 +
  5.2638 +  entry.destAddr = dest;
  5.2639 +  entry.nextAddr = next;
  5.2640 +  entry.interface = interface;
  5.2641 +  entry.distance = distance;
  5.2642 +}
  5.2643 +
  5.2644 +void
  5.2645 +RoutingProtocol::AddEntry (Ipv4Address const &dest,
  5.2646 +                        Ipv4Address const &next,
  5.2647 +                        Ipv4Address const &interfaceAddress,
  5.2648 +                        uint32_t distance)
  5.2649 +{
  5.2650 +  NS_LOG_FUNCTION (this << dest << next << interfaceAddress << distance << m_mainAddress);
  5.2651 +
  5.2652 +  NS_ASSERT (distance > 0);
  5.2653 +  NS_ASSERT (m_ipv4);
  5.2654 +
  5.2655 +  RoutingTableEntry entry;
  5.2656 +  for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
  5.2657 +    {
  5.2658 +      if (m_ipv4->GetAddress (i) == interfaceAddress)
  5.2659 +        {
  5.2660 +          AddEntry (dest, next, i, distance);
  5.2661 +          return;
  5.2662 +        }
  5.2663 +    }
  5.2664 +  NS_ASSERT (false); // should not be reached
  5.2665 +  AddEntry (dest, next, 0, distance);
  5.2666 +}
  5.2667 +
  5.2668 +
  5.2669 +std::vector<RoutingTableEntry>
  5.2670 +RoutingProtocol::GetEntries () const
  5.2671 +{
  5.2672 +  std::vector<RoutingTableEntry> retval;
  5.2673 +  for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
  5.2674 +       iter != m_table.end (); iter++)
  5.2675 +    {
  5.2676 +      retval.push_back (iter->second);
  5.2677 +    }
  5.2678 +  return retval;
  5.2679 +}
  5.2680 +
  5.2681 +
  5.2682 +}} // namespace olsr, ns3
  5.2683 +
  5.2684 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/routing/olsr/olsr-routing-protocol.h	Mon Mar 23 14:37:43 2009 +0100
     6.3 @@ -0,0 +1,236 @@
     6.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     6.5 +/*
     6.6 + * Copyright (c) 2004 Francisco J. Ros 
     6.7 + * Copyright (c) 2007 INESC Porto
     6.8 + *
     6.9 + * This program is free software; you can redistribute it and/or modify
    6.10 + * it under the terms of the GNU General Public License version 2 as
    6.11 + * published by the Free Software Foundation;
    6.12 + *
    6.13 + * This program is distributed in the hope that it will be useful,
    6.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.16 + * GNU General Public License for more details.
    6.17 + *
    6.18 + * You should have received a copy of the GNU General Public License
    6.19 + * along with this program; if not, write to the Free Software
    6.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6.21 + *
    6.22 + * Authors: Francisco J. Ros  <fjrm@dif.um.es>
    6.23 + *          Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
    6.24 + */
    6.25 +
    6.26 +
    6.27 +#ifndef __OLSR_AGENT_IMPL_H__
    6.28 +#define __OLSR_AGENT_IMPL_H__
    6.29 +
    6.30 +#include "olsr-header.h"
    6.31 +#include "olsr-state.h"
    6.32 +#include "olsr-repositories.h"
    6.33 +
    6.34 +#include "ns3/object.h"
    6.35 +#include "ns3/packet.h"
    6.36 +#include "ns3/node.h"
    6.37 +#include "ns3/socket.h"
    6.38 +#include "ns3/event-garbage-collector.h"
    6.39 +#include "ns3/timer.h"
    6.40 +#include "ns3/traced-callback.h"
    6.41 +#include "ns3/ipv4.h"
    6.42 +
    6.43 +#include <vector>
    6.44 +#include <map>
    6.45 +
    6.46 +
    6.47 +namespace ns3 {
    6.48 +namespace olsr {
    6.49 +
    6.50 +
    6.51 +/// An %OLSR's routing table entry.
    6.52 +struct RoutingTableEntry
    6.53 +{
    6.54 +  Ipv4Address destAddr;	///< Address of the destination node.
    6.55 +  Ipv4Address nextAddr;	///< Address of the next hop.
    6.56 +  uint32_t interface; ///< Interface index
    6.57 +  uint32_t distance; ///< Distance in hops to the destination.
    6.58 +
    6.59 +  RoutingTableEntry () : // default values
    6.60 +    destAddr (), nextAddr (),
    6.61 +    interface (0), distance (0) {};
    6.62 +};
    6.63 +
    6.64 +
    6.65 +class RoutingProtocol : public Ipv4RoutingProtocol
    6.66 +{
    6.67 +public:
    6.68 +  static TypeId GetTypeId (void);
    6.69 +
    6.70 +  RoutingProtocol ();
    6.71 +  virtual ~RoutingProtocol ();
    6.72 +
    6.73 +  void SetNode (Ptr<Node> node);
    6.74 +
    6.75 +  void Start ();
    6.76 +  void SetMainInterface (uint32_t interface);
    6.77 +
    6.78 +private:
    6.79 +  std::map<Ipv4Address, RoutingTableEntry> m_table; ///< Data structure for the routing table.
    6.80 +
    6.81 +  EventGarbageCollector m_events;
    6.82 +
    6.83 +  /// Address of the routing agent.
    6.84 +  Ipv4Address m_routingAgentAddr;
    6.85 +	
    6.86 +  /// Packets sequence number counter.
    6.87 +  uint16_t m_packetSequenceNumber;
    6.88 +  /// Messages sequence number counter.
    6.89 +  uint16_t m_messageSequenceNumber;
    6.90 +  /// Advertised Neighbor Set sequence number.
    6.91 +  uint16_t m_ansn;
    6.92 +  
    6.93 +  /// HELLO messages' emission interval.
    6.94 +  Time m_helloInterval;
    6.95 +  /// TC messages' emission interval.
    6.96 +  Time m_tcInterval;
    6.97 +  /// MID messages' emission interval.
    6.98 +  Time m_midInterval;
    6.99 +  /// Willingness for forwarding packets on behalf of other nodes.
   6.100 +  uint8_t m_willingness;
   6.101 +	
   6.102 +  /// Internal state with all needed data structs.
   6.103 +  OlsrState m_state;
   6.104 +
   6.105 +  Ptr<Ipv4> m_ipv4;
   6.106 +	
   6.107 +private:
   6.108 +
   6.109 +  void Clear ();
   6.110 +  uint32_t GetSize () const { return m_table.size (); }
   6.111 +  std::vector<RoutingTableEntry> GetEntries () const;
   6.112 +  void RemoveEntry (const Ipv4Address &dest);
   6.113 +  void AddEntry (const Ipv4Address &dest,
   6.114 +                 const Ipv4Address &next,
   6.115 +                 uint32_t interface,
   6.116 +                 uint32_t distance);
   6.117 +  void AddEntry (const Ipv4Address &dest,
   6.118 +                 const Ipv4Address &next,
   6.119 +                 const Ipv4Address &interfaceAddress,
   6.120 +                 uint32_t distance);
   6.121 +  bool Lookup (const Ipv4Address &dest,
   6.122 +               RoutingTableEntry &outEntry) const;
   6.123 +  bool FindSendEntry (const RoutingTableEntry &entry,
   6.124 +                      RoutingTableEntry &outEntry) const;
   6.125 +
   6.126 +  // From Ipv4RoutingProtocol
   6.127 +  virtual bool RequestRoute (uint32_t ifIndex,
   6.128 +                             const Ipv4Header &ipHeader,
   6.129 +                             Ptr<Packet> packet,
   6.130 +                             RouteReplyCallback routeReply);
   6.131 +  virtual bool RequestIfIndex (Ipv4Address destination, 
   6.132 +                               uint32_t& ifIndex);
   6.133 +
   6.134 +
   6.135 +  void DoDispose ();
   6.136 +
   6.137 +  void SendPacket (Ptr<Packet> packet, const MessageList &containedMessages);
   6.138 +	
   6.139 +  /// Increments packet sequence number and returns the new value.
   6.140 +  inline uint16_t GetPacketSequenceNumber ();
   6.141 +  /// Increments message sequence number and returns the new value.
   6.142 +  inline uint16_t GetMessageSequenceNumber ();
   6.143 +	
   6.144 +  void RecvOlsr (Ptr<Socket> socket);
   6.145 +
   6.146 +  void MprComputation ();
   6.147 +  void RoutingTableComputation ();
   6.148 +  Ipv4Address GetMainAddress (Ipv4Address iface_addr) const;
   6.149 +
   6.150 +  // Timer handlers
   6.151 +  Timer m_helloTimer;
   6.152 +  void HelloTimerExpire ();
   6.153 +  
   6.154 +  Timer m_tcTimer;
   6.155 +  void TcTimerExpire ();
   6.156 +
   6.157 +  Timer m_midTimer;
   6.158 +  void MidTimerExpire ();
   6.159 +
   6.160 +  void DupTupleTimerExpire (Ipv4Address address, uint16_t sequenceNumber);
   6.161 +  bool m_linkTupleTimerFirstTime;
   6.162 +  void LinkTupleTimerExpire (Ipv4Address neighborIfaceAddr);
   6.163 +  void Nb2hopTupleTimerExpire (Ipv4Address neighborMainAddr, Ipv4Address twoHopNeighborAddr);
   6.164 +  void MprSelTupleTimerExpire (Ipv4Address mainAddr);
   6.165 +  void TopologyTupleTimerExpire (Ipv4Address destAddr, Ipv4Address lastAddr);
   6.166 +  void IfaceAssocTupleTimerExpire (Ipv4Address ifaceAddr);
   6.167 +
   6.168 +  void IncrementAnsn ();
   6.169 +
   6.170 +  /// A list of pending messages which are buffered awaiting for being sent.
   6.171 +  olsr::MessageList m_queuedMessages;
   6.172 +  Timer m_queuedMessagesTimer; // timer for throttling outgoing messages
   6.173 +
   6.174 +  void ForwardDefault (olsr::MessageHeader olsrMessage,
   6.175 +                       DuplicateTuple *duplicated,
   6.176 +                       const Ipv4Address &localIface,
   6.177 +                       const Ipv4Address &senderAddress);
   6.178 +  void QueueMessage (const olsr::MessageHeader &message, Time delay);
   6.179 +  void SendQueuedMessages ();
   6.180 +  void SendHello ();
   6.181 +  void SendTc ();
   6.182 +  void SendMid ();
   6.183 +
   6.184 +  void NeighborLoss (const LinkTuple &tuple);
   6.185 +  void AddDuplicateTuple (const DuplicateTuple &tuple);
   6.186 +  void RemoveDuplicateTuple (const DuplicateTuple &tuple);
   6.187 +  void LinkTupleAdded (const LinkTuple &tuple, uint8_t willingness);
   6.188 +  void RemoveLinkTuple (const LinkTuple &tuple);
   6.189 +  void LinkTupleUpdated (const LinkTuple &tuple, uint8_t willingness);
   6.190 +  void AddNeighborTuple (const NeighborTuple &tuple);
   6.191 +  void RemoveNeighborTuple (const NeighborTuple &tuple);
   6.192 +  void AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple);
   6.193 +  void RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple);
   6.194 +  void AddMprSelectorTuple (const MprSelectorTuple  &tuple);
   6.195 +  void RemoveMprSelectorTuple (const MprSelectorTuple &tuple);
   6.196 +  void AddTopologyTuple (const TopologyTuple &tuple);
   6.197 +  void RemoveTopologyTuple (const TopologyTuple &tuple);
   6.198 +  void AddIfaceAssocTuple (const IfaceAssocTuple &tuple);
   6.199 +  void RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple);
   6.200 +
   6.201 +  void ProcessHello (const olsr::MessageHeader &msg,
   6.202 +                     const Ipv4Address &receiverIface,
   6.203 +                     const Ipv4Address &senderIface);
   6.204 +  void ProcessTc (const olsr::MessageHeader &msg,
   6.205 +                  const Ipv4Address &senderIface);
   6.206 +  void ProcessMid (const olsr::MessageHeader &msg,
   6.207 +                   const Ipv4Address &senderIface);
   6.208 +
   6.209 +  void LinkSensing (const olsr::MessageHeader &msg,
   6.210 +                    const olsr::MessageHeader::Hello &hello,
   6.211 +                    const Ipv4Address &receiverIface,
   6.212 +                    const Ipv4Address &sender_iface);
   6.213 +  void PopulateNeighborSet (const olsr::MessageHeader &msg,
   6.214 +                            const olsr::MessageHeader::Hello &hello);
   6.215 +  void PopulateTwoHopNeighborSet (const olsr::MessageHeader &msg,
   6.216 +                                  const olsr::MessageHeader::Hello &hello);
   6.217 +  void PopulateMprSelectorSet (const olsr::MessageHeader &msg,
   6.218 +                               const olsr::MessageHeader::Hello &hello);
   6.219 +
   6.220 +  int Degree (NeighborTuple const &tuple);
   6.221 +
   6.222 +  Ipv4Address m_mainAddress;
   6.223 +
   6.224 +  // One socket per interface, each bound to that interface's address
   6.225 +  // (reason: for OLSR Link Sensing we need to know on which interface
   6.226 +  // HELLO messages arrive)
   6.227 +  std::map< Ptr<Socket>, Ipv4Address > m_socketAddresses;
   6.228 +
   6.229 +  TracedCallback <const PacketHeader &,
   6.230 +                  const MessageList &> m_rxPacketTrace;
   6.231 +  TracedCallback <const PacketHeader &,
   6.232 +                  const MessageList &> m_txPacketTrace;
   6.233 +  TracedCallback <uint32_t> m_routingTableChanged;
   6.234 +
   6.235 +};
   6.236 +
   6.237 +}} // namespace ns3
   6.238 +
   6.239 +#endif
     7.1 --- a/src/routing/olsr/wscript	Mon Mar 23 14:29:31 2009 +0100
     7.2 +++ b/src/routing/olsr/wscript	Mon Mar 23 14:37:43 2009 +0100
     7.3 @@ -6,13 +6,13 @@
     7.4      module.source = [
     7.5          'olsr-header.cc',
     7.6          'olsr-state.cc',
     7.7 -        'olsr-agent-impl.cc',
     7.8 +        'olsr-routing-protocol.cc',
     7.9          ]
    7.10  
    7.11      headers = bld.new_task_gen('ns3header')
    7.12      headers.module = 'olsr'
    7.13      headers.source = [
    7.14 -        'olsr-agent-impl.h',
    7.15 +        'olsr-routing-protocol.h',
    7.16          'olsr-header.h',
    7.17          'olsr-state.h',
    7.18          'olsr-repositories.h',
     8.1 --- a/utils/print-introspected-doxygen.cc	Mon Mar 23 14:29:31 2009 +0100
     8.2 +++ b/utils/print-introspected-doxygen.cc	Mon Mar 23 14:37:43 2009 +0100
     8.3 @@ -239,7 +239,7 @@
     8.4    info.RecordAggregationInfo ("ns3::Node", "ns3::TcpSocketFactory");
     8.5    info.RecordAggregationInfo ("ns3::Node", "ns3::UdpSocketFactory");
     8.6    info.RecordAggregationInfo ("ns3::Node", "ns3::PacketSocketFactory");
     8.7 -  info.RecordAggregationInfo ("ns3::Node", "ns3::olsr::Agent");
     8.8 +  info.RecordAggregationInfo ("ns3::Node", "ns3::olsr::RoutingProtocol");
     8.9    info.RecordAggregationInfo ("ns3::Node", "ns3::MobilityModel");
    8.10    info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4L3Protocol");
    8.11    info.RecordAggregationInfo ("ns3::Node", "ns3::ArpL3Protocol");