ns3-wifi学习记录-aodv与其他模块的连接
2014-01-22 09:25阅读:
为了找到AODV与其他模块的联系,用调试工具跟踪例子程序aodv.cc(src/aodv/examples/aodv.cc)。
发现的事:
1.在脚本文件写的方法AodvExample::InstallInternetStack ()中,
void
AodvExample::InstallInternetStack ()
{
AodvHelper aodv;
// you can configure AODV attributes here using
aodv.Set(name, value)
InternetStackHelper stack;
stack.SetRoutingHelper (aodv); // has effect on the next
Install ()
stack.Install (nodes);
Ipv4AddressHelper address;
address.SetBase ('10.0.0.0', '255.0.0.0');
interfaces = address.Assign (devices);
...
}
通过stack.SetRoutingHelper
(aodv);来把AodvHelper存到InternetStackHelper的成员变量之中。
2.在InternetStackHelper::Install (Ptr node) const
中,用来绑定路由协议的部分是这样的:
// Set routing
Ptr ipv4 =
node->GetObject ();
Ptr ipv4Routing = m_routin
g->Create (node);
ipv4->SetRoutingProtocol
(ipv4Routing);
2.1 其中m_routing->Create
(node);这一句调用的是:
Ptr
AodvHelper::Create (Ptr node) const
{
Ptr agent = m_agentFactory.Create ();
node->AggregateObject (agent); //与节点聚合
return agent;
}
它做的只是创建了一个AODV,并且将它与节点聚合(关于NS3中的聚合机制,可以去官网找资料)。
2.2 而 ipv4->SetRoutingProtocol (ipv4Routing);这一句调用的是
void
Ipv4L3Protocol::SetRoutingProtocol (Ptr routingProtocol)
{
NS_LOG_FUNCTION (this << routingProtocol);
m_routingProtocol = routingProtocol;
m_routingProtocol->SetIpv4 (this);
}
这里的 m_routingProtocol = routingProtocol;
是将AODV赋值为成员变量,
而 m_routingProtocol->SetIpv4 (this);是调用了RoutingProtocol::SetIpv4
(Ptr ipv4)
其中的代码如下:
void
RoutingProtocol::SetIpv4 (Ptr ipv4)
{
NS_ASSERT (ipv4 != 0);
NS_ASSERT (m_ipv4 == 0);
//与AODV中的HELLO数据包有关
if (EnableHello)
{
m_htimer.SetFunction
(&RoutingProtocol::HelloTimerExpire, this);
m_htimer.Schedule
(MilliSeconds (m_uniformRandomVariable->GetInteger (0,
100)));
}
//赋值为成员变量
m_ipv4 = ipv4;
//这里显示此时的ipv4中只有一个接口,而且它是环回的接口(loopback)
// Create lo route. It is asserted that the only one
interface up for now is loopback
NS_ASSERT (m_ipv4->GetNInterfaces () == 1 &&
m_ipv4->GetAddress (0, 0).GetLocal () == Ipv4Address
('127.0.0.1'));
m_lo = m_ipv4->GetNetDevice (0);
NS_ASSERT (m_lo != 0);
//加个loopback的路由表
// Remember lo
route
RoutingTableEntry rt ( m_lo, Ipv4Address::GetLoopback (),
true,
0, Ipv4InterfaceAddress
(Ipv4Address::GetLoopback (), Ipv4Mask ('255.0.0.0')),
1, Ipv4Address::GetLoopback (),
Simulator::GetMaximumSimulationTime ());
m_routingTable.AddRoute (rt);
//启动AODV
Simulator::ScheduleNow (&RoutingProtocol::Start,
this);
}
这个方法做的事可以总结为3点:
(1) 准备启动路由协议
(2) 使这个ipv4成为成员变量
(3) 确定这个ipv4只有一个loopback接口,并将其存到路由表中
3.实际上,我最想了解的是在多个NetDevice时各模块之间的关系。
根据官网的教程文件,一个节点的ipv4L3Protocol
只有一个(它是聚合在节点上的),(ipv4L3Protocol是ipv4的子类),
按照之前2.2部分的分析,AODV刚绑定在节点上时,ipv4上只有一个loopback interface
.而一个节点显然可以有多个NetDevice,那其它的interface是怎么加进去的呢?
继续从例子脚本程序aodv.cc开始追踪:
脚本中的这一句 interfaces = address.Assign (devices);把device
interface与AODV联系起来了。
它调用的方法是
Ipv4InterfaceContainer
Ipv4AddressHelper::Assign (const NetDeviceContainer &c)
这个方法中有几句
int32_t interface =
ipv4->GetInterfaceForDevice (device);
...
ipv4->AddAddress
(interface, ipv4Addr);
ipv4->SetMetric
(interface, 1);
ipv4->SetUp
(interface);
...
第一句得到与device相关的interface ,第二句则使ipv4加入这个接口,在这里我得到的分析结果是:
ipv4,也就是ipv4L3Protocol 和netDevice
打交道是通过interface进行的。(现在我还不太了解互联网协议)
进到最后一句 ipv4->SetUp (interface);之中可以看到有一句:
m_routingProtocol->NotifyInterfaceUp (i);
这个NotifyInterfaceUp (i)就是调用了AODV中的这个函数;
void
RoutingProtocol::NotifyInterfaceUp (uint32_t i)
{
...
Ptr socket = Socket::CreateSocket (GetObject (),
UdpSocketFactory::GetTypeId
());
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback
(&RoutingProtocol::RecvAodv, this));
socket->BindToNetDevice (l3->GetNetDevice (i));
socket->Bind (InetSocketAddress (Ipv4Address::GetAny (),
AODV_PORT));
socket->SetAllowBroadcast (true);
socket->SetAttribute ('IpTtl', UintegerValue (1));
m_socketAddresses.insert (std::make_pair (socket,
iface));
...
}
看到它在创建一个socket ,
观察AODV的声明代码,可以看到在类成员声明中有一个:
/// Raw socket per each IP interface, map socket ->
iface address (IP + mask)
std::map< Ptr, Ipv4InterfaceAddress >
m_socketAddresses;
看来AODV的接口是与Socket绑定起来的。AODV协议实际上是使用UDP来收发数据的,这里的socket是AODV协议自己使用的AODV
UDP SOCKET,端口号是固定的 ,AODV_PORT=654。
(未完)