Tải bản đầy đủ (.doc) (19 trang)

Ví dụ cài đặt giao thức định tuyến địa lý GPSR trong công cụ mô phỏng NS3

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (51.55 KB, 19 trang )

#define NS_LOG_APPEND_CONTEXT
\
if (m_ipv4) { std::clog << "[node " << m_ipv4->GetObject<Node> ()->GetId () <<
"] "; }
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

"gpsr.h"
"ns3/log.h"
"ns3/boolean.h"
"ns3/random-variable.h"
"ns3/inet-socket-address.h"
"ns3/trace-source-accessor.h"
"ns3/udp-socket-factory.h"
"ns3/wifi-net-device.h"
"ns3/adhoc-wifi-mac.h"
<algorithm>
<limits>

#define GPSR_LS_GOD 0
#define GPSR_LS_RLS 1
NS_LOG_COMPONENT_DEFINE ("GpsrRoutingProtocol");


namespace ns3 {
namespace gpsr {

struct DeferredRouteOutputTag : public Tag
{
/// Positive if output device is fixed in RouteOutput
uint32_t m_isCallFromL3;
DeferredRouteOutputTag () : Tag (),
m_isCallFromL3 (0)
{
}
static TypeId GetTypeId ()
{
static TypeId tid = TypeId
("ns3::gpsr::DeferredRouteOutputTag").SetParent<Tag> ();
return tid;
}
TypeId GetInstanceTypeId () const
{
return GetTypeId ();
}
uint32_t GetSerializedSize () const
{
return sizeof(uint32_t);
}
void Serialize (TagBuffer i) const
{
i.WriteU32 (m_isCallFromL3);
}
void

{

Deserialize (TagBuffer i)


m_isCallFromL3 = i.ReadU32 ();
}
void Print (std::ostream &os) const
{
os << "DeferredRouteOutputTag: m_isCallFromL3 = " << m_isCallFromL3;
}
};

/********** Miscellaneous constants **********/
/// Maximum allowed jitter.
#define GPSR_MAXJITTER
(HelloInterval.GetSeconds () / 2)
/// Random number between [(-GPSR_MAXJITTER)-GPSR_MAXJITTER] used to jitter
HELLO packet transmission.
#define JITTER (Seconds (UniformVariable ().GetValue (-GPSR_MAXJITTER,
GPSR_MAXJITTER)))
#define FIRST_JITTER (Seconds (UniformVariable ().GetValue (0, GPSR_MAXJITTER)))
//first Hello can not be in the past, used only on SetIpv4

NS_OBJECT_ENSURE_REGISTERED (RoutingProtocol);
/// UDP Port for GPSR control traffic, not defined by IANA yet
const uint32_t RoutingProtocol::GPSR_PORT = 666;
RoutingProtocol::RoutingProtocol ()
: HelloInterval (Seconds (1)),
MaxQueueLen (64),

MaxQueueTime (Seconds (30)),
m_queue (MaxQueueLen, MaxQueueTime),
HelloIntervalTimer (Timer::CANCEL_ON_DESTROY),
PerimeterMode (false)
{
m_neighbors = PositionTable ();
}
TypeId
RoutingProtocol::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::gpsr::RoutingProtocol")
.SetParent<Ipv4RoutingProtocol> ()
.AddConstructor<RoutingProtocol> ()
.AddAttribute ("HelloInterval", "HELLO messages emission interval.",
TimeValue (Seconds (1)),
MakeTimeAccessor (&RoutingProtocol::HelloInterval),
MakeTimeChecker ())
.AddAttribute ("LocationServiceName", "Indicates wich Location Service is
enabled",
EnumValue (GPSR_LS_GOD),
MakeEnumAccessor (&RoutingProtocol::LocationServiceName),
MakeEnumChecker (GPSR_LS_GOD, "GOD",
GPSR_LS_RLS, "RLS"))
.AddAttribute ("PerimeterMode ", "Indicates if PerimeterMode is enabled",
BooleanValue (false),
MakeBooleanAccessor (&RoutingProtocol::PerimeterMode),
MakeBooleanChecker ())
;



