因为做毕设的原因,需要在aodv路由协议中,在节点收到rreq包的时候,顺便记录下当前节点的剩余能量,之前是在NS2上做过,但是才接触NS3没多久,所以不太会,在网上以及NS3给的example中也没有看懂查看的方法,所以想来咨询下有关于能量模块的具体实现方式,energy module以及energy helper有大佬可以帮我解惑一下么- -谢谢了!
RoutingProtocol::RecvRequest (Ptr p, Ipv4Address receiver, Ipv4Address src)
// src is neigbor's IP
{
NS_LOG_FUNCTION (this);
RreqHeader rreqHeader;
p->RemoveHeader (rreqHeader);
// A node ignores all RREQs received from any node in its blacklist
RoutingTableEntry toPrev;
if (m_routingTable.LookupRoute (src, toPrev))
{
if (toPrev.IsUnidirectional ())
{
NS_LOG_DEBUG ("Ignoring RREQ from node in blacklist");
return;
}
}
uint32_t id = rreqHeader.GetId ();
Ipv4Address origin = rreqHeader.GetOrigin (); // Originator is not always neighbor (RREQ forwarding)
NS_LOG_DEBUG ("Recv RREQ [ID=" << rreqHeader.GetId () << ",OriginSeqNo=" << rreqHeader.GetOriginSeqno () << "]: " << src << " --> " << receiver << ", originator " << origin << " dst " << rreqHeader.GetDst ());
// Increment RREQ hop count
uint8_t hop = rreqHeader.GetHopCount () + 1;
rreqHeader.SetHopCount (hop);
// Add in RREQ ETX metrix for last hop from neighbor to this node
// Now RREQ contains ETX from origin to this node
uint32_t etx = m_nbEtx.GetEtxForNeighbor (src); // src is always neighbor, origin maybe isn't
if (etx == NeighborEtx::EtxMaxValue ())
{ // this should never happen because neighbor has limited ETX, but it is better to check!
NS_LOG_DEBUG ("ETX -> oo !!! ");
rreqHeader.SetEtx (etx);
}
else
{
rreqHeader.SetEtx (etx + rreqHeader.GetEtx ());
}
NS_LOG_DEBUG ("Recv RREQ header: hop " << int(hop) << ", ETX " << rreqHeader.GetEtx ());
/*
This is modified to include ETX, so RREQ is discarded only if etx of previously received RREQ is beter (smaller) then this one
*/
if (m_rreqIdCache.IsDuplicate (origin, id))
{
RoutingTableEntry rte;
if (m_routingTable.LookupRoute (origin, rte))
{
if (rte.GetEtx () <= rreqHeader.GetEtx ())
{
NS_LOG_DEBUG ("Ignoring RREQ due to duplicate, previous RREQ had better ETX.");
NS_LOG_DEBUG ("Duplicate, IGNORE previous RREQ had better ETX.");
return;
}
NS_LOG_DEBUG ("Duplicate, but better ETX. Continue...");
}
NS_LOG_DEBUG ("Duplicate, but no route in the table. Continue...");
}
else
NS_LOG_DEBUG ("Not found duplicate. Continue...");
// This should be solved by previous if due to duplicate RREQ, but it is not?!
if (receiver == rreqHeader.GetOrigin ())
{
NS_LOG_DEBUG ("This is my own RREQ, so drop!");
return;
}
/*
When the reverse route is created or updated, the following actions on the route are also carried out:
in the route table entry and copied if greater than the existing value there
MinimalLifetime = current time + 2*NetTraversalTime - 2*HopCount*NodeTraversalTime
RoutingTableEntry toNeighbor;
if (!m_routingTable.LookupRoute (src, toNeighbor))
{ // Nenad: No rute in routing table, this should never happen since the route for neighbor is created in RecvAodv ()
NS_LOG_DEBUG ("Neighbor:" << src << " not found in routing table. Creating an entry");
Ptr dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver));
RoutingTableEntry newEntry (dev, src, false, rreqHeader.GetOriginSeqno (), /* Nenad: not clear to me why seqno is not valid? /
m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0),
1, src, m_activeRouteTimeout,
/*etx/ m_nbEtx.GetEtxForNeighbor (src));
m_routingTable.AddRoute (newEntry);
}
else
{ // Update existing route
toNeighbor.SetLifeTime (m_activeRouteTimeout);
toNeighbor.SetValidSeqNo (false); // Nenad: not clear to me why seqno is not valid?
toNeighbor.SetSeqNo (rreqHeader.GetOriginSeqno ());
toNeighbor.SetFlag (VALID);
toNeighbor.SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (receiver)));
toNeighbor.SetInterface (m_ipv4->GetAddress (m_ipv4->GetInterfaceForAddress (receiver), 0));
toNeighbor.SetHop (1);
toNeighbor.SetNextHop (src);
toNeighbor.SetEtx (m_nbEtx.GetEtxForNeighbor (src));
m_routingTable.Update (toNeighbor);
}
// Update neighbors
m_nb.Update (src, Time (m_allowedHelloLoss * m_helloInterval));
NS_LOG_LOGIC (receiver << " receive RREQ with hop count " << static_cast(rreqHeader.GetHopCount ())
<< " ID " << rreqHeader.GetId ()
<< " to destination " << rreqHeader.GetDst ());
// A node generates a RREP if either:
// (i) it is itself the destination,
if (IsMyOwnAddress (rreqHeader.GetDst ()))
{
m_routingTable.LookupRoute (origin, toOrigin);
NS_LOG_DEBUG ("Send reply since I am the destination");
SendReply (rreqHeader, toOrigin);
return;
}
/*
(ii) or it has an active route to the destination, the destination sequence number in the node's existing route table entry for the destination
is valid and greater than or equal to the Destination Sequence Number of the RREQ, and the "destination only" flag is NOT set.
/
RoutingTableEntry toDst;
Ipv4Address dst = rreqHeader.GetDst ();
if (m_routingTable.LookupRoute (dst, toDst))
{
/
// Forward RREQ
SocketIpTtlTag tag;
p->RemovePacketTag (tag);
if (tag.GetTtl () < 2)
{
NS_LOG_DEBUG ("TTL exceeded. Drop RREQ origin " << src << " destination " << dst );
return;
}
for (std::map, Ipv4InterfaceAddress>::const_iterator j =
m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
{
Ptr socket = j->first;
Ipv4InterfaceAddress iface = j->second;
Ptr packet = Create ();
SocketIpTtlTag ttl;
ttl.SetTtl (tag.GetTtl () - 1);
packet->AddPacketTag (ttl);
packet->AddHeader (rreqHeader);
TypeHeader tHeader (AODVTYPE_RREQ);
packet->AddHeader (tHeader);
// Send to all-hosts broadcast if on /32 addr, subnet-directed otherwise
Ipv4Address destination;
if (iface.GetMask () == Ipv4Mask::GetOnes ())
{
destination = Ipv4Address ("255.255.255.255");
}
else
{
destination = iface.GetBroadcast ();
}
m_lastBcastTime = Simulator::Now ();
Simulator::Schedule (Time (MilliSeconds (m_uniformRandomVariable->GetInteger (0, 10))), &RoutingProtocol::SendTo, this, socket, packet, destination);
}
}