return tid;
}
RoutingProtocol::~RoutingProtocol ()
{
}
void
RoutingProtocol::DoDispose ()
{
m_ipv4 = 0;
Ipv4RoutingProtocol::DoDispose ();
}
Ptr<LocationService>
RoutingProtocol::GetLS ()
{
return m_locationService;
}
void
RoutingProtocol::SetLS (Ptr<LocationService> locationService)
{
m_locationService = locationService;
}
bool RoutingProtocol::RouteInput (Ptr<const Packet> p, const Ipv4Header &header,
Ptr<const NetDevice> idev,
UnicastForwardCallback ucb,
MulticastForwardCallback mcb,
LocalDeliverCallback lcb, ErrorCallback ecb)
{
NS_LOG_FUNCTION (this << p->GetUid () << header.GetDestination () << idev>GetAddress ());
if (m_socketAddresses.empty ())
{

NS_LOG_LOGIC ("No gpsr interfaces");
return false;
}
NS_ASSERT (m_ipv4 != 0);
NS_ASSERT (p != 0);
// Check if input device supports IP
NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
Ipv4Address dst = header.GetDestination ();
Ipv4Address origin = header.GetSource ();
DeferredRouteOutputTag tag; //FIXME since I have to check if it's in origin
for it to work it means I'm not taking some tag out...
if (p->PeekPacketTag (tag) && IsMyOwnAddress (origin))
{
Ptr<Packet> packet = p->Copy (); //FIXME ja estou a abusar de tirar tags
packet->RemovePacketTag(tag);
DeferredRouteOutput (packet, header, ucb, ecb);
return true;
}

if (m_ipv4->IsDestinationAddress (dst, iif))
{


Ptr<Packet> packet = p->Copy ();
TypeHeader tHeader (GPSRTYPE_POS);
packet->RemoveHeader (tHeader);
if (!tHeader.IsValid ())
{
NS_LOG_DEBUG ("GPSR message " << packet->GetUid () << " with unknown

type received: " << tHeader.Get () << ". Ignored");
return false;
}
if (tHeader.Get () == GPSRTYPE_POS)
{
PositionHeader phdr;
packet->RemoveHeader (phdr);
}
if (dst != m_ipv4->GetAddress (1, 0).GetBroadcast ())
{
NS_LOG_LOGIC ("Unicast local delivery to " << dst);
}
else
{
NS_LOG_LOGIC ("Broadcast local delivery to " << dst);
}
lcb (packet, header, iif);
return true;
}
return Forwarding (p, header, ucb, ecb);
}
void
RoutingProtocol::DeferredRouteOutput (Ptr<const Packet> p, const Ipv4Header &
header,
UnicastForwardCallback ucb, ErrorCallback
ecb)
{
NS_LOG_FUNCTION (this << p << header);
NS_ASSERT (p != 0 && p != Ptr<Packet> ());
if (m_queue.GetSize () == 0)

{
CheckQueueTimer.Cancel ();
CheckQueueTimer.Schedule (Time ("500ms"));
}
QueueEntry newEntry (p, header, ucb, ecb);
bool result = m_queue.Enqueue (newEntry);
m_queuedAddresses.insert (m_queuedAddresses.begin (), header.GetDestination
());
m_queuedAddresses.unique ();
if (result)
{
NS_LOG_LOGIC ("Add packet " << p->GetUid () << " to queue. Protocol " <<
(uint16_t) header.GetProtocol ());


}
}
void
RoutingProtocol::CheckQueue ()
{
CheckQueueTimer.Cancel ();
std::list<Ipv4Address> toRemove;
for (std::list<Ipv4Address>::iterator i = m_queuedAddresses.begin (); i !=
m_queuedAddresses.end (); ++i)
{
if (SendPacketFromQueue (*i))
{
//Insert in a list to remove later
toRemove.insert (toRemove.begin (), *i);
}

}
//remove all that are on the list
for (std::list<Ipv4Address>::iterator i = toRemove.begin (); i != toRemove.end
(); ++i)
{
m_queuedAddresses.remove (*i);
}
if (!m_queuedAddresses.empty ()) //Only need to schedule if the queue is not
empty
{
CheckQueueTimer.Schedule (Time ("500ms"));
}
}
bool
RoutingProtocol::SendPacketFromQueue (Ipv4Address dst)
{
NS_LOG_FUNCTION (this);
bool recovery = false;
QueueEntry queueEntry;
std::cout<<"Sent from Queue \n";
if (m_locationService->IsInSearch (dst))
{
return false;
}
if (!m_locationService->HasPosition (dst)) // Location-service stoped looking
for the dst
{
m_queue.DropPacketWithDst (dst);
NS_LOG_LOGIC ("Location Service did not find dst. Drop packet to " <<
dst);

return true;
}
Vector myPos;
Ptr<MobilityModel> MM = m_ipv4->GetObject<MobilityModel> ();
myPos.x = MM->GetPosition ().x;


myPos.y = MM->GetPosition ().y;
Ipv4Address nextHop;
if(m_neighbors.isNeighbour (dst))
{
nextHop = dst;
}
else{
Vector dstPos = m_locationService->GetPosition (dst);
nextHop = m_neighbors.BestNeighbor (dstPos, myPos);
if (nextHop == Ipv4Address::GetZero ())
{
NS_LOG_LOGIC ("Fallback to recovery-mode. Packets to " << dst);
recovery = true;
}
if(recovery)
{
Vector Position;
Vector previousHop;
uint32_t updated;

();

while(m_queue.Dequeue (dst, queueEntry))

{
Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
UnicastForwardCallback ucb = queueEntry.GetUnicastForwardCallback
Ipv4Header header = queueEntry.GetIpv4Header ();

TypeHeader tHeader (GPSRTYPE_POS);
p->RemoveHeader (tHeader);
if (!tHeader.IsValid ())
{
NS_LOG_DEBUG ("GPSR message " << p->GetUid () << " with unknown
type received: " << tHeader.Get () << ". Drop");
return false;
// drop
}
if (tHeader.Get () == GPSRTYPE_POS)
{
PositionHeader hdr;
p->RemoveHeader (hdr);
Position.x = hdr.GetDstPosx ();
Position.y = hdr.GetDstPosy ();
updated = hdr.GetUpdated ();
}
PositionHeader posHeader (Position.x, Position.y, updated, myPos.x,
myPos.y, (uint8_t) 1, Position.x, Position.y);
p->AddHeader (posHeader); //enters in recovery with last edge from
Dst
p->AddHeader (tHeader);
RecoveryMode(dst, p, ucb, header);
}
return true;

}
}
Ptr<Ipv4Route> route = Create<Ipv4Route> ();
route->SetDestination (dst);
route->SetGateway (nextHop);
// FIXME: Does not work for multiple interfaces


route->SetOutputDevice (m_ipv4->GetNetDevice (1));
while (m_queue.Dequeue (dst, queueEntry))
{
DeferredRouteOutputTag tag;
Ptr<Packet> p = ConstCast<Packet> (queueEntry.GetPacket ());
UnicastForwardCallback ucb = queueEntry.GetUnicastForwardCallback ();
Ipv4Header header = queueEntry.GetIpv4Header ();
if (header.GetSource () == Ipv4Address ("102.102.102.102"))
{
route->SetSource (m_ipv4->GetAddress (1, 0).GetLocal ());
header.SetSource (m_ipv4->GetAddress (1, 0).GetLocal ());
}
else
{
route->SetSource (header.GetSource ());
}
ucb (route, p, header);

}

}
return true;


void
RoutingProtocol::RecoveryMode(Ipv4Address dst, Ptr<Packet> p,
UnicastForwardCallback ucb, Ipv4Header header){
Vector Position;
Vector previousHop;
uint32_t updated;
uint64_t positionX;
uint64_t positionY;
Vector myPos;
Vector recPos;
Ptr<MobilityModel> MM = m_ipv4->GetObject<MobilityModel> ();
positionX = MM->GetPosition ().x;
positionY = MM->GetPosition ().y;
myPos.x = positionX;
myPos.y = positionY;
TypeHeader tHeader (GPSRTYPE_POS);
p->RemoveHeader (tHeader);
if (!tHeader.IsValid ())
{
NS_LOG_DEBUG ("GPSR message " << p->GetUid () << " with unknown type
received: " << tHeader.Get () << ". Drop");
return;
// drop
}
if (tHeader.Get () == GPSRTYPE_POS)
{
PositionHeader hdr;
p->RemoveHeader (hdr);
Position.x = hdr.GetDstPosx ();

Position.y = hdr.GetDstPosy ();
updated = hdr.GetUpdated ();
recPos.x = hdr.GetRecPosx ();
recPos.y = hdr.GetRecPosy ();
previousHop.x = hdr.GetLastPosx ();
previousHop.y = hdr.GetLastPosy ();


}
PositionHeader posHeader (Position.x, Position.y,
recPos.y, (uint8_t) 1, myPos.x, myPos.y);
p->AddHeader (posHeader);
p->AddHeader (tHeader);

updated, recPos.x,

Ipv4Address nextHop = m_neighbors.BestAngle (previousHop, myPos);
if (nextHop == Ipv4Address::GetZero ())
{
return;
}
Ptr<Ipv4Route> route = Create<Ipv4Route> ();
route->SetDestination (dst);
route->SetGateway (nextHop);
// FIXME: Does not work for multiple interfaces
route->SetOutputDevice (m_ipv4->GetNetDevice (1));
route->SetSource (header.GetSource ());
ucb (route, p, header);
return;
}

void
RoutingProtocol::NotifyInterfaceUp (uint32_t interface)
{
NS_LOG_FUNCTION (this << m_ipv4->GetAddress (interface, 0).GetLocal ());
Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
if (l3->GetNAddresses (interface) > 1)
{
NS_LOG_WARN ("GPSR does not work with more then one address per each
interface.");
}
Ipv4InterfaceAddress iface = l3->GetAddress (interface, 0);
if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
{
return;
}
// Create a socket to listen only on this interface
Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
UdpSocketFactory::GetTypeId ());
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvGPSR, this));
socket->BindToNetDevice (l3->GetNetDevice (interface));
socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), GPSR_PORT));
socket->SetAllowBroadcast (true);
socket->SetAttribute ("IpTtl", UintegerValue (1));
m_socketAddresses.insert (std::make_pair (socket, iface));
// Allow neighbor manager use this interface for layer 2 feedback if possible
Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress
(iface.GetLocal ()));
Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
if (wifi == 0)

{


return;
}
Ptr<WifiMac> mac = wifi->GetMac ();
if (mac == 0)
{
return;
}
mac->TraceConnectWithoutContext ("TxErrHeader", m_neighbors.GetTxErrorCallback
());
}
void
RoutingProtocol::RecvGPSR (Ptr<Socket> socket)
{
NS_LOG_FUNCTION (this << socket);
Address sourceAddress;
Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
TypeHeader tHeader (GPSRTYPE_HELLO);
packet->RemoveHeader (tHeader);
if (!tHeader.IsValid ())
{
NS_LOG_DEBUG ("GPSR message " << packet->GetUid () << " with unknown type
received: " << tHeader.Get () << ". Ignored");
return;
}
HelloHeader hdr;
packet->RemoveHeader (hdr);
Vector Position;

Position.x = hdr.GetOriginPosx ();
Position.y = hdr.GetOriginPosy ();
InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom
(sourceAddress);
Ipv4Address sender = inetSourceAddr.GetIpv4 ();
Ipv4Address receiver = m_socketAddresses[socket].GetLocal ();
UpdateRouteToNeighbor (sender, receiver, Position);
}
void
RoutingProtocol::UpdateRouteToNeighbor (Ipv4Address sender, Ipv4Address
receiver, Vector Pos)
{
m_neighbors.AddEntry (sender, Pos);
}

void
RoutingProtocol::NotifyInterfaceDown (uint32_t interface)
{
NS_LOG_FUNCTION (this << m_ipv4->GetAddress (interface, 0).GetLocal ());
// Disable layer 2 link state monitoring (if possible)
Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();


Ptr<NetDevice> dev = l3->GetNetDevice (interface);
Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
if (wifi != 0)
{
Ptr<WifiMac> mac = wifi->GetMac ()->GetObject<AdhocWifiMac> ();
if (mac != 0)
{

mac->TraceDisconnectWithoutContext ("TxErrHeader",
m_neighbors.GetTxErrorCallback
());
}
}
// Close socket
Ptr<Socket> socket = FindSocketWithInterfaceAddress (m_ipv4->GetAddress
(interface, 0));
NS_ASSERT (socket);
socket->Close ();
m_socketAddresses.erase (socket);
if (m_socketAddresses.empty ())
{
NS_LOG_LOGIC ("No gpsr interfaces");
m_neighbors.Clear ();
m_locationService->Clear ();
return;
}
}
Ptr<Socket>
RoutingProtocol::FindSocketWithInterfaceAddress (Ipv4InterfaceAddress addr )
const
{
NS_LOG_FUNCTION (this << addr);
for (std::map::const_iterator j =
m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
{
Ptr<Socket> socket = j->first;
Ipv4InterfaceAddress iface = j->second;
if (iface == addr)

{
return socket;
}
}
Ptr<Socket> socket;
return socket;
}

void RoutingProtocol::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress
address)
{
NS_LOG_FUNCTION (this << " interface " << interface << " address " <<
address);
Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
if (!l3->IsUp (interface))
{
return;
}
if (l3->GetNAddresses ((interface) == 1))
{


Ipv4InterfaceAddress iface = l3->GetAddress (interface, 0);
Ptr<Socket> socket = FindSocketWithInterfaceAddress (iface);
if (!socket)
{
if (iface.GetLocal () == Ipv4Address ("127.0.0.1"))
{
return;
}

// Create a socket to listen only on this interface
Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
UdpSocketFactory::GetTypeId
());

NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback
(&RoutingProtocol::RecvGPSR,this));
socket->BindToNetDevice (l3->GetNetDevice (interface));
// Bind to any IP address so that broadcasts can be received
socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), GPSR_PORT));
socket->SetAllowBroadcast (true);
m_socketAddresses.insert (std::make_pair (socket, iface));
Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4>GetInterfaceForAddress (iface.GetLocal ()));
}
}
else
{
NS_LOG_LOGIC ("GPSR does not work with more then one address per each
interface. Ignore added address");
}
}
void
RoutingProtocol::NotifyRemoveAddress (uint32_t i, Ipv4InterfaceAddress address)
{
NS_LOG_FUNCTION (this);
Ptr<Socket> socket = FindSocketWithInterfaceAddress (address);
if (socket)
{


());

m_socketAddresses.erase (socket);
Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
if (l3->GetNAddresses (i))
{
Ipv4InterfaceAddress iface = l3->GetAddress (i, 0);
// Create a socket to listen only on this interface
Ptr<Socket> socket = Socket::CreateSocket (GetObject<Node> (),
UdpSocketFactory::GetTypeId
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvGPSR,

this));

// Bind to any IP address so that broadcasts can be received
socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), GPSR_PORT));
socket->SetAllowBroadcast (true);
m_socketAddresses.insert (std::make_pair (socket, iface));

// Add local broadcast record to the routing table
Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4>GetInterfaceForAddress (iface.GetLocal ()));
}


if (m_socketAddresses.empty ())
{
NS_LOG_LOGIC ("No gpsr interfaces");
m_neighbors.Clear ();
m_locationService->Clear ();

return;
}

}

}
else
{
NS_LOG_LOGIC ("Remove address not participating in GPSR operation");
}

void
RoutingProtocol::SetIpv4 (Ptr<Ipv4> ipv4)
{
NS_ASSERT (ipv4 != 0);
NS_ASSERT (m_ipv4 == 0);
m_ipv4 = ipv4;
HelloIntervalTimer.SetFunction (&RoutingProtocol::HelloTimerExpire, this);
HelloIntervalTimer.Schedule (FIRST_JITTER);
//Schedule only when it has packets on queue
CheckQueueTimer.SetFunction (&RoutingProtocol::CheckQueue, this);
Simulator::ScheduleNow (&RoutingProtocol::Start, this);
}
void
RoutingProtocol::HelloTimerExpire ()
{
SendHello ();
HelloIntervalTimer.Cancel ();
HelloIntervalTimer.Schedule (HelloInterval + JITTER);
}

void
RoutingProtocol::SendHello ()
{
NS_LOG_FUNCTION (this);
double positionX;
double positionY;
Ptr<MobilityModel> MM = m_ipv4->GetObject<MobilityModel> ();
positionX = MM->GetPosition ().x;
positionY = MM->GetPosition ().y;
for (std::map::const_iterator j =
m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
{
Ptr<Socket> socket = j->first;
Ipv4InterfaceAddress iface = j->second;
HelloHeader helloHeader (((uint64_t) positionX),((uint64_t) positionY));
Ptr<Packet> packet = Create<Packet> ();
packet->AddHeader (helloHeader);
TypeHeader tHeader (GPSRTYPE_HELLO);
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 ();

}
socket->SendTo (packet, 0, InetSocketAddress (destination, GPSR_PORT));
}
}
bool
RoutingProtocol::IsMyOwnAddress (Ipv4Address src)
{
NS_LOG_FUNCTION (this << src);
for (std::map::const_iterator j =
m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
{
Ipv4InterfaceAddress iface = j->second;
if (src == iface.GetLocal ())
{
return true;
}
}
return false;
}

void
RoutingProtocol::Start ()
{
NS_LOG_FUNCTION (this);
m_queuedAddresses.clear ();
//FIXME ajustar timer, meter valor parametrizavel
Time tableTime ("2s");
switch (LocationServiceName)
{
case GPSR_LS_GOD:

NS_LOG_DEBUG ("GodLS in use");
m_locationService = CreateObject<GodLocationService> ();
break;
case GPSR_LS_RLS:
NS_LOG_UNCOND ("RLS not yet implemented");
break;
}
}
Ptr<Ipv4Route>
RoutingProtocol::LoopbackRoute (const Ipv4Header & hdr, Ptr<NetDevice> oif)
{
NS_LOG_FUNCTION (this << hdr);
m_lo = m_ipv4->GetNetDevice (0);
NS_ASSERT (m_lo != 0);


Ptr<Ipv4Route> rt = Create<Ipv4Route> ();
rt->SetDestination (hdr.GetDestination ());
std::map::const_iterator j =
m_socketAddresses.begin ();
if (oif)
{
// Iterate to find an address on the oif device
for (j = m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
{
Ipv4Address addr = j->second.GetLocal ();
int32_t interface = m_ipv4->GetInterfaceForAddress (addr);
if (oif == m_ipv4->GetNetDevice (static_cast<uint32_t> (interface)))
{
rt->SetSource (addr);

break;
}
}
}
else
{
rt->SetSource (j->second.GetLocal ());
}
NS_ASSERT_MSG (rt->GetSource () != Ipv4Address (), "Valid GPSR source address
not found");
rt->SetGateway (Ipv4Address ("127.0.0.1"));
rt->SetOutputDevice (m_lo);
return rt;
}
int
RoutingProtocol::GetProtocolNumber (void) const
{
return GPSR_PORT;
}
void
RoutingProtocol::AddHeaders (Ptr<Packet> p, Ipv4Address source, Ipv4Address
destination, uint8_t protocol, Ptr<Ipv4Route> route)
{
NS_LOG_FUNCTION (this << " source " << source << " destination " <<
destination);
Vector myPos;
Ptr<MobilityModel> MM = m_ipv4->GetObject<MobilityModel> ();
myPos.x = MM->GetPosition ().x;
myPos.y = MM->GetPosition ().y;
Ipv4Address nextHop;

if(m_neighbors.isNeighbour (destination))
{
nextHop = destination;
}
else
{
nextHop = m_neighbors.BestNeighbor (m_locationService->GetPosition
(destination), myPos);
}


uint16_t positionX = 0;
uint16_t positionY = 0;
uint32_t hdrTime = 0;
if(destination != m_ipv4->GetAddress (1, 0).GetBroadcast ())
{
positionX = m_locationService->GetPosition (destination).x;
positionY = m_locationService->GetPosition (destination).y;
hdrTime = (uint32_t) m_locationService->GetEntryUpdateTime
(destination).GetSeconds ();
}
PositionHeader posHeader (positionX, positionY,
(uint64_t) 0, (uint8_t) 0, myPos.x, myPos.y);
p->AddHeader (posHeader);
TypeHeader tHeader (GPSRTYPE_POS);
p->AddHeader (tHeader);

hdrTime, (uint64_t) 0,

m_downTarget (p, source, destination, protocol, route);

}
bool
RoutingProtocol::Forwarding (Ptr<const Packet> packet, const Ipv4Header &
header,
UnicastForwardCallback ucb, ErrorCallback ecb)
{
Ptr<Packet> p = packet->Copy ();
NS_LOG_FUNCTION (this);
Ipv4Address dst = header.GetDestination ();
Ipv4Address origin = header.GetSource ();
m_neighbors.Purge ();
uint32_t updated = 0;
Vector Position;
Vector RecPosition;
uint8_t inRec = 0;
TypeHeader tHeader (GPSRTYPE_POS);
PositionHeader hdr;
p->RemoveHeader (tHeader);
if (!tHeader.IsValid ())
{
NS_LOG_DEBUG ("GPSR message " << p->GetUid () << " with unknown type
received: " << tHeader.Get () << ". Drop");
return false;
// drop
}
if (tHeader.Get () == GPSRTYPE_POS)
{
p->RemoveHeader (hdr);
Position.x = hdr.GetDstPosx ();
Position.y = hdr.GetDstPosy ();

updated = hdr.GetUpdated ();
RecPosition.x = hdr.GetRecPosx ();
RecPosition.y = hdr.GetRecPosy ();
inRec = hdr.GetInRec ();
}
Vector myPos;


Ptr<MobilityModel> MM = m_ipv4->GetObject<MobilityModel> ();
myPos.x = MM->GetPosition ().x;
myPos.y = MM->GetPosition ().y;
if(inRec == 1 && CalculateDistance (myPos, Position) < CalculateDistance
(RecPosition, Position)){
inRec = 0;
hdr.SetInRec(0);
NS_LOG_LOGIC ("No longer in Recovery to " << dst << " in " << myPos);
}
if(inRec){
p->AddHeader (hdr);
p->AddHeader (tHeader); //put headers back so that the RecoveryMode is
compatible with Forwarding and SendFromQueue
std::cout<<"Forwarding RecoveryMode \n ";
RecoveryMode (dst, p, ucb, header);
return true;
}

uint32_t myUpdated = (uint32_t) m_locationService->GetEntryUpdateTime
(dst).GetSeconds ();
if (myUpdated > updated) //check if node has an update to the position of
destination

{
Position.x = m_locationService->GetPosition (dst).x;
Position.y = m_locationService->GetPosition (dst).y;
updated = myUpdated;
}
Ipv4Address nextHop;
if(m_neighbors.isNeighbour (dst))
{
nextHop = dst;
}
else
{
nextHop = m_neighbors.BestNeighbor (Position, myPos);
if (nextHop != Ipv4Address::GetZero ())
{
PositionHeader posHeader (Position.x, Position.y,
0, (uint64_t) 0, (uint8_t) 0, myPos.x, myPos.y);
p->AddHeader (posHeader);
p->AddHeader (tHeader);

updated, (uint64_t)

Ptr<NetDevice> oif = m_ipv4->GetObject<NetDevice> ();
Ptr<Ipv4Route> route = Create<Ipv4Route> ();
route->SetDestination (dst);
route->SetSource (header.GetSource ());
route->SetGateway (nextHop);
// FIXME: Does not work for multiple interfaces
route->SetOutputDevice (m_ipv4->GetNetDevice (1));
route->SetDestination (header.GetDestination ());

NS_ASSERT (route != 0);
NS_LOG_DEBUG ("Exist route to " << route->GetDestination () << " from


interface " << route->GetOutputDevice ());
NS_LOG_LOGIC (route->GetOutputDevice () << " forwarding to " << dst <<
" from " << origin << " through " << route->GetGateway () << " packet " << p>GetUid ());
ucb (route, p, header);
return true;
}
}
hdr.SetInRec(1);
hdr.SetRecPosx (myPos.x);
hdr.SetRecPosy (myPos.y);
hdr.SetLastPosx (Position.x); //when entering Recovery, the first edge is the
Dst
hdr.SetLastPosy (Position.y);
p->AddHeader (hdr);
p->AddHeader (tHeader);
std::cout<<"Forwarding RecoveryMode 1 \n ";
RecoveryMode (dst, p, ucb, header);
NS_LOG_LOGIC ("Entering recovery-mode to " << dst << " in " << m_ipv4>GetAddress (1, 0).GetLocal ());
return true;
}

void
RoutingProtocol::SetDownTarget (IpL4Protocol::DownTargetCallback callback)
{
m_downTarget = callback;
}

IpL4Protocol::DownTargetCallback
RoutingProtocol::GetDownTarget (void) const
{
return m_downTarget;
}

Ptr<Ipv4Route>
RoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header,
Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
{
NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
if (!p)
{
return LoopbackRoute (header, oif);
}
if (m_socketAddresses.empty ())
{
sockerr = Socket::ERROR_NOROUTETOHOST;

// later


NS_LOG_LOGIC ("No gpsr interfaces");
Ptr<Ipv4Route> route;
return route;
}
sockerr = Socket::ERROR_NOTERROR;
Ptr<Ipv4Route> route = Create<Ipv4Route> ();
Ipv4Address dst = header.GetDestination ();
Vector dstPos = Vector (1, 0, 0);

if (!(dst == m_ipv4->GetAddress (1, 0).GetBroadcast ()))
{
dstPos = m_locationService->GetPosition (dst);
}
if (CalculateDistance (dstPos, m_locationService->GetInvalidPosition ()) == 0
&& m_locationService->IsInSearch (dst))
{
DeferredRouteOutputTag tag;
if (!p->PeekPacketTag (tag))
{
p->AddPacketTag (tag);
}
return LoopbackRoute (header, oif);
}
Vector myPos;
Ptr<MobilityModel> MM = m_ipv4->GetObject<MobilityModel> ();
myPos.x = MM->GetPosition ().x;
myPos.y = MM->GetPosition ().y;
Ipv4Address nextHop;
if(m_neighbors.isNeighbour (dst))
{
nextHop = dst;
}
else
{
nextHop = m_neighbors.BestNeighbor (dstPos, myPos);
}
if (nextHop != Ipv4Address::GetZero ())
{
NS_LOG_DEBUG ("Destination: " << dst);

route->SetDestination (dst);
if (header.GetSource () == Ipv4Address ("102.102.102.102"))
{
route->SetSource (m_ipv4->GetAddress (1, 0).GetLocal ());
}
else
{
route->SetSource (header.GetSource ());
}
route->SetGateway (nextHop);
route->SetOutputDevice (m_ipv4->GetNetDevice (m_ipv4>GetInterfaceForAddress (route->GetSource ())));
route->SetDestination (header.GetDestination ());
NS_ASSERT (route != 0);


NS_LOG_DEBUG ("Exist route to " << route->GetDestination () << " from
interface " << route->GetSource ());
if (oif != 0 && route->GetOutputDevice () != oif)
{
NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
sockerr = Socket::ERROR_NOROUTETOHOST;
return Ptr<Ipv4Route> ();
}
return route;
}
else
{
DeferredRouteOutputTag tag;
if (!p->PeekPacketTag (tag))
{

p->AddPacketTag (tag);
}
return LoopbackRoute (header, oif);
//in RouteInput the recovery-mode
is called
}
}
}
}



×