Merge 802.11s code.
This commit is contained in:
108
examples/mesh.cc
Normal file
108
examples/mesh.cc
Normal file
@@ -0,0 +1,108 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Evgeny Khorov <horov@frtk.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/simulator-module.h"
|
||||
#include "ns3/node-module.h"
|
||||
#include "ns3/helper-module.h"
|
||||
#include "ns3/global-routing-module.h"
|
||||
#include "ns3/wifi-module.h"
|
||||
#include "ns3/mobility-module.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("TestMeshScript");
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
// Creating square topology with nNodes x nNodes grid:
|
||||
int xSize = 5;
|
||||
int ySize = 5;
|
||||
double step = 100.0; //Grid with one-hop edge
|
||||
double randomStart = 0.1; //One beacon interval
|
||||
NodeContainer nodes;
|
||||
CommandLine cmd;
|
||||
MobilityHelper mobility;
|
||||
MeshWifiHelper wifi;
|
||||
NetDeviceContainer meshDevices;
|
||||
// Defining a size of our network:
|
||||
cmd.AddValue("x-size", "Number of nodes in a row grid", xSize);
|
||||
cmd.AddValue("y-size", "Number of rows in a grid", ySize);
|
||||
cmd.AddValue("step", "Size of edge in our grid", step);
|
||||
cmd.AddValue("start", "Random start parameter", randomStart);
|
||||
cmd.Parse (argc, argv);
|
||||
NS_LOG_DEBUG("Grid:"<<xSize<<"*"<<ySize);
|
||||
// Creating nodes:
|
||||
nodes.Create (ySize*xSize);
|
||||
|
||||
// Setting channel:
|
||||
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
|
||||
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
|
||||
wifiPhy.SetChannel (wifiChannel.Create ());
|
||||
// Setting Wifi:
|
||||
//wifi.SetPhy("ns3::WifiPhy");
|
||||
wifi.SetRemoteStationManager("ns3::AarfWifiManager");
|
||||
Ssid ssid = Ssid("MyMeSH");
|
||||
wifi.SetMac ("ns3::MeshWifiMac",
|
||||
"Ssid", SsidValue (ssid),
|
||||
"RandomStart", TimeValue (Seconds (randomStart))
|
||||
);
|
||||
wifi.SetPeerLinkManager ("ns3::WifiPeerManager");
|
||||
wifi.SetL2RoutingProtocol ("ns3::Hwmp");
|
||||
wifi.SetL2RoutingNetDevice ("ns3::L2RoutingNetDevice");
|
||||
meshDevices = wifi.Install (wifiPhy,nodes,1);
|
||||
// Installing Mobility.
|
||||
mobility.SetPositionAllocator
|
||||
("ns3::GridPositionAllocator",
|
||||
"MinX", DoubleValue (0.0),
|
||||
"MinY", DoubleValue (0.0),
|
||||
"DeltaX", DoubleValue (step),
|
||||
"DeltaY", DoubleValue (step),
|
||||
"GridWidth", UintegerValue (xSize),
|
||||
"LayoutType", StringValue("RowFirst"));
|
||||
mobility.SetMobilityModel ("ns3::StaticMobilityModel");
|
||||
mobility.Install (nodes);
|
||||
|
||||
// Setting Internet Stack:
|
||||
InternetStackHelper stack;
|
||||
stack.Install(nodes);
|
||||
Ipv4AddressHelper address;
|
||||
address.SetBase ("10.1.1.0", "255.255.255.0");
|
||||
Ipv4InterfaceContainer interfaces = address.Assign (meshDevices);
|
||||
UdpEchoServerHelper echoServer (9);
|
||||
ApplicationContainer serverApps = echoServer.Install (nodes.Get (0));
|
||||
serverApps.Start (Seconds (1.0));
|
||||
serverApps.Stop (Seconds (10.0));
|
||||
UdpEchoClientHelper echoClient (interfaces.GetAddress (0), 9);
|
||||
echoClient.SetAttribute ("MaxPackets", UintegerValue (1000));
|
||||
echoClient.SetAttribute ("Interval", TimeValue (Seconds (0.001)));
|
||||
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
|
||||
ApplicationContainer clientApps = echoClient.Install (nodes.Get (1));
|
||||
clientApps.Start (Seconds (2.0));
|
||||
clientApps.Stop (Seconds (10.0));
|
||||
//end
|
||||
Simulator::Stop (Seconds (10.0));
|
||||
Simulator::Run();
|
||||
Simulator::Destroy();
|
||||
return 0;
|
||||
}
|
||||
@@ -120,6 +120,10 @@ def build(bld):
|
||||
['core', 'simulator', 'mobility', 'wifi'])
|
||||
obj.source = 'wifi-ap.cc'
|
||||
|
||||
obj = bld.create_ns3_program('mesh',
|
||||
['core', 'simulator', 'mobility', 'wifi'])
|
||||
obj.source = 'mesh.cc'
|
||||
|
||||
bld.add_subdirs('stats')
|
||||
|
||||
obj = bld.create_ns3_program('wifi-wired-bridging',
|
||||
|
||||
282
src/devices/l2-routing/l2-routing-hwmp/hwmp-rtable.cc
Normal file
282
src/devices/l2-routing/l2-routing-hwmp/hwmp-rtable.cc
Normal file
@@ -0,0 +1,282 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/node.h"
|
||||
#include "hwmp-rtable.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("HwmpRtable");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (HwmpRtable);
|
||||
|
||||
TypeId
|
||||
HwmpRtable::GetTypeId(void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::HwmpRtable")
|
||||
.SetParent<Object> ()
|
||||
.AddConstructor<HwmpRtable> ();
|
||||
return tid;
|
||||
|
||||
}
|
||||
|
||||
HwmpRtable::HwmpRtable()
|
||||
{
|
||||
}
|
||||
|
||||
HwmpRtable::~HwmpRtable()
|
||||
{
|
||||
DoDispose();
|
||||
}
|
||||
|
||||
void
|
||||
HwmpRtable::DoDispose()
|
||||
{
|
||||
NS_LOG_UNCOND("RTABLE DISPOSE STARTED");
|
||||
m_routes.clear();
|
||||
m_roots.clear();
|
||||
}
|
||||
|
||||
void
|
||||
HwmpRtable::AddReactivePath(
|
||||
Mac48Address destination,
|
||||
Mac48Address retransmitter,
|
||||
uint32_t port,
|
||||
uint32_t metric,
|
||||
Time lifetime,
|
||||
uint32_t seqnum
|
||||
)
|
||||
{
|
||||
std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
|
||||
if(i == m_routes.end())
|
||||
{
|
||||
struct ReactiveRoute newroute;
|
||||
m_routes[destination] = newroute;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* if outport differs from stored, routing info is
|
||||
* actual and metric is worse - we ignore this
|
||||
* information
|
||||
*/
|
||||
if(
|
||||
(i->second.port != port) &&
|
||||
(i->second.metric < metric) &&
|
||||
/**
|
||||
* The routing info is actual or it
|
||||
* was received from peer
|
||||
*/
|
||||
((i->second.whenExpire > Simulator::Now())||(i->second.whenExpire == Seconds(0)))
|
||||
)
|
||||
return;
|
||||
}
|
||||
i = m_routes.find(destination);
|
||||
NS_ASSERT(i != m_routes.end());
|
||||
i->second.retransmitter = retransmitter;
|
||||
i->second.port = port;
|
||||
i->second.metric = metric;
|
||||
if(lifetime != Seconds(0))
|
||||
i->second.whenExpire = MilliSeconds(Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
|
||||
else
|
||||
/**
|
||||
* Information about peer does not have lifetime
|
||||
*/
|
||||
i->second.whenExpire = Seconds(0);
|
||||
i->second.seqnum = seqnum;
|
||||
}
|
||||
|
||||
void
|
||||
HwmpRtable::AddProactivePath(
|
||||
uint32_t metric,
|
||||
Mac48Address root,
|
||||
Mac48Address retransmitter,
|
||||
uint32_t port,
|
||||
Time lifetime,
|
||||
uint32_t seqnum
|
||||
)
|
||||
{
|
||||
struct ProactiveRoute newroute;
|
||||
m_roots[port] = newroute;
|
||||
std::map<uint32_t,struct ProactiveRoute>::iterator i = m_roots.find(port);
|
||||
NS_ASSERT(i != m_roots.end());
|
||||
i->second.root = root;
|
||||
i->second.retransmitter = retransmitter;
|
||||
i->second.metric = metric;
|
||||
i->second.whenExpire = MilliSeconds(Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds());
|
||||
i->second.seqnum = seqnum;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
HwmpRtable::AddPrecursor(Mac48Address destination, uint32_t port, Mac48Address precursor)
|
||||
{
|
||||
bool should_add = true;
|
||||
std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
|
||||
if((i != m_routes.end()) && (i->second.port == port))
|
||||
{
|
||||
for(unsigned int j = 0 ; j < i->second.precursors.size(); j ++)
|
||||
if(i->second.precursors[j] == precursor)
|
||||
{
|
||||
should_add = false;
|
||||
break;
|
||||
}
|
||||
if(should_add)
|
||||
i->second.precursors.push_back(precursor);
|
||||
}
|
||||
std::map<uint32_t,struct ProactiveRoute>::iterator k = m_roots.find(port);
|
||||
if(k!= m_roots.end())
|
||||
{
|
||||
for(unsigned int j = 0 ; j < k->second.precursors.size(); j ++)
|
||||
if(k->second.precursors[j] == precursor)
|
||||
return;
|
||||
k->second.precursors.push_back(precursor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HwmpRtable::DeleteProactivePath(uint32_t port)
|
||||
{
|
||||
std::map<uint32_t,struct ProactiveRoute>::iterator j = m_roots.find(port);
|
||||
if(j != m_roots.end())
|
||||
m_roots.erase(j);
|
||||
|
||||
}
|
||||
void
|
||||
HwmpRtable::DeleteProactivePath(Mac48Address root, uint32_t port)
|
||||
{
|
||||
std::map<uint32_t,struct ProactiveRoute>::iterator j = m_roots.find(port);
|
||||
if((j != m_roots.end())&&(j->second.root == root))
|
||||
m_roots.erase(j);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
HwmpRtable::DeleteReactivePath(Mac48Address destination, uint32_t port)
|
||||
{
|
||||
std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
|
||||
if(i != m_routes.end())
|
||||
if(i->second.port == port)
|
||||
m_routes.erase(i);
|
||||
}
|
||||
|
||||
struct HwmpRtable::LookupResult
|
||||
HwmpRtable::LookupReactive(Mac48Address destination)
|
||||
{
|
||||
struct LookupResult result;
|
||||
result.retransmitter = Mac48Address::GetBroadcast();
|
||||
result.metric = MAX_METRIC;
|
||||
result.ifIndex = PORT_ANY;
|
||||
|
||||
std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
|
||||
if(i == m_routes.end())
|
||||
return result;
|
||||
result.ifIndex = i->second.port;
|
||||
//Seconds(0) means that this is routing
|
||||
if(i->second.whenExpire < Simulator::Now())
|
||||
if(i->second.retransmitter != destination)
|
||||
return result;
|
||||
result.retransmitter = i->second.retransmitter;
|
||||
result.metric = i->second.metric;
|
||||
result.seqnum = i->second.seqnum;
|
||||
return result;
|
||||
}
|
||||
|
||||
struct HwmpRtable::LookupResult
|
||||
HwmpRtable::LookupProactive(uint32_t port)
|
||||
{
|
||||
struct LookupResult result;
|
||||
result.retransmitter = Mac48Address::GetBroadcast();
|
||||
result.metric = MAX_METRIC;
|
||||
result.ifIndex = PORT_ANY;
|
||||
std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator i = m_roots.find(port);
|
||||
if(i == m_roots.end())
|
||||
return result;
|
||||
result.ifIndex = i->first;
|
||||
if(i->second.whenExpire < Simulator::Now())
|
||||
return result;
|
||||
result.retransmitter = i->second.retransmitter;
|
||||
result.metric = i->second.metric;
|
||||
result.seqnum = i->second.seqnum;
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<struct HwmpRtable::FailedDestination>
|
||||
HwmpRtable::GetUnreachableDestinations(Mac48Address peerAddress, uint32_t port)
|
||||
{
|
||||
std::vector<struct FailedDestination> retval;
|
||||
for(std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.begin(); i!= m_routes.end(); i++)
|
||||
if((i->second.retransmitter == peerAddress)&&(i->second.port == port))
|
||||
{
|
||||
struct FailedDestination dst;
|
||||
dst.destination = i->first;
|
||||
i->second.seqnum ++;
|
||||
dst.seqnum = i->second.seqnum;
|
||||
retval.push_back(dst);
|
||||
}
|
||||
/**
|
||||
* Lookup a path to root
|
||||
*/
|
||||
std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator i = m_roots.find(port);
|
||||
if((i != m_roots.end())&&(i->second.retransmitter == peerAddress))
|
||||
{
|
||||
struct FailedDestination dst;
|
||||
dst.destination = i->second.root;
|
||||
dst.seqnum = i->second.seqnum;
|
||||
retval.push_back(dst);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
uint32_t
|
||||
HwmpRtable::RequestSeqnum(Mac48Address destination)
|
||||
{
|
||||
std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator i = m_routes.find(destination);
|
||||
if(i == m_routes.end())
|
||||
return 0;
|
||||
return i->second.seqnum;
|
||||
}
|
||||
|
||||
std::vector<Mac48Address>
|
||||
HwmpRtable::GetPrecursors(Mac48Address destination, uint32_t port)
|
||||
{
|
||||
std::vector<Mac48Address> retval;
|
||||
std::map<uint32_t, struct ProactiveRoute, addrcmp>::iterator root = m_roots.find(port);
|
||||
if((root != m_roots.end()) &&(root->second.root == destination))
|
||||
{
|
||||
for(unsigned int i = 0; i < root->second.precursors.size(); i ++)
|
||||
retval.push_back(root->second.precursors[i]);
|
||||
}
|
||||
std::map<Mac48Address, struct ReactiveRoute, addrcmp>::iterator route = m_routes.find(destination);
|
||||
if( (route != m_routes.end()) && (route->second.port == port) )
|
||||
{
|
||||
for(unsigned int i = 0; i < route->second.precursors.size(); i ++)
|
||||
retval.push_back(route->second.precursors[i]);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
}//namespace ns3
|
||||
125
src/devices/l2-routing/l2-routing-hwmp/hwmp-rtable.h
Normal file
125
src/devices/l2-routing/l2-routing-hwmp/hwmp-rtable.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HWMP_RTABLE_H
|
||||
#define HWMP_RTABLE_H
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/event-id.h"
|
||||
#include "ns3/packet.h"
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
class HwmpRtable : public Object
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
HwmpRtable();
|
||||
~HwmpRtable();
|
||||
void DoDispose();
|
||||
void AddReactivePath(
|
||||
Mac48Address destination,
|
||||
Mac48Address retransmitter,
|
||||
uint32_t port,
|
||||
uint32_t metric,
|
||||
Time lifetime,
|
||||
uint32_t seqnum
|
||||
);
|
||||
void AddProactivePath(
|
||||
uint32_t metric,
|
||||
Mac48Address root,
|
||||
Mac48Address retransmitter,
|
||||
uint32_t port,
|
||||
Time lifetime,
|
||||
uint32_t seqnum
|
||||
);
|
||||
void AddPrecursor(Mac48Address destination, uint32_t port, Mac48Address precursor);
|
||||
void DeleteProactivePath(uint32_t port);
|
||||
void DeleteProactivePath(Mac48Address root, uint32_t port);
|
||||
void DeleteReactivePath(Mac48Address destination, uint32_t port);
|
||||
struct LookupResult
|
||||
{
|
||||
Mac48Address retransmitter;
|
||||
uint32_t ifIndex;
|
||||
uint32_t metric;
|
||||
uint32_t seqnum;
|
||||
};
|
||||
struct LookupResult
|
||||
LookupReactive(Mac48Address destination);
|
||||
struct LookupResult
|
||||
LookupProactive(uint32_t port);
|
||||
//path error routines:
|
||||
struct FailedDestination
|
||||
{
|
||||
Mac48Address destination;
|
||||
uint32_t seqnum;
|
||||
};
|
||||
std::vector<struct FailedDestination>
|
||||
GetUnreachableDestinations(Mac48Address peerAddress, uint32_t port);
|
||||
uint32_t
|
||||
RequestSeqnum(Mac48Address dst);
|
||||
std::vector<Mac48Address>
|
||||
GetPrecursors(Mac48Address destination, uint32_t port);
|
||||
const static uint32_t PORT_ANY = 0xffffffff;
|
||||
const static uint32_t MAX_METRIC = 0xffffffff;
|
||||
private:
|
||||
struct ReactiveRoute
|
||||
{
|
||||
Mac48Address retransmitter;
|
||||
uint32_t port;
|
||||
uint32_t metric;
|
||||
Time whenExpire;
|
||||
uint32_t seqnum;
|
||||
std::vector<Mac48Address> precursors;
|
||||
};
|
||||
struct ProactiveRoute
|
||||
{
|
||||
Mac48Address root;
|
||||
Mac48Address retransmitter;
|
||||
uint32_t metric;
|
||||
Time whenExpire;
|
||||
uint32_t seqnum;
|
||||
std::vector<Mac48Address> precursors;
|
||||
};
|
||||
struct addrcmp
|
||||
{
|
||||
bool operator()(const Mac48Address addr1, const Mac48Address addr2) const
|
||||
{
|
||||
uint8_t s1[6], s2[6];
|
||||
addr1.CopyTo(s1);
|
||||
addr2.CopyTo(s2);
|
||||
for(int i = 0; i < 6; i ++)
|
||||
if(s1[i] > s2[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
std::map<Mac48Address, struct ReactiveRoute, addrcmp>
|
||||
m_routes;
|
||||
std::map<uint32_t, struct ProactiveRoute>
|
||||
m_roots;
|
||||
};
|
||||
} //namespace ns3
|
||||
#endif
|
||||
539
src/devices/l2-routing/l2-routing-hwmp/hwmp-state.cc
Normal file
539
src/devices/l2-routing/l2-routing-hwmp/hwmp-state.cc
Normal file
@@ -0,0 +1,539 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "hwmp-state.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/log.h"
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("HwmpState");
|
||||
TypeId
|
||||
HwmpState::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::HwmpState")
|
||||
.SetParent<Object> ()
|
||||
.AddConstructor<HwmpState> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
HwmpState::HwmpState()
|
||||
{
|
||||
m_myPreq = m_preqQueue.end();
|
||||
m_preqId = 1;
|
||||
m_myDsn = 1;
|
||||
m_maxTtl = 10;
|
||||
m_disabled = false;
|
||||
}
|
||||
void
|
||||
HwmpState::SetRequestRouteCallback(
|
||||
Callback<struct HwmpRtable::LookupResult, const Mac48Address&> cb)
|
||||
{
|
||||
m_requestRouteCallback = cb;
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::SetRequestRootPathCallback(
|
||||
Callback<struct HwmpRtable::LookupResult, uint32_t> cb)
|
||||
{
|
||||
m_requestRootPathCallback = cb;
|
||||
}
|
||||
|
||||
//Setting MAC
|
||||
void
|
||||
HwmpState::SetMac(Ptr<MeshWifiMac> mac)
|
||||
{
|
||||
mac->SetPeerStatusCallback(MakeCallback(&HwmpState::PeerStatus, this));
|
||||
mac->SetPreqReceivedCallback(MakeCallback(&HwmpState::ReceivePreq, this));
|
||||
mac->SetPrepReceivedCallback(MakeCallback(&HwmpState::ReceivePrep, this));
|
||||
mac->SetPerrReceivedCallback(MakeCallback(&HwmpState::ReceivePerr, this));
|
||||
m_address = mac->GetAddress();
|
||||
m_preqCallback = MakeCallback(&MeshWifiMac::SendPreq, mac);
|
||||
m_prepCallback = MakeCallback(&MeshWifiMac::SendPrep, mac);
|
||||
m_perrCallback = MakeCallback(&MeshWifiMac::SendPerr, mac);
|
||||
}
|
||||
HwmpState::~HwmpState()
|
||||
{
|
||||
m_preqQueue.clear();
|
||||
}
|
||||
//Interaction with HWMP:
|
||||
void
|
||||
HwmpState::SetRoutingInfoCallback(
|
||||
Callback<void, INFO> cb
|
||||
)
|
||||
{
|
||||
m_routingInfoCallback = cb;
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::SetRetransmittersOfPerrCallback(
|
||||
Callback<std::vector<Mac48Address>, std::vector<struct HwmpRtable::FailedDestination>, uint32_t> cb)
|
||||
{
|
||||
m_retransmittersOfPerrCallback = cb;
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::RequestDestination(Mac48Address dst)
|
||||
{
|
||||
if(m_preqQueue.end() == m_myPreq)
|
||||
{
|
||||
WifiPreqInformationElement preq;
|
||||
//fill PREQ:
|
||||
preq.SetHopcount(0);
|
||||
preq.SetTTL(m_maxTtl);
|
||||
preq.SetPreqID(m_preqId++);
|
||||
if(m_preqId == MAX_PREQ_ID)
|
||||
m_preqId = 0;
|
||||
preq.SetLifetime(TIME_TO_TU(dot11sParameters::dot11MeshHWMPactivePathTimeout));
|
||||
preq.SetOriginatorSeqNumber(m_myDsn++);
|
||||
if(m_myDsn == MAX_DSN)
|
||||
m_myDsn = 0;
|
||||
preq.SetOriginatorAddress(m_address);
|
||||
preq.AddDestinationAddressElement(false, false, dst, 0); //DO = 0, RF = 0
|
||||
if(m_preqTimer.IsRunning())
|
||||
{
|
||||
NS_LOG_DEBUG("No my preq");
|
||||
m_preqQueue.push_back(preq);
|
||||
//set iterator position to my preq:
|
||||
m_myPreq = m_preqQueue.end() -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG("Send PREQ now, "<<preq.GetPreqID()<<" destinations, now is "<<Simulator::Now());
|
||||
m_preqCallback(preq);
|
||||
NS_ASSERT(!m_preqTimer.IsRunning());
|
||||
m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT(m_myPreq->GetOriginatorAddress() == m_address);
|
||||
NS_LOG_DEBUG("add a destination "<<dst);
|
||||
m_myPreq->AddDestinationAddressElement(false, false, dst, 0); //DO = 0, RF = 0
|
||||
}
|
||||
}
|
||||
void
|
||||
HwmpState::SendPathError(std::vector<struct HwmpRtable::FailedDestination> destinations)
|
||||
{
|
||||
std::vector<Mac48Address> receivers = m_retransmittersOfPerrCallback(destinations, m_ifIndex);
|
||||
NS_LOG_DEBUG("SendPathError started");
|
||||
if(receivers.size()== 0)
|
||||
return;
|
||||
NS_LOG_DEBUG(m_address<<" Should Send PERR to");
|
||||
for(unsigned int i = 0; i < receivers.size(); i ++)
|
||||
{
|
||||
AddPerrReceiver(receivers[i]);
|
||||
NS_LOG_DEBUG(receivers[i]);
|
||||
}
|
||||
NS_LOG_DEBUG("To tel about failure with");
|
||||
for(unsigned int i = 0; i < destinations.size(); i ++)
|
||||
{
|
||||
m_myPerr.AddAddressUnit(destinations[i]);
|
||||
NS_LOG_DEBUG(destinations[i].destination);
|
||||
}
|
||||
if(!m_perrTimer.IsRunning())
|
||||
{
|
||||
m_perrCallback(m_myPerr,m_myPerrReceivers);
|
||||
m_myPerr.ResetPerr();
|
||||
m_perrTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPperrMinInterval,&HwmpState::SendOnePerr,this);
|
||||
}
|
||||
}
|
||||
//needed to fill routing information structure
|
||||
void
|
||||
HwmpState::SetAssociatedIfaceId(uint32_t interface)
|
||||
{
|
||||
m_ifIndex = interface;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
HwmpState::GetAssociatedIfaceId()
|
||||
{
|
||||
return m_ifIndex;
|
||||
}
|
||||
|
||||
//Interaction with MAC:
|
||||
void
|
||||
HwmpState::ReceivePreq(WifiPreqInformationElement& preq, const Mac48Address& from, const uint32_t& metric)
|
||||
{
|
||||
if(m_disabled)
|
||||
return;
|
||||
if(preq.GetOriginatorAddress() == m_address)
|
||||
return;
|
||||
preq.DecrementTtl();
|
||||
preq.IncrementMetric(metric);
|
||||
if(preq.GetTtl() == 0)
|
||||
return;
|
||||
//acceptance cretirea:
|
||||
std::map<Mac48Address, uint32_t, addrcmp>::iterator i = m_dsnDatabase.find(preq.GetOriginatorAddress());
|
||||
if(i == m_dsnDatabase.end())
|
||||
{
|
||||
m_dsnDatabase[preq.GetOriginatorAddress()] = preq.GetOriginatorSeqNumber();
|
||||
m_preqMetricDatabase[preq.GetOriginatorAddress()] = preq.GetMetric();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(i->second > preq.GetOriginatorSeqNumber())
|
||||
return;
|
||||
if(i->second == preq.GetOriginatorSeqNumber())
|
||||
{
|
||||
//find metric
|
||||
std::map<Mac48Address, uint32_t, addrcmp>::iterator j =
|
||||
m_preqMetricDatabase.find(preq.GetOriginatorAddress());
|
||||
NS_ASSERT(j != m_dsnDatabase.end());
|
||||
if(j->second <= preq.GetMetric())
|
||||
return;
|
||||
}
|
||||
m_dsnDatabase[preq.GetOriginatorAddress()] = preq.GetOriginatorSeqNumber();
|
||||
m_preqMetricDatabase[preq.GetOriginatorAddress()] = preq.GetMetric();
|
||||
}
|
||||
NS_LOG_DEBUG(
|
||||
"PREQ from "<< preq.GetOriginatorAddress()
|
||||
<<", at "<< m_address
|
||||
<<", TTL ="<< (int)preq.GetTtl()
|
||||
<<", metric = "<< preq.GetMetric()
|
||||
<<", hopcount = "<< (int)preq.GetHopCount()
|
||||
<<", preqId = "<< preq.GetPreqID()
|
||||
<<", transmitter is "<<from);
|
||||
//fill routingTable
|
||||
INFO newInfo;
|
||||
newInfo.me = m_address;
|
||||
newInfo.destination = preq.GetOriginatorAddress();
|
||||
newInfo.nextHop = from;
|
||||
newInfo.metric = preq.GetMetric();
|
||||
newInfo.lifetime = TU_TO_TIME(preq.GetLifetime());
|
||||
newInfo.outPort = m_ifIndex;
|
||||
newInfo.dsn = preq.GetOriginatorSeqNumber();
|
||||
newInfo.type = INFO_PREQ;
|
||||
//check if can answer:
|
||||
std::vector<Ptr<DestinationAddressUnit> > destinations = preq.GetDestinationList ();
|
||||
for(std::vector<Ptr<DestinationAddressUnit> >::iterator i = destinations.begin(); i!= destinations.end(); i++)
|
||||
{
|
||||
if((*i)->GetDestinationAddress() == Mac48Address::GetBroadcast())
|
||||
{
|
||||
//only proactive PREQ contains destination
|
||||
//address as broadcast! Proactive preq MUST
|
||||
//have destination count equal to 1 and
|
||||
//per destination flags DO and RF
|
||||
NS_ASSERT(preq.GetDestCount() == 1);
|
||||
NS_ASSERT(((*i)->IsDo()) && ((*i)->IsRf()));
|
||||
NS_LOG_DEBUG("PROACTIVE PREQ RECEIVED");
|
||||
newInfo.type = INFO_PROACTIVE;
|
||||
m_routingInfoCallback(newInfo);
|
||||
if(!preq.IsNeedNotPrep())
|
||||
{
|
||||
SendPrep(
|
||||
preq.GetOriginatorAddress(),
|
||||
m_address,
|
||||
from,
|
||||
preq.GetMetric(),
|
||||
preq.GetOriginatorSeqNumber(),
|
||||
m_myDsn ++,
|
||||
preq.GetLifetime()
|
||||
);
|
||||
if(m_myDsn == MAX_DSN)
|
||||
m_myDsn = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if((*i)->GetDestinationAddress()==m_address)
|
||||
{
|
||||
preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
|
||||
SendPrep(
|
||||
preq.GetOriginatorAddress(),
|
||||
m_address,
|
||||
from,
|
||||
0,
|
||||
preq.GetOriginatorSeqNumber(),
|
||||
m_myDsn++,
|
||||
preq.GetLifetime()
|
||||
);
|
||||
if(m_myDsn == MAX_DSN)
|
||||
m_myDsn = 0;
|
||||
continue;
|
||||
}
|
||||
//check if can answer:
|
||||
struct HwmpRtable::LookupResult result = m_requestRouteCallback((*i)->GetDestinationAddress());
|
||||
if((!((*i)->IsDo())) && (result.retransmitter!=Mac48Address::GetBroadcast()))
|
||||
{
|
||||
//have a valid information and acn answer
|
||||
if((*i)->IsRf())
|
||||
(*i)->SetFlags(true, false); //DO = 1, RF = 0 (as it was)
|
||||
else
|
||||
{
|
||||
//send a PREP and delete destination
|
||||
preq.DelDestinationAddressElement((*i)->GetDestinationAddress());
|
||||
SendPrep(
|
||||
preq.GetOriginatorAddress(),
|
||||
(*i)->GetDestinationAddress(),
|
||||
result.retransmitter,
|
||||
result.metric,
|
||||
preq.GetOriginatorSeqNumber(),
|
||||
result.seqnum,
|
||||
preq.GetLifetime()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_routingInfoCallback(newInfo);
|
||||
//chack if must retransmit:
|
||||
if(preq.GetDestCount() == 0)
|
||||
return;
|
||||
if(m_preqTimer.IsRunning())
|
||||
{
|
||||
m_preqQueue.push_back(preq);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_preqCallback(preq);
|
||||
NS_ASSERT(!m_preqTimer.IsRunning());
|
||||
m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::ReceivePrep(WifiPrepInformationElement& prep, const Mac48Address& from, const uint32_t& metric)
|
||||
{
|
||||
if(m_disabled)
|
||||
return;
|
||||
prep.DecrementTtl();
|
||||
prep.IncrementMetric(metric);
|
||||
//acceptance cretirea:
|
||||
std::map<Mac48Address, uint32_t, addrcmp>::iterator i = m_dsnDatabase.find(prep.GetDestinationAddress());
|
||||
if(i == m_dsnDatabase.end())
|
||||
{
|
||||
m_dsnDatabase[prep.GetDestinationAddress()] = prep.GetDestinationSeqNumber();
|
||||
}
|
||||
else
|
||||
if(i->second > prep.GetDestinationSeqNumber())
|
||||
return;
|
||||
//update routing info
|
||||
struct HwmpRtable::LookupResult result = m_requestRouteCallback(prep.GetDestinationAddress());
|
||||
if(result.retransmitter == Mac48Address::GetBroadcast())
|
||||
//try to look for default route
|
||||
result = m_requestRootPathCallback(m_ifIndex);
|
||||
if((result.retransmitter == Mac48Address::GetBroadcast())&&(m_address != prep.GetDestinationAddress()))
|
||||
return;
|
||||
INFO newInfo;
|
||||
newInfo.me = m_address;
|
||||
newInfo.destination = prep.GetOriginatorAddress();
|
||||
newInfo.source = prep.GetDestinationAddress();
|
||||
newInfo.nextHop = from;
|
||||
newInfo.metric = prep.GetMetric();
|
||||
newInfo.lifetime = TU_TO_TIME(prep.GetLifetime());
|
||||
newInfo.outPort = m_ifIndex;
|
||||
newInfo.dsn = prep.GetOriginatorSeqNumber();
|
||||
newInfo.prevHop = result.retransmitter;
|
||||
newInfo.type = INFO_PREP;
|
||||
NS_LOG_DEBUG("Path to "<<newInfo.source<<", i am "<<m_address<<", precursor is "<<from);
|
||||
NS_LOG_DEBUG("Path to "<<newInfo.destination<<", i am "<<m_address<<", precursor is "<<result.retransmitter);
|
||||
m_routingInfoCallback(newInfo);
|
||||
if(prep.GetDestinationAddress() == m_address)
|
||||
{
|
||||
NS_LOG_DEBUG("Destination resolved"<<newInfo.destination);
|
||||
return;
|
||||
}
|
||||
m_prepCallback(prep, result.retransmitter);
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::ReceivePerr(WifiPerrInformationElement& perr, const Mac48Address& from)
|
||||
{
|
||||
if(m_disabled)
|
||||
return;
|
||||
NS_LOG_DEBUG(m_address<<" RECEIVED PERR from "<<from);
|
||||
/**
|
||||
* Check forwarding conditions:
|
||||
*/
|
||||
std::vector<HwmpRtable::FailedDestination> destinations = perr.GetAddressUnitVector();
|
||||
for(unsigned int i = 0; i < destinations.size(); i ++)
|
||||
{
|
||||
/**
|
||||
* Lookup for a valid routing information
|
||||
*/
|
||||
struct HwmpRtable::LookupResult result = m_requestRouteCallback(destinations[i].destination);
|
||||
if(
|
||||
(result.retransmitter != from)
|
||||
||(result.seqnum >= destinations[i].seqnum)
|
||||
)
|
||||
|
||||
perr.DeleteAddressUnit(destinations[i].destination);
|
||||
}
|
||||
NS_LOG_DEBUG("Retransmit "<<(int)perr.GetNumOfDest());
|
||||
if(perr.GetNumOfDest() == 0)
|
||||
return;
|
||||
destinations = perr.GetAddressUnitVector();
|
||||
SendPathError(destinations);
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::PeerStatus(const Mac48Address peerAddress, const bool status, const uint32_t metric)
|
||||
{
|
||||
INFO newInfo;
|
||||
newInfo.me = m_address;
|
||||
newInfo.destination = peerAddress;
|
||||
newInfo.nextHop = peerAddress;
|
||||
newInfo.metric = metric;
|
||||
newInfo.outPort = m_ifIndex;
|
||||
newInfo.dsn = 0;
|
||||
if(status)
|
||||
newInfo.type = INFO_NEW_PEER;
|
||||
else
|
||||
newInfo.type = INFO_FAILED_PEER;
|
||||
m_routingInfoCallback(newInfo);
|
||||
}
|
||||
|
||||
bool
|
||||
HwmpState::SetRoot()
|
||||
{
|
||||
#if 0
|
||||
//TODO:: delete this lines!!!!!!!
|
||||
if(m_address != Mac48Address("00:00:00:00:00:10"))
|
||||
return false;
|
||||
//TODO
|
||||
#endif
|
||||
Simulator::Schedule(dot11sParameters::dot11MeshHWMPactiveRootTimeout, &HwmpState::SendProactivePreq, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::SendProactivePreq()
|
||||
{
|
||||
NS_LOG_DEBUG("Sending proactive PREQ");
|
||||
WifiPreqInformationElement preq;
|
||||
//By default: must answer
|
||||
preq.SetHopcount(0);
|
||||
preq.SetTTL(m_maxTtl);
|
||||
preq.SetPreqID(m_preqId++);
|
||||
if(m_preqId == MAX_PREQ_ID)
|
||||
m_preqId = 0;
|
||||
preq.SetLifetime(TIME_TO_TU(dot11sParameters::dot11MeshHWMPpathToRootInterval));
|
||||
preq.SetOriginatorSeqNumber(m_myDsn++);
|
||||
if(m_myDsn == MAX_DSN)
|
||||
m_myDsn = 0;
|
||||
preq.SetOriginatorAddress(m_address);
|
||||
preq.AddDestinationAddressElement(
|
||||
true,
|
||||
true,
|
||||
Mac48Address::GetBroadcast()
|
||||
,0);
|
||||
if(m_preqTimer.IsRunning())
|
||||
m_preqQueue.push_back(preq);
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG("Send now "<<preq.GetPreqID());
|
||||
m_preqCallback(preq);
|
||||
NS_ASSERT(!m_preqTimer.IsRunning());
|
||||
m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
|
||||
}
|
||||
Simulator::Schedule(dot11sParameters::dot11MeshHWMPactiveRootTimeout, &HwmpState::SendProactivePreq, this);
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::AddPerrReceiver(Mac48Address receiver)
|
||||
{
|
||||
/**
|
||||
* add new vector of addresses to m_perrReceiversand check
|
||||
* duplicates
|
||||
*/
|
||||
for(unsigned int j = 0; j < m_myPerrReceivers.size(); j++)
|
||||
if(m_myPerrReceivers[j] == receiver)
|
||||
return;
|
||||
m_myPerrReceivers.push_back(receiver);
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::UnSetRoot()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::Disable()
|
||||
{
|
||||
m_disabled = true;
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::Enable()
|
||||
{
|
||||
m_disabled = false;
|
||||
}
|
||||
|
||||
Mac48Address
|
||||
HwmpState::GetAddress()
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::SendOnePreq()
|
||||
{
|
||||
if(m_preqQueue.size() == 0)
|
||||
return;
|
||||
if(m_myPreq == m_preqQueue.begin())
|
||||
m_myPreq == m_preqQueue.end();
|
||||
WifiPreqInformationElement preq = m_preqQueue[0];
|
||||
NS_LOG_DEBUG(
|
||||
"Sending PREQ from "<<preq.GetOriginatorAddress() <<
|
||||
" destinations are "<<(int)preq.GetDestCount()<<
|
||||
", at "<<Simulator::Now()<<
|
||||
", store in queue "<<m_preqQueue.size()<<
|
||||
" preqs"<<", I am "<<m_address);
|
||||
m_preqCallback(preq);
|
||||
//erase first!
|
||||
m_preqQueue.erase(m_preqQueue.begin());
|
||||
//reschedule sending PREQ
|
||||
NS_ASSERT(!m_preqTimer.IsRunning());
|
||||
m_preqTimer = Simulator::Schedule(dot11sParameters::dot11MeshHWMPpreqMinInterval, &HwmpState::SendOnePreq, this);
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::SendPrep(Mac48Address dst,
|
||||
Mac48Address src,
|
||||
Mac48Address retransmitter,
|
||||
uint32_t initMetric,
|
||||
uint32_t dsn,
|
||||
uint32_t originatorDsn,
|
||||
uint32_t lifetime)
|
||||
{
|
||||
WifiPrepInformationElement prep;
|
||||
prep.SetHopcount(0);
|
||||
prep.SetTTL(m_maxTtl);
|
||||
prep.SetDestinationAddress(dst);
|
||||
prep.SetDestinationSeqNumber(dsn);
|
||||
prep.SetLifetime(lifetime);
|
||||
prep.SetMetric(0);
|
||||
prep.SetOriginatorAddress(src);
|
||||
prep.SetOriginatorSeqNumber(originatorDsn);
|
||||
m_prepCallback(prep, retransmitter);
|
||||
}
|
||||
|
||||
void
|
||||
HwmpState::SendOnePerr()
|
||||
{
|
||||
if(m_myPerr.GetNumOfDest() == 0)
|
||||
return;
|
||||
m_perrCallback(m_myPerr, m_myPerrReceivers);
|
||||
m_myPerr.ResetPerr();
|
||||
}
|
||||
}//namespace ns3
|
||||
206
src/devices/l2-routing/l2-routing-hwmp/hwmp-state.h
Normal file
206
src/devices/l2-routing/l2-routing-hwmp/hwmp-state.h
Normal file
@@ -0,0 +1,206 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HWMP_STATE_H
|
||||
#define HWMP_STATE_H
|
||||
#include <map>
|
||||
#include "ns3/event-id.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/hwmp-rtable.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/wifi-net-device.h"
|
||||
#include "ns3/mesh-wifi-mac.h"
|
||||
#include "ns3/mesh-wifi-preq-information-element.h"
|
||||
#include "ns3/mesh-wifi-prep-information-element.h"
|
||||
#include "ns3/mesh-wifi-perr-information-element.h"
|
||||
#include "ns3/dot11s-parameters.h"
|
||||
namespace ns3 {
|
||||
/**
|
||||
* \brief Handles HWMP state machine at each real interface
|
||||
* \details Implements the following:
|
||||
* 1. Keep it's own DSN,
|
||||
* 2. Keep PREQ and PREP timers adn send this frames in
|
||||
* accordance with HWMP-limitations
|
||||
* 3. Deliver routing information to Hwmp main class
|
||||
* 4. Notify about broken peers
|
||||
*/
|
||||
class HwmpState : public Object {
|
||||
public:
|
||||
static TypeId GetTypeId();
|
||||
HwmpState();
|
||||
~HwmpState();
|
||||
|
||||
/**
|
||||
* \brief Interface with HWMP - Hwmp can only
|
||||
* request address and collect routing
|
||||
* information
|
||||
*/
|
||||
void SetRequestRouteCallback(
|
||||
Callback<struct HwmpRtable::LookupResult, const Mac48Address&> cb);
|
||||
void SetRequestRootPathCallback(
|
||||
Callback<struct HwmpRtable::LookupResult, uint32_t> cb);
|
||||
|
||||
enum InfoType {
|
||||
INFO_PREQ,
|
||||
INFO_PREP,
|
||||
INFO_PERR,
|
||||
INFO_PROACTIVE,
|
||||
INFO_NEW_PEER,
|
||||
INFO_FAILED_PEER
|
||||
};
|
||||
typedef struct RoutingInfo{
|
||||
Mac48Address me;
|
||||
Mac48Address destination;
|
||||
Mac48Address source;
|
||||
Mac48Address nextHop;
|
||||
Mac48Address prevHop;
|
||||
uint32_t outPort;
|
||||
uint32_t metric;
|
||||
std::vector<Mac48Address>
|
||||
failedDestinations;
|
||||
uint32_t dsn;
|
||||
Time lifetime;
|
||||
enum InfoType type;
|
||||
} INFO;
|
||||
void SetRoutingInfoCallback(
|
||||
Callback<void, INFO> cb
|
||||
);
|
||||
void SetRetransmittersOfPerrCallback(
|
||||
Callback<std::vector<Mac48Address>, std::vector<struct HwmpRtable::FailedDestination>, uint32_t> cb);
|
||||
void RequestDestination(Mac48Address dest);
|
||||
void SendPathError(std::vector<struct HwmpRtable::FailedDestination> destinations);
|
||||
void SetAssociatedIfaceId(uint32_t interface);
|
||||
uint32_t
|
||||
GetAssociatedIfaceId();
|
||||
//Mac interaction:
|
||||
void SetMac(Ptr<MeshWifiMac> mac);
|
||||
void SetSendPreqCallback(
|
||||
Callback<void, const WifiPreqInformationElement&> cb);
|
||||
void SetSendPrepCallback(
|
||||
Callback<void, const WifiPrepInformationElement&> cb);
|
||||
void SetSendPerrCallback(
|
||||
Callback<void, const WifiPerrInformationElement&, std::vector<Mac48Address> > cb);
|
||||
void ReceivePreq(WifiPreqInformationElement&, const Mac48Address& from, const uint32_t& metric);
|
||||
void ReceivePrep(WifiPrepInformationElement&, const Mac48Address& from, const uint32_t& metric);
|
||||
void ReceivePerr(WifiPerrInformationElement&, const Mac48Address& from);
|
||||
void PeerStatus(
|
||||
const Mac48Address peerAddress,
|
||||
const bool status,
|
||||
const uint32_t metric
|
||||
);
|
||||
//Proactive mode routines:
|
||||
bool SetRoot();
|
||||
void UnSetRoot();
|
||||
//external handling:
|
||||
void Disable();
|
||||
void Enable();
|
||||
//DEBUG purpose:
|
||||
Mac48Address GetAddress();
|
||||
private:
|
||||
static const uint32_t MAX_PREQ_ID = 0xffffffff;
|
||||
static const uint32_t MAX_DSN = 0xffffffff;
|
||||
//information about associated port:
|
||||
Mac48Address m_address;
|
||||
//index when HWMP state is attached
|
||||
uint32_t m_ifIndex;
|
||||
//timers for PREQ and PREP:
|
||||
EventId m_preqTimer;
|
||||
void SendOnePreq();
|
||||
std::vector<WifiPreqInformationElement>
|
||||
m_preqQueue;
|
||||
//true means that we can add a destination to
|
||||
//existing PREQ element
|
||||
//False means that we must send
|
||||
EventId m_prepTimer;
|
||||
void SendPrep(
|
||||
Mac48Address dst, //dst is PREQ's originator address
|
||||
Mac48Address src, //src is PREQ's destination address
|
||||
Mac48Address retransmitter,
|
||||
uint32_t initMetric,
|
||||
uint32_t dsn,/* taken form PREQ*/
|
||||
uint32_t originatorDsn, //taken from rtable or as m_myDsn ++;
|
||||
uint32_t lifetime //taken from PREQ
|
||||
);
|
||||
std::vector<WifiPreqInformationElement>::iterator
|
||||
m_myPreq;
|
||||
//HWMP interaction callbacks:
|
||||
Callback<void, INFO>
|
||||
m_routingInfoCallback;
|
||||
Callback<std::vector<Mac48Address>, std::vector<struct HwmpRtable::FailedDestination>, uint32_t>
|
||||
m_retransmittersOfPerrCallback;
|
||||
Callback<struct HwmpRtable::LookupResult, const Mac48Address&>
|
||||
m_requestRouteCallback;
|
||||
Callback<struct HwmpRtable::LookupResult, uint32_t>
|
||||
m_requestRootPathCallback;
|
||||
//Mac interaction callbacks:
|
||||
Callback<void, const WifiPreqInformationElement&>
|
||||
m_preqCallback;
|
||||
Callback<void, const WifiPrepInformationElement&, const Mac48Address&>
|
||||
m_prepCallback;
|
||||
Callback<void, const WifiPerrInformationElement&, std::vector<Mac48Address> >
|
||||
m_perrCallback;
|
||||
//HwmpCounters:
|
||||
uint32_t m_preqId;
|
||||
uint32_t m_myDsn;
|
||||
//Seqno and metric database
|
||||
struct addrcmp
|
||||
{
|
||||
bool operator()(const Mac48Address addr1, Mac48Address addr2) const
|
||||
{
|
||||
uint8_t s1[6], s2[6];
|
||||
addr1.CopyTo(s1);
|
||||
addr2.CopyTo(s2);
|
||||
for(int i = 0; i < 6; i ++)
|
||||
if(s1[i] > s2[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
std::map<Mac48Address, uint32_t, addrcmp>
|
||||
m_dsnDatabase;
|
||||
std::map<Mac48Address, uint32_t, addrcmp>
|
||||
m_preqMetricDatabase;
|
||||
//Disable/enable functionality
|
||||
bool m_disabled;
|
||||
//Proactive PREQ mechanism:
|
||||
EventId m_proactivePreqTimer;
|
||||
void SendProactivePreq();
|
||||
/**
|
||||
* \brief Two PERRs may not be sent closer to
|
||||
* each other than
|
||||
* dot11MeshHWMPperrMinInterval, so, each HWMP
|
||||
* state collects all unreachable destinations
|
||||
* and once in dot11MeshHWMPperrMinInterval
|
||||
* should send PERR, and PERR element should
|
||||
* be cleared
|
||||
*/
|
||||
WifiPerrInformationElement
|
||||
m_myPerr;
|
||||
std::vector<Mac48Address>
|
||||
m_myPerrReceivers;
|
||||
void AddPerrReceiver(Mac48Address receiver);
|
||||
EventId m_perrTimer;
|
||||
void SendOnePerr();
|
||||
//Configurable parameters:
|
||||
uint8_t m_maxTtl;
|
||||
};
|
||||
} //namespace ns3
|
||||
#endif
|
||||
699
src/devices/l2-routing/l2-routing-hwmp/hwmp.cc
Normal file
699
src/devices/l2-routing/l2-routing-hwmp/hwmp.cc
Normal file
@@ -0,0 +1,699 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "ns3/hwmp.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/simulator.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("Hwmp");
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (Hwmp);
|
||||
NS_OBJECT_ENSURE_REGISTERED (HwmpTag);
|
||||
//Class HwmpTag:
|
||||
HwmpTag::HwmpTag()
|
||||
{
|
||||
}
|
||||
|
||||
HwmpTag::~HwmpTag()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HwmpTag::SetAddress(Mac48Address retransmitter)
|
||||
{
|
||||
m_address = retransmitter;
|
||||
}
|
||||
|
||||
Mac48Address
|
||||
HwmpTag::GetAddress()
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
|
||||
void
|
||||
HwmpTag::SetTtl(uint8_t ttl)
|
||||
{
|
||||
m_ttl = ttl;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
HwmpTag::GetTtl()
|
||||
{
|
||||
return m_ttl;
|
||||
}
|
||||
|
||||
void
|
||||
HwmpTag::SetMetric(uint32_t metric)
|
||||
{
|
||||
m_metric = metric;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
HwmpTag::GetMetric()
|
||||
{
|
||||
return m_metric;
|
||||
}
|
||||
|
||||
void
|
||||
HwmpTag::SetSeqno(uint32_t seqno)
|
||||
{
|
||||
m_seqno = seqno;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
HwmpTag::GetSeqno()
|
||||
{
|
||||
return m_seqno;
|
||||
}
|
||||
|
||||
TypeId
|
||||
HwmpTag::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::HwmpTag")
|
||||
.SetParent<Tag> ()
|
||||
.AddConstructor<HwmpTag> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
TypeId
|
||||
HwmpTag::GetInstanceTypeId(void) const
|
||||
{
|
||||
return GetTypeId();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
HwmpTag::GetSerializedSize(void) const
|
||||
{
|
||||
|
||||
return 6 //address
|
||||
+1 //ttl
|
||||
+4; //metric
|
||||
}
|
||||
|
||||
void
|
||||
HwmpTag::Serialize(TagBuffer i) const
|
||||
{
|
||||
uint8_t address[6];
|
||||
int j;
|
||||
m_address.CopyTo(address);
|
||||
i.WriteU8(m_ttl);
|
||||
i.WriteU32(m_metric);
|
||||
for(j = 0;j < 6;j ++)
|
||||
i.WriteU8(address[j]);
|
||||
}
|
||||
|
||||
void
|
||||
HwmpTag::Deserialize (TagBuffer i)
|
||||
{
|
||||
uint8_t address[6];
|
||||
int j;
|
||||
m_ttl = i.ReadU8();
|
||||
m_metric = i.ReadU32();
|
||||
for(j = 0;j < 6;j ++)
|
||||
address[j] = i.ReadU8();
|
||||
m_address.CopyFrom(address);
|
||||
}
|
||||
|
||||
void
|
||||
HwmpTag::Print (std::ostream &os) const
|
||||
{
|
||||
os << "address=" << m_address;
|
||||
os << "ttl=" << m_ttl;
|
||||
os << "metrc=" << m_metric;
|
||||
}
|
||||
void
|
||||
HwmpTag::DecrementTtl()
|
||||
{
|
||||
m_ttl --;
|
||||
}
|
||||
//Class HWMP:
|
||||
TypeId
|
||||
Hwmp::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::Hwmp")
|
||||
.SetParent<L2RoutingProtocol> ()
|
||||
.AddConstructor<Hwmp>();
|
||||
return tid;
|
||||
}
|
||||
Hwmp::Hwmp()
|
||||
{
|
||||
m_maxTtl = 32;
|
||||
m_broadcastPerr = false;
|
||||
m_rtable = CreateObject<HwmpRtable> ();
|
||||
}
|
||||
|
||||
Hwmp::~Hwmp()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Hwmp::DoDispose()
|
||||
{
|
||||
for(std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.begin(); i != m_timeoutDatabase.end(); i ++)
|
||||
i->second.Cancel();
|
||||
m_timeoutDatabase.clear();
|
||||
m_seqnoDatabase.clear();
|
||||
m_rtable = 0;
|
||||
|
||||
/**
|
||||
* clear routing queue:
|
||||
*/
|
||||
for(
|
||||
std::map<Mac48Address, std::queue<struct QueuedPacket> >::iterator i = m_rqueue.begin();
|
||||
i != m_rqueue.end();
|
||||
i++
|
||||
)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
if(i->second.empty())
|
||||
break;
|
||||
i->second.pop();
|
||||
}
|
||||
}
|
||||
m_rqueue.clear();
|
||||
/**
|
||||
* clear HWMP states
|
||||
*/
|
||||
for(unsigned int i = 0; i < m_hwmpStates.size(); i ++)
|
||||
m_hwmpStates[i] = 0;
|
||||
m_hwmpStates.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
Hwmp::RequestRoute(
|
||||
uint32_t sourceIface,
|
||||
const Mac48Address source,
|
||||
const Mac48Address destination,
|
||||
Ptr<Packet> packet,
|
||||
uint16_t protocolType, //ethrnet 'Protocol' field
|
||||
L2RoutingProtocol::RouteReplyCallback routeReply
|
||||
)
|
||||
{
|
||||
struct HwmpRtable::LookupResult result;
|
||||
HwmpTag tag;
|
||||
if(sourceIface == m_interface)
|
||||
{
|
||||
if(destination == Mac48Address::GetBroadcast())
|
||||
{
|
||||
//set seqno!
|
||||
tag.SetSeqno(m_seqno++);
|
||||
if(m_seqno == MAX_SEQNO)
|
||||
m_seqno = 0;
|
||||
}
|
||||
tag.SetTtl(m_maxTtl);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT(packet->FindFirstMatchingTag(tag));
|
||||
//check seqno!
|
||||
if(destination == Mac48Address::GetBroadcast())
|
||||
{
|
||||
std::map<Mac48Address, uint32_t, addrcmp>::iterator i = m_seqnoDatabase.find(source);
|
||||
if(i == m_seqnoDatabase.end())
|
||||
m_seqnoDatabase[source] = tag.GetSeqno();
|
||||
else
|
||||
{
|
||||
if(i->second >= tag.GetSeqno())
|
||||
return false;
|
||||
m_seqnoDatabase[source] = tag.GetSeqno();
|
||||
}
|
||||
}
|
||||
}
|
||||
tag.SetAddress(Mac48Address::GetBroadcast());
|
||||
if(tag.GetTtl() == 0)
|
||||
return false;
|
||||
tag.DecrementTtl();
|
||||
if(destination == Mac48Address::GetBroadcast())
|
||||
{
|
||||
//add RA tag RA = broadcast
|
||||
packet->RemoveAllTags();
|
||||
packet->AddTag(tag);
|
||||
routeReply(
|
||||
true,
|
||||
packet,
|
||||
source,
|
||||
destination,
|
||||
protocolType,
|
||||
HwmpRtable::PORT_ANY
|
||||
);
|
||||
return true;
|
||||
}
|
||||
result = m_rtable->LookupReactive(destination);
|
||||
if (result.retransmitter == Mac48Address::GetBroadcast())
|
||||
{
|
||||
//no actual route exists, queue packet and start route
|
||||
//discover procedure
|
||||
if(sourceIface != m_interface)
|
||||
{
|
||||
//Start path error procedure:
|
||||
NS_LOG_DEBUG("Must Send PERR");
|
||||
std::vector<struct HwmpRtable::FailedDestination> destinations;
|
||||
struct HwmpRtable::FailedDestination dst;
|
||||
dst.seqnum = m_rtable->RequestSeqnum(destination);
|
||||
dst.destination = destination;
|
||||
destinations.push_back(dst);
|
||||
StartPathErrorProcedure(destinations, result.ifIndex);
|
||||
}
|
||||
struct L2RoutingProtocol::QueuedPacket pkt;
|
||||
packet->RemoveAllTags();
|
||||
packet->AddTag(tag);
|
||||
pkt.pkt = packet;
|
||||
pkt.dst = destination;
|
||||
pkt.src = source;
|
||||
pkt.protocol = protocolType;
|
||||
pkt.reply = routeReply;
|
||||
pkt.inPort = sourceIface;
|
||||
QueuePacket(pkt);
|
||||
for(unsigned int i = 0; i< m_requestCallback.size(); i++)
|
||||
{
|
||||
if((m_modes[i] == REACTIVE) || (m_modes[i] == ROOT))
|
||||
{
|
||||
if(ShouldSendPreq(destination))
|
||||
m_requestCallback[i](destination);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT(false);
|
||||
//PROACTIVE mode
|
||||
//lookup a default route
|
||||
result = m_rtable->LookupProactive(m_hwmpStates[i]->GetAssociatedIfaceId());
|
||||
if(result.retransmitter == Mac48Address::GetBroadcast())
|
||||
{
|
||||
m_rtable->DeleteProactivePath(m_hwmpStates[i]->GetAssociatedIfaceId());
|
||||
m_modes[i] = REACTIVE;
|
||||
if(ShouldSendPreq(destination))
|
||||
m_requestCallback[i](destination);
|
||||
continue;
|
||||
}
|
||||
tag.SetAddress(result.retransmitter);
|
||||
packet->RemoveAllTags();
|
||||
packet->AddTag(tag);
|
||||
routeReply(
|
||||
true,
|
||||
packet,
|
||||
source,
|
||||
destination,
|
||||
protocolType,
|
||||
result.ifIndex
|
||||
);
|
||||
}
|
||||
}
|
||||
for(unsigned int i = 0; i< m_requestCallback.size(); i++)
|
||||
{
|
||||
m_requestCallback[i](Mac48Address("00:00:00:00:00:19"));
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tag.SetAddress(result.retransmitter);
|
||||
packet->RemoveAllTags();
|
||||
packet->AddTag(tag);
|
||||
routeReply(
|
||||
true,
|
||||
packet,
|
||||
source,
|
||||
destination,
|
||||
protocolType,
|
||||
result.ifIndex
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
Hwmp::AttachPorts(std::vector<Ptr<NetDevice> > ports)
|
||||
{
|
||||
for(std::vector<Ptr<NetDevice> >::iterator i = ports.begin(); i != ports.end(); i++)
|
||||
{
|
||||
//Checking netdevice:
|
||||
const WifiNetDevice * wifiNetDev = dynamic_cast<const WifiNetDevice *> (PeekPointer (*i));
|
||||
if(wifiNetDev == NULL)
|
||||
return false;
|
||||
MeshWifiMac * meshWifiMac = dynamic_cast<MeshWifiMac *> (PeekPointer (wifiNetDev->GetMac()));
|
||||
if(meshWifiMac == NULL)
|
||||
return false;
|
||||
//Adding HWMP-state
|
||||
Ptr<HwmpState> hwmpState = CreateObject<HwmpState> ();
|
||||
hwmpState->SetRoutingInfoCallback(MakeCallback(&Hwmp::ObtainRoutingInformation, this));
|
||||
hwmpState->SetMac(meshWifiMac);
|
||||
hwmpState->SetRequestRouteCallback(MakeCallback(&Hwmp::RequestRouteForAddress, this));
|
||||
hwmpState->SetRequestRootPathCallback(MakeCallback(&Hwmp::RequestRootPathForPort, this));
|
||||
hwmpState->SetAssociatedIfaceId(wifiNetDev->GetIfIndex());
|
||||
hwmpState->SetRetransmittersOfPerrCallback(MakeCallback(&Hwmp::GetRetransmittersForFailedDestinations,this));
|
||||
m_hwmpStates.push_back(hwmpState);
|
||||
m_requestCallback.push_back(MakeCallback(&HwmpState::RequestDestination, hwmpState));
|
||||
m_pathErrorCallback.push_back(MakeCallback(&HwmpState::SendPathError, hwmpState));
|
||||
//Default mode is reactive, default state is enabled
|
||||
enum DeviceState state = ENABLED;
|
||||
enum DeviceMode mode = REACTIVE;
|
||||
m_states.push_back(state);
|
||||
m_modes.push_back(mode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Hwmp::SetIfIndex(uint32_t interface)
|
||||
{
|
||||
m_interface = interface;
|
||||
}
|
||||
|
||||
void
|
||||
Hwmp::DisablePort(uint32_t port)
|
||||
{
|
||||
int position = 0;
|
||||
for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
|
||||
{
|
||||
if((*i)->GetAssociatedIfaceId() == port)
|
||||
{
|
||||
m_states[position] = DISABLED;
|
||||
m_hwmpStates[position]->Disable();
|
||||
return;
|
||||
}
|
||||
position ++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Hwmp::EnablePort(uint32_t port)
|
||||
{
|
||||
int position = 0;
|
||||
for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
|
||||
{
|
||||
if((*i)->GetAssociatedIfaceId() == port)
|
||||
{
|
||||
m_states[position] = ENABLED;
|
||||
m_hwmpStates[position]->Enable();
|
||||
return;
|
||||
}
|
||||
position ++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Hwmp::SetRoot(uint32_t port)
|
||||
{
|
||||
int position = 0;
|
||||
for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
|
||||
{
|
||||
if(((*i)->GetAssociatedIfaceId() == port)||(port == HwmpRtable::PORT_ANY))
|
||||
{
|
||||
if(m_hwmpStates[position]->SetRoot())
|
||||
{
|
||||
m_modes[position] = ROOT;
|
||||
NS_LOG_DEBUG("I am proactive");
|
||||
}
|
||||
}
|
||||
position ++;
|
||||
}
|
||||
}
|
||||
void
|
||||
Hwmp::SetProactive(uint32_t port)
|
||||
{
|
||||
int position = 0;
|
||||
for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
|
||||
{
|
||||
if((*i)->GetAssociatedIfaceId() == port)
|
||||
{
|
||||
m_modes[position] = PROACTIVE;
|
||||
return;
|
||||
}
|
||||
position ++;
|
||||
}
|
||||
}
|
||||
bool
|
||||
Hwmp::IsRoot(uint32_t port)
|
||||
{
|
||||
int position = 0;
|
||||
for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
|
||||
{
|
||||
if((*i)->GetAssociatedIfaceId() == port)
|
||||
if(m_modes[position] == ROOT)
|
||||
return true;
|
||||
position ++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void
|
||||
Hwmp::UnSetRoot(uint32_t port)
|
||||
{
|
||||
int position = 0;
|
||||
for(std::vector<Ptr<HwmpState> >::iterator i = m_hwmpStates.begin(); i!= m_hwmpStates.end(); i++)
|
||||
{
|
||||
if(((*i)->GetAssociatedIfaceId() == port)||(port == HwmpRtable::PORT_ANY))
|
||||
{
|
||||
m_modes[position] = REACTIVE;
|
||||
m_hwmpStates[position]->UnSetRoot();
|
||||
}
|
||||
position ++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Hwmp::ObtainRoutingInformation(
|
||||
HwmpState::INFO info
|
||||
)
|
||||
{
|
||||
switch(info.type)
|
||||
{
|
||||
case HwmpState::INFO_PREP:
|
||||
if(info.me != info.source)
|
||||
{
|
||||
m_rtable->AddPrecursor(info.source, info.outPort, info.nextHop);
|
||||
m_rtable->AddPrecursor(info.destination, info.outPort, info.prevHop);
|
||||
NS_LOG_DEBUG("path to "<<info.source<<" precursor is "<<info.nextHop);
|
||||
NS_LOG_DEBUG("path to "<<info.destination<<" precursor is "<<info.prevHop);
|
||||
}
|
||||
case HwmpState::INFO_PREQ:
|
||||
m_rtable->AddReactivePath(
|
||||
info.destination,
|
||||
info.nextHop,
|
||||
info.outPort,
|
||||
info.metric,
|
||||
info.lifetime,
|
||||
info.dsn);
|
||||
SendAllPossiblePackets(info.destination);
|
||||
break;
|
||||
case HwmpState::INFO_PERR:
|
||||
//delete first subentry
|
||||
case HwmpState::INFO_PROACTIVE:
|
||||
//add information to the root MP.
|
||||
m_rtable->AddProactivePath(
|
||||
info.metric,
|
||||
info.destination,
|
||||
info.nextHop,
|
||||
info.outPort,
|
||||
info.lifetime,
|
||||
info.dsn);
|
||||
//Set mode as PROACTIVE:
|
||||
SetProactive(info.outPort);
|
||||
break;
|
||||
case HwmpState::INFO_NEW_PEER:
|
||||
#if 0
|
||||
m_rtable->AddReactivePath(
|
||||
info.destination,
|
||||
info.nextHop,
|
||||
info.outPort,
|
||||
info.metric,
|
||||
Seconds(0),
|
||||
0);
|
||||
#endif
|
||||
break;
|
||||
case HwmpState::INFO_FAILED_PEER:
|
||||
/**
|
||||
* Conditions for generating PERR
|
||||
*/
|
||||
{
|
||||
NS_LOG_DEBUG("Failed peer"<<info.destination);
|
||||
std::vector<struct HwmpRtable::FailedDestination> failedDestinations =
|
||||
m_rtable->GetUnreachableDestinations(info.destination, info.outPort);
|
||||
/**
|
||||
* Entry about peer does not contain seqnum
|
||||
*/
|
||||
struct HwmpRtable::FailedDestination peer;
|
||||
peer.destination = info.destination;
|
||||
peer.seqnum = 0;
|
||||
failedDestinations.push_back(peer);
|
||||
StartPathErrorProcedure(failedDestinations, info.outPort);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
struct HwmpRtable::LookupResult
|
||||
Hwmp::RequestRouteForAddress(const Mac48Address& dst)
|
||||
{
|
||||
return m_rtable->LookupReactive(dst);
|
||||
}
|
||||
|
||||
struct HwmpRtable::LookupResult
|
||||
Hwmp::RequestRootPathForPort(uint32_t port)
|
||||
{
|
||||
return m_rtable->LookupProactive(port);
|
||||
}
|
||||
|
||||
void
|
||||
Hwmp::StartPathErrorProcedure(std::vector<struct HwmpRtable::FailedDestination> destinations, uint32_t port)
|
||||
{
|
||||
NS_LOG_DEBUG("START PERR");
|
||||
for(unsigned int i = 0; i < m_hwmpStates.size(); i++)
|
||||
if(m_hwmpStates[i]->GetAssociatedIfaceId() == port)
|
||||
m_pathErrorCallback[i](destinations);
|
||||
}
|
||||
std::vector<Mac48Address>
|
||||
Hwmp::GetRetransmittersForFailedDestinations(std::vector<struct HwmpRtable::FailedDestination> failedDest, uint32_t port)
|
||||
{
|
||||
std::vector<Mac48Address> retransmitters;
|
||||
if(m_broadcastPerr)
|
||||
retransmitters.push_back(Mac48Address::GetBroadcast());
|
||||
else
|
||||
for(unsigned int i = 0; i< failedDest.size(); i ++)
|
||||
{
|
||||
std::vector<Mac48Address> precursors =
|
||||
m_rtable->GetPrecursors(failedDest[i].destination, port);
|
||||
for(unsigned int j = 0; j < precursors.size(); j++)
|
||||
{
|
||||
for(unsigned int k = 0; k < retransmitters.size(); k ++)
|
||||
if(retransmitters[k] == precursors[j])
|
||||
break;
|
||||
retransmitters.push_back(precursors[j]);
|
||||
}
|
||||
}
|
||||
for(unsigned int i = 0; i < failedDest.size(); i ++)
|
||||
{
|
||||
m_rtable->DeleteReactivePath(failedDest[i].destination, port);
|
||||
m_rtable->DeleteProactivePath(failedDest[i].destination, port);
|
||||
}
|
||||
return retransmitters;
|
||||
}
|
||||
void
|
||||
Hwmp::SetMaxQueueSize(int maxPacketsPerDestination)
|
||||
{
|
||||
m_maxQueueSize = maxPacketsPerDestination;
|
||||
}
|
||||
|
||||
bool
|
||||
Hwmp::QueuePacket(struct L2RoutingProtocol::QueuedPacket packet)
|
||||
{
|
||||
if((int)m_rqueue[packet.dst].size() > m_maxQueueSize)
|
||||
return false;
|
||||
m_rqueue[packet.dst].push(packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct L2RoutingProtocol::QueuedPacket
|
||||
Hwmp::DequeuePacket(Mac48Address dst)
|
||||
{
|
||||
struct L2RoutingProtocol::QueuedPacket retval;
|
||||
retval.pkt = NULL;
|
||||
//Ptr<Packet> in this structure is NULL when queue is empty
|
||||
std::map<Mac48Address, std::queue<struct QueuedPacket>, addrcmp>:: iterator i = m_rqueue.find(dst);
|
||||
if(i == m_rqueue.end())
|
||||
return retval;
|
||||
if((int)m_rqueue[dst].size() == 0)
|
||||
return retval;
|
||||
if((int)i->second.size() == 0)
|
||||
{
|
||||
m_rqueue.erase(i);
|
||||
return retval;
|
||||
}
|
||||
retval = m_rqueue[dst].front();
|
||||
m_rqueue[dst].pop();
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
Hwmp::SendAllPossiblePackets(Mac48Address dst)
|
||||
{
|
||||
struct HwmpRtable::LookupResult result = m_rtable->LookupReactive(dst);
|
||||
struct L2RoutingProtocol::QueuedPacket packet;
|
||||
while(1)
|
||||
|
||||
{
|
||||
packet = DequeuePacket(dst);
|
||||
if(packet.pkt == NULL)
|
||||
return;
|
||||
//set RA tag for retransmitter:
|
||||
HwmpTag tag;
|
||||
NS_ASSERT(packet.pkt->FindFirstMatchingTag(tag));
|
||||
tag.SetAddress(result.retransmitter);
|
||||
NS_ASSERT(result.retransmitter!=Mac48Address::GetBroadcast());
|
||||
packet.pkt->RemoveAllTags();
|
||||
packet.pkt->AddTag(tag);
|
||||
packet.reply(true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Hwmp::ShouldSendPreq(Mac48Address dst)
|
||||
{
|
||||
std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.find(dst);
|
||||
if(i == m_timeoutDatabase.end())
|
||||
{
|
||||
m_timeoutDatabase[dst] = Simulator::Schedule(
|
||||
MilliSeconds(2*(dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
|
||||
&Hwmp::RetryPathDiscovery, this, dst, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void
|
||||
Hwmp::RetryPathDiscovery(Mac48Address dst, uint8_t numOfRetry)
|
||||
{
|
||||
struct HwmpRtable::LookupResult result = m_rtable->LookupReactive(dst);
|
||||
if(result.retransmitter != Mac48Address::GetBroadcast())
|
||||
{
|
||||
std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.find(dst);
|
||||
NS_ASSERT(i!= m_timeoutDatabase.end());
|
||||
m_timeoutDatabase.erase(i);
|
||||
return;
|
||||
}
|
||||
numOfRetry++;
|
||||
if(numOfRetry > dot11sParameters::dot11MeshHWMPmaxPREQretries)
|
||||
{
|
||||
struct L2RoutingProtocol::QueuedPacket packet;
|
||||
//purge queue and delete entry from retryDatabase
|
||||
while(1)
|
||||
{
|
||||
packet = DequeuePacket(dst);
|
||||
if(packet.pkt == NULL)
|
||||
break;
|
||||
packet.reply(false, packet.pkt, packet.src, packet.dst, packet.protocol, HwmpRtable::MAX_METRIC);
|
||||
}
|
||||
std::map<Mac48Address, EventId, addrcmp>::iterator i = m_timeoutDatabase.find(dst);
|
||||
NS_ASSERT(i!= m_timeoutDatabase.end());
|
||||
m_timeoutDatabase.erase(i);
|
||||
return;
|
||||
}
|
||||
for(unsigned int i = 0; i< m_requestCallback.size(); i++)
|
||||
if((m_modes[i] == REACTIVE) || (m_modes[i] == ROOT))
|
||||
m_requestCallback[i](dst);
|
||||
m_timeoutDatabase[dst] = Simulator::Schedule(
|
||||
MilliSeconds(2*(dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime.GetMilliSeconds())),
|
||||
&Hwmp::RetryPathDiscovery, this, dst, numOfRetry);
|
||||
}
|
||||
} //namespace ns3
|
||||
303
src/devices/l2-routing/l2-routing-hwmp/hwmp.h
Normal file
303
src/devices/l2-routing/l2-routing-hwmp/hwmp.h
Normal file
@@ -0,0 +1,303 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HWMP_H
|
||||
#define HWMP_H
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include "ns3/tag.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/l2-routing-protocol.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "hwmp-state.h"
|
||||
namespace ns3 {
|
||||
class HwmpState;
|
||||
/**
|
||||
* \brief Hwmp tag implements interaction between HWMP
|
||||
* protocol and MeshWifiMac
|
||||
* \details Hwmp tag keeps the following:
|
||||
* 1. When packet is passed from Hwmp to 11sMAC:
|
||||
* - retransmitter address,
|
||||
* - TTL value,
|
||||
* 2. When packet is passed to Hwmp from 11sMAC:
|
||||
* - lasthop address,
|
||||
* - TTL value,
|
||||
* - metric value (metric of link is recalculated
|
||||
* at each packet, but routing table stores metric
|
||||
* obtained during path discovery procedure)
|
||||
*/
|
||||
class HwmpTag : public Tag
|
||||
{
|
||||
public:
|
||||
HwmpTag();
|
||||
~HwmpTag();
|
||||
void SetAddress(Mac48Address retransmitter);
|
||||
Mac48Address GetAddress();
|
||||
void SetTtl(uint8_t ttl);
|
||||
uint8_t GetTtl();
|
||||
void SetMetric(uint32_t metric);
|
||||
uint32_t GetMetric();
|
||||
void SetSeqno(uint32_t seqno);
|
||||
uint32_t GetSeqno();
|
||||
void DecrementTtl();
|
||||
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (TagBuffer i) const;
|
||||
virtual void Deserialize (TagBuffer i);
|
||||
virtual void Print (std::ostream &os) const;
|
||||
private:
|
||||
Mac48Address m_address;
|
||||
uint8_t m_ttl;
|
||||
uint32_t m_metric;
|
||||
uint32_t m_seqno;
|
||||
};
|
||||
class Hwmp : public L2RoutingProtocol
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId();
|
||||
Hwmp();
|
||||
~Hwmp();
|
||||
void DoDispose();
|
||||
//intheritedfrom L2RoutingProtocol
|
||||
/**
|
||||
* \brief L2Routing protocol base class metod
|
||||
*
|
||||
* \details Route resolving procedure consits
|
||||
* of the following steps:
|
||||
* 1. Find reactive route and send a packet.
|
||||
* 2. Find all ports which are operate in
|
||||
* 'Proactive' mode and find a proper default
|
||||
* routes. and send packet to all proactive
|
||||
* 'ports'.
|
||||
* 3. If there are ports which are operate in
|
||||
* reactive mode - queue packet and start
|
||||
* route reactive path discovery
|
||||
*
|
||||
* \bug Now packet is sent to the 'best root'
|
||||
* rather than to the best root at each port
|
||||
*/
|
||||
bool RequestRoute(
|
||||
uint32_t sourceIface,
|
||||
const Mac48Address source,
|
||||
const Mac48Address destination,
|
||||
Ptr<Packet> packet,
|
||||
uint16_t protocolType,
|
||||
L2RoutingProtocol::RouteReplyCallback
|
||||
routeReply
|
||||
);
|
||||
bool AttachPorts(std::vector<Ptr<NetDevice> >);
|
||||
void SetIfIndex(uint32_t interface);
|
||||
/**
|
||||
* \brief Disables port by index.
|
||||
* \details Needed for external modules like
|
||||
* clusterization.
|
||||
*/
|
||||
void DisablePort(uint32_t port);
|
||||
/**
|
||||
* \brief enables port
|
||||
*/
|
||||
void EnablePort(uint32_t port);
|
||||
/**
|
||||
* \brief Setting proative mode.
|
||||
* \details To enable proactive mode you must
|
||||
* set a root node. Choosing the route is made
|
||||
* in accordance with the following:
|
||||
* 1. Find 'reactive' route. If route is
|
||||
* found - send a packet using this
|
||||
* information
|
||||
* 2. If there is no reactive route -
|
||||
* find proactive or 'default' route.
|
||||
* \attention Comparsion between proactive and
|
||||
* reactive routes is incorrect, because we
|
||||
* have metric to root MP in te first case and
|
||||
* metric to the destination in the second
|
||||
* case.
|
||||
* \param port is the port where proactive
|
||||
* mode should be activated
|
||||
*/
|
||||
void SetRoot(uint32_t port);
|
||||
/**
|
||||
* \brief Disable root functionality at a
|
||||
* given port
|
||||
*/
|
||||
void UnSetRoot(uint32_t port);
|
||||
/**
|
||||
* \brief HwmpState retrns to Hwmp class all
|
||||
* routing information obtained from all HWMP
|
||||
* action frames
|
||||
*/
|
||||
void ObtainRoutingInformation(
|
||||
HwmpState::INFO info
|
||||
);
|
||||
/**
|
||||
* \brief Hwmp state noyifyes that neighbour
|
||||
* is dissapeared. Hwmp state knows about peer
|
||||
* failure from MAC
|
||||
*/
|
||||
void PeerFailure(Mac48Address peerAddress);
|
||||
void SetMaxTtl(uint8_t ttl);
|
||||
uint8_t
|
||||
GetMaxTtl();
|
||||
private:
|
||||
static const uint32_t MAX_SEQNO = 0xffffffff;
|
||||
//candidate queue is implemented inside the
|
||||
//protocol:
|
||||
void SetMaxQueueSize(int maxPacketsPerDestination);
|
||||
int m_maxQueueSize;
|
||||
bool QueuePacket(struct L2RoutingProtocol::QueuedPacket packet);
|
||||
struct L2RoutingProtocol::QueuedPacket
|
||||
DequeuePacket(Mac48Address dst);
|
||||
void SendAllPossiblePackets(Mac48Address dst);
|
||||
struct addrcmp
|
||||
{
|
||||
bool operator()(const Mac48Address addr1, Mac48Address addr2) const
|
||||
{
|
||||
uint8_t s1[6], s2[6];
|
||||
addr1.CopyTo(s1);
|
||||
addr2.CopyTo(s2);
|
||||
for(int i = 0; i < 6; i ++)
|
||||
if(s1[i] > s2[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
std::map<Mac48Address, std::queue<struct QueuedPacket> >
|
||||
m_rqueue;
|
||||
//devices and HWMP states:
|
||||
enum DeviceState {
|
||||
ENABLED,
|
||||
DISABLED
|
||||
};
|
||||
enum DeviceMode {
|
||||
REACTIVE,
|
||||
PROACTIVE,
|
||||
ROOT
|
||||
};
|
||||
std::vector<enum DeviceState>
|
||||
m_states;
|
||||
std::vector<enum DeviceMode>
|
||||
m_modes;
|
||||
std::vector<Ptr<HwmpState> >
|
||||
m_hwmpStates;
|
||||
//Routing table:
|
||||
Ptr<HwmpRtable>
|
||||
m_rtable;
|
||||
//Proactive routines:
|
||||
/**
|
||||
* \brief Set port state as proactive.
|
||||
* \details mode is supposed to be proactive
|
||||
* when proatcive PREQ with a valid
|
||||
* information was received.
|
||||
*/
|
||||
void SetProactive(uint32_t port);
|
||||
/**
|
||||
* \brief Checks if the port is root, if true
|
||||
* - no default routes must be used at this
|
||||
* port
|
||||
*/
|
||||
bool IsRoot(uint32_t port);
|
||||
/**
|
||||
* \brief Interaction with HwmpState class -
|
||||
* request for starting routing discover
|
||||
* procedure (reactive route discovery!)
|
||||
* \param Mac48Address is destination to be
|
||||
* resolved
|
||||
*/
|
||||
std::vector< Callback<void, Mac48Address> >
|
||||
m_requestCallback;
|
||||
/**
|
||||
* \brief Callback that shall be executed when
|
||||
* need to send Path error
|
||||
* \param std::vector<Mac48Address> is the
|
||||
* list of unreachable destinations
|
||||
* \param std::vector<Mac48Address> is
|
||||
* receivers of PERR
|
||||
*/
|
||||
std::vector<Callback<void,std::vector<struct HwmpRtable::FailedDestination> > >
|
||||
m_pathErrorCallback;
|
||||
void StartPathErrorProcedure(
|
||||
std::vector<struct HwmpRtable::FailedDestination> destinations,
|
||||
uint32_t port);
|
||||
/**
|
||||
* \brief HwmpState need to know where to
|
||||
* retransmit PERR, only HWMP knows how to
|
||||
* retransmit it (broadcast/unicast) and only
|
||||
* HWMP has accessto routing table
|
||||
*/
|
||||
std::vector<Mac48Address>
|
||||
GetRetransmittersForFailedDestinations(
|
||||
std::vector<struct HwmpRtable::FailedDestination> failedDest,
|
||||
uint32_t port);
|
||||
/**
|
||||
* \brief Needed by HwmpState to find routes in case
|
||||
* of intermediate reply and choosing the
|
||||
* better route
|
||||
*
|
||||
*/
|
||||
struct HwmpRtable::LookupResult
|
||||
RequestRouteForAddress(const Mac48Address& destination);
|
||||
struct HwmpRtable::LookupResult
|
||||
RequestRootPathForPort(uint32_t port);
|
||||
|
||||
/**
|
||||
* \brief interface which is the HWMP attached to
|
||||
* (Virtual netdevice)
|
||||
*/
|
||||
uint32_t m_interface;
|
||||
/**
|
||||
* \attention mesh seqno is processed at HWMP
|
||||
*/
|
||||
uint32_t m_seqno;
|
||||
std::map<Mac48Address, uint32_t, addrcmp>
|
||||
m_seqnoDatabase;
|
||||
//Timers:
|
||||
/**
|
||||
* /brief checks when last preq was initiated, returns
|
||||
* false when retry has not expired
|
||||
*/
|
||||
bool ShouldSendPreq(Mac48Address dst);
|
||||
/**
|
||||
* \brief Generates PREQ retry when route is
|
||||
* still unresolved after first PREQ
|
||||
* If number of retries greater than
|
||||
* dot11sParameters::dot11MeshHWMPmaxPREQretries,
|
||||
* we return all packets to upper layers
|
||||
*/
|
||||
void RetryPathDiscovery(Mac48Address dst, uint8_t numOfRetry);
|
||||
/**
|
||||
* Keeps PREQ retry timers for every
|
||||
* destination
|
||||
*/
|
||||
std::map<Mac48Address, EventId, addrcmp>
|
||||
m_timeoutDatabase;
|
||||
/**
|
||||
* Configurable parameters:
|
||||
*/
|
||||
uint8_t m_maxTtl;
|
||||
bool m_broadcastPerr;
|
||||
};
|
||||
} //namespace ns3
|
||||
#endif
|
||||
1
src/devices/l2-routing/l2-routing-hwmp/waf
vendored
Normal file
1
src/devices/l2-routing/l2-routing-hwmp/waf
vendored
Normal file
@@ -0,0 +1 @@
|
||||
exec "`dirname "$0"`"/../../../../waf "$@"
|
||||
16
src/devices/l2-routing/l2-routing-hwmp/wscript
Normal file
16
src/devices/l2-routing/l2-routing-hwmp/wscript
Normal file
@@ -0,0 +1,16 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
obj = bld.create_ns3_module('l2-routing-hwmp', ['node', 'l2-routing-main'])
|
||||
obj.source = [
|
||||
'hwmp-rtable.cc',
|
||||
'hwmp-state.cc',
|
||||
'hwmp.cc',
|
||||
]
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers.module = 'l2-routing-hwmp'
|
||||
headers.source = [
|
||||
'hwmp-rtable.h',
|
||||
'hwmp-state.h',
|
||||
'hwmp.h',
|
||||
]
|
||||
355
src/devices/l2-routing/l2-routing-main/l2-routing-net-device.cc
Normal file
355
src/devices/l2-routing/l2-routing-main/l2-routing-net-device.cc
Normal file
@@ -0,0 +1,355 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/channel.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/l2-routing-net-device.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("L2RoutingNetDevice");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (L2RoutingNetDevice);
|
||||
|
||||
|
||||
TypeId
|
||||
L2RoutingNetDevice::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::L2RoutingNetDevice")
|
||||
.SetParent<NetDevice> ()
|
||||
.AddConstructor<L2RoutingNetDevice> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
|
||||
L2RoutingNetDevice::L2RoutingNetDevice ()
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
m_channel = CreateObject<BridgeChannel> ();
|
||||
}
|
||||
|
||||
L2RoutingNetDevice::~L2RoutingNetDevice()
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
}
|
||||
|
||||
void
|
||||
L2RoutingNetDevice::DoDispose ()
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++)
|
||||
*iter = 0;
|
||||
m_ports.clear ();
|
||||
m_node = 0;
|
||||
NetDevice::DoDispose ();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
L2RoutingNetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol,
|
||||
Address const &src, Address const &dst, PacketType packetType)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
NS_LOG_DEBUG ("UID is " << packet->GetUid ());
|
||||
const Mac48Address src48 = Mac48Address::ConvertFrom (src);
|
||||
const Mac48Address dst48 = Mac48Address::ConvertFrom (dst);
|
||||
if (!m_promiscRxCallback.IsNull ())
|
||||
m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
|
||||
switch (packetType)
|
||||
{
|
||||
case PACKET_HOST:
|
||||
if (dst48 == m_address)
|
||||
m_rxCallback (this, packet, protocol, src);
|
||||
break;
|
||||
case PACKET_BROADCAST:
|
||||
case PACKET_MULTICAST:
|
||||
m_rxCallback (this, packet, protocol, src);
|
||||
case PACKET_OTHERHOST:
|
||||
Forward (incomingPort, packet->Copy(), protocol, src48, dst48);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
L2RoutingNetDevice::Forward (Ptr<NetDevice> inport, Ptr<Packet> packet,
|
||||
uint16_t protocol, const Mac48Address src, const Mac48Address dst)
|
||||
{
|
||||
//pass through routing protocol
|
||||
m_requestRoute(inport->GetIfIndex(), src, dst, packet, protocol, m_myResponse);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
L2RoutingNetDevice::GetNPorts (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return m_ports.size ();
|
||||
}
|
||||
|
||||
Ptr<NetDevice>
|
||||
L2RoutingNetDevice::GetPort (uint32_t n) const
|
||||
{
|
||||
NS_ASSERT(m_ports.size () > n);
|
||||
return m_ports[n];
|
||||
}
|
||||
|
||||
void
|
||||
L2RoutingNetDevice::AddPort (Ptr<NetDevice> routingPort)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
NS_ASSERT (routingPort != this);
|
||||
if (!Mac48Address::IsMatchingType (routingPort->GetAddress ()))
|
||||
NS_FATAL_ERROR ("Device does not support eui 48 addresses: cannot be added to bridge.");
|
||||
if (!routingPort->SupportsSendFrom ())
|
||||
NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to bridge.");
|
||||
m_address = Mac48Address::ConvertFrom (routingPort->GetAddress ());
|
||||
NS_LOG_DEBUG ("RegisterProtocolHandler for " << routingPort->GetName ());
|
||||
m_node->RegisterProtocolHandler (MakeCallback (&L2RoutingNetDevice::ReceiveFromDevice, this),
|
||||
0, routingPort, true);
|
||||
m_ports.push_back (routingPort);
|
||||
m_channel->AddChannel (routingPort->GetChannel ());
|
||||
}
|
||||
|
||||
void
|
||||
L2RoutingNetDevice::SetName(const std::string name)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
std::string
|
||||
L2RoutingNetDevice::GetName(void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void
|
||||
L2RoutingNetDevice::SetIfIndex(const uint32_t index)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
m_ifIndex = index;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
L2RoutingNetDevice::GetIfIndex(void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return m_ifIndex;
|
||||
}
|
||||
|
||||
Ptr<Channel>
|
||||
L2RoutingNetDevice::GetChannel (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return m_channel;
|
||||
}
|
||||
|
||||
Address
|
||||
L2RoutingNetDevice::GetAddress (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return m_address;
|
||||
}
|
||||
|
||||
bool
|
||||
L2RoutingNetDevice::SetMtu (const uint16_t mtu)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
m_mtu = mtu;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
L2RoutingNetDevice::GetMtu (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return 1500;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
L2RoutingNetDevice::IsLinkUp (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
L2RoutingNetDevice::SetLinkChangeCallback (Callback<void> callback)
|
||||
{}
|
||||
|
||||
bool
|
||||
L2RoutingNetDevice::IsBroadcast (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Address
|
||||
L2RoutingNetDevice::GetBroadcast (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return Mac48Address ("ff:ff:ff:ff:ff:ff");
|
||||
}
|
||||
|
||||
bool
|
||||
L2RoutingNetDevice::IsMulticast (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return true;
|
||||
}
|
||||
|
||||
Address
|
||||
L2RoutingNetDevice::GetMulticast (Ipv4Address multicastGroup) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << multicastGroup);
|
||||
Mac48Address multicast = Mac48Address::GetMulticast (multicastGroup);
|
||||
return multicast;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
L2RoutingNetDevice::IsPointToPoint (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
L2RoutingNetDevice::IsBridge (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
L2RoutingNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
|
||||
{
|
||||
|
||||
const Mac48Address dst48 = Mac48Address::ConvertFrom (dest);
|
||||
return m_requestRoute(m_ifIndex, m_address, dst48, packet, protocolNumber, m_myResponse);
|
||||
}
|
||||
|
||||
bool
|
||||
L2RoutingNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
|
||||
{
|
||||
const Mac48Address src48 = Mac48Address::ConvertFrom (src);
|
||||
const Mac48Address dst48 = Mac48Address::ConvertFrom (dest);
|
||||
return m_requestRoute(m_ifIndex, src48, dst48, packet, protocolNumber, m_myResponse);
|
||||
}
|
||||
|
||||
|
||||
Ptr<Node>
|
||||
L2RoutingNetDevice::GetNode (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return m_node;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
L2RoutingNetDevice::SetNode (Ptr<Node> node)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
m_node = node;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
L2RoutingNetDevice::NeedsArp (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
L2RoutingNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
m_rxCallback = cb;
|
||||
}
|
||||
|
||||
void
|
||||
L2RoutingNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
m_promiscRxCallback = cb;
|
||||
}
|
||||
|
||||
bool
|
||||
L2RoutingNetDevice::SupportsSendFrom () const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return true;
|
||||
}
|
||||
|
||||
Address
|
||||
L2RoutingNetDevice::GetMulticast (Ipv6Address addr) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << addr);
|
||||
return Mac48Address::GetMulticast (addr);
|
||||
}
|
||||
//L2RouitingSpecific methods:
|
||||
|
||||
bool
|
||||
L2RoutingNetDevice::AttachProtocol(Ptr<L2RoutingProtocol> protocol)
|
||||
{
|
||||
m_requestRoute = MakeCallback(&L2RoutingProtocol::RequestRoute, protocol);
|
||||
m_myResponse = MakeCallback(&L2RoutingNetDevice::ProtocolResponse, this);
|
||||
protocol->SetIfIndex(m_ifIndex);
|
||||
return protocol->AttachPorts(m_ports);
|
||||
}
|
||||
|
||||
void
|
||||
L2RoutingNetDevice::ProtocolResponse(
|
||||
bool success,
|
||||
Ptr<Packet> packet,
|
||||
Mac48Address src,
|
||||
Mac48Address dst,
|
||||
uint16_t protocol,
|
||||
uint32_t outPort
|
||||
)
|
||||
{
|
||||
if(!success)
|
||||
{
|
||||
NS_LOG_UNCOND("Resolve failed");
|
||||
//TODO: SendError callback
|
||||
return;
|
||||
}
|
||||
//just do sendFrom!
|
||||
if(outPort!=0xffffffff)
|
||||
GetPort(outPort)->SendFrom(packet, src, dst, protocol);
|
||||
else
|
||||
for(std::vector<Ptr<NetDevice> >::iterator i = m_ports.begin(); i!= m_ports.end(); i++)
|
||||
(*i) -> SendFrom(packet, src, dst, protocol);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
167
src/devices/l2-routing/l2-routing-main/l2-routing-net-device.h
Normal file
167
src/devices/l2-routing/l2-routing-main/l2-routing-net-device.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef L2ROUTING_NET_DEVICE_H
|
||||
#define L2ROUTING_NET_DEVICE_H
|
||||
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/bridge-net-device.h"
|
||||
#include "ns3/bridge-channel.h"
|
||||
#include "ns3/l2-routing-protocol.h"
|
||||
|
||||
namespace ns3 {
|
||||
class Node;
|
||||
/**
|
||||
* \ingroup devices
|
||||
* \defgroup L2RoutingNetDevice L2routingNetDevice
|
||||
*/
|
||||
/**
|
||||
* \ingroup L2RoutingNetDevice
|
||||
* \brief a virtual net device that may forward packets
|
||||
* between real network devices using routing protocols of
|
||||
* MAC-layer
|
||||
* \details This is a virtual netdevice, which aggreagates
|
||||
* real netdevices and uses interface of L2RoutingProtocol to
|
||||
* forward packets
|
||||
* \attention The idea of L2RoutingNetDevice is similar to
|
||||
* BridgeNetDevice, but the packets, which going through
|
||||
* L2RoutingNetDevice may be changed (because routing protocol
|
||||
* may require its own headers or tags).
|
||||
*/
|
||||
class L2RoutingNetDevice : public NetDevice
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
L2RoutingNetDevice ();
|
||||
virtual ~L2RoutingNetDevice ();
|
||||
/**
|
||||
* \brief Attaches a 'port' to a virtual
|
||||
* L2RoutingNetDevice, and this port is handled
|
||||
* by L2RoutingProtocol.
|
||||
* \attention Like in a bridge,
|
||||
* L2RoutingNetDevice's ports must not have IP
|
||||
* addresses, and only L2RoutingNetDevice
|
||||
* itself may have an IP address.
|
||||
*
|
||||
* \attention L2RoutingNetDevice may be a port
|
||||
* of BridgeNetDevice.
|
||||
*/
|
||||
void AddPort (Ptr<NetDevice> port);
|
||||
/**
|
||||
* \returns number of ports attached to
|
||||
* L2RoutingNetDevice
|
||||
*/
|
||||
uint32_t GetNPorts (void) const;
|
||||
/**
|
||||
* \returns a pointer to netdevice
|
||||
* \param n is device ID to be returned
|
||||
*/
|
||||
Ptr<NetDevice> GetPort (uint32_t n) const;
|
||||
//inherited from netdevice:
|
||||
virtual void SetName(const std::string name);
|
||||
virtual std::string GetName(void) const;
|
||||
virtual void SetIfIndex(const uint32_t index);
|
||||
virtual uint32_t GetIfIndex(void) const;
|
||||
virtual Ptr<Channel> GetChannel (void) const;
|
||||
virtual Address GetAddress (void) const;
|
||||
virtual bool SetMtu (const uint16_t mtu);
|
||||
virtual uint16_t GetMtu (void) const;
|
||||
virtual bool IsLinkUp (void) const;
|
||||
virtual void SetLinkChangeCallback (Callback<void> callback);
|
||||
virtual bool IsBroadcast (void) const;
|
||||
virtual Address GetBroadcast (void) const;
|
||||
virtual bool IsMulticast (void) const;
|
||||
virtual Address GetMulticast (Ipv4Address multicastGroup) const;
|
||||
virtual bool IsPointToPoint (void) const;
|
||||
virtual bool IsBridge (void) const;
|
||||
virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
|
||||
virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
|
||||
virtual Ptr<Node> GetNode (void) const;
|
||||
virtual void SetNode (Ptr<Node> node);
|
||||
virtual bool NeedsArp (void) const;
|
||||
virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
|
||||
virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
|
||||
virtual bool SupportsSendFrom () const;
|
||||
virtual Address GetMulticast (Ipv6Address addr) const;
|
||||
virtual void DoDispose (void);
|
||||
/**
|
||||
* \brief Attaches protocol to a given virtual
|
||||
* device
|
||||
* \returns true if success
|
||||
*/
|
||||
virtual bool AttachProtocol(Ptr<L2RoutingProtocol> protocol);
|
||||
protected:
|
||||
/**
|
||||
* \brief This is similar to BridgeNetDevice
|
||||
* method
|
||||
*/
|
||||
void ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
|
||||
Address const &source, Address const &destination, PacketType packetType);
|
||||
/**
|
||||
* \brief This is similar to BridgeNetDevice
|
||||
* method
|
||||
*/
|
||||
void Forward (Ptr<NetDevice> incomingPort, Ptr<Packet> packet,
|
||||
uint16_t protocol, const Mac48Address src, const Mac48Address dst);
|
||||
/**
|
||||
* \brief This is a function, which should be
|
||||
* passed to L2RoutingProtocol as response
|
||||
* callback (see L2RoutingProtocol).
|
||||
*/
|
||||
virtual void ProtocolResponse(
|
||||
bool success,
|
||||
Ptr<Packet>,
|
||||
Mac48Address src,
|
||||
Mac48Address dst,
|
||||
uint16_t protocol,
|
||||
uint32_t outPort
|
||||
);
|
||||
private:
|
||||
NetDevice::ReceiveCallback
|
||||
m_rxCallback;
|
||||
NetDevice::PromiscReceiveCallback
|
||||
m_promiscRxCallback;
|
||||
Mac48Address m_address;
|
||||
Ptr<Node> m_node;
|
||||
std::string m_name;
|
||||
std::vector< Ptr<NetDevice> >
|
||||
m_ports;
|
||||
uint32_t m_ifIndex;
|
||||
uint16_t m_mtu;
|
||||
Ptr<BridgeChannel>
|
||||
m_channel;
|
||||
Callback<
|
||||
bool,
|
||||
uint32_t,
|
||||
Mac48Address,
|
||||
Mac48Address,
|
||||
Ptr<Packet>,
|
||||
uint16_t,
|
||||
L2RoutingProtocol::RouteReplyCallback>
|
||||
m_requestRoute;
|
||||
//What we give to L2Routing
|
||||
L2RoutingProtocol::RouteReplyCallback
|
||||
m_myResponse;
|
||||
};
|
||||
} //namespace ns3
|
||||
#endif
|
||||
1
src/devices/l2-routing/l2-routing-main/waf
vendored
Normal file
1
src/devices/l2-routing/l2-routing-main/waf
vendored
Normal file
@@ -0,0 +1 @@
|
||||
exec "`dirname "$0"`"/../../../../waf "$@"
|
||||
12
src/devices/l2-routing/l2-routing-main/wscript
Normal file
12
src/devices/l2-routing/l2-routing-main/wscript
Normal file
@@ -0,0 +1,12 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
obj = bld.create_ns3_module('l2-routing-main', ['node', 'bridge'])
|
||||
obj.source = [
|
||||
'l2-routing-net-device.cc',
|
||||
]
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers.module = 'l2-routing-main'
|
||||
headers.source = [
|
||||
'l2-routing-net-device.h',
|
||||
]
|
||||
@@ -161,6 +161,7 @@ private:
|
||||
bool m_accessOngoing;
|
||||
Ptr<const Packet> m_currentPacket;
|
||||
WifiMacHeader m_currentHdr;
|
||||
uint8_t m_currentRetry;
|
||||
uint8_t m_fragmentNumber;
|
||||
};
|
||||
|
||||
|
||||
89
src/devices/wifi/dot11s-codes.h
Normal file
89
src/devices/wifi/dot11s-codes.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
* Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DOT11S_CODES_H
|
||||
#define DOT11S_CODES_H
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
enum dot11sElementID {
|
||||
MESH_CONFIGURATION = 18,
|
||||
MESH_ID,
|
||||
LINK_METRIC_REPORT,
|
||||
CONGESTION_NOTIFICATION,
|
||||
PEER_LINK_MANAGEMENT,
|
||||
MESH_CHANNEL_SWITCH_ANNOUNCEMENT,
|
||||
MESH_TIM,
|
||||
AWAKE_WINDOW,
|
||||
SYNCHRONIZATION_PROTOCOL,
|
||||
BEACON_TIMING,
|
||||
MDAOP_SETUP_REQUEST,
|
||||
MDAOP_SETUP_REPLY,
|
||||
MDAOP_ADVERTISEMENT,
|
||||
MDAOP_SET_TEARDOWN,
|
||||
CONNECTIVITY_REPORT,
|
||||
PORTAL_ANNOUNCEMENT,
|
||||
ROOT_ANNOUCEMENT,
|
||||
PATH_REQUEST,
|
||||
PATH_REPLY,
|
||||
PATH_ERROR,
|
||||
PROXY_UPDATE,
|
||||
PROXY_UPDATE_CONFIRMATION,
|
||||
MSCIE,
|
||||
MSAIE,
|
||||
};
|
||||
|
||||
enum dot11sReasonCode {
|
||||
PEER_LINK_CANCELLED,
|
||||
MESH_MAX_PEERS,
|
||||
MESH_CAPABILITY_POLICY_VIOLATION,
|
||||
MESH_CLOSE_RCVD,
|
||||
MESH_MAX_RETRIES,
|
||||
MESH_CONFIRM_TIMEOUT,
|
||||
MESH_SECURITY_ROLE_NEGOTIATION_DIFFERS,
|
||||
MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE,
|
||||
MESH_SECURITY_FAILED_VERIFICATION,
|
||||
MESH_INVALID_GTK,
|
||||
MESH_MISMATCH_GTK,
|
||||
MESH_INCONSISTENT_PARAMETERS,
|
||||
MESH_CONFIGURATION_POLICY_VIOLATION,
|
||||
DOT11S_REASON_RESERVED,
|
||||
};
|
||||
|
||||
enum dot11sStatusCode {
|
||||
PEAR_LINK_ESTABLISHED,
|
||||
PEAR_LINK_CLOSED,
|
||||
NO_LISTED_KEY_HOLDER,
|
||||
MESH_KEY_HANDSHAKE_MALFORMED,
|
||||
PEAR_LINK_MAX_RETRIES,
|
||||
PEAR_LINK_NO_PMK,
|
||||
PEAR_LINK_ALT_PMK,
|
||||
PEAR_LINK_NO_AKM,
|
||||
PEAR_LINK_ALT_AKM,
|
||||
PEAR_LINK_NO_KDF,
|
||||
PEAR_LINK_SA_ESTABLISHED,
|
||||
AUTHENTICATION_REJECTED_CLOGGING,
|
||||
DOT11S_STATUS_RESERVED,
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
43
src/devices/wifi/dot11s-parameters.cc
Normal file
43
src/devices/wifi/dot11s-parameters.cc
Normal file
@@ -0,0 +1,43 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
* Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "ns3/dot11s-parameters.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
uint8_t dot11sParameters::dot11MeshMaxRetries = 4;
|
||||
Time dot11sParameters::dot11MeshRetryTimeout = TU_TO_TIME(40);
|
||||
Time dot11sParameters::dot11MeshHoldingTimeout = TU_TO_TIME(40);
|
||||
Time dot11sParameters::dot11MeshConfirmTimeout = TU_TO_TIME(40);
|
||||
|
||||
|
||||
uint8_t dot11sParameters::dot11MeshHWMPmaxPREQretries = 3;
|
||||
Time dot11sParameters::dot11MeshHWMPnetDiameterTraversalTime = TU_TO_TIME(10);
|
||||
Time dot11sParameters::dot11MeshHWMPpreqMinInterval = TU_TO_TIME(100);
|
||||
Time dot11sParameters::dot11MeshHWMPperrMinInterval = TU_TO_TIME(100);
|
||||
Time dot11sParameters::dot11MeshHWMPactiveRootTimeout = TU_TO_TIME(5000);
|
||||
Time dot11sParameters::dot11MeshHWMPactivePathTimeout = TU_TO_TIME(5000);
|
||||
Time dot11sParameters::dot11MeshHWMPpathToRootInterval = TU_TO_TIME(5000);
|
||||
Time dot11sParameters::dot11MeshHWMPrannInterval = TU_TO_TIME(1000);
|
||||
|
||||
}
|
||||
53
src/devices/wifi/dot11s-parameters.h
Normal file
53
src/devices/wifi/dot11s-parameters.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
* Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DOT11S_PARAMETERS_H
|
||||
#define DOT11S_PARAMETERS_H
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/nstime.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
#define TU_TO_TIME(x) MicroSeconds(x*1024)
|
||||
#define TIME_TO_TU(x) x.GetMicroSeconds()/1024
|
||||
|
||||
struct dot11sParameters
|
||||
{
|
||||
/** Peer Link */
|
||||
static uint8_t dot11MeshMaxRetries;
|
||||
static Time dot11MeshRetryTimeout;
|
||||
static Time dot11MeshHoldingTimeout;
|
||||
static Time dot11MeshConfirmTimeout;
|
||||
/** HWMP */
|
||||
static uint8_t dot11MeshHWMPmaxPREQretries;
|
||||
static Time dot11MeshHWMPnetDiameterTraversalTime;
|
||||
static Time dot11MeshHWMPpreqMinInterval;
|
||||
static Time dot11MeshHWMPperrMinInterval;
|
||||
static Time dot11MeshHWMPactiveRootTimeout;
|
||||
static Time dot11MeshHWMPactivePathTimeout;
|
||||
static Time dot11MeshHWMPpathToRootInterval;
|
||||
static Time dot11MeshHWMPrannInterval;
|
||||
};
|
||||
|
||||
};
|
||||
#endif
|
||||
134
src/devices/wifi/dot11s-peer-management-element.cc
Normal file
134
src/devices/wifi/dot11s-peer-management-element.cc
Normal file
@@ -0,0 +1,134 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "dot11s-peer-management-element.h"
|
||||
#include "ns3/assert.h"
|
||||
|
||||
|
||||
//NS_LOG_COMPONENT_DEFINE ("MeshPeerLinkManagementelement");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
PeerLinkManagementElement::PeerLinkManagementElement ():
|
||||
m_length(0),
|
||||
m_subtype(PEER_OPEN),
|
||||
m_localLinkId(0),
|
||||
m_peerLinkId(0),
|
||||
m_reasonCode(DOT11S_REASON_RESERVED)
|
||||
{}
|
||||
|
||||
|
||||
void
|
||||
PeerLinkManagementElement::SetPeerOpen(uint16_t localLinkId)
|
||||
{
|
||||
m_length = 3;
|
||||
m_subtype=PEER_OPEN;
|
||||
m_localLinkId = localLinkId;
|
||||
}
|
||||
void
|
||||
PeerLinkManagementElement::SetPeerClose(uint16_t localLinkId, uint16_t peerLinkId, dot11sReasonCode reasonCode)
|
||||
{
|
||||
m_length = 7;
|
||||
m_subtype=PEER_CLOSE;
|
||||
m_localLinkId = localLinkId;
|
||||
m_peerLinkId = peerLinkId;
|
||||
m_reasonCode = reasonCode;
|
||||
}
|
||||
|
||||
void
|
||||
PeerLinkManagementElement::SetPeerConfirm(uint16_t localLinkId, uint16_t peerLinkId)
|
||||
{
|
||||
m_length = 5;
|
||||
m_subtype=PEER_CONFIRM;
|
||||
m_localLinkId = localLinkId;
|
||||
m_peerLinkId = peerLinkId;
|
||||
}
|
||||
|
||||
dot11sReasonCode
|
||||
PeerLinkManagementElement::GetReasonCode() const
|
||||
{
|
||||
return m_reasonCode;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
PeerLinkManagementElement::GetLocalLinkId() const
|
||||
{
|
||||
return m_localLinkId;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
PeerLinkManagementElement::GetPeerLinkId() const
|
||||
{
|
||||
return m_peerLinkId;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PeerLinkManagementElement::GetSerializedSize (void) const
|
||||
{
|
||||
return m_length+2;
|
||||
}
|
||||
|
||||
bool
|
||||
PeerLinkManagementElement::SubtypeIsOpen() const
|
||||
{
|
||||
return (m_subtype == PEER_OPEN);
|
||||
}
|
||||
bool
|
||||
PeerLinkManagementElement::SubtypeIsClose() const
|
||||
{
|
||||
return (m_subtype == PEER_CLOSE);
|
||||
}
|
||||
bool
|
||||
PeerLinkManagementElement::SubtypeIsConfirm() const
|
||||
{
|
||||
return (m_subtype == PEER_CONFIRM);
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
PeerLinkManagementElement::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteU8(PEER_LINK_MANAGEMENT);
|
||||
i.WriteU8(m_length);
|
||||
i.WriteU8(m_subtype);
|
||||
i.WriteHtonU16(m_localLinkId);
|
||||
if(m_length > 3)
|
||||
i.WriteHtonU16(m_peerLinkId);
|
||||
if(m_length > 5)
|
||||
i.WriteHtonU16(m_reasonCode);
|
||||
return i;
|
||||
}
|
||||
Buffer::Iterator
|
||||
PeerLinkManagementElement::Deserialize (Buffer::Iterator i)
|
||||
{
|
||||
dot11sElementID ElementId;
|
||||
ElementId = (dot11sElementID)i.ReadU8();
|
||||
NS_ASSERT(ElementId == PEER_LINK_MANAGEMENT);
|
||||
m_length = i.ReadU8();
|
||||
m_subtype = i.ReadU8();
|
||||
m_localLinkId = i.ReadNtohU16();
|
||||
if(m_length > 3)
|
||||
m_peerLinkId = i.ReadNtohU16();
|
||||
if(m_length > 5)
|
||||
m_reasonCode = (dot11sReasonCode)i.ReadNtohU16();
|
||||
return i;
|
||||
}
|
||||
} //namespace NS3
|
||||
66
src/devices/wifi/dot11s-peer-management-element.h
Normal file
66
src/devices/wifi/dot11s-peer-management-element.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MESH_PEER_MAN_ELEMENT
|
||||
#define MESH_PEER_MAN_ELEMENT
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/buffer.h"
|
||||
#include "dot11s-codes.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
class PeerLinkManagementElement
|
||||
{
|
||||
public:
|
||||
enum Subtype {
|
||||
PEER_OPEN = 0,
|
||||
PEER_CLOSE = 1,
|
||||
PEER_CONFIRM = 2,
|
||||
};
|
||||
public:
|
||||
PeerLinkManagementElement ();
|
||||
|
||||
void SetPeerOpen(uint16_t localLinkId);
|
||||
void SetPeerClose(uint16_t localLinkID, uint16_t peerLinkId, dot11sReasonCode reasonCode);
|
||||
void SetPeerConfirm(uint16_t localLinkID, uint16_t peerLinkId);
|
||||
|
||||
dot11sReasonCode GetReasonCode() const;
|
||||
uint16_t GetLocalLinkId() const;
|
||||
uint16_t GetPeerLinkId() const;
|
||||
bool SubtypeIsOpen() const;
|
||||
bool SubtypeIsClose() const;
|
||||
bool SubtypeIsConfirm() const ;
|
||||
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
Buffer::Iterator Serialize (Buffer::Iterator i) const;
|
||||
Buffer::Iterator Deserialize (Buffer::Iterator i);
|
||||
private:
|
||||
uint8_t m_length;
|
||||
uint8_t m_subtype;
|
||||
uint16_t m_localLinkId; //always is present
|
||||
uint16_t m_peerLinkId; //only in confirm and may be present in close frame
|
||||
dot11sReasonCode m_reasonCode; //only in close frame
|
||||
};
|
||||
} //namespace NS3
|
||||
#endif
|
||||
|
||||
178
src/devices/wifi/mesh-configuration-element.cc
Normal file
178
src/devices/wifi/mesh-configuration-element.cc
Normal file
@@ -0,0 +1,178 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "mesh-configuration-element.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "dot11s-codes.h"
|
||||
|
||||
//NS_LOG_COMPONENT_DEFINE ("MeshConfigurationElement");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
dot11sMeshCapability::dot11sMeshCapability():
|
||||
acceptPeerLinks(true),
|
||||
MDAEnabled(false),
|
||||
forwarding(true),
|
||||
beaconTimingReport(false),
|
||||
TBTTAdjustment(false),
|
||||
powerSaveLevel(false)
|
||||
{}
|
||||
|
||||
uint32_t dot11sMeshCapability::GetSerializedSize (void) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
Buffer::Iterator dot11sMeshCapability::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
uint16_t result = 0;
|
||||
if(acceptPeerLinks)
|
||||
result |= 1 << 0;
|
||||
if(MDAEnabled)
|
||||
result |= 1 << 1;
|
||||
if(forwarding)
|
||||
result |= 1 << 2;
|
||||
if(beaconTimingReport)
|
||||
result |= 1 << 3;
|
||||
if(TBTTAdjustment)
|
||||
result |= 1 << 4;
|
||||
if(powerSaveLevel)
|
||||
result |= 1 << 5;
|
||||
i.WriteHtonU16(result);
|
||||
return i;
|
||||
}
|
||||
|
||||
Buffer::Iterator dot11sMeshCapability::Deserialize (Buffer::Iterator i)
|
||||
{
|
||||
uint16_t cap = i.ReadNtohU16();
|
||||
acceptPeerLinks = Is(cap,0);
|
||||
MDAEnabled = Is(cap,1);
|
||||
forwarding = Is(cap,2);
|
||||
beaconTimingReport = Is(cap,3);
|
||||
TBTTAdjustment = Is(cap,4);
|
||||
powerSaveLevel = Is(cap,5);
|
||||
return i;
|
||||
}
|
||||
|
||||
bool dot11sMeshCapability::Is(uint16_t cap, uint8_t n) const
|
||||
{
|
||||
uint16_t mask = 1<<n;
|
||||
return (cap & mask) == mask;
|
||||
}
|
||||
|
||||
MeshConfigurationElement::MeshConfigurationElement ():
|
||||
m_APSId(PROTOCOL_HWMP),
|
||||
m_APSMId(METRIC_AIRTIME),
|
||||
m_CCMId(CONGESTION_DEFAULT),
|
||||
m_CP(CHANNEL_PRECEDENCE_OFF)
|
||||
{}
|
||||
|
||||
uint32_t
|
||||
MeshConfigurationElement::GetSerializedSize (void) const
|
||||
{
|
||||
return 1 // ID
|
||||
+ 1 // Length
|
||||
+ 1 // Version
|
||||
+ 4 // APSPId
|
||||
+ 4 // APSMId
|
||||
+ 4 // CCMId
|
||||
+ 4 // CP
|
||||
+ m_meshCap.GetSerializedSize()
|
||||
;
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
MeshConfigurationElement::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
|
||||
i.WriteU8 (MESH_CONFIGURATION);
|
||||
i.WriteU8 (GetSerializedSize()); // Length
|
||||
i.WriteU8 (1); //Version
|
||||
// Active Path Selection Protocol ID:
|
||||
i.WriteHtonU32(m_APSId);
|
||||
// Active Path Metric ID:
|
||||
i.WriteHtonU32(m_APSMId);
|
||||
// Congestion Control Mode ID:
|
||||
i.WriteU32(m_CCMId);
|
||||
// Channel Precedence:
|
||||
i.WriteU32(m_CP);
|
||||
i = m_meshCap.Serialize(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
MeshConfigurationElement::Deserialize (Buffer::Iterator i)
|
||||
{
|
||||
|
||||
uint8_t elementId;
|
||||
uint8_t size;
|
||||
uint8_t version;
|
||||
elementId = i.ReadU8 ();
|
||||
|
||||
NS_ASSERT (elementId == MESH_CONFIGURATION);
|
||||
|
||||
size = i.ReadU8 ();
|
||||
version = i.ReadU8();
|
||||
// Active Path Selection Protocol ID:
|
||||
m_APSId = (dot11sPathSelectionProtocol)i.ReadNtohU32();
|
||||
// Active Path Metric ID:
|
||||
m_APSMId = (dot11sPathSelectionMetric)i.ReadNtohU32();
|
||||
// Congestion Control Mode ID:
|
||||
m_CCMId = (dot11sCongestionControlMode)i.ReadU32();
|
||||
// Channel Precedence:
|
||||
m_CP = (dot11sChannelPrecedence)i.ReadU32();
|
||||
i = m_meshCap.Deserialize(i);
|
||||
return i;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MeshConfigurationElement::SetRouting(dot11sPathSelectionProtocol routingId)
|
||||
{
|
||||
m_APSId = routingId ;
|
||||
}
|
||||
|
||||
void
|
||||
MeshConfigurationElement::SetMetric(dot11sPathSelectionMetric metricId)
|
||||
{
|
||||
m_APSMId = metricId;
|
||||
}
|
||||
|
||||
bool
|
||||
MeshConfigurationElement::IsHWMP(void)
|
||||
{
|
||||
return (m_APSId == PROTOCOL_HWMP);
|
||||
}
|
||||
|
||||
bool
|
||||
MeshConfigurationElement::IsAirtime(void)
|
||||
{
|
||||
return (m_APSMId == METRIC_AIRTIME);
|
||||
}
|
||||
|
||||
dot11sMeshCapability const& MeshConfigurationElement::MeshCapability()
|
||||
{
|
||||
return m_meshCap;
|
||||
}
|
||||
|
||||
} //namespace NS3
|
||||
101
src/devices/wifi/mesh-configuration-element.h
Normal file
101
src/devices/wifi/mesh-configuration-element.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MESH_CONFIGURATION_H
|
||||
#define MESH_CONFIGURATION_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/buffer.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
enum dot11sPathSelectionProtocol
|
||||
{
|
||||
PROTOCOL_HWMP = 0x000fac00,
|
||||
PROTOCOL_NULL = 0x000facff,
|
||||
};
|
||||
|
||||
enum dot11sPathSelectionMetric
|
||||
{
|
||||
METRIC_AIRTIME = 0x000fac00,
|
||||
METRIC_NULL = 0x000facff,
|
||||
};
|
||||
|
||||
enum dot11sCongestionControlMode
|
||||
{
|
||||
CONGESTION_DEFAULT = 0x000fac00,
|
||||
CONGESTION_NULL = 0x000facff,
|
||||
};
|
||||
|
||||
enum dot11sChannelPrecedence
|
||||
{
|
||||
CHANNEL_PRECEDENCE_OFF = 0x000fac00,
|
||||
};
|
||||
|
||||
|
||||
class dot11sMeshCapability
|
||||
{
|
||||
public:
|
||||
dot11sMeshCapability();
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
Buffer::Iterator Serialize (Buffer::Iterator i) const;
|
||||
Buffer::Iterator Deserialize (Buffer::Iterator i);
|
||||
bool acceptPeerLinks;
|
||||
bool MDAEnabled;
|
||||
bool forwarding;
|
||||
bool beaconTimingReport;
|
||||
bool TBTTAdjustment;
|
||||
bool powerSaveLevel;
|
||||
private:
|
||||
bool Is(uint16_t cap,uint8_t n) const;
|
||||
};
|
||||
|
||||
class MeshConfigurationElement
|
||||
{
|
||||
public:
|
||||
MeshConfigurationElement();
|
||||
void SetRouting(dot11sPathSelectionProtocol routingId);
|
||||
void SetMetric(dot11sPathSelectionMetric metricId);
|
||||
bool IsHWMP(void);
|
||||
bool IsAirtime(void);
|
||||
|
||||
dot11sMeshCapability const& MeshCapability();
|
||||
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
Buffer::Iterator Serialize (Buffer::Iterator i) const;
|
||||
Buffer::Iterator Deserialize (Buffer::Iterator i);
|
||||
// TODO: Release and fill other fields in configuration
|
||||
// element
|
||||
private:
|
||||
/** Active Path Selection Protocol ID */
|
||||
dot11sPathSelectionProtocol m_APSId;
|
||||
/** Active Path Metric ID */
|
||||
dot11sPathSelectionMetric m_APSMId;
|
||||
/** Congestion Control Mode ID */
|
||||
dot11sCongestionControlMode m_CCMId;
|
||||
/* Channel Precedence */
|
||||
dot11sChannelPrecedence m_CP;
|
||||
dot11sMeshCapability m_meshCap;
|
||||
};
|
||||
} //name space NS3
|
||||
#endif
|
||||
226
src/devices/wifi/mesh-mgt-headers.cc
Normal file
226
src/devices/wifi/mesh-mgt-headers.cc
Normal file
@@ -0,0 +1,226 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Yana Podkosova <yanapdk@rambler.ru>
|
||||
* Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "mesh-mgt-headers.h"
|
||||
#include "ns3/address-utils.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/assert.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
/***********************************************************
|
||||
* PeerLinkOpen frame:
|
||||
************************************************************/
|
||||
NS_OBJECT_ENSURE_REGISTERED (MeshMgtPeerLinkManFrame);
|
||||
|
||||
MeshMgtPeerLinkManFrame::MeshMgtPeerLinkManFrame()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MeshMgtPeerLinkManFrame::SetAid(uint16_t aid)
|
||||
{
|
||||
Aid = aid;
|
||||
}
|
||||
|
||||
void
|
||||
MeshMgtPeerLinkManFrame::SetSupportedRates(SupportedRates rates)
|
||||
{
|
||||
Rates = rates;
|
||||
}
|
||||
|
||||
void
|
||||
MeshMgtPeerLinkManFrame::SetQosField(uint16_t qos)
|
||||
{
|
||||
QoS= qos;
|
||||
}
|
||||
|
||||
void
|
||||
MeshMgtPeerLinkManFrame::SetMeshId(Ssid Id)
|
||||
{
|
||||
MeshId = Id;
|
||||
}
|
||||
|
||||
void
|
||||
MeshMgtPeerLinkManFrame::SetMeshConfigurationElement(MeshConfigurationElement MeshConf)
|
||||
{
|
||||
MeshConfig = MeshConf;
|
||||
}
|
||||
|
||||
void
|
||||
MeshMgtPeerLinkManFrame::SetPeerLinkManagementElement(PeerLinkManagementElement MeshPeerElement)
|
||||
{
|
||||
PeerLinkMan = MeshPeerElement;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
MeshMgtPeerLinkManFrame::GetAid()
|
||||
{
|
||||
return Aid;
|
||||
}
|
||||
|
||||
SupportedRates
|
||||
MeshMgtPeerLinkManFrame::GetSupportedRates()
|
||||
{
|
||||
return Rates;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
MeshMgtPeerLinkManFrame::GetQosField()
|
||||
{
|
||||
return QoS;
|
||||
}
|
||||
|
||||
Ssid
|
||||
MeshMgtPeerLinkManFrame::GetMeshId()
|
||||
{
|
||||
return MeshId;
|
||||
}
|
||||
|
||||
MeshConfigurationElement
|
||||
MeshMgtPeerLinkManFrame::GetMeshConfigurationElement()
|
||||
{
|
||||
return MeshConfig;
|
||||
}
|
||||
|
||||
PeerLinkManagementElement
|
||||
MeshMgtPeerLinkManFrame::GetPeerLinkManagementElement()
|
||||
{
|
||||
return PeerLinkMan;
|
||||
}
|
||||
|
||||
TypeId
|
||||
MeshMgtPeerLinkManFrame::GetTypeId(void)
|
||||
{
|
||||
static TypeId tid =
|
||||
TypeId ("ns3::MeshMgtPeerLinkManFrame")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<MeshMgtPeerLinkManFrame> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
TypeId
|
||||
MeshMgtPeerLinkManFrame::GetInstanceTypeId(void) const
|
||||
{
|
||||
return GetTypeId();
|
||||
}
|
||||
|
||||
void
|
||||
MeshMgtPeerLinkManFrame::Print(std::ostream &os) const
|
||||
{
|
||||
//TODO:fill this method
|
||||
}
|
||||
|
||||
uint32_t
|
||||
MeshMgtPeerLinkManFrame::GetSerializedSize(void) const
|
||||
{
|
||||
uint32_t size = 1; //Subtype
|
||||
if(MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
|
||||
size +=2; //AID of remote peer
|
||||
if(MESH_MGT_HEADER_PEER_CLOSE != Subtype)
|
||||
{
|
||||
size += Rates.GetSerializedSize ();
|
||||
size +=2;
|
||||
size += MeshId.GetSerializedSize ();
|
||||
size += MeshConfig.GetSerializedSize ();
|
||||
}
|
||||
size += PeerLinkMan.GetSerializedSize ();
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
MeshMgtPeerLinkManFrame::Serialize(Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
i.WriteU8(Subtype); //Like a Category in Standart
|
||||
if(MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
|
||||
|
||||
i.WriteHtonU16(Aid);
|
||||
if(MESH_MGT_HEADER_PEER_CLOSE != Subtype)
|
||||
{
|
||||
i = Rates.Serialize(i);
|
||||
//now QoS capabilities
|
||||
i.WriteHtonU16(QoS);
|
||||
i = MeshId.Serialize (i);
|
||||
i = MeshConfig.Serialize (i);
|
||||
}
|
||||
i = PeerLinkMan.Serialize (i);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
MeshMgtPeerLinkManFrame::Deserialize(Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
Subtype = i.ReadU8();
|
||||
if(MESH_MGT_HEADER_PEER_CONFIRM == Subtype)
|
||||
Aid = i.ReadNtohU16();
|
||||
if(MESH_MGT_HEADER_PEER_CLOSE != Subtype)
|
||||
{
|
||||
i = Rates.Deserialize(i);
|
||||
QoS = i.ReadNtohU16();
|
||||
i = MeshId.Deserialize (i);
|
||||
i = MeshConfig.Deserialize (i);
|
||||
}
|
||||
i = PeerLinkMan.Deserialize (i);
|
||||
return i.GetDistanceFrom (start);
|
||||
}
|
||||
void
|
||||
MeshMgtPeerLinkManFrame::SetOpen()
|
||||
{
|
||||
Subtype = MESH_MGT_HEADER_PEER_OPEN;
|
||||
}
|
||||
|
||||
void
|
||||
MeshMgtPeerLinkManFrame::SetConfirm()
|
||||
{
|
||||
Subtype = MESH_MGT_HEADER_PEER_CONFIRM;
|
||||
}
|
||||
|
||||
void
|
||||
MeshMgtPeerLinkManFrame::SetClose()
|
||||
{
|
||||
Subtype = MESH_MGT_HEADER_PEER_CLOSE;
|
||||
}
|
||||
|
||||
bool
|
||||
MeshMgtPeerLinkManFrame::IsOpen()
|
||||
{
|
||||
return (Subtype==MESH_MGT_HEADER_PEER_OPEN);
|
||||
}
|
||||
|
||||
bool
|
||||
MeshMgtPeerLinkManFrame::IsConfirm()
|
||||
{
|
||||
return (Subtype==MESH_MGT_HEADER_PEER_CONFIRM);
|
||||
}
|
||||
|
||||
bool
|
||||
MeshMgtPeerLinkManFrame::IsClose()
|
||||
{
|
||||
return (Subtype==MESH_MGT_HEADER_PEER_CLOSE);
|
||||
}
|
||||
|
||||
} //namespace NS3
|
||||
|
||||
|
||||
95
src/devices/wifi/mesh-mgt-headers.h
Normal file
95
src/devices/wifi/mesh-mgt-headers.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Yana Podkosova <yanapdk@rambler.ru>
|
||||
* Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MESH_MGT_HEADERS_H
|
||||
#define MESH_MGT_HEADERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ns3/header.h"
|
||||
#include "status-code.h"
|
||||
#include "dot11s-peer-management-element.h"
|
||||
#include "supported-rates.h"
|
||||
#include "mesh-configuration-element.h"
|
||||
#include "mesh-wifi-preq-information-element.h"
|
||||
#include "mesh-wifi-prep-information-element.h"
|
||||
#include "mesh-wifi-perr-information-element.h"
|
||||
#include "mesh-wifi-rann-information-element.h"
|
||||
#include "ssid.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class MeshMgtPeerLinkManFrame : public Header
|
||||
{
|
||||
public:
|
||||
MeshMgtPeerLinkManFrame ();
|
||||
void SetAid(uint16_t aid);
|
||||
void SetSupportedRates(SupportedRates rates);
|
||||
void SetQosField(uint16_t qos);
|
||||
void SetMeshId(Ssid Id);
|
||||
void SetMeshConfigurationElement(MeshConfigurationElement MeshConf);
|
||||
void SetPeerLinkManagementElement(PeerLinkManagementElement MeshPeerElement);
|
||||
|
||||
uint16_t GetAid();
|
||||
SupportedRates GetSupportedRates();
|
||||
uint16_t GetQosField();
|
||||
Ssid GetMeshId();
|
||||
MeshConfigurationElement GetMeshConfigurationElement();
|
||||
PeerLinkManagementElement GetPeerLinkManagementElement();
|
||||
|
||||
static TypeId GetTypeId(void);
|
||||
virtual TypeId GetInstanceTypeId(void) const;
|
||||
virtual void Print(std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize(void) const;
|
||||
virtual void Serialize(Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize(Buffer::Iterator start);
|
||||
//Subtype defining methods:
|
||||
void SetOpen();
|
||||
void SetConfirm();
|
||||
void SetClose();
|
||||
|
||||
bool IsOpen();
|
||||
bool IsConfirm();
|
||||
bool IsClose();
|
||||
|
||||
private:
|
||||
uint8_t Subtype;
|
||||
static const uint8_t MESH_MGT_HEADER_PEER_OPEN = 1;
|
||||
static const uint8_t MESH_MGT_HEADER_PEER_CONFIRM = 2;
|
||||
static const uint8_t MESH_MGT_HEADER_PEER_CLOSE = 3;
|
||||
// Standart is also requires a ReasonCode to be within
|
||||
// PeerLinkClose frame format, but it is present within
|
||||
// PeerLinkManagementElement, so we did not duplicate
|
||||
// it.
|
||||
uint16_t Aid; //only in Confirm
|
||||
SupportedRates Rates; //only in Open and Confirm
|
||||
uint16_t QoS; //only in Open and Confirm
|
||||
Ssid MeshId; //only in Open and Confirm
|
||||
MeshConfigurationElement MeshConfig; //only in Open and Confirm
|
||||
PeerLinkManagementElement PeerLinkMan; //in all types of frames
|
||||
};
|
||||
|
||||
}//namespace NS3
|
||||
#endif
|
||||
|
||||
|
||||
195
src/devices/wifi/mesh-wifi-beacon-timing-element.cc
Normal file
195
src/devices/wifi/mesh-wifi-beacon-timing-element.cc
Normal file
@@ -0,0 +1,195 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "mesh-wifi-beacon-timing-element.h"
|
||||
#define ELEMENT_ID (19)
|
||||
namespace ns3 {
|
||||
/*******************************************
|
||||
* WifiBeaconTimingElementUnit
|
||||
*******************************************/
|
||||
WifiBeaconTimingElementUnit::WifiBeaconTimingElementUnit()
|
||||
{
|
||||
AID = 0;
|
||||
LastBeacon = 0;
|
||||
BeaconInterval = 0;
|
||||
}
|
||||
|
||||
void
|
||||
WifiBeaconTimingElementUnit::SetAID(uint8_t aid)
|
||||
{
|
||||
AID = aid;
|
||||
}
|
||||
|
||||
void
|
||||
WifiBeaconTimingElementUnit::SetLastBeacon(uint16_t last_beacon)
|
||||
{
|
||||
LastBeacon = last_beacon;
|
||||
}
|
||||
|
||||
void
|
||||
WifiBeaconTimingElementUnit::SetBeaconInterval(uint16_t beacon_interval)
|
||||
{
|
||||
BeaconInterval = beacon_interval;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
WifiBeaconTimingElementUnit::GetAID()
|
||||
{
|
||||
return AID;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
WifiBeaconTimingElementUnit::GetLastBeacon()
|
||||
{
|
||||
return LastBeacon;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
WifiBeaconTimingElementUnit::GetBeaconInterval()
|
||||
{
|
||||
return BeaconInterval;
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* WifiBeaconTimingElement
|
||||
*******************************************/
|
||||
WifiBeaconTimingElement::WifiBeaconTimingElement()
|
||||
{
|
||||
m_maxSize = DEFAULT_MAX_SIZE;
|
||||
m_numOfUnits = 0;
|
||||
}
|
||||
|
||||
NeighboursTimingUnitsList
|
||||
WifiBeaconTimingElement::GetNeighboursTimingElementsList()
|
||||
{
|
||||
return m_neighbours;
|
||||
}
|
||||
|
||||
void
|
||||
WifiBeaconTimingElement::AddNeighboursTimingElementUnit(
|
||||
uint16_t aid,
|
||||
Time last_beacon, //MicroSeconds!
|
||||
Time beacon_interval //MicroSeconds!
|
||||
)
|
||||
{
|
||||
//Firs we lookup if this element already exists
|
||||
for(NeighboursTimingUnitsList::iterator i = m_neighbours.begin(); i!= m_neighbours.end(); i++)
|
||||
if(
|
||||
((*i)->GetAID() == AID_TO_U8(aid))
|
||||
&& ((*i)->GetLastBeacon() == TIMESTAMP_TO_U16(last_beacon))
|
||||
&& ((*i)->GetBeaconInterval() == BEACON_INTERVAL_TO_U16(beacon_interval))
|
||||
)
|
||||
return;
|
||||
Ptr<WifiBeaconTimingElementUnit>new_element = Create<WifiBeaconTimingElementUnit>();
|
||||
new_element->SetAID(AID_TO_U8(aid));
|
||||
new_element->SetLastBeacon(TIMESTAMP_TO_U16(last_beacon));
|
||||
new_element->SetBeaconInterval(BEACON_INTERVAL_TO_U16(beacon_interval));
|
||||
m_neighbours.push_back(new_element);
|
||||
m_numOfUnits++;
|
||||
}
|
||||
|
||||
void
|
||||
WifiBeaconTimingElement::DelNeighboursTimingElementUnit(
|
||||
uint16_t aid,
|
||||
Time last_beacon, //MicroSeconds!
|
||||
Time beacon_interval //MicroSeconds!
|
||||
)
|
||||
{
|
||||
for(NeighboursTimingUnitsList::iterator i = m_neighbours.begin(); i!= m_neighbours.end(); i++)
|
||||
if(
|
||||
((*i)->GetAID() == AID_TO_U8(aid))
|
||||
&& ((*i)->GetLastBeacon() == TIMESTAMP_TO_U16(last_beacon))
|
||||
&& ((*i)->GetBeaconInterval() == BEACON_INTERVAL_TO_U16(beacon_interval))
|
||||
)
|
||||
{
|
||||
m_neighbours.erase(i);
|
||||
m_numOfUnits--;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
WifiBeaconTimingElement::ClearTimingElement()
|
||||
{
|
||||
uint16_t to_delete = 0;
|
||||
uint16_t i;
|
||||
for(NeighboursTimingUnitsList::iterator j = m_neighbours.begin(); j!= m_neighbours.end(); j++)
|
||||
{
|
||||
to_delete++;
|
||||
(*j) = 0;
|
||||
}
|
||||
for(i = 0; i < to_delete; i ++)
|
||||
m_neighbours.pop_back();
|
||||
m_neighbours.clear();
|
||||
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiBeaconTimingElement::GetSerializedSize (void) const
|
||||
{
|
||||
return (2+5*m_numOfUnits > m_maxSize) ? 2+((m_maxSize-2)/5)*5 : 2+5*m_numOfUnits;
|
||||
}
|
||||
Buffer::Iterator
|
||||
WifiBeaconTimingElement::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
uint8_t can_be_written = (2+5*m_numOfUnits > m_maxSize) ? ((m_maxSize-2)/5) : m_numOfUnits;
|
||||
int actually_written = 0;
|
||||
i.WriteU8 (ELEMENT_ID);
|
||||
i.WriteU8 (can_be_written);
|
||||
for(NeighboursTimingUnitsList::const_iterator j = m_neighbours.begin(); j!= m_neighbours.end(); j++)
|
||||
{
|
||||
i.WriteU8 ((*j)->GetAID());
|
||||
i.WriteHtonU16 ((*j)->GetLastBeacon());
|
||||
i.WriteHtonU16 ((*j)->GetBeaconInterval());
|
||||
actually_written++;
|
||||
if(actually_written > can_be_written)
|
||||
break;
|
||||
}
|
||||
if(can_be_written < m_numOfUnits)
|
||||
{
|
||||
//move written units to the end of our list, so they
|
||||
//can be sent in timing element with next beacon
|
||||
//TODO:swap elements
|
||||
|
||||
}
|
||||
return i;
|
||||
}
|
||||
Buffer::Iterator
|
||||
WifiBeaconTimingElement::Deserialize (Buffer::Iterator i)
|
||||
{
|
||||
uint8_t elementId;
|
||||
uint8_t num_to_read = 0;
|
||||
int j;
|
||||
elementId = i.ReadU8();
|
||||
NS_ASSERT(elementId == ELEMENT_ID);
|
||||
num_to_read = i.ReadU8();
|
||||
for(j=0;j<num_to_read; j++)
|
||||
{
|
||||
Ptr<WifiBeaconTimingElementUnit> new_element = Create<WifiBeaconTimingElementUnit>();
|
||||
new_element->SetAID(i.ReadU8());
|
||||
new_element->SetLastBeacon(i.ReadNtohU16());
|
||||
new_element->SetBeaconInterval(i.ReadNtohU16());
|
||||
m_neighbours.push_back(new_element);
|
||||
}
|
||||
return i;
|
||||
};
|
||||
} //namespace ns3
|
||||
103
src/devices/wifi/mesh-wifi-beacon-timing-element.h
Normal file
103
src/devices/wifi/mesh-wifi-beacon-timing-element.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WIFI_TIMING_ELEMENT_H
|
||||
#define WIFI_TIMING_ELEMENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/buffer.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include <list>
|
||||
namespace ns3
|
||||
{
|
||||
class WifiBeaconTimingElementUnit : public RefCountBase
|
||||
{
|
||||
public:
|
||||
WifiBeaconTimingElementUnit();
|
||||
void SetAID(uint8_t aid);
|
||||
void SetLastBeacon(uint16_t last_beacon);
|
||||
void SetBeaconInterval(uint16_t beacon_interval);
|
||||
|
||||
uint8_t GetAID();
|
||||
uint16_t GetLastBeacon();
|
||||
uint16_t GetBeaconInterval();
|
||||
private:
|
||||
//Least significant octet of AID:
|
||||
uint8_t AID;
|
||||
//Last time we received a beacon in accordance with a
|
||||
//local TSF measured in 256 microseconds unit:
|
||||
uint16_t LastBeacon;
|
||||
//Beacon interval of remote mesh point:
|
||||
uint16_t BeaconInterval;
|
||||
};
|
||||
//This type is a list of timing elements obtained from neigbours with their beacons:
|
||||
typedef Ptr<WifiBeaconTimingElementUnit> WifiBeaconTimingElementPointer;
|
||||
typedef std::list<WifiBeaconTimingElementPointer> NeighboursTimingUnitsList;
|
||||
|
||||
class WifiBeaconTimingElement
|
||||
{
|
||||
public:
|
||||
WifiBeaconTimingElement();
|
||||
//This methods are needed for beacon collision
|
||||
//avoidance module:
|
||||
NeighboursTimingUnitsList
|
||||
GetNeighboursTimingElementsList();
|
||||
//The arguments of the following methods are different
|
||||
//from internalBeaconTimingElementUnint. This was made
|
||||
//for better communication with peer manager.
|
||||
//BeaconTimingElement class should convert it into
|
||||
//proper types:
|
||||
void AddNeighboursTimingElementUnit(
|
||||
uint16_t aid,
|
||||
Time last_beacon, //MicroSeconds!
|
||||
Time beacon_interval //MicroSeconds!
|
||||
);
|
||||
void DelNeighboursTimingElementUnit(
|
||||
uint16_t aid,
|
||||
Time last_beacon, //MicroSeconds!
|
||||
Time beacon_interval //MicroSeconds!
|
||||
);
|
||||
void ClearTimingElement();
|
||||
uint16_t TIMESTAMP_TO_U16(Time x)
|
||||
{
|
||||
return ((uint16_t)((x.GetMicroSeconds() >> 8)&0xffff));
|
||||
};
|
||||
uint16_t BEACON_INTERVAL_TO_U16(Time x)
|
||||
{
|
||||
return ((uint16_t)(x.GetMicroSeconds() >>10)&0xffff);
|
||||
};
|
||||
uint8_t AID_TO_U8(uint16_t x)
|
||||
{
|
||||
return (uint8_t)(x&0xff);
|
||||
};
|
||||
//Serialize-deserialize methods:
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
Buffer::Iterator Serialize (Buffer::Iterator i) const;
|
||||
Buffer::Iterator Deserialize (Buffer::Iterator i);
|
||||
private:
|
||||
NeighboursTimingUnitsList m_neighbours;
|
||||
//The maximum size of this element:
|
||||
const static uint16_t DEFAULT_MAX_SIZE = 255*5 +2;
|
||||
uint16_t m_maxSize;
|
||||
uint16_t m_numOfUnits;
|
||||
};
|
||||
}//namespace ns3
|
||||
#endif
|
||||
957
src/devices/wifi/mesh-wifi-mac.cc
Normal file
957
src/devices/wifi/mesh-wifi-mac.cc
Normal file
@@ -0,0 +1,957 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Ivan Pustogarov <chinsa1@rambler.ru>
|
||||
* Evgeny Khorov <horov@frtk.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/random-variable.h"
|
||||
|
||||
#include "mesh-wifi-mac.h"
|
||||
#include "dca-txop.h"
|
||||
#include "wifi-mac-header.h"
|
||||
#include "mgt-headers.h"
|
||||
#include "wifi-phy.h"
|
||||
#include "dcf-manager.h"
|
||||
#include "mac-rx-middle.h"
|
||||
#include "mac-low.h"
|
||||
#include "ns3/tx-statistics.h"
|
||||
#include "ns3/hwmp.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("MeshWifiMac");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (MeshWifiMac);
|
||||
|
||||
TypeId
|
||||
MeshWifiMac::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::MeshWifiMac")
|
||||
.SetParent<WifiMac> ()
|
||||
.AddConstructor<MeshWifiMac> ()
|
||||
.AddAttribute ("BeaconInterval", "Beacon Interval",
|
||||
TimeValue (Seconds (1.0)),
|
||||
MakeTimeAccessor (&MeshWifiMac::m_beaconInterval),
|
||||
MakeTimeChecker ()
|
||||
)
|
||||
.AddAttribute ("RandomStart", "Window when beacon generating starts (uniform random) in seconds",
|
||||
TimeValue (Seconds (0.1)),
|
||||
MakeTimeAccessor (&MeshWifiMac::m_randomStart),
|
||||
MakeTimeChecker ()
|
||||
)
|
||||
.AddAttribute ("SoftwareDelay", "Window of uniformely distributed random software handling delay",
|
||||
TimeValue (MicroSeconds (500)),
|
||||
MakeTimeAccessor (&MeshWifiMac::m_softwareDelay),
|
||||
MakeTimeChecker ()
|
||||
)
|
||||
.AddAttribute ("BeaconGeneration", "Enable/Disable Beaconing.",
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (
|
||||
&MeshWifiMac::SetBeaconGeneration,
|
||||
&MeshWifiMac::GetBeaconGeneration
|
||||
),
|
||||
MakeBooleanChecker ()
|
||||
);
|
||||
return tid;
|
||||
}
|
||||
|
||||
MeshWifiMac::MeshWifiMac ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_rxMiddle = new MacRxMiddle ();
|
||||
m_rxMiddle->SetForwardCallback (MakeCallback (&MeshWifiMac::Receive, this));
|
||||
|
||||
m_low = CreateObject<MacLow> ();
|
||||
m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
|
||||
|
||||
m_dcfManager = new DcfManager ();
|
||||
m_dcfManager->SetupLowListener (m_low);
|
||||
|
||||
m_beaconDca = CreateObject<DcaTxop> ();
|
||||
m_beaconDca->SetLow (m_low);
|
||||
m_beaconDca->SetMinCw (0);
|
||||
m_beaconDca->SetMaxCw (0);
|
||||
m_beaconDca->SetAifsn(1);
|
||||
m_beaconDca->SetManager (m_dcfManager);
|
||||
|
||||
m_VO = CreateObject<DcaTxop> ();
|
||||
m_VO->SetLow (m_low);
|
||||
m_VO->SetMinCw (3);
|
||||
m_VO->SetMaxCw (7);
|
||||
m_VO->SetManager (m_dcfManager);
|
||||
m_VO->SetTxOkCallback (MakeCallback (&MeshWifiMac::TxOk, this));
|
||||
m_VO->SetTxFailedCallback (MakeCallback (&MeshWifiMac::TxFailed, this));
|
||||
|
||||
m_BE = CreateObject<DcaTxop> ();
|
||||
m_BE->SetLow (m_low);
|
||||
m_BE->SetManager (m_dcfManager);
|
||||
m_BE->SetTxOkCallback (MakeCallback (&MeshWifiMac::TxOk, this));
|
||||
m_BE->SetTxFailedCallback (MakeCallback (&MeshWifiMac::TxFailed, this));
|
||||
}
|
||||
|
||||
MeshWifiMac::~MeshWifiMac ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
/*
|
||||
* Public Methods:
|
||||
*/
|
||||
void
|
||||
MeshWifiMac::SetSlot (Time slotTime)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << slotTime);
|
||||
m_dcfManager->SetSlot (slotTime);
|
||||
m_slot = slotTime;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetSifs (Time sifs)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << sifs);
|
||||
m_dcfManager->SetSifs (sifs);
|
||||
m_sifs = sifs;
|
||||
}
|
||||
void
|
||||
MeshWifiMac::SetAckTimeout (Time ackTimeout)
|
||||
{
|
||||
m_low->SetAckTimeout (ackTimeout);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetCtsTimeout (Time ctsTimeout)
|
||||
{
|
||||
m_low->SetCtsTimeout (ctsTimeout);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetPifs (Time pifs)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << pifs);
|
||||
m_pifs = pifs;
|
||||
}
|
||||
void
|
||||
MeshWifiMac::SetEifsNoDifs (Time eifsNoDifs)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << eifsNoDifs);
|
||||
m_dcfManager->SetEifsNoDifs (eifsNoDifs);
|
||||
m_eifsNoDifs = eifsNoDifs;
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiMac::GetSlot (void) const
|
||||
{
|
||||
return m_slot;
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiMac::GetSifs (void) const
|
||||
{
|
||||
return m_sifs;
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiMac::GetEifsNoDifs (void) const
|
||||
{
|
||||
return m_eifsNoDifs;
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiMac::GetAckTimeout (void) const
|
||||
{
|
||||
return m_low->GetAckTimeout ();
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiMac::GetCtsTimeout (void) const
|
||||
{
|
||||
return m_low->GetCtsTimeout ();
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiMac::GetPifs (void) const
|
||||
{
|
||||
return m_low->GetPifs ();
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << phy);
|
||||
m_phy = phy;
|
||||
m_dcfManager->SetupPhyListener (phy);
|
||||
m_low->SetPhy (phy);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << stationManager);
|
||||
m_stationManager = stationManager;
|
||||
m_BE->SetWifiRemoteStationManager (stationManager);
|
||||
m_VO->SetWifiRemoteStationManager (stationManager);
|
||||
m_beaconDca->SetWifiRemoteStationManager (stationManager);
|
||||
m_low->SetWifiRemoteStationManager (stationManager);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetPeerLinkManager (Ptr<WifiPeerManager> manager)
|
||||
{
|
||||
m_peerManager = manager;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << packet << to << from);
|
||||
ForwardDown (packet, from, to);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << packet << to);
|
||||
ForwardDown (packet, m_low->GetAddress (), to);
|
||||
}
|
||||
|
||||
bool
|
||||
MeshWifiMac::SupportsSendFrom (void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_upCallback = upCallback;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetLinkUpCallback (Callback<void> linkUp)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (!linkUp.IsNull ())
|
||||
{
|
||||
linkUp ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetLinkDownCallback (Callback<void> linkDown)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
Mac48Address
|
||||
MeshWifiMac::GetAddress (void) const
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
Mac48Address
|
||||
MeshWifiMac::GetBssid (void) const
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
|
||||
Ssid
|
||||
MeshWifiMac::GetSsid (void) const
|
||||
{
|
||||
return m_MeshId;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetAddress (Mac48Address address)
|
||||
{
|
||||
NS_LOG_FUNCTION (address);
|
||||
m_low->SetAddress(address);
|
||||
m_address = address;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetSsid (Ssid ssid)
|
||||
{
|
||||
NS_LOG_FUNCTION (ssid);
|
||||
m_MeshId = ssid;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetBeaconInterval (Time interval)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << interval);
|
||||
m_beaconInterval = interval;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::DoDispose (void)
|
||||
{
|
||||
delete m_rxMiddle;
|
||||
delete m_dcfManager;
|
||||
//Delete smart pointers:
|
||||
m_beaconSendEvent.Cancel ();
|
||||
m_beaconFormEvent.Cancel ();
|
||||
m_low = 0;
|
||||
m_BE = 0;
|
||||
m_VO = 0;
|
||||
m_beaconDca = 0;
|
||||
m_phy = 0;
|
||||
m_peerManager=0;
|
||||
WifiMac::DoDispose ();
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address src, Mac48Address dst)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << packet << src);
|
||||
m_upCallback (packet, src, dst);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
|
||||
{
|
||||
//TODO:Classify and queue
|
||||
WifiMacHeader hdr;
|
||||
Ptr<Packet> packet_to_send = packet->Copy();
|
||||
WifiMeshHeader meshHdr;
|
||||
//Address 1 we receive from HWMP tag
|
||||
HwmpTag tag;
|
||||
NS_ASSERT(packet->FindFirstMatchingTag(tag));
|
||||
meshHdr.SetMeshTtl(tag.GetTtl());
|
||||
meshHdr.SetMeshSeqno(tag.GetSeqno());
|
||||
#if 0
|
||||
NS_LOG_DEBUG(
|
||||
"TX Packet sa = "<<from<<
|
||||
", da = "<<to<<
|
||||
", ra = "<<tag.GetAddress()<<
|
||||
", I am "<<GetAddress()<<
|
||||
", ttl = "<<(int)meshHdr.GetMeshTtl()
|
||||
);
|
||||
#endif
|
||||
if(to!= Mac48Address::GetBroadcast())
|
||||
NS_ASSERT(tag.GetAddress()!=Mac48Address::GetBroadcast());
|
||||
hdr.SetTypeData ();
|
||||
hdr.SetAddr1 (tag.GetAddress());
|
||||
hdr.SetAddr2 (GetAddress ());
|
||||
hdr.SetAddr3 (to);
|
||||
hdr.SetAddr4(from);
|
||||
hdr.SetDsFrom ();
|
||||
hdr.SetDsTo ();
|
||||
//TODO: classify should be fixed!
|
||||
packet_to_send->AddHeader(meshHdr);
|
||||
WifiRemoteStation *destination = m_stationManager->Lookup (to);
|
||||
|
||||
if (destination->IsBrandNew ())
|
||||
{
|
||||
// in adhoc mode, we assume that every destination
|
||||
// supports all the rates we support.
|
||||
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
|
||||
{
|
||||
destination->AddSupportedMode (m_phy->GetMode (i));
|
||||
}
|
||||
destination->RecordDisassociated ();
|
||||
}
|
||||
m_BE->Queue (packet_to_send, hdr);
|
||||
}
|
||||
|
||||
SupportedRates
|
||||
MeshWifiMac::GetSupportedRates (void) const
|
||||
{
|
||||
// send the set of supported rates and make sure that we indicate
|
||||
// the Basic Rate set in this set of supported rates.
|
||||
SupportedRates rates;
|
||||
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
|
||||
{
|
||||
WifiMode mode = m_phy->GetMode (i);
|
||||
rates.AddSupportedRate (mode.GetDataRate ());
|
||||
}
|
||||
// set the basic rates
|
||||
for (uint32_t j = 0; j < m_stationManager->GetNBasicModes (); j++)
|
||||
{
|
||||
WifiMode mode = m_stationManager->GetBasicMode (j);
|
||||
rates.SetBasicRate (mode.GetDataRate ());
|
||||
}
|
||||
return rates;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SendOneBeacon (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_DEBUG(GetAddress()<<" is sending beacon");
|
||||
//Software delay should never be bigger than beacon interval!
|
||||
NS_ASSERT(!m_beaconSendEvent.IsRunning());
|
||||
Time last_software_delay = m_beaconFormingRandomDelay;
|
||||
MgtMeshBeaconHeader beacon;
|
||||
beacon.SetSsid (GetSsid ());
|
||||
beacon.SetSupportedRates (GetSupportedRates ());
|
||||
beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
|
||||
beacon.SetWifiBeaconTimingElement(m_peerManager->GetWifiBeaconTimingElementForMyBeacon(GetAddress()));
|
||||
m_beaconSendEvent = Simulator::Schedule(
|
||||
m_beaconFormingRandomDelay,
|
||||
&MeshWifiMac::QueueOneBeacon,
|
||||
this,
|
||||
beacon);
|
||||
UniformVariable coefficient(0.0, m_beaconFormingRandomDelay.GetSeconds());
|
||||
m_beaconFormingRandomDelay = Seconds(coefficient.GetValue());
|
||||
|
||||
//MBCA functionality, TODO: add the switch off/on MBCA mechanism capability
|
||||
//Let's find when we send the next beacon
|
||||
Time myNextTBTT = Simulator::Now ()+m_beaconInterval+last_software_delay;
|
||||
//The mext function compares my TBTT with neighbor's TBTTs using timing elemnt
|
||||
//and returns time shift for the next beacon if future collision is detected
|
||||
Time nextBeaconShift = m_peerManager->GetNextBeaconShift(GetAddress(), myNextTBTT);
|
||||
|
||||
m_beaconFormEvent = Simulator::Schedule (m_beaconInterval-m_beaconFormingRandomDelay+last_software_delay+nextBeaconShift, &MeshWifiMac::SendOneBeacon, this);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::QueueOneBeacon (MgtMeshBeaconHeader beacon_hdr)
|
||||
{
|
||||
WifiMacHeader hdr;
|
||||
hdr.SetBeacon ();
|
||||
hdr.SetAddr1 (Mac48Address::GetBroadcast ());
|
||||
hdr.SetAddr2 (GetAddress ());
|
||||
hdr.SetAddr3 (GetAddress ());
|
||||
hdr.SetDsNotFrom ();
|
||||
hdr.SetDsNotTo ();
|
||||
Ptr<Packet> packet = Create<Packet> ();
|
||||
|
||||
packet->AddHeader (beacon_hdr);
|
||||
m_beaconDca->Queue(packet, hdr);
|
||||
m_peerManager->SetSentBeaconTimers(
|
||||
GetAddress(),
|
||||
Simulator::Now (),
|
||||
MicroSeconds(beacon_hdr.GetBeaconIntervalUs())
|
||||
);
|
||||
|
||||
}
|
||||
void
|
||||
MeshWifiMac::SetBeaconGeneration (bool enable)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << enable);
|
||||
if (enable)
|
||||
{
|
||||
UniformVariable coefficient(0.0, m_randomStart.GetSeconds());
|
||||
Time randomStart = Seconds(coefficient.GetValue());
|
||||
// Beacons must be sent with a random delay,
|
||||
// otherwise, they will all be broken
|
||||
m_beaconFormEvent = Simulator::Schedule (randomStart, &MeshWifiMac::SendOneBeacon, this);
|
||||
}
|
||||
else
|
||||
m_beaconFormEvent.Cancel ();
|
||||
}
|
||||
|
||||
bool
|
||||
MeshWifiMac::GetBeaconGeneration (void) const
|
||||
{
|
||||
return m_beaconFormEvent.IsRunning ();
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::TxOk (WifiMacHeader const &hdr)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::TxFailed (WifiMacHeader const &hdr)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
|
||||
{
|
||||
if (hdr->IsBeacon ())
|
||||
{
|
||||
MgtMeshBeaconHeader beacon;
|
||||
Mac48Address from = hdr->GetAddr2();
|
||||
packet->RemoveHeader (beacon);
|
||||
NS_LOG_DEBUG("Beacon received from "<<hdr->GetAddr2()<<
|
||||
" to "<<GetAddress()<<
|
||||
" at "<<Simulator::Now ().GetMicroSeconds ()<<
|
||||
" microseconds");
|
||||
#if 0
|
||||
NeighboursTimingUnitsList neighbours;
|
||||
neighbours = beacon.GetWifiBeaconTimingElement().GetNeighboursTimingElementsList();
|
||||
for(NeighboursTimingUnitsList::const_iterator j = neighbours.begin(); j!= neighbours.end(); j++)
|
||||
fprintf(
|
||||
stderr,
|
||||
"neigbours:\nAID=%u, last_beacon=%u ,beacon_interval=%u\n",
|
||||
(*j)->GetAID(),
|
||||
(*j)->GetLastBeacon(),
|
||||
(*j)->GetBeaconInterval()
|
||||
);
|
||||
#endif
|
||||
m_peerManager->SetReceivedBeaconTimers(
|
||||
GetAddress(),
|
||||
from,
|
||||
Simulator::Now (),
|
||||
MicroSeconds(beacon.GetBeaconIntervalUs()),
|
||||
beacon.GetWifiBeaconTimingElement()
|
||||
);
|
||||
if(!beacon.GetSsid().IsEqual(GetSsid()))
|
||||
return;
|
||||
SupportedRates rates = beacon.GetSupportedRates ();
|
||||
WifiRemoteStation *peerSta = m_stationManager->Lookup (hdr->GetAddr2 ());
|
||||
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
|
||||
{
|
||||
WifiMode mode = m_phy->GetMode (i);
|
||||
if (rates.IsSupportedRate (mode.GetDataRate ()))
|
||||
{
|
||||
peerSta->AddSupportedMode (mode);
|
||||
if (rates.IsBasicRate (mode.GetDataRate ()))
|
||||
{
|
||||
m_stationManager->AddBasicMode (mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO:Chack MeshConfigurationElement(now is nothing
|
||||
// to be checked)
|
||||
m_peerManager->AskIfOpenNeeded(GetAddress(), from);
|
||||
return;
|
||||
}
|
||||
if(hdr->IsMultihopAction())
|
||||
{
|
||||
WifiMeshHeader meshHdr;
|
||||
//no mesh header parameters are needed here:
|
||||
//TODO: check TTL
|
||||
packet->RemoveHeader(meshHdr);
|
||||
WifiMeshMultihopActionHeader multihopHdr;
|
||||
//parse multihop action header:
|
||||
packet->RemoveHeader(multihopHdr);
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE
|
||||
actionValue = multihopHdr.GetAction();
|
||||
switch(multihopHdr.GetCategory())
|
||||
{
|
||||
case WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT:
|
||||
{
|
||||
Mac48Address peerAddress;
|
||||
MeshMgtPeerLinkManFrame peer_frame;
|
||||
if(hdr->GetAddr1 () != GetAddress ())
|
||||
return;
|
||||
peerAddress = hdr->GetAddr2();
|
||||
packet->RemoveHeader (peer_frame);
|
||||
if(actionValue.peerLink != WifiMeshMultihopActionHeader::PEER_LINK_CLOSE)
|
||||
{
|
||||
//check Supported Rates
|
||||
SupportedRates rates = peer_frame.GetSupportedRates();
|
||||
for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++)
|
||||
{
|
||||
WifiMode mode = m_stationManager->GetBasicMode (i);
|
||||
if (!rates.IsSupportedRate (mode.GetDataRate ()))
|
||||
{
|
||||
m_peerManager->ConfigurationMismatch(GetAddress(), peerAddress);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//Check SSID
|
||||
if(!peer_frame.GetMeshId().IsEqual(GetSsid()))
|
||||
{
|
||||
m_peerManager->ConfigurationMismatch(GetAddress(), peerAddress);
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch(actionValue.peerLink)
|
||||
{
|
||||
case WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM:
|
||||
m_peerManager->SetConfirmReceived(
|
||||
GetAddress(),
|
||||
peerAddress,
|
||||
peer_frame.GetAid(),
|
||||
peer_frame.GetPeerLinkManagementElement(),
|
||||
m_meshConfig
|
||||
);
|
||||
return;
|
||||
case WifiMeshMultihopActionHeader::PEER_LINK_OPEN:
|
||||
m_peerManager->SetOpenReceived(
|
||||
GetAddress(),
|
||||
peerAddress,
|
||||
peer_frame.GetPeerLinkManagementElement(),
|
||||
m_meshConfig
|
||||
);
|
||||
return;
|
||||
case WifiMeshMultihopActionHeader::PEER_LINK_CLOSE:
|
||||
m_peerManager->SetCloseReceived(
|
||||
GetAddress(),
|
||||
peerAddress,
|
||||
peer_frame.GetPeerLinkManagementElement()
|
||||
);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WifiMeshMultihopActionHeader::MESH_PATH_SELECTION:
|
||||
{
|
||||
if(!m_peerManager->IsActiveLink(GetAddress(), hdr->GetAddr2()))
|
||||
return;
|
||||
switch(actionValue.pathSelection)
|
||||
{
|
||||
case WifiMeshMultihopActionHeader::PATH_REQUEST:
|
||||
{
|
||||
WifiPreqInformationElement preq;
|
||||
packet->RemoveHeader(preq);
|
||||
//TODO:recalculate
|
||||
//metric
|
||||
m_preqReceived(preq, hdr->GetAddr2(), CalculateMetric(hdr->GetAddr2()));
|
||||
return;
|
||||
}
|
||||
case WifiMeshMultihopActionHeader::PATH_REPLY:
|
||||
{
|
||||
WifiPrepInformationElement prep;
|
||||
packet->RemoveHeader(prep);
|
||||
m_prepReceived(prep, hdr->GetAddr2(), CalculateMetric(hdr->GetAddr2()));
|
||||
}
|
||||
return;
|
||||
case WifiMeshMultihopActionHeader::PATH_ERROR:
|
||||
{
|
||||
WifiPerrInformationElement perr;
|
||||
packet->RemoveHeader(perr);
|
||||
m_perrReceived(perr, hdr->GetAddr2());
|
||||
}
|
||||
return;
|
||||
case WifiMeshMultihopActionHeader::ROOT_ANNOUNCEMENT:
|
||||
return;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(hdr->IsData())
|
||||
{
|
||||
NS_ASSERT((hdr->IsFromDs()) && (hdr->IsToDs()));
|
||||
NS_ASSERT(hdr->GetAddr4()!=Mac48Address::GetBroadcast());
|
||||
//check seqno
|
||||
WifiMeshHeader meshHdr;
|
||||
packet->RemoveHeader(meshHdr);
|
||||
NS_LOG_DEBUG(
|
||||
"DATA TA="<< hdr->GetAddr2()<<
|
||||
", da="<<hdr->GetAddr3()<<
|
||||
", sa="<<hdr->GetAddr4()<<
|
||||
", TTL="<<(int)meshHdr.GetMeshTtl());
|
||||
HwmpTag tag;
|
||||
//mesh header is present within DATA and multihop action frames, so it must be done within MAC
|
||||
tag.SetSeqno(meshHdr.GetMeshSeqno());
|
||||
tag.SetAddress(hdr->GetAddr2());
|
||||
tag.SetTtl(meshHdr.GetMeshTtl());
|
||||
//metric should be later
|
||||
packet->RemoveAllTags();
|
||||
packet->AddTag(tag);
|
||||
if(m_peerManager->IsActiveLink(GetAddress(), hdr->GetAddr2()))
|
||||
ForwardUp(packet, hdr->GetAddr4(), hdr->GetAddr3());
|
||||
}
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiMac::CalcSwDelay()
|
||||
{
|
||||
UniformVariable coefficient(0.0, m_softwareDelay.GetSeconds());
|
||||
Time delay = Seconds(coefficient.GetValue());
|
||||
if(delay.GetSeconds() + Simulator::Now().GetSeconds() < m_lastMgtFrame.GetSeconds())
|
||||
delay = Seconds(m_lastMgtFrame.GetSeconds() - Simulator::Now().GetSeconds());
|
||||
m_lastMgtFrame = Seconds(Simulator::Now().GetSeconds()+delay.GetSeconds());
|
||||
NS_ASSERT(delay.GetSeconds() >= 0);
|
||||
return delay;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SendPeerLinkOpen(PeerLinkManagementElement peer_element, Mac48Address peerAddress)
|
||||
{
|
||||
MeshMgtPeerLinkManFrame open;
|
||||
open.SetOpen();
|
||||
open.SetMeshConfigurationElement(m_meshConfig);
|
||||
open.SetPeerLinkManagementElement(peer_element);
|
||||
Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePeerLinkFrame, this, open, peerAddress);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SendPeerLinkConfirm(PeerLinkManagementElement peer_element, Mac48Address peerAddress, uint16_t aid)
|
||||
{
|
||||
MeshMgtPeerLinkManFrame confirm;
|
||||
confirm.SetConfirm();
|
||||
confirm.SetMeshConfigurationElement(m_meshConfig);
|
||||
confirm.SetPeerLinkManagementElement(peer_element);
|
||||
confirm.SetAid(aid);
|
||||
Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePeerLinkFrame, this, confirm, peerAddress);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SendPeerLinkClose(PeerLinkManagementElement peer_element, Mac48Address peerAddress)
|
||||
{
|
||||
MeshMgtPeerLinkManFrame close;
|
||||
close.SetClose();
|
||||
close.SetMeshConfigurationElement(m_meshConfig);
|
||||
close.SetPeerLinkManagementElement(peer_element);
|
||||
Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePeerLinkFrame, this, close, peerAddress);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::PeerLinkStatus(Mac48Address peerAddress, bool status)
|
||||
{
|
||||
//pass information to HwmpState
|
||||
m_peerStatusCallback(peerAddress, status, CalculateMetric(peerAddress));
|
||||
}
|
||||
void
|
||||
MeshWifiMac::QueuePeerLinkFrame(MeshMgtPeerLinkManFrame peer_frame, Mac48Address peerAddress)
|
||||
{
|
||||
Ptr<Packet> packet = Create<Packet> ();
|
||||
//Setting peer frame:
|
||||
peer_frame.SetSupportedRates(GetSupportedRates ());
|
||||
peer_frame.SetQosField(0);
|
||||
peer_frame.SetMeshId(GetSsid());
|
||||
packet->AddHeader (peer_frame);
|
||||
//multihop header:
|
||||
WifiMeshMultihopActionHeader multihopHdr;
|
||||
if(peer_frame.IsOpen())
|
||||
{
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE action;
|
||||
action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_OPEN;
|
||||
multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
|
||||
}
|
||||
if(peer_frame.IsConfirm())
|
||||
{
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE action;
|
||||
action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CONFIRM;
|
||||
multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
|
||||
}
|
||||
if(peer_frame.IsClose())
|
||||
{
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE action;
|
||||
action.peerLink = WifiMeshMultihopActionHeader::PEER_LINK_CLOSE;
|
||||
multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PEER_LINK_MGT, action);
|
||||
}
|
||||
packet->AddHeader(multihopHdr);
|
||||
//mesh header:
|
||||
WifiMeshHeader meshHdr;
|
||||
meshHdr.SetMeshTtl(1);
|
||||
meshHdr.SetMeshSeqno(0);
|
||||
packet->AddHeader(meshHdr);
|
||||
//Wifi Mac header:
|
||||
WifiMacHeader hdr;
|
||||
hdr.SetMultihopAction();
|
||||
hdr.SetAddr1 (peerAddress);
|
||||
hdr.SetAddr2 (GetAddress ());
|
||||
hdr.SetAddr3 (GetAddress ());
|
||||
hdr.SetDsNotFrom ();
|
||||
hdr.SetDsNotTo ();
|
||||
//queue:
|
||||
m_VO->Queue(packet,hdr);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetSoftwareDelay(Time delay)
|
||||
{
|
||||
m_softwareDelay = delay;
|
||||
}
|
||||
|
||||
Time
|
||||
MeshWifiMac::GetSoftwareDelay()
|
||||
{
|
||||
return m_softwareDelay;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SendPreq(const WifiPreqInformationElement& preq)
|
||||
{
|
||||
//Add a PREQ
|
||||
Ptr<Packet> packet = Create<Packet> ();
|
||||
packet->AddHeader(preq);
|
||||
//Add a Action values:
|
||||
WifiMeshMultihopActionHeader multihopHdr;
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE action;
|
||||
action.pathSelection = WifiMeshMultihopActionHeader::PATH_REQUEST;
|
||||
multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
|
||||
packet->AddHeader(multihopHdr);
|
||||
//Add a mesh Header
|
||||
WifiMeshHeader meshHdr;
|
||||
//TODO: normal seqno!
|
||||
meshHdr.SetMeshTtl(1);
|
||||
meshHdr.SetMeshSeqno(0);
|
||||
packet->AddHeader(meshHdr);
|
||||
//Add a wifi header:
|
||||
WifiMacHeader hdr;
|
||||
hdr.SetMultihopAction();
|
||||
hdr.SetAddr1 (Mac48Address::GetBroadcast ());
|
||||
hdr.SetAddr2 (GetAddress ());
|
||||
hdr.SetAddr3 (Mac48Address("00:00:00:00:00:00"));
|
||||
hdr.SetDsNotFrom ();
|
||||
hdr.SetDsNotTo ();
|
||||
Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePathSelectionFrame, this, packet, hdr);
|
||||
//m_VO->Queue(packet,hdr);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SendPrep(const WifiPrepInformationElement& prep, const Mac48Address& to)
|
||||
{
|
||||
if(!m_peerManager->IsActiveLink(GetAddress(), to))
|
||||
return;
|
||||
Ptr<Packet> packet = Create<Packet> ();
|
||||
packet->AddHeader(prep);
|
||||
//Add a Action values:
|
||||
WifiMeshMultihopActionHeader multihopHdr;
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE action;
|
||||
action.pathSelection = WifiMeshMultihopActionHeader::PATH_REPLY;
|
||||
multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
|
||||
packet->AddHeader(multihopHdr);
|
||||
//Add a mesh Header
|
||||
WifiMeshHeader meshHdr;
|
||||
//TODO: normal seqno!
|
||||
meshHdr.SetMeshTtl(1);
|
||||
meshHdr.SetMeshSeqno(0);
|
||||
packet->AddHeader(meshHdr);
|
||||
//Add a wifi header:
|
||||
WifiMacHeader hdr;
|
||||
hdr.SetMultihopAction();
|
||||
hdr.SetDsNotTo();
|
||||
hdr.SetDsNotFrom();
|
||||
hdr.SetAddr1(to);
|
||||
hdr.SetAddr2(GetAddress());
|
||||
hdr.SetAddr3(Mac48Address("00:00:00:00:00:00"));
|
||||
//m_VO->Queue(packet,hdr);
|
||||
Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePathSelectionFrame, this, packet, hdr);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SendPerr(const WifiPerrInformationElement& perr, std::vector<Mac48Address> receivers)
|
||||
{
|
||||
NS_ASSERT(receivers.size()!=0);
|
||||
Ptr<Packet> packet = Create<Packet> ();
|
||||
packet->AddHeader(perr);
|
||||
//Add a Action values:
|
||||
WifiMeshMultihopActionHeader multihopHdr;
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE action;
|
||||
action.pathSelection = WifiMeshMultihopActionHeader::PATH_ERROR;
|
||||
multihopHdr.SetAction(WifiMeshMultihopActionHeader::MESH_PATH_SELECTION, action);
|
||||
packet->AddHeader(multihopHdr);
|
||||
//Add a mesh Header
|
||||
WifiMeshHeader meshHdr;
|
||||
//TODO: normal seqno!
|
||||
meshHdr.SetMeshTtl(1);
|
||||
meshHdr.SetMeshSeqno(0);
|
||||
packet->AddHeader(meshHdr);
|
||||
//Add a wifi header:
|
||||
WifiMacHeader hdr;
|
||||
hdr.SetMultihopAction();
|
||||
hdr.SetDsNotTo();
|
||||
hdr.SetDsNotFrom();
|
||||
hdr.SetAddr2(GetAddress());
|
||||
hdr.SetAddr3(Mac48Address("00:00:00:00:00:00"));
|
||||
//m_VO->Queue(packet,hdr);
|
||||
for(unsigned int i = 0; i < receivers.size(); i ++)
|
||||
{
|
||||
NS_LOG_DEBUG(GetAddress()<<" is sending PERR to "<<receivers[i]);
|
||||
hdr.SetAddr1(receivers[i]);
|
||||
Simulator::Schedule(CalcSwDelay() ,&MeshWifiMac::QueuePathSelectionFrame, this, packet, hdr);
|
||||
}
|
||||
}
|
||||
void
|
||||
MeshWifiMac::QueuePathSelectionFrame(Ptr<Packet> packet, const WifiMacHeader hdr)
|
||||
{
|
||||
m_VO->Queue(packet, hdr);
|
||||
}
|
||||
void
|
||||
MeshWifiMac::SetPreqReceivedCallback(
|
||||
Callback<void, WifiPreqInformationElement&, const Mac48Address&, const uint32_t&> cb)
|
||||
{
|
||||
m_preqReceived = cb;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetPrepReceivedCallback(
|
||||
Callback<void, WifiPrepInformationElement&, const Mac48Address&, const uint32_t&> cb)
|
||||
{
|
||||
m_prepReceived = cb;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetPerrReceivedCallback(
|
||||
Callback<void, WifiPerrInformationElement&, const Mac48Address&> cb)
|
||||
{
|
||||
m_perrReceived = cb;
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiMac::SetPeerStatusCallback(
|
||||
Callback<void, Mac48Address, bool, uint32_t> cb)
|
||||
{
|
||||
m_peerStatusCallback = cb;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
MeshWifiMac::CalculateMetric(Mac48Address peerAddress)
|
||||
{
|
||||
//suppose Bt == 1000 bytes;
|
||||
uint32_t testLength = 1000;
|
||||
WifiRemoteStation *peerSta = m_stationManager->Lookup (peerAddress);
|
||||
WifiTxStatistics::RATE_LENGTH_STAT stats = peerSta->GetTxStat().statistics;
|
||||
Time overhead = m_sifs + MicroSeconds(32) + MicroSeconds(8);
|
||||
uint32_t metric = (uint32_t)((double)overhead.GetNanoSeconds()/102.4);
|
||||
uint32_t maxRate = 0;
|
||||
uint32_t packet_sent = 0;
|
||||
for(WifiTxStatistics::RATE_LENGTH_STAT::iterator lengthPos = stats.begin(); lengthPos !=stats.end(); lengthPos++)
|
||||
{
|
||||
if(lengthPos->first > testLength)
|
||||
continue;
|
||||
for(
|
||||
WifiTxStatistics::RATE_STAT::iterator ratePos = lengthPos->second.begin();
|
||||
ratePos != lengthPos->second.end();
|
||||
ratePos ++
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
NS_LOG_DEBUG("Rate is "<<ratePos->first
|
||||
<<": SUCCESS = "<<ratePos->second.packetsAcked
|
||||
<<", RRETRY = " <<ratePos->second.packetsRetried
|
||||
<<", FAILURE = "<<ratePos->second.packetsFailed);
|
||||
#endif
|
||||
double coefficient =
|
||||
(double)(
|
||||
ratePos->second.packetsRetried
|
||||
+ ratePos->second.packetsAcked
|
||||
)/((double)ratePos->second.packetsAcked);
|
||||
uint16_t avgLength = 0;
|
||||
if(ratePos->second.packetsAcked == 0)
|
||||
avgLength = lengthPos->first;
|
||||
else
|
||||
avgLength = ratePos->second.bytesAcked/ratePos->second.packetsAcked;
|
||||
uint32_t payload = (uint32_t)((double)avgLength / ((double)ratePos->first)*1e9);
|
||||
if(packet_sent < ratePos->second.packetsAcked)
|
||||
{
|
||||
metric = (uint32_t)(coefficient*((double)overhead.GetNanoSeconds() + (double)payload)/10240);
|
||||
packet_sent = ratePos->second.packetsAcked;
|
||||
maxRate = ratePos->first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//NS_LOG_DEBUG("RATE is "<<maxRate<<" metric is "<<metric);
|
||||
//peerSta->ResetTxStat();
|
||||
NS_ASSERT(metric !=0);
|
||||
return metric;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
399
src/devices/wifi/mesh-wifi-mac.h
Normal file
399
src/devices/wifi/mesh-wifi-mac.h
Normal file
@@ -0,0 +1,399 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Evgeny Khorov <horov@frtk.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MAC_HIGH_MESH_H
|
||||
#define MAC_HIGH_MESH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "mgt-headers.h"
|
||||
#include "mesh-mgt-headers.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "mesh-wifi-beacon-timing-element.h"
|
||||
#include "wifi-remote-station-manager.h"
|
||||
#include "mesh-wifi-peer-manager.h"
|
||||
#include "wifi-mac.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class WifiMacHeader;
|
||||
class DcaTxop;
|
||||
class WifiPhy;
|
||||
class DcfManager;
|
||||
class MacRxMiddle;
|
||||
class MacLow;
|
||||
class WifiPeerManager;
|
||||
/**
|
||||
* \brief Implements MAC-layer of mesh point: beaconing and
|
||||
* peer link management.
|
||||
*
|
||||
* \details Handles sending and receiving beacons. Tells all
|
||||
* needed information about beacons to MeshWifiPeerManager class, which
|
||||
* handles peer link management state machine. Asks
|
||||
* WifiPeerManager wether
|
||||
* receive or discard frame obtained from neighbour.
|
||||
* Now only three output queues are used:
|
||||
* one for beacons (PIFS and no backoff),
|
||||
* one for background traffic,
|
||||
* one for management and priority traffic.
|
||||
*/
|
||||
class MeshWifiMac : public WifiMac
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
MeshWifiMac ();
|
||||
~MeshWifiMac ();
|
||||
// inherited from WifiMac.
|
||||
virtual void SetSlot (Time slotTime);
|
||||
virtual void SetSifs (Time sifs);
|
||||
virtual void SetPifs (Time pifs);
|
||||
virtual void SetCtsTimeout (Time ctsTimeout);
|
||||
virtual void SetAckTimeout (Time ackTimeout);
|
||||
virtual void SetEifsNoDifs (Time eifsNoDifs);
|
||||
virtual Time GetSlot (void) const;
|
||||
virtual Time GetSifs (void) const;
|
||||
virtual Time GetPifs (void) const;
|
||||
virtual Time GetCtsTimeout (void) const;
|
||||
virtual Time GetAckTimeout (void) const;
|
||||
virtual Time GetEifsNoDifs (void) const;
|
||||
virtual void SetWifiPhy (Ptr<WifiPhy> phy);
|
||||
virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
|
||||
virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
|
||||
virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
|
||||
virtual bool SupportsSendFrom (void) const;
|
||||
virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
|
||||
virtual void SetLinkUpCallback (Callback<void> linkUp);
|
||||
virtual void SetLinkDownCallback (Callback<void> linkDown);
|
||||
virtual Mac48Address GetAddress (void) const;
|
||||
virtual Mac48Address GetBssid (void) const;
|
||||
virtual Ssid GetSsid (void) const;
|
||||
virtual void SetAddress (Mac48Address address);
|
||||
virtual void SetSsid (Ssid ssid);
|
||||
/**
|
||||
* \param interval is an interval between two
|
||||
* successive beacons
|
||||
*/
|
||||
void SetBeaconInterval (Time interval);
|
||||
/**
|
||||
* \returns interval between two beacons
|
||||
*/
|
||||
Time GetBeaconInterval (void) const;
|
||||
/**
|
||||
* \param delay is the maximum software delay.
|
||||
*
|
||||
* \details Software delay is calculated as uniformely
|
||||
* distributed random value between zero and
|
||||
* given parameter.
|
||||
*
|
||||
* All management frames are sent after software delay is passed,
|
||||
* for example, beacon is formed at software
|
||||
* delay before putting it to the queue.
|
||||
*
|
||||
* \attention The software delay is supposed
|
||||
* to be independent from traffic intensity.
|
||||
*
|
||||
*/
|
||||
void SetSoftwareDelay(Time delay);
|
||||
/**
|
||||
* \returns software delay parameter
|
||||
*/
|
||||
Time GetSoftwareDelay();
|
||||
/**
|
||||
* \param manager is pointer to the
|
||||
* WifiPeerManager class, which implements
|
||||
* peer-link management state machine.
|
||||
*
|
||||
* \details The purpose of peer manager is
|
||||
* obtaining all needed information from
|
||||
* beacons and send peer link management
|
||||
* frames.
|
||||
*
|
||||
* This funcion sets all needed callbacks to
|
||||
* a given peer manager
|
||||
*/
|
||||
void SetPeerLinkManager(Ptr<WifiPeerManager> manager);
|
||||
virtual void SetPreqReceivedCallback(
|
||||
Callback<void, WifiPreqInformationElement&, const Mac48Address&, const uint32_t&> cb);
|
||||
/**
|
||||
* \brief this callback is set by Hwmp routing
|
||||
* protocol and executed when MAC has received
|
||||
* PREP.
|
||||
* \param cb is a callback to be executed when
|
||||
* receiving PREP.
|
||||
*/
|
||||
virtual void SetPrepReceivedCallback(
|
||||
Callback<void, WifiPrepInformationElement&, const Mac48Address&, const uint32_t&> cb);
|
||||
/**
|
||||
* \brief this callback is set by Hwmp routing
|
||||
* protocol and executed when MAC has received
|
||||
* PERR.
|
||||
* \param cb is a callback to be executed when
|
||||
* receiving PERR.
|
||||
*/
|
||||
virtual void SetPerrReceivedCallback(
|
||||
Callback<void, WifiPerrInformationElement&, const Mac48Address&> cb);
|
||||
|
||||
/**
|
||||
* \brief this callback is set by Hwmp routing
|
||||
* protocol and executed when MAC has detected
|
||||
* the peer link failure
|
||||
* \param cb is a callback to be executed when
|
||||
* peer failure has ben detected
|
||||
*/
|
||||
virtual void SetPeerStatusCallback(
|
||||
Callback<void, Mac48Address, bool, uint32_t> cb);
|
||||
/**
|
||||
* \brief Sends a PREQ frame.
|
||||
* \param preq is preq information element
|
||||
* formed by protocol. This function just adds
|
||||
* a proper WifiMacHeader
|
||||
* \attention This method is public, because
|
||||
* HWMP makes a callback using this method
|
||||
*/
|
||||
virtual void SendPreq(const WifiPreqInformationElement& preq);
|
||||
/**
|
||||
* \brief Sends a PREP frame.
|
||||
* \param prep is prep information element
|
||||
* formed by protocol. This function just adds
|
||||
* a proper WifiMacHeader
|
||||
* \param to is an address of retransmitter of
|
||||
* the prep
|
||||
* \attention This method is public, because
|
||||
* HWMP makes a callback using this method
|
||||
*/
|
||||
|
||||
virtual void SendPrep(const WifiPrepInformationElement& prep, const Mac48Address& to);
|
||||
/**
|
||||
* \brief Sends a PERR frame.
|
||||
* \param perr is perr information element
|
||||
* formed by protocol. This function just adds
|
||||
* a proper WifiMacHeader.
|
||||
* \param receivers is list of addresses where
|
||||
* to send PERR (unicast PERR case)
|
||||
* \attention This method is public, because
|
||||
* HWMP makes a callback using this method
|
||||
*/
|
||||
virtual void SendPerr(const WifiPerrInformationElement& perr, std::vector<Mac48Address> receivers);
|
||||
/**
|
||||
* \brief Sends PeerLinkOpen frame to a given
|
||||
* address. Mac only forms a proper
|
||||
* WifiMacHeader.
|
||||
* \param peer_element is peer link frame to
|
||||
* be sent
|
||||
* \param peerAddress is the address of
|
||||
* destination of given frame
|
||||
*/
|
||||
void SendPeerLinkOpen(
|
||||
PeerLinkManagementElement peer_element,
|
||||
Mac48Address peerAddress
|
||||
);
|
||||
/**
|
||||
* \brief Sends PeerLinkConfirm frame to a given
|
||||
* address. Mac only forms a proper
|
||||
* WifiMacHeader.
|
||||
* \param peer_element is peer link frame to
|
||||
* be sent
|
||||
* \param peerAddress is the address of
|
||||
* destination of given frame
|
||||
* \param aid is the assocciation ID stored in
|
||||
* peer manager
|
||||
*/
|
||||
void SendPeerLinkConfirm(
|
||||
PeerLinkManagementElement peer_element,
|
||||
Mac48Address peerAddress,
|
||||
uint16_t aid
|
||||
);
|
||||
/**
|
||||
* \brief Sends PeerLinkClose frame to a given
|
||||
* address. Mac only forms a proper
|
||||
* WifiMacHeader.
|
||||
* \param peer_element is peer link frame to
|
||||
* be sent
|
||||
* \param peerAddress is the address of
|
||||
* destination of given frame
|
||||
*/
|
||||
void SendPeerLinkClose(
|
||||
PeerLinkManagementElement peer_element,
|
||||
Mac48Address peerAddress
|
||||
);
|
||||
/**
|
||||
* \brief this method is executed by peer
|
||||
* manager when peer link opened or closed
|
||||
* \param status true when link was opened,
|
||||
* false if link was closed
|
||||
* \param peerAddress is the address of
|
||||
* destination of given frame
|
||||
*/
|
||||
virtual void PeerLinkStatus(Mac48Address peerAddress, bool status);
|
||||
|
||||
/**
|
||||
* \brief Peer Manager notifyes MAC about new
|
||||
* peer link or peer link failure.
|
||||
* \details This method should pass this event
|
||||
* to HWMP, and it should generate new routing
|
||||
* information or should generate Path Error
|
||||
* \param peerAddress it the address of
|
||||
* neighbour
|
||||
* \param status If true - new peer link, perr
|
||||
* link failure otherwise
|
||||
*/
|
||||
void PeerEvent(
|
||||
Mac48Address peerAddress,
|
||||
bool status
|
||||
);
|
||||
private:
|
||||
void Receive (Ptr<Packet> packet, WifiMacHeader const *hdr);
|
||||
virtual void ForwardUp (Ptr<Packet> packet, Mac48Address src, Mac48Address dst);
|
||||
void ForwardDown(
|
||||
Ptr<const Packet> packet,
|
||||
Mac48Address from,
|
||||
Mac48Address to
|
||||
);
|
||||
void TxOk (WifiMacHeader const &hdr);
|
||||
void TxFailed (WifiMacHeader const &hdr);
|
||||
/**
|
||||
* \brief At the software delay before TBTT
|
||||
* SendOneBeacon is ececuted. It forms a
|
||||
* beacon frame body. Then calculates software
|
||||
* delay and schedules QueueOneBeacon
|
||||
*/
|
||||
void SendOneBeacon (void);
|
||||
/**
|
||||
* \brief Puts a formed beacon to the output
|
||||
* queue. SendOneBeacon forms a beacon and
|
||||
* after software delay QueueOneBeacon is
|
||||
* executed
|
||||
* \param beacon_hdr is beacon to be queued
|
||||
*/
|
||||
void QueueOneBeacon (MgtMeshBeaconHeader beacon_hdr);
|
||||
/**
|
||||
* \brief Executed after software delay by
|
||||
* SendPeerLinkOpen/Confirm/Close frames and
|
||||
* puts this frame to the output queue.
|
||||
* \param peer_frame peer link management
|
||||
* frame
|
||||
* \param peerAddress the address of
|
||||
* destination.
|
||||
*/
|
||||
void QueuePeerLinkFrame(MeshMgtPeerLinkManFrame peer_frame, Mac48Address peerAddress);
|
||||
/**
|
||||
* \brief Executed after software delay by
|
||||
* SendPreq/Prep/Perr frames and
|
||||
* puts this frame to the output queue.
|
||||
* \param packet is packet body,
|
||||
* \param hdr is WifiMacHeader
|
||||
*/
|
||||
void QueuePathSelectionFrame(Ptr<Packet> packet, const WifiMacHeader hdr);
|
||||
void SetBeaconGeneration (bool enable);
|
||||
bool GetBeaconGeneration (void) const;
|
||||
SupportedRates GetSupportedRates (void) const;
|
||||
virtual void DoDispose (void);
|
||||
|
||||
Ptr<DcaTxop> m_BE;
|
||||
Ptr<DcaTxop> m_BK;
|
||||
Ptr<DcaTxop> m_VI;
|
||||
Ptr<DcaTxop> m_VO;
|
||||
Ptr<DcaTxop> m_beaconDca;
|
||||
Ptr<WifiRemoteStationManager> m_stationManager;
|
||||
Ptr<WifiPhy> m_phy;
|
||||
Callback<void,Ptr<Packet>, Mac48Address, Mac48Address>
|
||||
m_upCallback;
|
||||
Time m_beaconInterval;
|
||||
Time m_randomStart;
|
||||
|
||||
DcfManager * m_dcfManager;
|
||||
MacRxMiddle * m_rxMiddle;
|
||||
Ptr<MacLow> m_low;
|
||||
Mac48Address m_address;
|
||||
Ssid m_MeshId;
|
||||
EventId m_beaconFormEvent;
|
||||
EventId m_beaconSendEvent;
|
||||
Time m_slot;
|
||||
Time m_sifs;
|
||||
Time m_pifs;
|
||||
Time m_ackTimeout;
|
||||
Time m_ctsTimeout;
|
||||
|
||||
Time m_eifsNoDifs;
|
||||
MeshConfigurationElement m_meshConfig; //Stores my configuration;
|
||||
//Peer Descriptor pointer:
|
||||
Ptr<WifiPeerManager> m_peerManager;
|
||||
Time m_softwareDelay;
|
||||
/**
|
||||
* \attention Software delay is used for management
|
||||
* frames, so, if this delay is calculated
|
||||
* independenly, the packet order may be
|
||||
* broken, so the last mgt frame sending time
|
||||
* should be keeped within MAC
|
||||
*/
|
||||
Time m_lastMgtFrame;
|
||||
/**
|
||||
* \returns the value of software delay
|
||||
* uniformely distributed between 0 and
|
||||
* m_softwareDealy (initiated by
|
||||
* SetSoftwareDelay method).
|
||||
*/
|
||||
Time CalcSwDelay();
|
||||
/**
|
||||
* \brief keeps delay for sending first
|
||||
* beacon. this delay is uniformely
|
||||
* distributed between 0 and given value
|
||||
*/
|
||||
Time m_beaconFormingRandomDelay;
|
||||
Callback<void, WifiPreqInformationElement&, const Mac48Address&, const uint32_t&>
|
||||
m_preqReceived;
|
||||
Callback<void, WifiPrepInformationElement&, const Mac48Address&, const uint32_t&>
|
||||
m_prepReceived;
|
||||
Callback<void, WifiPerrInformationElement&, const Mac48Address&>
|
||||
m_perrReceived;
|
||||
Callback<void, Mac48Address, bool, uint32_t>
|
||||
m_peerStatusCallback;
|
||||
/**
|
||||
* \brief metric calculation parameters
|
||||
*/
|
||||
uint32_t CalculateMetric(Mac48Address peerAddress);
|
||||
struct addrcmp
|
||||
{
|
||||
bool operator()(const Mac48Address addr1, Mac48Address addr2) const
|
||||
{
|
||||
uint8_t s1[6], s2[6];
|
||||
addr1.CopyTo(s1);
|
||||
addr2.CopyTo(s2);
|
||||
for(int i = 0; i < 6; i ++)
|
||||
if(s1[i] > s2[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
std::map<Mac48Address, uint32_t, addrcmp>
|
||||
m_metricDatabase;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
#endif /* MAC_HIGH_MESH_H */
|
||||
987
src/devices/wifi/mesh-wifi-peer-manager.cc
Normal file
987
src/devices/wifi/mesh-wifi-peer-manager.cc
Normal file
@@ -0,0 +1,987 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
* Ivan Pustogarov <chinsa1@rambler.ru>
|
||||
* Evgeny Khorov <horov@frtk.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "mesh-wifi-peer-manager.h"
|
||||
#include "dot11s-parameters.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/random-variable.h"
|
||||
NS_LOG_COMPONENT_DEFINE ("WifiPeerManager");
|
||||
namespace ns3 {
|
||||
/***************************************************
|
||||
* PeerLinkDescriptor
|
||||
***************************************************/
|
||||
WifiPeerLinkDescriptor::WifiPeerLinkDescriptor():
|
||||
m_localLinkId(0),
|
||||
m_peerLinkId(0),
|
||||
m_state(IDLE),
|
||||
m_retryCounter(0),
|
||||
m_maxBeaconLoss(3)
|
||||
{}
|
||||
|
||||
void
|
||||
WifiPeerLinkDescriptor::SetPeerAddress(Mac48Address macaddr)
|
||||
{
|
||||
m_peerAddress = macaddr;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerLinkDescriptor::SetLocalAddress(Mac48Address macaddr)
|
||||
{
|
||||
m_localAddress = macaddr;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerLinkDescriptor::SetLocalLinkId(uint16_t id)
|
||||
{
|
||||
m_localLinkId = id;
|
||||
}
|
||||
void
|
||||
WifiPeerLinkDescriptor::SetLocalAid(uint16_t aid)
|
||||
{
|
||||
m_assocId = aid;
|
||||
}
|
||||
void
|
||||
WifiPeerLinkDescriptor::SetBeaconInformation(Time lastBeacon, Time beaconInterval)
|
||||
{
|
||||
m_lastBeacon = lastBeacon;
|
||||
m_beaconInterval = beaconInterval;
|
||||
m_beaconLossTimer.Cancel();
|
||||
Time delay = Seconds(beaconInterval.GetSeconds()*m_maxBeaconLoss);
|
||||
NS_ASSERT(delay.GetMicroSeconds()!= 0);
|
||||
m_beaconLossTimer = Simulator::Schedule(delay, &WifiPeerLinkDescriptor::BeaconLoss, this);
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerLinkDescriptor::SetMaxBeaconLoss(uint8_t maxBeaconLoss)
|
||||
{
|
||||
m_maxBeaconLoss = maxBeaconLoss;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerLinkDescriptor::SetLinkStatusCallback(Callback<void, Mac48Address, Mac48Address, bool> cb)
|
||||
{
|
||||
m_linkStatusCallback = cb;
|
||||
}
|
||||
void
|
||||
WifiPeerLinkDescriptor::BeaconLoss()
|
||||
{
|
||||
StateMachine(CNCL);
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerLinkDescriptor::SetBeaconTimingElement(WifiBeaconTimingElement beaconTiming)
|
||||
{
|
||||
m_beaconTiming = beaconTiming;
|
||||
}
|
||||
|
||||
Mac48Address
|
||||
WifiPeerLinkDescriptor::GetPeerAddress() const
|
||||
{
|
||||
return m_peerAddress;
|
||||
}
|
||||
|
||||
Mac48Address
|
||||
WifiPeerLinkDescriptor::GetLocalAddress() const
|
||||
{
|
||||
return m_localAddress;
|
||||
}
|
||||
|
||||
|
||||
uint16_t
|
||||
WifiPeerLinkDescriptor::GetLocalAid()const
|
||||
{
|
||||
return m_assocId;
|
||||
}
|
||||
|
||||
Time
|
||||
WifiPeerLinkDescriptor::GetLastBeacon() const
|
||||
{
|
||||
return m_lastBeacon;
|
||||
}
|
||||
|
||||
Time
|
||||
WifiPeerLinkDescriptor::GetBeaconInterval() const
|
||||
{
|
||||
return m_beaconInterval;
|
||||
}
|
||||
WifiBeaconTimingElement
|
||||
WifiPeerLinkDescriptor::GetBeaconTimingElement() const
|
||||
{
|
||||
return m_beaconTiming;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerLinkDescriptor::ClearTimingElement()
|
||||
{
|
||||
m_beaconTiming.ClearTimingElement();
|
||||
}
|
||||
|
||||
|
||||
void WifiPeerLinkDescriptor::MLMECancelPeerLink(dot11sReasonCode reason)
|
||||
{
|
||||
StateMachine(CNCL,reason);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::MLMEPassivePeerLinkOpen()
|
||||
{
|
||||
StateMachine(PASOPN);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::MLMEActivePeerLinkOpen()
|
||||
{
|
||||
StateMachine(ACTOPN);
|
||||
}
|
||||
void WifiPeerLinkDescriptor::MLMEPeeringRequestReject()
|
||||
{
|
||||
StateMachine(REQ_RJCT, PEER_LINK_CANCELLED);
|
||||
}
|
||||
#if 0
|
||||
void WifiPeerLinkDescriptor::MLMEBindSecurityAssociation()
|
||||
{
|
||||
StateMachine(BNDSA);
|
||||
}
|
||||
#endif
|
||||
void
|
||||
WifiPeerLinkDescriptor::SetMac(Ptr<MeshWifiMac> mac)
|
||||
{
|
||||
m_mac = mac;
|
||||
}
|
||||
void WifiPeerLinkDescriptor::PeerLinkClose(uint16_t localLinkId,uint16_t peerLinkId, dot11sReasonCode reason)
|
||||
{
|
||||
if( peerLinkId != 0 && m_localLinkId != peerLinkId)
|
||||
return;
|
||||
if( m_peerLinkId == 0)
|
||||
m_peerLinkId = localLinkId;
|
||||
else if ( m_peerLinkId != localLinkId )
|
||||
return;
|
||||
StateMachine(CLS_ACPT,reason);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::PeerLinkOpenAccept(uint16_t localLinkId, MeshConfigurationElement conf)
|
||||
{
|
||||
if( m_peerLinkId == 0)
|
||||
m_peerLinkId = localLinkId;
|
||||
m_configuration = conf;
|
||||
StateMachine(OPN_ACPT);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::PeerLinkOpenReject(uint16_t localLinkId, MeshConfigurationElement conf,dot11sReasonCode reason)
|
||||
{
|
||||
if( m_peerLinkId == 0)
|
||||
m_peerLinkId = localLinkId;
|
||||
m_configuration = conf;
|
||||
StateMachine(OPN_RJCT,reason);
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerLinkDescriptor::PeerLinkConfirmAccept(uint16_t localLinkId,uint16_t peerLinkId, uint16_t peerAid, MeshConfigurationElement conf)
|
||||
{
|
||||
if( m_localLinkId != peerLinkId)
|
||||
return;
|
||||
if( m_peerLinkId == 0)
|
||||
m_peerLinkId = localLinkId;
|
||||
else if ( m_peerLinkId != localLinkId )
|
||||
return;
|
||||
m_configuration = conf;
|
||||
m_peerAssocId = peerAid;
|
||||
StateMachine(CNF_ACPT);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor:: PeerLinkConfirmReject(uint16_t localLinkId, uint16_t peerLinkId,
|
||||
MeshConfigurationElement conf,dot11sReasonCode reason)
|
||||
{
|
||||
if( m_localLinkId != peerLinkId)
|
||||
return;
|
||||
if( m_peerLinkId == 0)
|
||||
m_peerLinkId = localLinkId;
|
||||
else if ( m_peerLinkId != localLinkId )
|
||||
return;
|
||||
m_configuration = conf;
|
||||
StateMachine(CNF_RJCT,reason);
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPeerLinkDescriptor::LinkIsEstab() const
|
||||
{
|
||||
if(m_state == ESTAB)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPeerLinkDescriptor::LinkIsIdle() const
|
||||
{
|
||||
if(m_state == IDLE)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerLinkDescriptor::StateMachine(PeerEvent event,dot11sReasonCode reasoncode)
|
||||
{
|
||||
switch(m_state)
|
||||
{
|
||||
case IDLE:
|
||||
switch(event)
|
||||
{
|
||||
case PASOPN:
|
||||
m_state = LISTEN;
|
||||
break;
|
||||
case ACTOPN:
|
||||
m_state = OPN_SNT;
|
||||
SendPeerLinkOpen();
|
||||
SetRetryTimer();
|
||||
break;
|
||||
default:{}
|
||||
}
|
||||
break;
|
||||
case LISTEN:
|
||||
switch(event)
|
||||
{
|
||||
case CNCL:
|
||||
case CLS_ACPT:
|
||||
m_state=IDLE;
|
||||
// TODO Callback MLME-SignalPeerLinkStatus
|
||||
break;
|
||||
case REQ_RJCT:
|
||||
SendPeerLinkClose(reasoncode);
|
||||
break;
|
||||
case ACTOPN:
|
||||
m_state=OPN_SNT;
|
||||
SendPeerLinkOpen();
|
||||
SetRetryTimer();
|
||||
break;
|
||||
case OPN_ACPT:
|
||||
m_state = OPN_RCVD;
|
||||
SendPeerLinkConfirm();
|
||||
SendPeerLinkOpen();
|
||||
SetRetryTimer();
|
||||
break;
|
||||
default:{}
|
||||
}
|
||||
break;
|
||||
case OPN_SNT:
|
||||
switch(event)
|
||||
{
|
||||
case TOR1:
|
||||
SendPeerLinkOpen();
|
||||
m_retryCounter++;
|
||||
SetRetryTimer();
|
||||
break;
|
||||
case CNF_ACPT:
|
||||
m_state = CNF_RCVD;
|
||||
ClearRetryTimer();
|
||||
SetConfirmTimer();
|
||||
break;
|
||||
case OPN_ACPT:
|
||||
m_state = OPN_RCVD;
|
||||
SendPeerLinkConfirm();
|
||||
break;
|
||||
case CLS_ACPT:
|
||||
m_state = HOLDING;
|
||||
ClearRetryTimer();
|
||||
SendPeerLinkClose(MESH_CLOSE_RCVD);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
case OPN_RJCT:
|
||||
case CNF_RJCT:
|
||||
m_state = HOLDING;
|
||||
ClearRetryTimer();
|
||||
SendPeerLinkClose(reasoncode);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
case TOR2:
|
||||
m_state = HOLDING;
|
||||
ClearRetryTimer();
|
||||
SendPeerLinkClose(MESH_MAX_RETRIES);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
case CNCL:
|
||||
m_state = HOLDING;
|
||||
ClearRetryTimer();
|
||||
SendPeerLinkClose(PEER_LINK_CANCELLED);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
default:{}
|
||||
}
|
||||
break;
|
||||
case CNF_RCVD:
|
||||
switch(event)
|
||||
{
|
||||
case CNF_ACPT:
|
||||
break;
|
||||
case OPN_ACPT:
|
||||
m_state = ESTAB;
|
||||
NS_LOG_DEBUG("I am "<<m_localAddress<<", established link with "<<m_peerAddress<<", at "<<Simulator::Now());
|
||||
ClearConfirmTimer();
|
||||
SendPeerLinkConfirm();
|
||||
m_linkStatusCallback(m_localAddress, m_peerAddress, true);
|
||||
// TODO Callback MLME-SignalPeerLinkStatus
|
||||
break;
|
||||
case CLS_ACPT:
|
||||
m_state = HOLDING;
|
||||
ClearConfirmTimer();
|
||||
SendPeerLinkClose(MESH_CLOSE_RCVD);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
case CNF_RJCT:
|
||||
case OPN_RJCT:
|
||||
m_state = HOLDING;
|
||||
ClearConfirmTimer();
|
||||
SendPeerLinkClose(reasoncode);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
case CNCL:
|
||||
m_state = HOLDING;
|
||||
ClearConfirmTimer();
|
||||
SendPeerLinkClose(PEER_LINK_CANCELLED);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
case TOC:
|
||||
m_state = HOLDING;
|
||||
SendPeerLinkClose(MESH_CONFIRM_TIMEOUT);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
default:{}
|
||||
}
|
||||
break;
|
||||
case OPN_RCVD:
|
||||
switch(event)
|
||||
{
|
||||
case TOR1:
|
||||
SendPeerLinkOpen();
|
||||
m_retryCounter++;
|
||||
SetRetryTimer();
|
||||
break;
|
||||
case CNF_ACPT:
|
||||
NS_LOG_DEBUG("I am "<<m_localAddress<<", established link with "<<m_peerAddress<<", at "<<Simulator::Now());
|
||||
m_state = ESTAB;
|
||||
ClearRetryTimer();
|
||||
m_linkStatusCallback(m_localAddress, m_peerAddress, true);
|
||||
// TODO Callback MLME-SignalPeerLinkStatus
|
||||
break;
|
||||
case CLS_ACPT:
|
||||
m_state = HOLDING;
|
||||
ClearRetryTimer();
|
||||
SendPeerLinkClose(MESH_CLOSE_RCVD);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
case OPN_RJCT:
|
||||
case CNF_RJCT:
|
||||
m_state = HOLDING;
|
||||
ClearRetryTimer();
|
||||
SendPeerLinkClose(reasoncode);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
case TOR2:
|
||||
m_state = HOLDING;
|
||||
ClearRetryTimer();
|
||||
SendPeerLinkClose(MESH_MAX_RETRIES);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
case CNCL:
|
||||
m_state = HOLDING;
|
||||
ClearRetryTimer();
|
||||
SendPeerLinkClose(PEER_LINK_CANCELLED);
|
||||
SetHoldingTimer();
|
||||
break;
|
||||
default:{}
|
||||
}
|
||||
break;
|
||||
case ESTAB:
|
||||
switch(event)
|
||||
{
|
||||
#if 0
|
||||
case BNDSA:
|
||||
m_state = ESTAB;
|
||||
// TODO Callback MLME-SignalPeerLinkStatus
|
||||
// TODO
|
||||
break;
|
||||
#endif
|
||||
case OPN_ACPT:
|
||||
SendPeerLinkConfirm();
|
||||
break;
|
||||
case CLS_ACPT:
|
||||
NS_LOG_DEBUG("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Close received");
|
||||
m_state = HOLDING;
|
||||
SendPeerLinkClose(MESH_CLOSE_RCVD);
|
||||
SetHoldingTimer();
|
||||
m_linkStatusCallback(m_localAddress, m_peerAddress, false);
|
||||
break;
|
||||
case OPN_RJCT:
|
||||
case CNF_RJCT:
|
||||
NS_LOG_DEBUG("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Rejected open or confirm");
|
||||
m_state = HOLDING;
|
||||
ClearRetryTimer();
|
||||
SendPeerLinkClose(reasoncode);
|
||||
SetHoldingTimer();
|
||||
m_linkStatusCallback(m_localAddress, m_peerAddress, false);
|
||||
break;
|
||||
case CNCL:
|
||||
NS_LOG_DEBUG("I am "<<m_localAddress<<", CLOSED link with "<<m_peerAddress<<", at "<<Simulator::Now()<<" Link cancelled");
|
||||
m_state = HOLDING;
|
||||
SendPeerLinkClose(PEER_LINK_CANCELLED);
|
||||
SetHoldingTimer();
|
||||
m_linkStatusCallback(m_localAddress, m_peerAddress, false);
|
||||
break;
|
||||
default:{}
|
||||
}
|
||||
break;
|
||||
case HOLDING:
|
||||
switch(event)
|
||||
{
|
||||
case CLS_ACPT:
|
||||
ClearHoldingTimer();
|
||||
case TOH:
|
||||
m_state = IDLE;
|
||||
// TODO Callback MLME-SignalPeerLinkStatus
|
||||
break;
|
||||
case OPN_ACPT:
|
||||
case CNF_ACPT:
|
||||
m_state = HOLDING;
|
||||
// reason not spec in D2.0
|
||||
SendPeerLinkClose(PEER_LINK_CANCELLED);
|
||||
break;
|
||||
case OPN_RJCT:
|
||||
case CNF_RJCT:
|
||||
m_state = HOLDING;
|
||||
SendPeerLinkClose(reasoncode);
|
||||
break;
|
||||
default:{}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::ClearRetryTimer()
|
||||
{
|
||||
m_retryTimer.Cancel();
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::ClearConfirmTimer()
|
||||
{
|
||||
m_confirmTimer.Cancel();
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::ClearHoldingTimer()
|
||||
{
|
||||
m_holdingTimer.Cancel();
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::SendPeerLinkClose(dot11sReasonCode reasoncode)
|
||||
{
|
||||
PeerLinkManagementElement peerElement;
|
||||
peerElement.SetPeerClose(m_localLinkId, m_peerLinkId, reasoncode);
|
||||
m_mac->SendPeerLinkClose(peerElement,m_peerAddress);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::SendPeerLinkOpen()
|
||||
{
|
||||
PeerLinkManagementElement peerElement;
|
||||
peerElement.SetPeerOpen(m_localLinkId);
|
||||
NS_ASSERT(m_mac!=NULL);
|
||||
m_mac->SendPeerLinkOpen(peerElement,m_peerAddress);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::SendPeerLinkConfirm()
|
||||
{
|
||||
PeerLinkManagementElement peerElement;
|
||||
peerElement.SetPeerConfirm(m_localLinkId, m_peerLinkId);
|
||||
m_mac->SendPeerLinkConfirm(peerElement,m_peerAddress, m_assocId);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::SetHoldingTimer()
|
||||
{
|
||||
m_holdingTimer = Simulator::Schedule(dot11sParameters::dot11MeshHoldingTimeout,&WifiPeerLinkDescriptor::HoldingTimeout,this);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::HoldingTimeout()
|
||||
{
|
||||
StateMachine(TOH);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::SetRetryTimer()
|
||||
{
|
||||
m_retryTimer = Simulator::Schedule(dot11sParameters::dot11MeshRetryTimeout,&WifiPeerLinkDescriptor::RetryTimeout,this);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::RetryTimeout()
|
||||
{
|
||||
if( m_retryCounter < dot11sParameters::dot11MeshMaxRetries)
|
||||
StateMachine(TOR1);
|
||||
else
|
||||
StateMachine(TOR2);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::SetConfirmTimer()
|
||||
{
|
||||
m_confirmTimer = Simulator::Schedule(dot11sParameters::dot11MeshConfirmTimeout,&WifiPeerLinkDescriptor::ConfirmTimeout,this);
|
||||
}
|
||||
|
||||
void WifiPeerLinkDescriptor::ConfirmTimeout()
|
||||
{
|
||||
StateMachine(TOC);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************
|
||||
* PeerManager
|
||||
***************************************************/
|
||||
NS_OBJECT_ENSURE_REGISTERED (WifiPeerManager);
|
||||
|
||||
TypeId
|
||||
WifiPeerManager::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::WifiPeerManager")
|
||||
.SetParent<Object> ()
|
||||
.AddConstructor<WifiPeerManager> ()
|
||||
//peerLinkCleanupTimeout. This constant is not specified in Draft 2.0
|
||||
.AddAttribute ("PeerLinkCleanupPeriod",
|
||||
"PeerLinkCleanupPeriod",
|
||||
TimeValue (MilliSeconds (80)),
|
||||
MakeTimeAccessor (&WifiPeerManager::m_peerLinkCleanupPeriod),
|
||||
MakeTimeChecker ()
|
||||
)
|
||||
//MaxBeaconLost. This constant is not specified in Draft 2.0
|
||||
.AddAttribute ("MaxBeaconLost", "Max Beacon Lost",
|
||||
UintegerValue (3),
|
||||
MakeUintegerAccessor (&WifiPeerManager::m_maxBeaconLoss),
|
||||
MakeUintegerChecker<uint8_t> ()
|
||||
)
|
||||
//maximum number of peer links.
|
||||
.AddAttribute ("MaxNumberOfPeerLinks",
|
||||
"Maximum number of peer links ",
|
||||
UintegerValue (32),
|
||||
MakeUintegerAccessor (&WifiPeerManager::m_maxNumberOfPeerLinks),
|
||||
MakeUintegerChecker<uint8_t> ()
|
||||
);
|
||||
return tid;
|
||||
|
||||
}
|
||||
WifiPeerManager::WifiPeerManager()
|
||||
{
|
||||
m_assocId = 0;
|
||||
m_numberOfActivePeers = 0;
|
||||
// firs peerLinkId is 1, because 0 means "unknown"
|
||||
m_localLinkId = 1;
|
||||
m_cleanupEvent = Simulator::Schedule (m_peerLinkCleanupPeriod, &WifiPeerManager::PeerCleanup, this);
|
||||
}
|
||||
WifiPeerManager::~WifiPeerManager()
|
||||
{
|
||||
m_cleanupEvent.Cancel();
|
||||
//TODO: delete a list of descriptors
|
||||
for(
|
||||
PeerDescriptorsMap::iterator j = m_peerDescriptors.begin();
|
||||
j!= m_peerDescriptors.end();
|
||||
j++)
|
||||
{
|
||||
int to_delete = 0;
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = j->second.begin(); i!= j->second.end(); i++)
|
||||
{
|
||||
to_delete ++;
|
||||
(*i)->ClearTimingElement();
|
||||
(*i) = 0;
|
||||
}
|
||||
for(int i = 0; i < to_delete; i ++)
|
||||
j->second.pop_back();
|
||||
j->second.clear();
|
||||
}
|
||||
m_peerDescriptors.clear();
|
||||
|
||||
}
|
||||
void
|
||||
WifiPeerManager::SetSentBeaconTimers(
|
||||
Mac48Address portAddress,
|
||||
Time ReferenceTbtt,
|
||||
Time BeaconInterval
|
||||
)
|
||||
{
|
||||
BeaconInfoMap::iterator myBeacon = m_myBeaconInfo.find(portAddress);
|
||||
NS_ASSERT(myBeacon != m_myBeaconInfo.end());
|
||||
myBeacon->second.referenceTbtt = ReferenceTbtt;
|
||||
myBeacon->second.beaconInterval = BeaconInterval;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerManager::SetReceivedBeaconTimers(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress,
|
||||
Time lastBeacon,
|
||||
Time beaconInterval,
|
||||
WifiBeaconTimingElement beaconTiming
|
||||
)
|
||||
{
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port!=m_peerDescriptors.end());
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
|
||||
{
|
||||
if((*i)->GetPeerAddress() == peerAddress)
|
||||
{
|
||||
(*i)->SetBeaconTimingElement(beaconTiming);
|
||||
(*i)->SetBeaconInformation(lastBeacon, beaconInterval);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Ptr<WifiPeerLinkDescriptor> new_descriptor =
|
||||
AddDescriptor(portAddress, peerAddress, Simulator::Now(), beaconInterval);
|
||||
new_descriptor->SetBeaconTimingElement(beaconTiming);
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPeerManager::AttachPorts(std::vector<Ptr<WifiNetDevice> > ports)
|
||||
{
|
||||
NS_ASSERT(ports.size()!=0);
|
||||
for(std::vector<Ptr<WifiNetDevice> >::iterator i = ports.begin(); i != ports.end(); i++)
|
||||
{
|
||||
MeshWifiMac * meshWifiMac = dynamic_cast<MeshWifiMac *> (PeekPointer ((*i)->GetMac()));
|
||||
if(meshWifiMac == NULL)
|
||||
return false;
|
||||
meshWifiMac->SetPeerLinkManager(this);
|
||||
//Add a mac pointer:
|
||||
m_macPointers[meshWifiMac->GetAddress()] = meshWifiMac;
|
||||
//Add descriptor array:
|
||||
std::vector<Ptr<WifiPeerLinkDescriptor> > descriptors;
|
||||
m_peerDescriptors[meshWifiMac->GetAddress()] = descriptors;
|
||||
//Add beacon timers:
|
||||
struct BeaconInfo myBeacon;
|
||||
m_myBeaconInfo[meshWifiMac->GetAddress()] = myBeacon;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void
|
||||
WifiPeerManager::AskIfOpenNeeded(Mac48Address portAddress, Mac48Address peerAddress)
|
||||
{
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port!=m_peerDescriptors.end());
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
|
||||
if((*i)->GetPeerAddress() == peerAddress)
|
||||
{
|
||||
if(ShouldSendOpen(portAddress, peerAddress))
|
||||
(*i)->MLMEActivePeerLinkOpen();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerManager::SetOpenReceived(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress,
|
||||
PeerLinkManagementElement peerMan,
|
||||
MeshConfigurationElement conf
|
||||
)
|
||||
{
|
||||
dot11sReasonCode reasonCode;
|
||||
if(!ShouldAcceptOpen(portAddress, peerAddress,reasonCode))
|
||||
return;
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port!=m_peerDescriptors.end());
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
|
||||
if((*i)->GetPeerAddress() == peerAddress)
|
||||
{
|
||||
(*i)->PeerLinkOpenAccept(peerMan.GetLocalLinkId(), conf);
|
||||
return;
|
||||
}
|
||||
BeaconInfoMap::iterator myBeacon = m_myBeaconInfo.find(portAddress);
|
||||
NS_ASSERT(myBeacon!=m_myBeaconInfo.end());
|
||||
Ptr<WifiPeerLinkDescriptor>new_descriptor = AddDescriptor(
|
||||
portAddress,
|
||||
peerAddress,
|
||||
Simulator::Now(),
|
||||
myBeacon->second.beaconInterval
|
||||
);
|
||||
new_descriptor->PeerLinkOpenAccept(peerMan.GetLocalLinkId(), conf);
|
||||
}
|
||||
void
|
||||
WifiPeerManager::SetConfirmReceived(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress,
|
||||
uint16_t peerAid,
|
||||
PeerLinkManagementElement peerMan,
|
||||
MeshConfigurationElement meshConfig
|
||||
)
|
||||
{
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port!= m_peerDescriptors.end());
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
|
||||
if((*i)->GetPeerAddress() == peerAddress)
|
||||
(*i)->PeerLinkConfirmAccept(peerMan.GetLocalLinkId(), peerMan.GetPeerLinkId(), peerAid, meshConfig);
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerManager::SetCloseReceived(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress,
|
||||
PeerLinkManagementElement peerMan
|
||||
)
|
||||
{
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port!= m_peerDescriptors.end());
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
|
||||
if((*i)->GetPeerAddress() == peerAddress)
|
||||
{
|
||||
(*i)->PeerLinkClose(peerMan.GetLocalLinkId(), peerMan.GetPeerLinkId(), peerMan.GetReasonCode());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerManager::ConfigurationMismatch(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress
|
||||
)
|
||||
{
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port!= m_peerDescriptors.end());
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
|
||||
if((*i)->GetPeerAddress() == peerAddress)
|
||||
{
|
||||
(*i)->MLMECancelPeerLink(MESH_CONFIGURATION_POLICY_VIOLATION);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WifiBeaconTimingElement
|
||||
WifiPeerManager::GetWifiBeaconTimingElementForMyBeacon(Mac48Address portAddress)
|
||||
{
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port!= m_peerDescriptors.end());
|
||||
WifiBeaconTimingElement return_val;
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
|
||||
{
|
||||
//Just go through all neighbor entries and add it to timing element:
|
||||
return_val.AddNeighboursTimingElementUnit(
|
||||
(*i)->GetLocalAid(),
|
||||
(*i)->GetLastBeacon(),
|
||||
(*i)->GetBeaconInterval()
|
||||
);
|
||||
}
|
||||
return return_val;
|
||||
|
||||
}
|
||||
WifiBeaconTimingElement
|
||||
WifiPeerManager::GetWifiBeaconTimingElementForAddress(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address addr)
|
||||
{
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port!= m_peerDescriptors.end());
|
||||
WifiBeaconTimingElement return_val;
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
|
||||
if((*i)->GetPeerAddress() == addr)
|
||||
return_val = (*i)->GetBeaconTimingElement();
|
||||
return return_val;
|
||||
|
||||
|
||||
}
|
||||
Ptr<WifiPeerLinkDescriptor>
|
||||
WifiPeerManager::AddDescriptor(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress,
|
||||
Time lastBeacon,
|
||||
Time beaconInterval)
|
||||
{
|
||||
Ptr<WifiPeerLinkDescriptor> new_descriptor = Create<WifiPeerLinkDescriptor>();
|
||||
if(m_assocId ==0xff)
|
||||
m_assocId = 0;
|
||||
if(m_localLinkId == 0xff)
|
||||
m_localLinkId = 0;
|
||||
new_descriptor->SetLocalAid(m_assocId++);
|
||||
new_descriptor->SetLocalLinkId(m_localLinkId++);
|
||||
new_descriptor->SetPeerAddress(peerAddress);
|
||||
new_descriptor->SetBeaconInformation(lastBeacon, beaconInterval);
|
||||
//DEBUG ONLY:
|
||||
new_descriptor->SetLocalAddress(portAddress);
|
||||
//check if port address is wrong
|
||||
MeshMacMap::iterator pos = m_macPointers.find(portAddress);
|
||||
NS_ASSERT(pos!= m_macPointers.end());
|
||||
//check if descriptors array exist
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port !=m_peerDescriptors.end());
|
||||
new_descriptor->SetMac(pos->second);
|
||||
new_descriptor->SetMaxBeaconLoss(m_maxBeaconLoss);
|
||||
new_descriptor->SetLinkStatusCallback(MakeCallback(&WifiPeerManager::PeerLinkStatus, this));
|
||||
NS_ASSERT(port != m_peerDescriptors.end());
|
||||
m_peerDescriptors[portAddress].push_back(new_descriptor);
|
||||
return new_descriptor;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerManager::PeerCleanup()
|
||||
{
|
||||
for(
|
||||
PeerDescriptorsMap::iterator j = m_peerDescriptors.begin();
|
||||
j!= m_peerDescriptors.end();
|
||||
j++)
|
||||
{
|
||||
std::vector<unsigned int> to_erase;
|
||||
for(unsigned int i = 0; i< j->second.size(); i++)
|
||||
if(j->second[i]->LinkIsIdle())
|
||||
{
|
||||
j->second[i]->ClearTimingElement();
|
||||
j->second[i] = 0;
|
||||
to_erase.push_back(i);
|
||||
}
|
||||
if(to_erase.size() == 0)
|
||||
return;
|
||||
for(unsigned int i = to_erase.size()-1 ; i >= 0; i--)
|
||||
j->second.erase(j->second.begin() + to_erase[i]);
|
||||
to_erase.clear();
|
||||
}
|
||||
m_cleanupEvent = Simulator::Schedule (m_peerLinkCleanupPeriod, &WifiPeerManager::PeerCleanup, this);
|
||||
}
|
||||
|
||||
std::vector<Mac48Address>
|
||||
WifiPeerManager::GetNeighbourAddressList(Mac48Address portAddress, Mac48Address peerAddress)
|
||||
{
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port!= m_peerDescriptors.end());
|
||||
std::vector<Mac48Address> return_value;
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
|
||||
return_value.push_back((*i)->GetPeerAddress());
|
||||
return return_value;
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPeerManager::IsActiveLink(Mac48Address portAddress, Mac48Address peerAddress)
|
||||
{
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port!= m_peerDescriptors.end());
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
|
||||
if((*i)->GetPeerAddress() == peerAddress)
|
||||
return ((*i)->LinkIsEstab());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPeerManager::ShouldSendOpen(Mac48Address portAddress, Mac48Address peerAddress)
|
||||
{
|
||||
if(m_numberOfActivePeers > m_maxNumberOfPeerLinks)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPeerManager::ShouldAcceptOpen(Mac48Address portAddress, Mac48Address peerAddress,dot11sReasonCode & reasonCode)
|
||||
{
|
||||
if(m_numberOfActivePeers > m_maxNumberOfPeerLinks)
|
||||
{
|
||||
reasonCode = MESH_MAX_PEERS;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Time
|
||||
WifiPeerManager::GetNextBeaconShift(
|
||||
Mac48Address portAddress,
|
||||
Time myNextTBTT
|
||||
)
|
||||
{
|
||||
//REMINDER:: in timing element 1) last beacon reception time is measured in units of 256 microseconds
|
||||
// 2) beacon interval is mesured in units of 1024 microseconds
|
||||
// 3) hereafter TU = 1024 microseconds
|
||||
//Im my MAC everything is stored in MicroSeconds
|
||||
|
||||
uint32_t myNextTBTTInTimeUnits = 0;
|
||||
uint32_t futureBeaconInTimeUnits = 0;
|
||||
//Going through all my timing elements and detecting future beacon collisions
|
||||
PeerDescriptorsMap::iterator port = m_peerDescriptors.find(portAddress);
|
||||
NS_ASSERT(port!= m_peerDescriptors.end());
|
||||
BeaconInfoMap::iterator myBeacon = m_myBeaconInfo.find(portAddress);
|
||||
NS_ASSERT(myBeacon!=m_myBeaconInfo.end());
|
||||
for(std::vector<Ptr<WifiPeerLinkDescriptor> >::iterator i = port->second.begin(); i!= port->second.end(); i++)
|
||||
{
|
||||
NeighboursTimingUnitsList neighbours;
|
||||
neighbours = (*i)->GetBeaconTimingElement().GetNeighboursTimingElementsList();
|
||||
//first let's form the list of all kown TBTTs
|
||||
for(NeighboursTimingUnitsList::const_iterator j = neighbours.begin(); j!= neighbours.end(); j++)
|
||||
{
|
||||
uint16_t beaconIntervalTimeUnits;
|
||||
beaconIntervalTimeUnits = (*j)->GetBeaconInterval();
|
||||
|
||||
//The last beacon time in timing elememt in Time Units
|
||||
uint32_t lastBeaconInTimeUnits;
|
||||
lastBeaconInTimeUnits = (*j)->GetLastBeacon()/4;
|
||||
|
||||
//The time of my next beacon sending in Time Units
|
||||
myNextTBTTInTimeUnits = myNextTBTT.GetMicroSeconds()/1024;
|
||||
|
||||
//My beacon interval in Time Units
|
||||
uint32_t myBeaconIntervalInTimeUnits;
|
||||
myBeaconIntervalInTimeUnits = myBeacon->second.beaconInterval.GetMicroSeconds()/1024;
|
||||
|
||||
//The time the beacon of other station will be sent
|
||||
//we need the time just after my next TBTT (or equal to my TBTT)
|
||||
futureBeaconInTimeUnits = lastBeaconInTimeUnits + beaconIntervalTimeUnits;
|
||||
|
||||
//We apply MBAC only if beacon Intervals are equal
|
||||
if (beaconIntervalTimeUnits == myBeaconIntervalInTimeUnits)
|
||||
{
|
||||
//We know when the neighbor STA transmitted it's beacon
|
||||
//Now we need to know when it's going to send it's beacon in the future
|
||||
//So let's use the valuse of it's beacon interval
|
||||
while (myNextTBTTInTimeUnits >= futureBeaconInTimeUnits)
|
||||
futureBeaconInTimeUnits = futureBeaconInTimeUnits + beaconIntervalTimeUnits;
|
||||
//If we found that my TBTT coincide with another STA's TBTT
|
||||
//break all cylce and return time shift for my next TBTT
|
||||
if (myNextTBTTInTimeUnits == futureBeaconInTimeUnits)
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (myNextTBTTInTimeUnits == futureBeaconInTimeUnits)
|
||||
break;
|
||||
}
|
||||
|
||||
//TBTTs coincide, so let's calculate the shift
|
||||
if (myNextTBTTInTimeUnits == futureBeaconInTimeUnits) {
|
||||
NS_LOG_DEBUG("MBCA: Future beacon collision is detected, applying avoidance mechanism");
|
||||
UniformVariable randomSign(-1, 1);
|
||||
int coefficientSign = -1;
|
||||
if (randomSign.GetValue() >= 0)
|
||||
coefficientSign = 1;
|
||||
UniformVariable randomShift(1, 15);
|
||||
//So, the shift is a random integer variable uniformly distributed in [-15;-1] U [1;15]
|
||||
int beaconShift = randomShift.GetInteger() * coefficientSign;
|
||||
NS_LOG_DEBUG("Shift value = " << beaconShift << " beacon TUs");
|
||||
//We need the result not in Time Units, but in microseconds
|
||||
return MicroSeconds(beaconShift * 1024);
|
||||
}
|
||||
//No collision detecterf, hence no shift is needed
|
||||
else
|
||||
return MicroSeconds(0);
|
||||
}
|
||||
|
||||
void
|
||||
WifiPeerManager::PeerLinkStatus(Mac48Address portAddress, Mac48Address peerAddress, bool status)
|
||||
{
|
||||
MeshMacMap::iterator pos = m_macPointers.find(portAddress);
|
||||
NS_ASSERT(pos!= m_macPointers.end());
|
||||
pos->second->PeerLinkStatus(peerAddress, status);
|
||||
}
|
||||
} //namespace NS3
|
||||
329
src/devices/wifi/mesh-wifi-peer-manager.h
Normal file
329
src/devices/wifi/mesh-wifi-peer-manager.h
Normal file
@@ -0,0 +1,329 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Aleksey Kovalenko <kovalenko@iitp.ru>
|
||||
* Ivan Pustogarov <chinsa1@rambler.ru>
|
||||
* Evgeny Khorov <horov@frtk.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WIFI_PEER_MAN_H
|
||||
#define WIFI_PEER_MAN_H
|
||||
|
||||
#include "ns3/event-id.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/wifi-net-device.h"
|
||||
#include "dot11s-peer-management-element.h"
|
||||
#include "mesh-wifi-beacon-timing-element.h"
|
||||
#include "mesh-wifi-mac.h"
|
||||
#include <list>
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
class MeshWifiMac;
|
||||
class WifiPeerLinkDescriptor : public RefCountBase
|
||||
{
|
||||
public:
|
||||
WifiPeerLinkDescriptor();
|
||||
/**
|
||||
* Beacon loss processing:
|
||||
*/
|
||||
void SetBeaconInformation(Time lastBeacon, Time BeaconInterval);
|
||||
void SetMaxBeaconLoss(uint8_t maxBeaconLoss);
|
||||
/**
|
||||
* \brief Methods used to detecet peer link changes
|
||||
* \param bool if true - opened new link, if
|
||||
* false - link closed
|
||||
*/
|
||||
void SetLinkStatusCallback(Callback<void, Mac48Address, Mac48Address, bool> cb);
|
||||
/**
|
||||
* Peer link geeters/setters
|
||||
*/
|
||||
void SetPeerAddress(Mac48Address macaddr);
|
||||
/**
|
||||
* Debug purpose
|
||||
*/
|
||||
void SetLocalAddress(Mac48Address macaddr);
|
||||
void SetLocalLinkId(uint16_t id);
|
||||
void SetPeerLinkId(uint16_t id);
|
||||
void SetLocalAid(uint16_t aid);
|
||||
void SetPeerAid(uint16_t aid);
|
||||
void SetBeaconTimingElement(WifiBeaconTimingElement beaconTiming);
|
||||
void SetPeerLinkDescriptorElement(
|
||||
PeerLinkManagementElement peerLinkElement
|
||||
);
|
||||
Mac48Address GetPeerAddress()const;
|
||||
/**
|
||||
* Debug purpose
|
||||
*/
|
||||
Mac48Address GetLocalAddress()const;
|
||||
uint16_t GetLocalAid()const;
|
||||
Time GetLastBeacon()const;
|
||||
Time GetBeaconInterval()const;
|
||||
WifiBeaconTimingElement
|
||||
GetBeaconTimingElement()const;
|
||||
PeerLinkManagementElement
|
||||
GetPeerLinkDescriptorElement()const;
|
||||
void ClearTimingElement();
|
||||
/* MLME */
|
||||
void MLMECancelPeerLink(dot11sReasonCode reason);
|
||||
void MLMEPassivePeerLinkOpen();
|
||||
void MLMEActivePeerLinkOpen();
|
||||
void MLMEPeeringRequestReject();
|
||||
#if 0
|
||||
void MLMEBindSecurityAssociation();
|
||||
#endif
|
||||
void SetMac(Ptr<MeshWifiMac> mac);
|
||||
void PeerLinkClose(uint16_t localLinkID,uint16_t peerLinkID, dot11sReasonCode reason);
|
||||
void PeerLinkOpenAccept(uint16_t localLinkId, MeshConfigurationElement conf);
|
||||
void PeerLinkOpenReject(uint16_t localLinkId, MeshConfigurationElement conf,dot11sReasonCode reason);
|
||||
void PeerLinkConfirmAccept(
|
||||
uint16_t localLinkId,
|
||||
uint16_t peerLinkId,
|
||||
uint16_t peerAid,
|
||||
MeshConfigurationElement conf
|
||||
);
|
||||
void PeerLinkConfirmReject(
|
||||
uint16_t localLinkId,
|
||||
uint16_t peerLinkId,
|
||||
MeshConfigurationElement conf,
|
||||
dot11sReasonCode reason
|
||||
);
|
||||
bool LinkIsEstab() const;
|
||||
bool LinkIsIdle() const;
|
||||
private:
|
||||
enum PeerState {
|
||||
IDLE,
|
||||
LISTEN,
|
||||
OPN_SNT,
|
||||
CNF_RCVD,
|
||||
OPN_RCVD,
|
||||
ESTAB,
|
||||
HOLDING,
|
||||
};
|
||||
enum PeerEvent
|
||||
{
|
||||
CNCL, /** MLME-CancelPeerLink */
|
||||
PASOPN, /** MLME-PassivePeerLinkOpen */
|
||||
ACTOPN, /** MLME-ActivePeerLinkOpen */
|
||||
//BNDSA, /** MLME-BindSecurityAssociation */
|
||||
CLS_ACPT, /** PeerLinkClose_Accept */
|
||||
//CLS_IGNR, /** PeerLinkClose_Ignore */
|
||||
OPN_ACPT, /** PeerLinkOpen_Accept */
|
||||
//OPN_IGNR, /** PeerLinkOpen_Ignore */
|
||||
OPN_RJCT, /** PeerLinkOpen_Reject */
|
||||
REQ_RJCT, /** PeerLinkOpenReject by internal reason */
|
||||
CNF_ACPT, /** PeerLinkConfirm_Accept */
|
||||
//CNF_IGNR, /** PeerLinkConfirm_Ignore */
|
||||
CNF_RJCT, /** PeerLinkConfirm_Reject */
|
||||
TOR1,
|
||||
TOR2,
|
||||
TOC,
|
||||
TOH,
|
||||
};
|
||||
private:
|
||||
void StateMachine(PeerEvent event,dot11sReasonCode = DOT11S_REASON_RESERVED);
|
||||
/** Events handlers */
|
||||
void ClearRetryTimer();
|
||||
void ClearConfirmTimer();
|
||||
void ClearHoldingTimer();
|
||||
void SetHoldingTimer();
|
||||
void SetRetryTimer();
|
||||
void SetConfirmTimer();
|
||||
|
||||
void SendPeerLinkClose(dot11sReasonCode reasoncode );
|
||||
void SendPeerLinkOpen();
|
||||
void SendPeerLinkConfirm();
|
||||
/** Private Event */
|
||||
void HoldingTimeout();
|
||||
void RetryTimeout();
|
||||
void ConfirmTimeout();
|
||||
private:
|
||||
Mac48Address m_peerAddress;
|
||||
Mac48Address m_localAddress;
|
||||
uint16_t m_localLinkId;
|
||||
uint16_t m_peerLinkId;
|
||||
// Used for beacon timing:
|
||||
// All values are stored in microseconds!
|
||||
Time m_lastBeacon;
|
||||
Time m_beaconInterval;
|
||||
uint16_t m_assocId; //Assigned Assoc ID
|
||||
uint16_t m_peerAssocId; //Assoc Id assigned to me by peer
|
||||
//State of our peer Link:
|
||||
PeerState m_state;
|
||||
|
||||
MeshConfigurationElement
|
||||
m_configuration;
|
||||
// State is a bitfield as defined as follows:
|
||||
// This are states for a given
|
||||
WifiBeaconTimingElement
|
||||
m_beaconTiming;
|
||||
|
||||
EventId m_retryTimer;
|
||||
EventId m_holdingTimer;
|
||||
EventId m_confirmTimer;
|
||||
uint16_t m_retryCounter;
|
||||
/**
|
||||
* Beacon loss timers:
|
||||
*/
|
||||
EventId m_beaconLossTimer;
|
||||
uint8_t m_maxBeaconLoss;
|
||||
void BeaconLoss();
|
||||
Ptr<MeshWifiMac> m_mac;
|
||||
Callback<void, Mac48Address, Mac48Address, bool>
|
||||
m_linkStatusCallback;
|
||||
};
|
||||
|
||||
class WifiPeerManager : public Object
|
||||
{
|
||||
public:
|
||||
WifiPeerManager();
|
||||
WifiPeerManager(Ptr<MeshWifiMac> mac_pointer);
|
||||
~WifiPeerManager();
|
||||
static TypeId GetTypeId (void);
|
||||
//Returns a beacon timing element stored for remote station:
|
||||
WifiBeaconTimingElement
|
||||
GetWifiBeaconTimingElementForAddress(Mac48Address portAddress, Mac48Address addr);
|
||||
//Returns a list of all addresses, which beacons can be decoded:
|
||||
std::vector<Mac48Address>
|
||||
GetNeighbourAddressList(Mac48Address portAddress, Mac48Address peerAddress);
|
||||
bool AttachPorts(std::vector<Ptr<WifiNetDevice> >);
|
||||
//void SetMac(Ptr<MeshWifiMac> mac);
|
||||
Time GetNextBeaconShift(Mac48Address portAddress, Time myNextTBTT);
|
||||
|
||||
void SetSentBeaconTimers(
|
||||
Mac48Address portAddress,
|
||||
Time ReferenceTBTT,
|
||||
Time BeaconInterval
|
||||
);
|
||||
void AskIfOpenNeeded(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress
|
||||
);
|
||||
void SetReceivedBeaconTimers(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress,
|
||||
Time lastBeacon,
|
||||
Time beaconInterval,
|
||||
WifiBeaconTimingElement
|
||||
beaconTiming
|
||||
);
|
||||
void SetOpenReceived(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress,
|
||||
PeerLinkManagementElement
|
||||
peerMan,
|
||||
MeshConfigurationElement conf
|
||||
);
|
||||
void SetConfirmReceived(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress,
|
||||
uint16_t peerAid,
|
||||
PeerLinkManagementElement
|
||||
peerMan,
|
||||
MeshConfigurationElement meshConfig
|
||||
);
|
||||
void SetCloseReceived(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress,
|
||||
PeerLinkManagementElement peerMan
|
||||
);
|
||||
//Using this function MAC
|
||||
void ConfigurationMismatch(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress
|
||||
);
|
||||
//Returns a beacon timing element to added into my beacon:
|
||||
WifiBeaconTimingElement
|
||||
GetWifiBeaconTimingElementForMyBeacon(
|
||||
Mac48Address portAddress
|
||||
);
|
||||
bool IsActiveLink(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress
|
||||
);
|
||||
private:
|
||||
struct BeaconInfo
|
||||
{
|
||||
Time referenceTbtt; //When one of my station's beacons was put into a beacon queue;
|
||||
Time beaconInterval; //Beacon interval of my station;
|
||||
};
|
||||
typedef std::map<Mac48Address, std::vector<Ptr<WifiPeerLinkDescriptor> >, std::less<Mac48Address> >
|
||||
PeerDescriptorsMap;
|
||||
typedef std::map<Mac48Address, Ptr<MeshWifiMac>,std::less<Mac48Address> > MeshMacMap;
|
||||
typedef std::map<Mac48Address, struct BeaconInfo, std::less<Mac48Address> > BeaconInfoMap;
|
||||
|
||||
//Ptr<MeshWifiMac> m_mac;
|
||||
//Maximum peers that may be opened:
|
||||
uint8_t m_maxNumberOfPeerLinks;
|
||||
/**
|
||||
* Peer manager identify interface by address
|
||||
* of MAC. So, for every interface we store
|
||||
* list of peer descriptors.
|
||||
*/
|
||||
PeerDescriptorsMap m_peerDescriptors;
|
||||
/**
|
||||
* List of MAC pointers - to iteract with each
|
||||
* mac
|
||||
*/
|
||||
MeshMacMap m_macPointers;
|
||||
uint8_t m_numberOfActivePeers; //number of established peer links
|
||||
uint16_t m_assocId; //last stored assoc ID
|
||||
uint16_t m_localLinkId; //last stored local link ID
|
||||
//This Variables used in beacon miss auto-cleanup:
|
||||
//How many beacons may we lose before the link is
|
||||
//considered to be broken:
|
||||
uint8_t m_maxBeaconLoss;
|
||||
//Periodically we scan the peer manager list of peers
|
||||
//and check if the too many beacons were lost:
|
||||
Time m_peerLinkCleanupPeriod;
|
||||
EventId m_cleanupEvent;
|
||||
Ptr<WifiPeerLinkDescriptor>
|
||||
AddDescriptor(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress,
|
||||
Time lastBeacon,
|
||||
Time beaconInterval
|
||||
);
|
||||
void PeerCleanup();
|
||||
//Mechanism of choosing PEERs:
|
||||
bool ShouldSendOpen(Mac48Address portAddress, Mac48Address peerAddress);
|
||||
bool ShouldAcceptOpen(
|
||||
Mac48Address portAddress,
|
||||
Mac48Address peerAddress,
|
||||
dot11sReasonCode & reasonCode
|
||||
);
|
||||
//Needed for Beacon Collision Avoidance module:
|
||||
BeaconInfoMap m_myBeaconInfo;
|
||||
/**
|
||||
* Peer link Open/Close callbacks: We need to
|
||||
* inform MAC about this events.
|
||||
* \brief Interaction with peer link
|
||||
* descriptor - notify that peer link was
|
||||
* opened or closed
|
||||
* \param status true - peer link opened, peer
|
||||
* link closed otherwise
|
||||
*/
|
||||
void PeerLinkStatus(Mac48Address portAddress, Mac48Address peerAddress, bool status);
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
#endif
|
||||
141
src/devices/wifi/mesh-wifi-perr-information-element.cc
Normal file
141
src/devices/wifi/mesh-wifi-perr-information-element.cc
Normal file
@@ -0,0 +1,141 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Yana Podkosova <yanapdk@rambler.ru>
|
||||
* Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "mesh-wifi-perr-information-element.h"
|
||||
#include "ns3/address-utils.h"
|
||||
#define ELEMENT_ID (21)
|
||||
|
||||
namespace ns3 {
|
||||
WifiPerrInformationElement::~WifiPerrInformationElement()
|
||||
{
|
||||
}
|
||||
|
||||
TypeId
|
||||
WifiPerrInformationElement::GetTypeId()
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::WifiPerrInformationElement")
|
||||
.SetParent<Object> ();
|
||||
return tid;
|
||||
}
|
||||
void
|
||||
WifiPerrInformationElement::Print(std::ostream &os) const
|
||||
{
|
||||
// FILL
|
||||
}
|
||||
TypeId
|
||||
WifiPerrInformationElement::GetInstanceTypeId(void) const
|
||||
{
|
||||
return GetTypeId();
|
||||
}
|
||||
WifiPerrInformationElement::WifiPerrInformationElement()
|
||||
{
|
||||
m_numOfDest = 0;
|
||||
}
|
||||
uint8_t
|
||||
WifiPerrInformationElement::GetNumOfDest()
|
||||
{
|
||||
return m_numOfDest;
|
||||
}
|
||||
void
|
||||
WifiPerrInformationElement::Serialize(Buffer::Iterator i)const
|
||||
{
|
||||
i.WriteU8 (ELEMENT_ID);
|
||||
i.WriteU8 (2+10*m_numOfDest);
|
||||
i.WriteU8(0);
|
||||
i.WriteU8 (m_numOfDest);
|
||||
NS_ASSERT(m_numOfDest == m_addressUnits.size());
|
||||
for(unsigned int j = 0; j < m_numOfDest; j++)
|
||||
{
|
||||
WriteTo(i,m_addressUnits[j].destination);
|
||||
i.WriteHtonU32(m_addressUnits[j].seqnum);
|
||||
}
|
||||
}
|
||||
uint32_t
|
||||
WifiPerrInformationElement::Deserialize(Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
uint8_t ElementId;
|
||||
ElementId = i.ReadU8();
|
||||
NS_ASSERT (ElementId = ELEMENT_ID);
|
||||
int length = i.ReadU8();
|
||||
i.Next(1); //Mode flags is not used now
|
||||
m_numOfDest = i.ReadU8();
|
||||
NS_ASSERT((2+10*m_numOfDest) == length);
|
||||
length = 0; //to avoid compiler warning in optimized builds
|
||||
for(unsigned int j = 0; j < m_numOfDest; j++)
|
||||
{
|
||||
struct HwmpRtable::FailedDestination unit;
|
||||
ReadFrom(i,unit.destination);
|
||||
unit.seqnum = i.ReadNtohU32();
|
||||
m_addressUnits.push_back(unit);
|
||||
}
|
||||
return i.GetDistanceFrom(start);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiPerrInformationElement::GetSerializedSize() const
|
||||
{
|
||||
uint32_t retval =
|
||||
1 //Element Id
|
||||
+1 //Length
|
||||
+1 //ModeFlags
|
||||
+1 //NumOfDests
|
||||
+6*m_numOfDest
|
||||
+4*m_numOfDest;
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPerrInformationElement::AddAddressUnit(struct HwmpRtable::FailedDestination unit)
|
||||
{
|
||||
for(unsigned int i = 0; i < m_addressUnits.size(); i ++)
|
||||
if(m_addressUnits[i].destination == unit.destination)
|
||||
return;
|
||||
m_addressUnits.push_back(unit);
|
||||
m_numOfDest++;
|
||||
}
|
||||
|
||||
std::vector<struct HwmpRtable::FailedDestination>
|
||||
WifiPerrInformationElement::GetAddressUnitVector()
|
||||
{
|
||||
return m_addressUnits;
|
||||
}
|
||||
void
|
||||
WifiPerrInformationElement::DeleteAddressUnit(Mac48Address address)
|
||||
{
|
||||
for(std::vector<struct HwmpRtable::FailedDestination>::iterator i = m_addressUnits.begin(); i != m_addressUnits.end(); i ++)
|
||||
if((*i).destination == address)
|
||||
{
|
||||
m_numOfDest --;
|
||||
m_addressUnits.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPerrInformationElement::ResetPerr()
|
||||
{
|
||||
m_numOfDest = 0;
|
||||
m_addressUnits.clear();
|
||||
}
|
||||
}//namespace ns3
|
||||
|
||||
65
src/devices/wifi/mesh-wifi-perr-information-element.h
Normal file
65
src/devices/wifi/mesh-wifi-perr-information-element.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Yana Podkosova <yanapdk@rambler.ru>
|
||||
* Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PERR_INFORMATION_ELEMENT_H
|
||||
#define PERR_INFORMATION_ELEMENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/buffer.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/hwmp-rtable.h"
|
||||
#include "ns3/header.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
class WifiPerrInformationElement : public Header
|
||||
{
|
||||
public:
|
||||
WifiPerrInformationElement();
|
||||
~WifiPerrInformationElement();
|
||||
static TypeId GetTypeId(void);
|
||||
virtual TypeId GetInstanceTypeId(void) const;
|
||||
virtual void Print(std::ostream &os) const;
|
||||
virtual void Serialize(Buffer::Iterator i) const;
|
||||
virtual uint32_t Deserialize(Buffer::Iterator start);
|
||||
virtual uint32_t GetSerializedSize() const;
|
||||
#if 0
|
||||
//RESERVED in D2.07
|
||||
uint8_t GetModeFlags();
|
||||
void SetModeFlags(uint8_t flags);
|
||||
#endif
|
||||
uint8_t GetNumOfDest();
|
||||
|
||||
void AddAddressUnit(struct HwmpRtable::FailedDestination unit);
|
||||
std::vector<struct HwmpRtable::FailedDestination>
|
||||
GetAddressUnitVector();
|
||||
void DeleteAddressUnit(Mac48Address address);
|
||||
void ResetPerr();
|
||||
private:
|
||||
uint8_t m_numOfDest;
|
||||
std::vector<struct HwmpRtable::FailedDestination>
|
||||
m_addressUnits;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
219
src/devices/wifi/mesh-wifi-prep-information-element.cc
Normal file
219
src/devices/wifi/mesh-wifi-prep-information-element.cc
Normal file
@@ -0,0 +1,219 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Yana Podkosova <yanapdk@rambler.ru>
|
||||
* Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "mesh-wifi-prep-information-element.h"
|
||||
#include "ns3/address-utils.h"
|
||||
#include "ns3/assert.h"
|
||||
#define ELEMENT_ID (30)
|
||||
namespace ns3{
|
||||
/********************************
|
||||
* WifiPrepInformationElement
|
||||
*******************************/
|
||||
WifiPrepInformationElement::~WifiPrepInformationElement()
|
||||
{
|
||||
}
|
||||
|
||||
TypeId
|
||||
WifiPrepInformationElement::GetTypeId()
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::WifiPrepInformationElement")
|
||||
.SetParent<Object> ();
|
||||
return tid;
|
||||
}
|
||||
void
|
||||
WifiPrepInformationElement::Print(std::ostream &os) const
|
||||
{
|
||||
//TODO:fill this method
|
||||
}
|
||||
TypeId
|
||||
WifiPrepInformationElement::GetInstanceTypeId(void) const
|
||||
{
|
||||
return GetTypeId();
|
||||
}
|
||||
WifiPrepInformationElement::WifiPrepInformationElement()
|
||||
{
|
||||
m_flags = 0;
|
||||
m_hopcount = 0;
|
||||
m_ttl = 0;
|
||||
m_destSeqNumber = 0;
|
||||
m_lifetime = 0;
|
||||
m_destinationAddress = Mac48Address::GetBroadcast();
|
||||
m_metric = 0;
|
||||
m_originatorSeqNumber = 0;
|
||||
}
|
||||
void
|
||||
WifiPrepInformationElement::SetFlags(uint8_t flags)
|
||||
{
|
||||
m_flags = flags;
|
||||
}
|
||||
void
|
||||
WifiPrepInformationElement::SetHopcount(uint8_t hopcount)
|
||||
{
|
||||
m_hopcount = hopcount;
|
||||
}
|
||||
void
|
||||
WifiPrepInformationElement::SetTTL(uint8_t ttl)
|
||||
{
|
||||
m_ttl = ttl;
|
||||
}
|
||||
void
|
||||
WifiPrepInformationElement::SetDestinationSeqNumber(uint32_t dest_seq_number)
|
||||
{
|
||||
m_destSeqNumber = dest_seq_number;
|
||||
}
|
||||
void
|
||||
WifiPrepInformationElement::SetDestinationAddress(Mac48Address dest_address)
|
||||
{
|
||||
m_destinationAddress = dest_address;
|
||||
}
|
||||
void
|
||||
WifiPrepInformationElement::SetMetric(uint32_t metric)
|
||||
{
|
||||
m_metric = metric;
|
||||
}
|
||||
void
|
||||
WifiPrepInformationElement::SetOriginatorAddress(Mac48Address originator_address)
|
||||
{
|
||||
m_originatorAddress = originator_address;
|
||||
}
|
||||
void
|
||||
WifiPrepInformationElement::SetOriginatorSeqNumber(uint32_t originator_seq_number)
|
||||
{
|
||||
m_originatorSeqNumber = originator_seq_number;
|
||||
}
|
||||
void
|
||||
WifiPrepInformationElement::SetLifetime(uint32_t lifetime)
|
||||
{
|
||||
m_lifetime = lifetime;
|
||||
}
|
||||
uint8_t
|
||||
WifiPrepInformationElement::GetFlags() const
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
uint8_t
|
||||
WifiPrepInformationElement::GetHopcount() const
|
||||
{
|
||||
return m_hopcount;
|
||||
}
|
||||
uint32_t
|
||||
WifiPrepInformationElement::GetTTL() const
|
||||
{
|
||||
return m_ttl;
|
||||
}
|
||||
uint32_t
|
||||
WifiPrepInformationElement::GetDestinationSeqNumber() const
|
||||
{
|
||||
return m_destSeqNumber;
|
||||
}
|
||||
Mac48Address
|
||||
WifiPrepInformationElement::GetDestinationAddress() const
|
||||
{
|
||||
return m_destinationAddress;
|
||||
}
|
||||
uint32_t
|
||||
WifiPrepInformationElement::GetMetric() const
|
||||
{
|
||||
return m_metric;
|
||||
}
|
||||
Mac48Address
|
||||
WifiPrepInformationElement::GetOriginatorAddress() const
|
||||
{
|
||||
return m_originatorAddress;
|
||||
}
|
||||
uint32_t
|
||||
WifiPrepInformationElement::GetOriginatorSeqNumber() const
|
||||
{
|
||||
return m_originatorSeqNumber;
|
||||
}
|
||||
uint32_t
|
||||
WifiPrepInformationElement::GetLifetime() const
|
||||
{
|
||||
return m_lifetime;
|
||||
}
|
||||
void
|
||||
WifiPrepInformationElement::DecrementTtl()
|
||||
{
|
||||
m_ttl --;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPrepInformationElement::IncrementMetric(uint32_t metric)
|
||||
{
|
||||
m_metric +=metric;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WifiPrepInformationElement::Serialize(Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteU8 (ELEMENT_ID);
|
||||
i.WriteU8 (32);//length = 32
|
||||
i.WriteU8 (m_flags);
|
||||
i.WriteU8 (m_hopcount);
|
||||
i.WriteU8 (m_ttl);
|
||||
WriteTo(i, m_destinationAddress);
|
||||
i.WriteHtonU32 (m_destSeqNumber);
|
||||
i.WriteHtonU32 (m_lifetime);
|
||||
i.WriteHtonU32 (m_metric);
|
||||
WriteTo(i, m_originatorAddress);
|
||||
i.WriteHtonU32 (m_originatorSeqNumber);
|
||||
}
|
||||
uint32_t
|
||||
WifiPrepInformationElement::Deserialize(Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
uint8_t ElementId;
|
||||
ElementId = i.ReadU8();
|
||||
NS_ASSERT (ElementId == ELEMENT_ID);
|
||||
i.Next(1); // length is constatnt
|
||||
m_flags = i.ReadU8();
|
||||
m_hopcount = i.ReadU8();
|
||||
m_ttl = i.ReadU8();
|
||||
ReadFrom(i,m_destinationAddress);
|
||||
m_destSeqNumber = i.ReadNtohU32();
|
||||
m_lifetime = i.ReadNtohU32();
|
||||
m_metric = i.ReadNtohU32();
|
||||
ReadFrom(i,m_originatorAddress);
|
||||
m_originatorSeqNumber = i.ReadNtohU32();
|
||||
return i.GetDistanceFrom(start);
|
||||
}
|
||||
uint32_t
|
||||
WifiPrepInformationElement::GetSerializedSize() const
|
||||
{
|
||||
uint32_t retval =
|
||||
1 //Element ID
|
||||
+1 //Length
|
||||
+1 //Flags
|
||||
+1 //Hopcount
|
||||
+1 //TTL
|
||||
+6 //Dest address
|
||||
+4 //Dest seqno
|
||||
+4 //Lifetime
|
||||
+4 //metric
|
||||
+6 //Originator address
|
||||
+4 //Originator seqno
|
||||
+1; //destination count
|
||||
return retval;
|
||||
|
||||
};
|
||||
} //namespace ns3
|
||||
81
src/devices/wifi/mesh-wifi-prep-information-element.h
Normal file
81
src/devices/wifi/mesh-wifi-prep-information-element.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Yana Podkosova <yanapdk@rambler.ru>
|
||||
* Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WIFI_PREP_INFORMATION_ELEMENT_H
|
||||
#define WIFI_PREP_INFORMATION_ELEMENT_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/buffer.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/header.h"
|
||||
namespace ns3
|
||||
{
|
||||
class WifiPrepInformationElement : public Header
|
||||
{
|
||||
public:
|
||||
WifiPrepInformationElement();
|
||||
~WifiPrepInformationElement();
|
||||
static TypeId GetTypeId(void);
|
||||
virtual TypeId GetInstanceTypeId(void) const;
|
||||
virtual void Print(std::ostream &os) const;
|
||||
void SetFlags(uint8_t flags);
|
||||
void SetHopcount(uint8_t hopcount);
|
||||
void SetTTL(uint8_t ttl);
|
||||
void SetDestinationAddress(Mac48Address dest_address);
|
||||
void SetDestinationSeqNumber(uint32_t dest_seq_number);
|
||||
void SetLifetime(uint32_t lifetime);
|
||||
void SetMetric(uint32_t metric);
|
||||
void SetOriginatorAddress(Mac48Address originator_address);
|
||||
void SetOriginatorSeqNumber(uint32_t originator_seg_number);
|
||||
virtual void Serialize(Buffer::Iterator i) const;
|
||||
virtual uint32_t Deserialize(Buffer::Iterator i);
|
||||
virtual uint32_t GetSerializedSize() const;
|
||||
|
||||
uint8_t GetFlags() const;
|
||||
uint8_t GetHopcount() const;
|
||||
uint32_t GetTTL() const;
|
||||
Mac48Address GetDestinationAddress() const;
|
||||
uint32_t GetDestinationSeqNumber() const;
|
||||
uint32_t GetLifetime() const;
|
||||
uint32_t GetMetric() const;
|
||||
Mac48Address GetOriginatorAddress() const;
|
||||
uint32_t GetOriginatorSeqNumber()const ;
|
||||
|
||||
void DecrementTtl();
|
||||
void IncrementMetric(uint32_t metric);
|
||||
private:
|
||||
|
||||
uint8_t m_flags;
|
||||
uint8_t m_hopcount;
|
||||
uint8_t m_ttl;
|
||||
Mac48Address m_destinationAddress;
|
||||
uint32_t m_destSeqNumber;
|
||||
uint32_t m_lifetime;
|
||||
uint32_t m_metric;
|
||||
Mac48Address m_originatorAddress;
|
||||
uint32_t m_originatorSeqNumber;
|
||||
};
|
||||
}//namespace ns3
|
||||
#endif
|
||||
|
||||
393
src/devices/wifi/mesh-wifi-preq-information-element.cc
Normal file
393
src/devices/wifi/mesh-wifi-preq-information-element.cc
Normal file
@@ -0,0 +1,393 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Yana Podkosova <yanapdk@rambler.ru>
|
||||
* Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "mesh-wifi-preq-information-element.h"
|
||||
#include "ns3/address-utils.h"
|
||||
#include "ns3/assert.h"
|
||||
#define ELEMENT_ID (22)
|
||||
namespace ns3{
|
||||
/*************************
|
||||
* DestinationAddressUnit
|
||||
************************/
|
||||
DestinationAddressUnit::DestinationAddressUnit()
|
||||
{
|
||||
m_do = false;
|
||||
m_rf = false;
|
||||
m_destSeqNumber = 0;
|
||||
uint8_t mac_buffer[6];
|
||||
for (int j = 0; j < 6; j++)
|
||||
{
|
||||
mac_buffer[j] = 0;
|
||||
}
|
||||
m_destinationAddress.CopyFrom(mac_buffer);
|
||||
}
|
||||
void
|
||||
DestinationAddressUnit::SetFlags(bool doFlag, bool rfFlag)
|
||||
{
|
||||
m_do = doFlag;
|
||||
m_rf = rfFlag;
|
||||
}
|
||||
|
||||
void
|
||||
DestinationAddressUnit::SetDestSeqNumber(uint32_t dest_seq_number)
|
||||
{
|
||||
m_destSeqNumber = dest_seq_number;
|
||||
}
|
||||
void
|
||||
DestinationAddressUnit::SetDestinationAddress(Mac48Address dest_address)
|
||||
{
|
||||
m_destinationAddress = dest_address;
|
||||
}
|
||||
bool
|
||||
DestinationAddressUnit::IsDo()
|
||||
{
|
||||
return m_do;
|
||||
}
|
||||
|
||||
bool
|
||||
DestinationAddressUnit::IsRf()
|
||||
{
|
||||
return m_rf;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
DestinationAddressUnit::GetDestSeqNumber() const
|
||||
{
|
||||
return m_destSeqNumber;
|
||||
}
|
||||
Mac48Address
|
||||
DestinationAddressUnit::GetDestinationAddress() const
|
||||
{
|
||||
return m_destinationAddress;
|
||||
}
|
||||
/********************************
|
||||
* WifiPreqInformationElement
|
||||
*******************************/
|
||||
WifiPreqInformationElement::~WifiPreqInformationElement()
|
||||
{
|
||||
}
|
||||
|
||||
TypeId
|
||||
WifiPreqInformationElement::GetTypeId()
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::WifiPreqInformationElement")
|
||||
.SetParent<Object> ();
|
||||
return tid;
|
||||
}
|
||||
void
|
||||
WifiPreqInformationElement::Print(std::ostream &os) const
|
||||
{
|
||||
//TODO:fill this method
|
||||
}
|
||||
|
||||
TypeId
|
||||
WifiPreqInformationElement::GetInstanceTypeId(void) const
|
||||
{
|
||||
return GetTypeId();
|
||||
}
|
||||
|
||||
WifiPreqInformationElement::WifiPreqInformationElement()
|
||||
{
|
||||
m_flags = 0;
|
||||
m_hopCount = 0;
|
||||
m_ttl = 0;
|
||||
m_preqId = 0;
|
||||
m_lifetime = 0;
|
||||
m_originatorAddress = Mac48Address::GetBroadcast();
|
||||
m_originatorSeqNumber = 0;
|
||||
m_metric = 0;
|
||||
m_destCount = 0;
|
||||
m_maxSize = DEF_MAX_SIZE;
|
||||
}
|
||||
void
|
||||
WifiPreqInformationElement::SetUnicastPreq()
|
||||
{
|
||||
m_flags |= 1<<1;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPreqInformationElement::SetNeedNotPrep()
|
||||
{
|
||||
m_flags |= 1<<2;
|
||||
}
|
||||
//void
|
||||
//WifiPreqInformationElement::SetFlags(uint8_t flags)
|
||||
//{
|
||||
// m_flags = flags;
|
||||
//}
|
||||
void
|
||||
WifiPreqInformationElement::SetHopcount(uint8_t hopcount)
|
||||
{
|
||||
m_hopCount = hopcount;
|
||||
}
|
||||
void
|
||||
WifiPreqInformationElement::SetTTL(uint8_t ttl)
|
||||
{
|
||||
m_ttl = ttl;
|
||||
}
|
||||
void
|
||||
WifiPreqInformationElement::SetPreqID(uint32_t preq_id)
|
||||
{
|
||||
m_preqId = preq_id;
|
||||
}
|
||||
void
|
||||
WifiPreqInformationElement::SetMetric(uint32_t metric)
|
||||
{
|
||||
m_metric = metric;
|
||||
}
|
||||
void
|
||||
WifiPreqInformationElement::SetOriginatorAddress(Mac48Address originator_address)
|
||||
{
|
||||
m_originatorAddress = originator_address;
|
||||
}
|
||||
void
|
||||
WifiPreqInformationElement::SetOriginatorSeqNumber(uint32_t originator_seq_number)
|
||||
{
|
||||
m_originatorSeqNumber = originator_seq_number;
|
||||
}
|
||||
void
|
||||
WifiPreqInformationElement::SetLifetime(uint32_t lifetime)
|
||||
{
|
||||
m_lifetime = lifetime;
|
||||
}
|
||||
void
|
||||
WifiPreqInformationElement::SetDestCount(uint8_t dest_count)
|
||||
{
|
||||
m_destCount = dest_count;
|
||||
}
|
||||
|
||||
//uint8_t
|
||||
//WifiPreqInformationElement::GetFlags() const
|
||||
//{
|
||||
// return m_flags;
|
||||
//}
|
||||
bool
|
||||
WifiPreqInformationElement::IsUnicastPreq() const
|
||||
{
|
||||
return (m_flags & (1<<1));
|
||||
}
|
||||
|
||||
bool
|
||||
WifiPreqInformationElement::IsNeedNotPrep() const
|
||||
{
|
||||
return (m_flags & (1<<2));
|
||||
}
|
||||
|
||||
uint8_t
|
||||
WifiPreqInformationElement::GetHopCount() const
|
||||
{
|
||||
return m_hopCount;
|
||||
}
|
||||
uint8_t
|
||||
WifiPreqInformationElement::GetTtl() const
|
||||
{
|
||||
return m_ttl;
|
||||
}
|
||||
uint32_t
|
||||
WifiPreqInformationElement::GetPreqID() const
|
||||
{
|
||||
return m_preqId;
|
||||
}
|
||||
uint32_t
|
||||
WifiPreqInformationElement::GetMetric() const
|
||||
{
|
||||
return m_metric;
|
||||
}
|
||||
Mac48Address
|
||||
WifiPreqInformationElement::GetOriginatorAddress() const
|
||||
{
|
||||
return m_originatorAddress;
|
||||
}
|
||||
uint32_t
|
||||
WifiPreqInformationElement::GetOriginatorSeqNumber() const
|
||||
{
|
||||
return m_originatorSeqNumber;
|
||||
}
|
||||
uint32_t
|
||||
WifiPreqInformationElement::GetLifetime() const
|
||||
{
|
||||
return m_lifetime;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
WifiPreqInformationElement::GetDestCount() const
|
||||
{
|
||||
return m_destCount;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPreqInformationElement::DecrementTtl()
|
||||
{
|
||||
m_ttl --;
|
||||
m_hopCount ++;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPreqInformationElement::IncrementMetric(uint32_t metric)
|
||||
{
|
||||
m_metric +=metric;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPreqInformationElement::Serialize(Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteU8 (ELEMENT_ID);
|
||||
//TODO:Check maxsize
|
||||
uint8_t length = m_destCount*11+28;
|
||||
if(m_destCount> m_maxSize)
|
||||
length -=(m_destCount-m_maxSize)*11;
|
||||
i.WriteU8(length);
|
||||
i.WriteU8 (m_flags);
|
||||
i.WriteU8 (m_hopCount);
|
||||
i.WriteU8 (m_ttl);
|
||||
i.WriteHtonU32 (m_preqId);
|
||||
WriteTo(i, m_originatorAddress);
|
||||
i.WriteHtonU32 (m_originatorSeqNumber);
|
||||
i.WriteHtonU32 (m_lifetime);
|
||||
i.WriteHtonU32 (m_metric);
|
||||
i.WriteU8 (m_destCount);
|
||||
int written = 0;
|
||||
for (std::vector<Ptr<DestinationAddressUnit> >::const_iterator j = m_destinations.begin(); j!= m_destinations.end(); j++)
|
||||
{
|
||||
uint8_t flags = 0;
|
||||
if((*j)->IsDo())
|
||||
flags +=128;
|
||||
if((*j)->IsRf())
|
||||
flags +=64;
|
||||
i.WriteU8(flags);
|
||||
WriteTo(i,(*j)->GetDestinationAddress());
|
||||
i.WriteHtonU32 ((*j)->GetDestSeqNumber());
|
||||
written++;
|
||||
if (written > m_maxSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiPreqInformationElement::Deserialize(Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
uint8_t ElementId;
|
||||
ElementId = i.ReadU8();
|
||||
NS_ASSERT (ElementId == ELEMENT_ID);
|
||||
uint8_t length;
|
||||
length = i.ReadU8();
|
||||
m_flags = i.ReadU8();
|
||||
m_hopCount = i.ReadU8();
|
||||
m_ttl = i.ReadU8();
|
||||
m_preqId = i.ReadNtohU32();
|
||||
ReadFrom(i,m_originatorAddress);
|
||||
m_originatorSeqNumber = i.ReadNtohU32();
|
||||
m_lifetime = i.ReadNtohU32();
|
||||
m_metric = i.ReadNtohU32();
|
||||
m_destCount = i.ReadU8();
|
||||
for (int j = 0; j < m_destCount; j++ )
|
||||
{
|
||||
Ptr<DestinationAddressUnit> new_element = Create<DestinationAddressUnit>();
|
||||
bool doFlag = false;
|
||||
bool rfFlag = false;
|
||||
uint8_t flags = i.ReadU8();
|
||||
if(flags >= 128)
|
||||
{
|
||||
doFlag = true;
|
||||
flags -=128;
|
||||
}
|
||||
if(flags >=64)
|
||||
rfFlag = true;
|
||||
new_element->SetFlags(doFlag, rfFlag);
|
||||
Mac48Address addr;
|
||||
ReadFrom(i,addr);
|
||||
new_element->SetDestinationAddress(addr);
|
||||
new_element->SetDestSeqNumber(i.ReadNtohU32());
|
||||
m_destinations.push_back(new_element);
|
||||
NS_ASSERT(28+j*11 < length);
|
||||
}
|
||||
return i.GetDistanceFrom(start);
|
||||
}
|
||||
uint32_t
|
||||
WifiPreqInformationElement::GetSerializedSize() const
|
||||
{
|
||||
uint32_t retval =
|
||||
1 //Element ID
|
||||
+1 //Length
|
||||
+1 //Flags
|
||||
+1 //Hopcount
|
||||
+1 //TTL
|
||||
+4 //PREQ ID
|
||||
+6 //Source address (originator)
|
||||
+4 //Originator seqno
|
||||
+4 //Lifetime
|
||||
+4 //metric
|
||||
+1; //destination count
|
||||
if(m_destCount > m_maxSize)
|
||||
retval+=(m_maxSize*11);
|
||||
else
|
||||
retval +=(m_destCount*11);
|
||||
return retval;
|
||||
}
|
||||
std::vector<Ptr<DestinationAddressUnit> >
|
||||
WifiPreqInformationElement::GetDestinationList()
|
||||
{
|
||||
return m_destinations;
|
||||
}
|
||||
void
|
||||
WifiPreqInformationElement::AddDestinationAddressElement(
|
||||
bool doFlag, bool rfFlag,
|
||||
Mac48Address dest_address,
|
||||
uint32_t dest_seq_number
|
||||
)
|
||||
{
|
||||
for(std::vector<Ptr<DestinationAddressUnit> >::iterator i = m_destinations.begin(); i!=m_destinations.end(); i++ )
|
||||
if((*i)->GetDestinationAddress() == dest_address)
|
||||
return;
|
||||
Ptr<DestinationAddressUnit>new_element = Create<DestinationAddressUnit>();
|
||||
new_element->SetFlags(doFlag, rfFlag);
|
||||
new_element->SetDestinationAddress(dest_address);
|
||||
new_element->SetDestSeqNumber(dest_seq_number);
|
||||
m_destinations.push_back(new_element);
|
||||
m_destCount++;
|
||||
}
|
||||
|
||||
void
|
||||
WifiPreqInformationElement::DelDestinationAddressElement(Mac48Address dest_address)
|
||||
{
|
||||
for(std::vector<Ptr<DestinationAddressUnit> >::iterator i = m_destinations.begin(); i!=m_destinations.end(); i++ )
|
||||
if((*i)->GetDestinationAddress() == dest_address)
|
||||
{
|
||||
m_destinations.erase(i);
|
||||
m_destCount--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiPreqInformationElement::ClearDestinationAddressElement()
|
||||
{
|
||||
int i;
|
||||
for(std::vector<Ptr<DestinationAddressUnit> >::iterator j = m_destinations.begin(); j!= m_destinations.end(); j++)
|
||||
(*j) = 0;
|
||||
for(i = 0; i < m_destCount; i ++)
|
||||
m_destinations.pop_back();
|
||||
m_destinations.clear();
|
||||
};
|
||||
|
||||
}
|
||||
124
src/devices/wifi/mesh-wifi-preq-information-element.h
Normal file
124
src/devices/wifi/mesh-wifi-preq-information-element.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Yana Podkosova <yanapdk@rambler.ru>
|
||||
* Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WIFI_PREQ_INFORMATION_ELEMENT_H
|
||||
#define WIFI_PREQ_INFORMATION_ELEMENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/buffer.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/header.h"
|
||||
#include <vector>
|
||||
namespace ns3
|
||||
{
|
||||
class DestinationAddressUnit : public RefCountBase
|
||||
{
|
||||
public:
|
||||
DestinationAddressUnit();
|
||||
void SetFlags(bool doFlag, bool rfflag);
|
||||
//void SetPerDestFlags(uint8_t per_dest_flags);
|
||||
void SetDestinationAddress(Mac48Address dest_address);
|
||||
void SetDestSeqNumber(uint32_t dest_seq_number);
|
||||
bool IsDo();
|
||||
bool IsRf();
|
||||
Mac48Address GetDestinationAddress() const;
|
||||
uint32_t GetDestSeqNumber() const;
|
||||
|
||||
private:
|
||||
bool m_do;
|
||||
bool m_rf;
|
||||
Mac48Address m_destinationAddress;
|
||||
uint32_t m_destSeqNumber;
|
||||
};
|
||||
|
||||
class WifiPreqInformationElement : public Header
|
||||
{
|
||||
public:
|
||||
WifiPreqInformationElement();
|
||||
~WifiPreqInformationElement (void);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId(void) const;
|
||||
virtual void Print(std::ostream &os) const;
|
||||
void AddDestinationAddressElement(
|
||||
bool doFlag,
|
||||
bool rfFlag,
|
||||
Mac48Address dest_address,
|
||||
uint32_t dest_seq_number
|
||||
);
|
||||
void DelDestinationAddressElement(Mac48Address dest_address);
|
||||
void ClearDestinationAddressElement();
|
||||
std::vector<Ptr<DestinationAddressUnit> > GetDestinationList ();
|
||||
//void SetFlags(uint8_t flags);
|
||||
void SetUnicastPreq();
|
||||
/*
|
||||
* \brief In proactive case: need we send PREP
|
||||
*/
|
||||
void SetNeedNotPrep();
|
||||
void SetHopcount(uint8_t hopcount);
|
||||
void SetTTL(uint8_t ttl);
|
||||
void SetPreqID(uint32_t id);
|
||||
void SetOriginatorAddress(Mac48Address originator_address);
|
||||
void SetOriginatorSeqNumber(uint32_t originator_seq_number);
|
||||
void SetLifetime(uint32_t lifetime);
|
||||
void SetMetric(uint32_t metric);
|
||||
void SetDestCount(uint8_t dest_count);
|
||||
|
||||
virtual void Serialize(Buffer::Iterator i) const;
|
||||
virtual uint32_t Deserialize(Buffer::Iterator i);
|
||||
virtual uint32_t GetSerializedSize() const;
|
||||
|
||||
//uint8_t GetFlags() const ;
|
||||
bool IsUnicastPreq() const;
|
||||
bool IsNeedNotPrep() const;
|
||||
uint8_t GetHopCount() const;
|
||||
uint8_t GetTtl()const ;
|
||||
uint32_t GetPreqID() const;
|
||||
Mac48Address GetOriginatorAddress() const;
|
||||
uint32_t GetOriginatorSeqNumber() const;
|
||||
uint32_t GetLifetime() const;
|
||||
uint32_t GetMetric() const;
|
||||
uint8_t GetDestCount() const;
|
||||
void DecrementTtl();
|
||||
void IncrementMetric(uint32_t metric);
|
||||
|
||||
private:
|
||||
std::vector<Ptr<DestinationAddressUnit> >
|
||||
m_destinations;
|
||||
//how many destinations we support
|
||||
uint8_t m_maxSize;
|
||||
//Fields:
|
||||
uint8_t m_flags;
|
||||
uint8_t m_hopCount;
|
||||
uint8_t m_ttl;
|
||||
uint32_t m_preqId;
|
||||
Mac48Address m_originatorAddress;
|
||||
uint32_t m_originatorSeqNumber;
|
||||
uint32_t m_lifetime;
|
||||
uint32_t m_metric;
|
||||
uint8_t m_destCount;
|
||||
#define DEF_MAX_SIZE 32
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
#endif
|
||||
|
||||
164
src/devices/wifi/mesh-wifi-rann-information-element.cc
Normal file
164
src/devices/wifi/mesh-wifi-rann-information-element.cc
Normal file
@@ -0,0 +1,164 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Yana Podkosova <yanapdk@rambler.ru>
|
||||
* Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "mesh-wifi-rann-information-element.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/address-utils.h"
|
||||
#define ELEMENT_ID (20)
|
||||
|
||||
namespace ns3{
|
||||
|
||||
WifiRannInformationElement::~WifiRannInformationElement()
|
||||
{
|
||||
}
|
||||
TypeId
|
||||
WifiRannInformationElement::GetTypeId()
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::WifiRannInformationElement").SetParent<Object> ();
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
WifiRannInformationElement::GetInstanceTypeId(void) const
|
||||
{
|
||||
return GetTypeId();
|
||||
}
|
||||
void
|
||||
WifiRannInformationElement::Print(std::ostream &os)const
|
||||
{
|
||||
// FILL
|
||||
}
|
||||
WifiRannInformationElement::WifiRannInformationElement()
|
||||
{ m_flags = 0;
|
||||
m_hopcount = 0;
|
||||
m_ttl = 0;
|
||||
m_destSeqNumber = 0;
|
||||
m_metric = 0;
|
||||
m_originatorAddress = Mac48Address::GetBroadcast();
|
||||
m_destSeqNumber = 0;
|
||||
|
||||
}
|
||||
void
|
||||
WifiRannInformationElement::SetFlags(uint8_t flags)
|
||||
{
|
||||
m_flags = flags;
|
||||
}
|
||||
void
|
||||
WifiRannInformationElement::SetHopcount(uint8_t hopcount)
|
||||
{
|
||||
m_hopcount = hopcount;
|
||||
}
|
||||
void
|
||||
WifiRannInformationElement::SetTTL(uint8_t ttl)
|
||||
{
|
||||
m_ttl = ttl;
|
||||
}
|
||||
void
|
||||
WifiRannInformationElement::SetDestSeqNumber(uint32_t dest_seq_number)
|
||||
{
|
||||
m_destSeqNumber = dest_seq_number;
|
||||
}
|
||||
void
|
||||
WifiRannInformationElement::SetMetric(uint32_t metric)
|
||||
{
|
||||
m_metric = metric;
|
||||
}
|
||||
void
|
||||
WifiRannInformationElement::SetOriginatorAddress(Mac48Address originator_address)
|
||||
{
|
||||
m_originatorAddress = originator_address;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
WifiRannInformationElement::GetFlags()
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
uint8_t
|
||||
WifiRannInformationElement::GetHopcount()
|
||||
{
|
||||
return m_hopcount;
|
||||
}
|
||||
uint8_t
|
||||
WifiRannInformationElement::GetTTL()
|
||||
{
|
||||
return m_ttl;
|
||||
}
|
||||
uint32_t
|
||||
WifiRannInformationElement::GetDestSeqNumber()
|
||||
{
|
||||
return m_destSeqNumber;
|
||||
}
|
||||
uint32_t
|
||||
WifiRannInformationElement::GetMetric()
|
||||
{
|
||||
return m_metric;
|
||||
}
|
||||
Mac48Address
|
||||
WifiRannInformationElement::GetOriginatorAddress()
|
||||
{
|
||||
return m_originatorAddress;
|
||||
}
|
||||
void
|
||||
WifiRannInformationElement::Serialize(Buffer::Iterator i) const
|
||||
{
|
||||
i.WriteU8 (ELEMENT_ID);
|
||||
i.WriteU8 (21);//length = 21
|
||||
i.WriteU8 (m_flags);
|
||||
i.WriteU8 (m_hopcount);
|
||||
i.WriteU8 (m_ttl);
|
||||
WriteTo(i, m_originatorAddress);
|
||||
i.WriteHtonU32 (m_destSeqNumber);
|
||||
i.WriteHtonU32 (m_metric);
|
||||
}
|
||||
uint32_t
|
||||
WifiRannInformationElement::Deserialize(Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
uint8_t ElementId;
|
||||
ElementId = i.ReadU8();
|
||||
NS_ASSERT (ElementId == ELEMENT_ID);
|
||||
i.Next(1);// length is constant
|
||||
m_flags = i.ReadU8();
|
||||
m_hopcount = i.ReadU8();
|
||||
m_ttl = i.ReadU8();
|
||||
ReadFrom(i, m_originatorAddress);
|
||||
m_destSeqNumber = i.ReadNtohU32();
|
||||
m_metric = i.ReadNtohU32();
|
||||
return i.GetDistanceFrom(start);
|
||||
}
|
||||
uint32_t
|
||||
WifiRannInformationElement::GetSerializedSize() const
|
||||
{
|
||||
uint32_t retval =
|
||||
1//ElementId
|
||||
+1//Length
|
||||
+1//Flags
|
||||
+1//Hopcount
|
||||
+1//TTL
|
||||
+6//OriginatorAddress
|
||||
+4//DestSeqNumber
|
||||
+4;//Metric
|
||||
return retval;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
72
src/devices/wifi/mesh-wifi-rann-information-element.h
Normal file
72
src/devices/wifi/mesh-wifi-rann-information-element.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Yana Podkosova <yanapdk@rambler.ru>
|
||||
* Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef RANN_INFORMATION_ELEMENT_H
|
||||
#define RANN_INFORMATION_ELEMENT_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/buffer.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/header.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
class WifiRannInformationElement
|
||||
{
|
||||
public:
|
||||
WifiRannInformationElement();
|
||||
virtual ~WifiRannInformationElement();
|
||||
static TypeId GetTypeId(void);
|
||||
virtual TypeId GetInstanceTypeId(void) const;
|
||||
virtual void Print(std::ostream &os) const;
|
||||
void SetFlags(uint8_t flags);
|
||||
void SetHopcount(uint8_t hopcount);
|
||||
void SetTTL(uint8_t ttl);
|
||||
void SetOriginatorAddress(Mac48Address originator_address);
|
||||
void SetDestSeqNumber(uint32_t dest_seq_number);
|
||||
void SetMetric(uint32_t metric);
|
||||
virtual void Serialize(Buffer::Iterator i) const;
|
||||
virtual uint32_t Deserialize(Buffer::Iterator start);
|
||||
virtual uint32_t GetSerializedSize() const;
|
||||
uint8_t GetFlags();
|
||||
uint8_t GetHopcount();
|
||||
uint8_t GetTTL();
|
||||
Mac48Address GetOriginatorAddress();
|
||||
uint32_t GetDestSeqNumber();
|
||||
uint32_t GetMetric();
|
||||
|
||||
void DecrementTtl();
|
||||
void IncrementMetric(uint32_t metric);
|
||||
|
||||
private:
|
||||
uint8_t m_flags;
|
||||
uint8_t m_hopcount;
|
||||
uint8_t m_ttl;
|
||||
Mac48Address m_originatorAddress;
|
||||
uint32_t m_destSeqNumber;
|
||||
uint32_t m_metric;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "mgt-headers.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/log.h"
|
||||
NS_LOG_COMPONENT_DEFINE("MgtHeaders");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -109,6 +111,11 @@ MgtProbeResponseHeader::MgtProbeResponseHeader ()
|
||||
MgtProbeResponseHeader::~MgtProbeResponseHeader ()
|
||||
{}
|
||||
|
||||
uint64_t
|
||||
MgtProbeResponseHeader::GetTimestamp()
|
||||
{
|
||||
return m_timestamp;
|
||||
}
|
||||
Ssid
|
||||
MgtProbeResponseHeader::GetSsid (void) const
|
||||
{
|
||||
@@ -198,7 +205,7 @@ uint32_t
|
||||
MgtProbeResponseHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
i.Next (8); // timestamp
|
||||
m_timestamp = i.ReadNtohU64();
|
||||
m_beaconInterval = i.ReadNtohU16 ();
|
||||
m_beaconInterval *= 1024;
|
||||
i = m_capability.Deserialize (i);
|
||||
@@ -207,6 +214,71 @@ MgtProbeResponseHeader::Deserialize (Buffer::Iterator start)
|
||||
//i.Next (3); // ds parameter set
|
||||
return i.GetDistanceFrom (start);
|
||||
}
|
||||
/***********************************************************
|
||||
* Mesh Beacon
|
||||
***********************************************************/
|
||||
void
|
||||
MgtMeshBeaconHeader::SetMeshConfigurationElement(MeshConfigurationElement mesh_config)
|
||||
{
|
||||
m_meshConfig = mesh_config;
|
||||
}
|
||||
|
||||
void
|
||||
MgtMeshBeaconHeader::SetWifiBeaconTimingElement(WifiBeaconTimingElement wifi_timing)
|
||||
{
|
||||
m_meshTiming = wifi_timing;
|
||||
}
|
||||
|
||||
MeshConfigurationElement
|
||||
MgtMeshBeaconHeader::GetMeshConfigurationElement()
|
||||
{
|
||||
return m_meshConfig;
|
||||
}
|
||||
|
||||
WifiBeaconTimingElement
|
||||
MgtMeshBeaconHeader::GetWifiBeaconTimingElement()
|
||||
{
|
||||
return m_meshTiming;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
MgtMeshBeaconHeader::GetSerializedSize (void) const
|
||||
{
|
||||
uint32_t size = (
|
||||
MgtBeaconHeader::GetSerializedSize()
|
||||
+ m_meshConfig.GetSerializedSize()
|
||||
+ m_meshTiming.GetSerializedSize()
|
||||
+ 9 //MSCIE
|
||||
);
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
MgtMeshBeaconHeader::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
//First we pack Beacon:
|
||||
NS_LOG_DEBUG("Serialization beacon");
|
||||
Buffer::Iterator i = start;
|
||||
MgtBeaconHeader::Serialize(i);
|
||||
i.Next(MgtBeaconHeader::GetSerializedSize());
|
||||
i = m_meshConfig.Serialize(i);
|
||||
i = m_meshTiming.Serialize(i);
|
||||
i.Next(9); //MSCIE
|
||||
}
|
||||
|
||||
uint32_t
|
||||
MgtMeshBeaconHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
NS_LOG_DEBUG("Deserialization beacon");
|
||||
Buffer::Iterator i = start;
|
||||
MgtBeaconHeader::Deserialize(start);
|
||||
i.Next(MgtBeaconHeader::GetSerializedSize());
|
||||
i = m_meshConfig.Deserialize(i);
|
||||
i = m_meshTiming.Deserialize(i);
|
||||
i.Next(9); //MSCIE
|
||||
return i.GetDistanceFrom (start);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************
|
||||
* Assoc Request
|
||||
|
||||
@@ -21,11 +21,14 @@
|
||||
#define MGT_HEADERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include "ns3/header.h"
|
||||
#include "status-code.h"
|
||||
#include "capability-information.h"
|
||||
#include "supported-rates.h"
|
||||
#include "mesh-configuration-element.h"
|
||||
#include "mesh-wifi-beacon-timing-element.h"
|
||||
#include "ssid.h"
|
||||
|
||||
namespace ns3 {
|
||||
@@ -117,6 +120,8 @@ public:
|
||||
void SetBeaconIntervalUs (uint64_t us);
|
||||
void SetSupportedRates (SupportedRates rates);
|
||||
|
||||
uint64_t GetTimestamp();
|
||||
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
@@ -125,6 +130,7 @@ public:
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
private:
|
||||
uint64_t m_timestamp;
|
||||
Ssid m_ssid;
|
||||
uint64_t m_beaconInterval;
|
||||
SupportedRates m_rates;
|
||||
@@ -132,6 +138,22 @@ private:
|
||||
};
|
||||
|
||||
class MgtBeaconHeader : public MgtProbeResponseHeader {};
|
||||
class MgtMeshBeaconHeader : public MgtBeaconHeader
|
||||
{
|
||||
public:
|
||||
void SetMeshConfigurationElement(MeshConfigurationElement mesh_config);
|
||||
void SetWifiBeaconTimingElement(WifiBeaconTimingElement wifi_timing);
|
||||
MeshConfigurationElement GetMeshConfigurationElement();
|
||||
WifiBeaconTimingElement GetWifiBeaconTimingElement();
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
private:
|
||||
MeshConfigurationElement m_meshConfig;
|
||||
WifiBeaconTimingElement m_meshTiming;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
186
src/devices/wifi/tx-statistics.cc
Normal file
186
src/devices/wifi/tx-statistics.cc
Normal file
@@ -0,0 +1,186 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "ns3/tx-statistics.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("WifiTxStatistics");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
TypeId
|
||||
WifiTxStatistics::GetTypeId(void)
|
||||
{
|
||||
static TypeId tid = TypeId("ns3::WifiTxStatistics")
|
||||
.SetParent<Object> ()
|
||||
.AddConstructor<WifiTxStatistics> ();
|
||||
return tid;
|
||||
}
|
||||
WifiTxStatistics::WifiTxStatistics():
|
||||
m_numOfGroups(10),
|
||||
m_maxLength(2500)
|
||||
{
|
||||
}
|
||||
WifiTxStatistics::~WifiTxStatistics()
|
||||
{
|
||||
}
|
||||
void
|
||||
WifiTxStatistics::SetLengthDivisionParams(uint16_t maxLength, uint8_t numOfGroups)
|
||||
{
|
||||
|
||||
}
|
||||
void
|
||||
WifiTxStatistics::NotifyDataSent(uint16_t length, uint32_t dataRate)
|
||||
{
|
||||
m_currentSize = length;
|
||||
m_currentRate = dataRate;
|
||||
}
|
||||
|
||||
WifiTxStatistics::RATE_STAT::iterator
|
||||
WifiTxStatistics::FillCurrentStatPosition(uint16_t length, uint32_t dataRate)
|
||||
{
|
||||
uint16_t group = (length/(m_maxLength/m_numOfGroups)+1)* (m_maxLength/m_numOfGroups);
|
||||
#if 0
|
||||
for(RATE_LENGTH_STAT::iterator i = m_stats.begin(); i != m_stats.end(); i ++)
|
||||
if(i->first == )
|
||||
#endif
|
||||
RATE_LENGTH_STAT::iterator lengthPos = m_stats.find(group);
|
||||
if(lengthPos == m_stats.end())
|
||||
{
|
||||
RATE_STAT newStat;
|
||||
m_stats[group] = newStat;
|
||||
}
|
||||
lengthPos = m_stats.find(group);
|
||||
NS_ASSERT(lengthPos != m_stats.end());
|
||||
RATE_STAT::iterator ratePos = lengthPos->second.find(dataRate);
|
||||
if(ratePos == lengthPos->second.end())
|
||||
{
|
||||
SIMPLE_STAT newStat;
|
||||
newStat.packetsFailed =0;
|
||||
newStat.packetsRetried = 0;
|
||||
newStat.packetsAcked = 0;
|
||||
newStat.rtsFailed = 0;
|
||||
newStat.rtsRetried = 0;
|
||||
newStat.rtsAcked = 0;
|
||||
newStat.bytesFailed = 0;
|
||||
newStat.bytesRetried = 0;
|
||||
newStat.bytesAcked = 0;
|
||||
lengthPos->second[dataRate] = newStat;
|
||||
}
|
||||
ratePos = lengthPos->second.find(dataRate);
|
||||
NS_ASSERT(ratePos != lengthPos->second.end());
|
||||
return ratePos;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::NotifyDataFailed()
|
||||
{
|
||||
RATE_STAT::iterator ratePos = FillCurrentStatPosition(m_currentSize, m_currentRate);
|
||||
ratePos->second.packetsFailed++;
|
||||
ratePos->second.bytesFailed += m_currentSize;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::NotifyGotAck(uint32_t retryCounter)
|
||||
{
|
||||
RATE_STAT::iterator ratePos = FillCurrentStatPosition(m_currentSize, m_currentRate);
|
||||
ratePos->second.packetsAcked++;
|
||||
ratePos->second.packetsRetried += retryCounter;
|
||||
ratePos->second.bytesAcked+= m_currentSize;
|
||||
ratePos->second.bytesRetried += (m_currentSize*retryCounter);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::NotifyRtsSend(uint32_t rtsRate, uint32_t dataLength)
|
||||
{
|
||||
m_currentSize = dataLength;
|
||||
m_currentRate = rtsRate;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::NotifyRtsFailed()
|
||||
{
|
||||
RATE_STAT::iterator ratePos = FillCurrentStatPosition(m_currentSize, m_currentRate);
|
||||
ratePos->second.rtsFailed++;
|
||||
ratePos->second.bytesFailed += m_currentSize;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::NotifyRtsSuccess(uint32_t retryCounter)
|
||||
{
|
||||
RATE_STAT::iterator ratePos = FillCurrentStatPosition(m_currentSize, m_currentRate);
|
||||
ratePos->second.rtsAcked++;
|
||||
ratePos->second.rtsRetried += retryCounter;
|
||||
ratePos->second.bytesAcked += m_currentSize;
|
||||
ratePos->second.bytesRetried += (m_currentSize*retryCounter);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTxStatistics::ResetStatistics()
|
||||
{
|
||||
for(RATE_LENGTH_STAT::iterator lengthPos = m_stats.begin(); lengthPos != m_stats.end(); lengthPos++)
|
||||
lengthPos->second.clear();
|
||||
}
|
||||
#if 0
|
||||
WifiTxStatistics::SIMPLE_STAT
|
||||
WifiTxStatistics::GetTxStatCommon()
|
||||
{
|
||||
}
|
||||
|
||||
WifiTxStatistics::RATE_STAT
|
||||
WifiTxStatistics::GetTxStatRate()
|
||||
{
|
||||
}
|
||||
|
||||
WifiTxStatistics::LENGTH_STAT
|
||||
WifiTxStatistics::GetTxStatLength()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
WifiTxStatistics::TX_STATISTICS
|
||||
WifiTxStatistics::GetTxStatRateLength()
|
||||
{
|
||||
TX_STATISTICS retval;
|
||||
retval.statistics = m_stats;
|
||||
retval.lengthInterval = m_maxLength / m_numOfGroups;
|
||||
retval.maxLength = m_maxLength;
|
||||
return retval;
|
||||
}
|
||||
#if 0
|
||||
void
|
||||
WifiTxStatistics::Print()
|
||||
{
|
||||
for(RATE_LENGTH_STAT::iterator lengthPos = m_stats.begin(); lengthPos != m_stats.end(); lengthPos++)
|
||||
{
|
||||
NS_LOG_UNCOND("\tGROUP = " <<lengthPos->first);
|
||||
for(RATE_STAT::iterator ratePos = lengthPos->second.begin(); ratePos != lengthPos->second.end(); ratePos ++)
|
||||
{
|
||||
NS_LOG_UNCOND("Rate is "<<ratePos->first
|
||||
<<": SUCCESS = "<<ratePos->second.packetsAcked
|
||||
<<", RRETRY = " <<ratePos->second.packetsRetried
|
||||
<<", FAILURE = "<<ratePos->second.packetsFailed);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} //namespace ns3
|
||||
104
src/devices/wifi/tx-statistics.h
Normal file
104
src/devices/wifi/tx-statistics.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TX_STAT_H
|
||||
#define TX_STAT_H
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/traced-value.h"
|
||||
#include "wifi-mode.h"
|
||||
|
||||
namespace ns3 {
|
||||
class WifiTxStatistics : public Object
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId(void);
|
||||
WifiTxStatistics();
|
||||
~WifiTxStatistics();
|
||||
|
||||
struct TxStat
|
||||
{
|
||||
/**
|
||||
* Packet counters:
|
||||
*/
|
||||
uint32_t packetsFailed;
|
||||
uint32_t packetsRetried;
|
||||
uint32_t packetsAcked;
|
||||
/**
|
||||
* RTS counters:
|
||||
*/
|
||||
uint32_t rtsFailed;
|
||||
uint32_t rtsRetried;
|
||||
uint32_t rtsAcked;
|
||||
/**
|
||||
* Byte counters:
|
||||
*/
|
||||
uint64_t bytesFailed;
|
||||
uint64_t bytesRetried;
|
||||
uint64_t bytesAcked;
|
||||
};
|
||||
typedef struct TxStat SIMPLE_STAT;
|
||||
typedef std::map<uint32_t, SIMPLE_STAT> RATE_STAT;
|
||||
#if 0
|
||||
typedef std::map<uint16_t, SIMPLE_STAT> LENGTH_STAT;
|
||||
#endif
|
||||
typedef std::map<uint16_t, RATE_STAT> RATE_LENGTH_STAT;
|
||||
|
||||
void SetLengthDivisionParams(uint16_t maxLength, uint8_t numOfGroups);
|
||||
|
||||
void NotifyDataSent(uint16_t length, uint32_t dataRate);
|
||||
void NotifyDataFailed();
|
||||
void NotifyGotAck(uint32_t retryCounter);
|
||||
|
||||
void NotifyRtsSend(uint32_t rtsRate, uint32_t dataLength);
|
||||
void NotifyRtsRetried();
|
||||
void NotifyRtsFailed();
|
||||
void NotifyRtsSuccess(uint32_t retryCounter);
|
||||
|
||||
void ResetStatistics();
|
||||
#if 0
|
||||
SIMPLE_STAT GetTxStatCommon();
|
||||
RATE_STAT GetTxStatRate();
|
||||
LENGTH_STAT GetTxStatLength();
|
||||
#endif
|
||||
typedef struct {
|
||||
RATE_LENGTH_STAT statistics;
|
||||
uint16_t lengthInterval;
|
||||
uint16_t maxLength;
|
||||
} TX_STATISTICS;
|
||||
TX_STATISTICS GetTxStatRateLength();
|
||||
private:
|
||||
RATE_STAT::iterator FillCurrentStatPosition(uint16_t length, uint32_t dataRate);
|
||||
//DEBUG PURPOSE
|
||||
//void Print();
|
||||
RATE_LENGTH_STAT m_stats;
|
||||
bool m_isTx;
|
||||
uint8_t m_numOfGroups;
|
||||
uint16_t m_maxLength;
|
||||
uint16_t m_currentSize;
|
||||
uint32_t m_currentRate;
|
||||
};
|
||||
} //namespace ns3
|
||||
#endif
|
||||
@@ -125,6 +125,13 @@ WifiMacHeader::SetTypeData (void)
|
||||
m_ctrlType = TYPE_DATA;
|
||||
m_ctrlSubtype = 0;
|
||||
}
|
||||
void
|
||||
WifiMacHeader::SetMultihopAction (void)
|
||||
{
|
||||
m_ctrlType = TYPE_MGT;
|
||||
m_ctrlSubtype = 15;
|
||||
}
|
||||
|
||||
void
|
||||
WifiMacHeader::SetType (enum WifiMacType_e type)
|
||||
{
|
||||
@@ -188,6 +195,9 @@ WifiMacHeader::SetType (enum WifiMacType_e type)
|
||||
case WIFI_MAC_MGT_DEAUTHENTICATION:
|
||||
m_ctrlType = TYPE_MGT;
|
||||
m_ctrlSubtype = 12;
|
||||
case WIFI_MAC_MGT_MULTIHOP_ACTION:
|
||||
m_ctrlType = TYPE_MGT;
|
||||
m_ctrlSubtype = 15;
|
||||
break;
|
||||
|
||||
case WIFI_MAC_DATA:
|
||||
@@ -360,6 +370,9 @@ WifiMacHeader::GetType (void) const
|
||||
case 12:
|
||||
return WIFI_MAC_MGT_DEAUTHENTICATION;
|
||||
break;
|
||||
case 15:
|
||||
return WIFI_MAC_MGT_MULTIHOP_ACTION;
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
@@ -553,6 +566,11 @@ WifiMacHeader::IsDeauthentication (void) const
|
||||
{
|
||||
return (GetType () == WIFI_MAC_MGT_DEAUTHENTICATION)?true:false;
|
||||
}
|
||||
bool
|
||||
WifiMacHeader::IsMultihopAction (void) const
|
||||
{
|
||||
return (GetType () == WIFI_MAC_MGT_MULTIHOP_ACTION)?true:false;
|
||||
}
|
||||
|
||||
|
||||
uint16_t
|
||||
@@ -861,6 +879,7 @@ WifiMacHeader::Print (std::ostream &os) const
|
||||
case WIFI_MAC_QOSDATA_NULL:
|
||||
case WIFI_MAC_QOSDATA_NULL_CFPOLL:
|
||||
case WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL:
|
||||
case WIFI_MAC_MGT_MULTIHOP_ACTION:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -961,4 +980,338 @@ WifiMacHeader::Deserialize (Buffer::Iterator start)
|
||||
return i.GetDistanceFrom (start);
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
* Here Mesh Mac Header functionality is defined.
|
||||
***********************************************************/
|
||||
TypeId
|
||||
WifiMeshHeader::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::WifiMeshHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<WifiMeshHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
WifiMeshHeader::WifiMeshHeader()
|
||||
{
|
||||
m_meshFlags = 0;
|
||||
}
|
||||
|
||||
WifiMeshHeader::~WifiMeshHeader()
|
||||
{
|
||||
}
|
||||
|
||||
TypeId
|
||||
WifiMeshHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
void
|
||||
WifiMeshHeader::SetAddr5 (Mac48Address address)
|
||||
{
|
||||
m_addr5 = address;
|
||||
}
|
||||
|
||||
void
|
||||
WifiMeshHeader::SetAddr6 (Mac48Address address)
|
||||
{
|
||||
m_addr6 = address;
|
||||
}
|
||||
|
||||
void
|
||||
WifiMeshHeader::SetAddr7 (Mac48Address address)
|
||||
{
|
||||
m_addr7 = address;
|
||||
}
|
||||
|
||||
Mac48Address
|
||||
WifiMeshHeader::GetAddr5 ()
|
||||
{
|
||||
return m_addr5;
|
||||
}
|
||||
|
||||
Mac48Address
|
||||
WifiMeshHeader::GetAddr6 ()
|
||||
{
|
||||
return m_addr6;
|
||||
}
|
||||
|
||||
Mac48Address
|
||||
WifiMeshHeader::GetAddr7 ()
|
||||
{
|
||||
return m_addr7;
|
||||
}
|
||||
|
||||
void
|
||||
WifiMeshHeader::SetMeshSeqno (uint32_t seqno)
|
||||
{
|
||||
m_meshSeqno = seqno;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiMeshHeader::GetMeshSeqno ()
|
||||
{
|
||||
return m_meshSeqno;
|
||||
}
|
||||
|
||||
void
|
||||
WifiMeshHeader::SetMeshTtl (uint8_t TTL)
|
||||
{
|
||||
m_meshTtl = TTL;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
WifiMeshHeader::GetMeshTtl ()
|
||||
{
|
||||
return m_meshTtl;
|
||||
}
|
||||
|
||||
void
|
||||
WifiMeshHeader::SetAddressExt (uint8_t num_of_addresses)
|
||||
{
|
||||
if (num_of_addresses > 3)
|
||||
return;
|
||||
m_meshFlags = MESH_AE_MASK| (num_of_addresses << MESH_AE_SHIFT);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
WifiMeshHeader::GetAddressExt ()
|
||||
{
|
||||
return ((MESH_AE_MASK & m_meshFlags) >> MESH_AE_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
WifiMeshHeader::GetSerializedSize (void) const
|
||||
{
|
||||
return 6 + ((MESH_AE_MASK & m_meshFlags) >> MESH_AE_SHIFT)*6;
|
||||
}
|
||||
|
||||
void
|
||||
WifiMeshHeader::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
i.WriteU8(m_meshFlags);
|
||||
i.WriteU8(m_meshTtl);
|
||||
i.WriteU32(m_meshSeqno);
|
||||
uint8_t addresses_to_add = (m_meshFlags & MESH_AE_MASK) >> MESH_AE_SHIFT;
|
||||
//Writing Address extensions:
|
||||
if(addresses_to_add > 0)
|
||||
WriteTo (i, m_addr5);
|
||||
if(addresses_to_add > 1)
|
||||
WriteTo (i, m_addr6);
|
||||
if(addresses_to_add > 2)
|
||||
WriteTo (i, m_addr7);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiMeshHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
uint8_t addresses_to_read = 0;
|
||||
m_meshFlags = i.ReadU8();
|
||||
m_meshTtl = i.ReadU8();
|
||||
m_meshSeqno = i.ReadU32();
|
||||
addresses_to_read = (m_meshFlags & MESH_AE_MASK) >> MESH_AE_SHIFT;
|
||||
if(addresses_to_read > 0)
|
||||
ReadFrom (i, m_addr5);
|
||||
if(addresses_to_read > 1)
|
||||
ReadFrom (i, m_addr6);
|
||||
if(addresses_to_read > 2)
|
||||
ReadFrom (i, m_addr7);
|
||||
return i.GetDistanceFrom(start);
|
||||
}
|
||||
void
|
||||
WifiMeshHeader::Print (std::ostream &os) const
|
||||
{
|
||||
os << "flags" << m_meshFlags
|
||||
<< "ttl" << m_meshTtl
|
||||
<< "seqno" << m_meshSeqno;
|
||||
}
|
||||
/**********************************************************
|
||||
* MultihopActionFrame
|
||||
**********************************************************/
|
||||
WifiMeshMultihopActionHeader::WifiMeshMultihopActionHeader ()
|
||||
{
|
||||
}
|
||||
|
||||
WifiMeshMultihopActionHeader::~WifiMeshMultihopActionHeader ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WifiMeshMultihopActionHeader::SetAction(
|
||||
enum WifiMeshMultihopActionHeader::CategoryValue type,
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE action)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case MESH_PEER_LINK_MGT:
|
||||
m_category = 4;
|
||||
switch (action.peerLink)
|
||||
{
|
||||
case PEER_LINK_OPEN:
|
||||
m_actionValue = 0;
|
||||
break;
|
||||
case PEER_LINK_CONFIRM:
|
||||
m_actionValue = 1;
|
||||
break;
|
||||
case PEER_LINK_CLOSE:
|
||||
m_actionValue = 2;
|
||||
break;
|
||||
};
|
||||
break;
|
||||
case MESH_LINK_METRIC:
|
||||
m_category = 5;
|
||||
break;
|
||||
case MESH_PATH_SELECTION:
|
||||
m_category = 6;
|
||||
switch(action.pathSelection)
|
||||
{
|
||||
case PATH_REQUEST:
|
||||
m_actionValue = 0;
|
||||
break;
|
||||
case PATH_REPLY:
|
||||
m_actionValue = 1;
|
||||
break;
|
||||
case PATH_ERROR:
|
||||
m_actionValue = 2;
|
||||
break;
|
||||
case ROOT_ANNOUNCEMENT:
|
||||
m_actionValue = 3;
|
||||
break;
|
||||
};
|
||||
break;
|
||||
case MESH_INTERWORK_ACTION:
|
||||
m_category = 7;
|
||||
break;
|
||||
case MESH_RESOURCE_COORDINATION:
|
||||
m_category = 8;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
enum WifiMeshMultihopActionHeader::CategoryValue
|
||||
WifiMeshMultihopActionHeader::GetCategory()
|
||||
{
|
||||
switch(m_category)
|
||||
{
|
||||
case 4:
|
||||
return MESH_PEER_LINK_MGT;
|
||||
case 5:
|
||||
return MESH_LINK_METRIC;
|
||||
case 6:
|
||||
return MESH_PATH_SELECTION;
|
||||
case 7:
|
||||
return MESH_INTERWORK_ACTION;
|
||||
case 8:
|
||||
return MESH_RESOURCE_COORDINATION;
|
||||
default:
|
||||
NS_ASSERT(false);
|
||||
return MESH_PEER_LINK_MGT;
|
||||
}
|
||||
}
|
||||
|
||||
WifiMeshMultihopActionHeader::ACTION_VALUE
|
||||
WifiMeshMultihopActionHeader::GetAction()
|
||||
{
|
||||
ACTION_VALUE retval;
|
||||
switch(m_category)
|
||||
{
|
||||
case 4:
|
||||
//MESH_PEER_LINK_MGT;
|
||||
switch(m_actionValue)
|
||||
{
|
||||
case 0:
|
||||
retval.peerLink = PEER_LINK_OPEN;
|
||||
return retval;
|
||||
case 1:
|
||||
retval.peerLink = PEER_LINK_CONFIRM;
|
||||
return retval;
|
||||
case 2:
|
||||
retval.peerLink = PEER_LINK_CLOSE;
|
||||
return retval;
|
||||
default:
|
||||
NS_ASSERT(false);
|
||||
return retval;
|
||||
|
||||
}
|
||||
case 5:
|
||||
//MESH_LINK_METRIC;
|
||||
case 6:
|
||||
//MESH_PATH_SELECTION;
|
||||
switch(m_actionValue)
|
||||
{
|
||||
case 0:
|
||||
retval.pathSelection = PATH_REQUEST;
|
||||
return retval;
|
||||
case 1:
|
||||
retval.pathSelection = PATH_REPLY;
|
||||
return retval;
|
||||
case 2:
|
||||
retval.pathSelection = PATH_ERROR;
|
||||
return retval;
|
||||
case 3:
|
||||
retval.pathSelection = ROOT_ANNOUNCEMENT;
|
||||
return retval;
|
||||
default:
|
||||
NS_ASSERT(false);
|
||||
return retval;
|
||||
}
|
||||
|
||||
case 7:
|
||||
//MESH_INTERWORK_ACTION;
|
||||
case 8:
|
||||
//MESH_RESOURCE_COORDINATION;
|
||||
default:
|
||||
NS_ASSERT(false);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
TypeId
|
||||
WifiMeshMultihopActionHeader::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::WifiMeshMultihopActionHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<WifiMeshMultihopActionHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
TypeId
|
||||
WifiMeshMultihopActionHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId();
|
||||
}
|
||||
|
||||
void
|
||||
WifiMeshMultihopActionHeader::Print (std::ostream &os) const
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiMeshMultihopActionHeader::GetSerializedSize (void) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
void
|
||||
WifiMeshMultihopActionHeader::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
start.WriteU8(m_category);
|
||||
start.WriteU8(m_actionValue);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiMeshMultihopActionHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
m_category = i.ReadU8();
|
||||
m_actionValue = i.ReadU8();
|
||||
return i.GetDistanceFrom(start);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -44,6 +44,8 @@ enum WifiMacType_e {
|
||||
WIFI_MAC_MGT_PROBE_RESPONSE,
|
||||
WIFI_MAC_MGT_AUTHENTICATION,
|
||||
WIFI_MAC_MGT_DEAUTHENTICATION,
|
||||
//Mesh management frames:
|
||||
WIFI_MAC_MGT_MULTIHOP_ACTION,
|
||||
|
||||
WIFI_MAC_DATA,
|
||||
WIFI_MAC_DATA_CFACK,
|
||||
@@ -83,6 +85,7 @@ public:
|
||||
void SetProbeResp (void);
|
||||
void SetBeacon (void);
|
||||
void SetTypeData (void);
|
||||
void SetMultihopAction();
|
||||
void SetDsFrom (void);
|
||||
void SetDsNotFrom (void);
|
||||
void SetDsTo (void);
|
||||
@@ -129,6 +132,7 @@ public:
|
||||
bool IsDisassociation (void) const;
|
||||
bool IsAuthentication (void) const;
|
||||
bool IsDeauthentication (void) const;
|
||||
bool IsMultihopAction(void) const;
|
||||
uint16_t GetRawDuration (void) const;
|
||||
Time GetDuration (void) const;
|
||||
uint16_t GetSequenceControl (void) const;
|
||||
@@ -176,7 +180,120 @@ private:
|
||||
uint8_t m_qosAckPolicy;
|
||||
uint16_t m_qosStuff;
|
||||
};
|
||||
class WifiMeshHeader : public Header //7.1.3.5b
|
||||
{
|
||||
public:
|
||||
WifiMeshHeader ();
|
||||
~WifiMeshHeader ();
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
|
||||
void SetAddr5 (Mac48Address address);
|
||||
void SetAddr6 (Mac48Address address);
|
||||
void SetAddr7 (Mac48Address address);
|
||||
Mac48Address GetAddr5 ();
|
||||
Mac48Address GetAddr6 ();
|
||||
Mac48Address GetAddr7 ();
|
||||
|
||||
void SetMeshSeqno (uint32_t seqno);
|
||||
uint32_t GetMeshSeqno ();
|
||||
|
||||
void SetMeshTtl (uint8_t TTL);
|
||||
uint8_t GetMeshTtl ();
|
||||
|
||||
#define MESH_AE_MASK 0xc0
|
||||
#define MESH_AE_SHIFT 6
|
||||
void SetAddressExt (uint8_t num_of_addresses);
|
||||
uint8_t GetAddressExt ();
|
||||
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
private:
|
||||
uint8_t m_meshFlags;
|
||||
uint8_t m_meshTtl;
|
||||
uint32_t m_meshSeqno;
|
||||
Mac48Address m_addr5;
|
||||
Mac48Address m_addr6;
|
||||
Mac48Address m_addr7;
|
||||
};
|
||||
class WifiMeshMultihopActionHeader : public Header //7.2.3.14
|
||||
{
|
||||
//Multichop action frame consists of Mesh header, Action, and
|
||||
//the last information. Mesh header is present within all data
|
||||
//frames and multihop action frames, so Mesh header is a
|
||||
//separate structure. Each MultihopAction frames (frames like
|
||||
//PREQ, PREP and other) start form Category field and Action
|
||||
//value field, so the Multihop Action Frame should containt
|
||||
//three fields: Category, Action Value;
|
||||
public:
|
||||
WifiMeshMultihopActionHeader ();
|
||||
~WifiMeshMultihopActionHeader ();
|
||||
enum CategoryValue //table 7-24 staring from 4
|
||||
{
|
||||
MESH_PEER_LINK_MGT =4,
|
||||
MESH_LINK_METRIC,
|
||||
MESH_PATH_SELECTION,
|
||||
MESH_INTERWORK_ACTION,
|
||||
MESH_RESOURCE_COORDINATION,
|
||||
};
|
||||
enum PeerLinkMgtActionValue
|
||||
{
|
||||
PEER_LINK_OPEN = 0,
|
||||
PEER_LINK_CONFIRM,
|
||||
PEER_LINK_CLOSE,
|
||||
};
|
||||
enum LinkMetricActionValue
|
||||
{
|
||||
LINK_METRIC_REQUEST = 0,
|
||||
LINK_METRIC_REPORT,
|
||||
};
|
||||
enum PathSelectionActionValue
|
||||
{
|
||||
PATH_REQUEST = 0,
|
||||
PATH_REPLY,
|
||||
PATH_ERROR,
|
||||
ROOT_ANNOUNCEMENT,
|
||||
};
|
||||
enum InterworkActionValue
|
||||
{
|
||||
PORTAL_ANNOUNCEMENT = 0,
|
||||
};
|
||||
enum ResourceCoordinationActionValue
|
||||
{
|
||||
CONGESTION_CONTROL_NOTIFICATION = 0,
|
||||
MDA_SETUP_REQUEST,
|
||||
MDA_SETUP_REPLY,
|
||||
MDAOP_ADVERTISMENT_REQUEST,
|
||||
MDAOP_ADVERTISMENTS,
|
||||
MDAOP_SET_TEARDOWN,
|
||||
BEACON_TIMING_REQUEST,
|
||||
BEACON_TIMING_RESPONSE,
|
||||
TBTT_ADJASTMENT_REQUEST,
|
||||
MESH_CHANNEL_SWITCH_ANNOUNCEMENT,
|
||||
};
|
||||
typedef union
|
||||
{
|
||||
enum PeerLinkMgtActionValue peerLink;
|
||||
enum LinkMetricActionValue linkMetrtic;
|
||||
enum PathSelectionActionValue pathSelection;
|
||||
enum InterworkActionValue interwork;
|
||||
enum ResourceCoordinationActionValue resourceCoordination;
|
||||
} ACTION_VALUE;
|
||||
void SetAction(enum CategoryValue type,ACTION_VALUE action);
|
||||
enum CategoryValue GetCategory();
|
||||
ACTION_VALUE GetAction();
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
private:
|
||||
uint8_t m_category;
|
||||
uint8_t m_actionValue;
|
||||
};
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
|
||||
@@ -422,7 +422,9 @@ WifiRemoteStation::WifiRemoteStation ()
|
||||
: m_state (BRAND_NEW),
|
||||
m_ssrc (0),
|
||||
m_slrc (0)
|
||||
{}
|
||||
{
|
||||
m_txStat = CreateObject<WifiTxStatistics> ();
|
||||
}
|
||||
WifiRemoteStation::~WifiRemoteStation ()
|
||||
{}
|
||||
|
||||
@@ -543,7 +545,7 @@ WifiRemoteStation::GetCtsMode (WifiMode rtsMode)
|
||||
WifiMode
|
||||
WifiRemoteStation::GetAckMode (WifiMode dataMode)
|
||||
{
|
||||
return GetControlAnswerMode (dataMode);
|
||||
return dataMode;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -572,12 +574,14 @@ WifiRemoteStation::GetDataMode (Ptr<const Packet> packet, uint32_t fullPacketSiz
|
||||
{
|
||||
if (GetManager ()->IsLowLatency ())
|
||||
{
|
||||
m_txStat->NotifyDataSent(fullPacketSize, DoGetDataMode (fullPacketSize).GetDataRate());
|
||||
return DoGetDataMode (fullPacketSize);
|
||||
}
|
||||
TxModeTag tag;
|
||||
bool found;
|
||||
found = packet->FindFirstMatchingTag (tag);
|
||||
NS_ASSERT (found);
|
||||
m_txStat->NotifyDataSent(fullPacketSize, tag.GetDataMode ().GetDataRate());
|
||||
return tag.GetDataMode ();
|
||||
}
|
||||
WifiMode
|
||||
@@ -585,12 +589,14 @@ WifiRemoteStation::GetRtsMode (Ptr<const Packet> packet)
|
||||
{
|
||||
if (GetManager ()->IsLowLatency ())
|
||||
{
|
||||
m_txStat->NotifyDataSent(packet->GetSize() +36, DoGetRtsMode().GetDataRate());
|
||||
return DoGetRtsMode ();
|
||||
}
|
||||
TxModeTag tag;
|
||||
bool found;
|
||||
found = packet->FindFirstMatchingTag (tag);
|
||||
NS_ASSERT (found);
|
||||
m_txStat->NotifyDataSent(packet->GetSize() +36, tag.GetRtsMode ().GetDataRate());
|
||||
return tag.GetRtsMode ();
|
||||
}
|
||||
|
||||
@@ -693,6 +699,7 @@ WifiRemoteStation::ReportDataFailed (void)
|
||||
void
|
||||
WifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
|
||||
{
|
||||
m_txStat->NotifyRtsSuccess(m_ssrc);
|
||||
m_ssrc = 0;
|
||||
DoReportRtsOk (ctsSnr, ctsMode, rtsSnr);
|
||||
}
|
||||
@@ -700,6 +707,7 @@ WifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
|
||||
void
|
||||
WifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
|
||||
{
|
||||
m_txStat->NotifyGotAck(m_slrc);
|
||||
m_slrc = 0;
|
||||
DoReportDataOk (ackSnr, ackMode, dataSnr);
|
||||
}
|
||||
@@ -708,6 +716,7 @@ void
|
||||
WifiRemoteStation::ReportFinalRtsFailed (void)
|
||||
{
|
||||
m_ssrc = 0;
|
||||
m_txStat->NotifyRtsFailed();
|
||||
DoReportFinalRtsFailed ();
|
||||
}
|
||||
|
||||
@@ -715,6 +724,7 @@ void
|
||||
WifiRemoteStation::ReportFinalDataFailed (void)
|
||||
{
|
||||
m_slrc = 0;
|
||||
m_txStat->NotifyDataFailed();
|
||||
DoReportFinalDataFailed ();
|
||||
}
|
||||
|
||||
@@ -723,5 +733,16 @@ WifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
|
||||
{
|
||||
DoReportRxOk (rxSnr, txMode);
|
||||
}
|
||||
WifiTxStatistics::TX_STATISTICS
|
||||
WifiRemoteStation::GetTxStat()
|
||||
{
|
||||
return m_txStat->GetTxStatRateLength();
|
||||
}
|
||||
void
|
||||
WifiRemoteStation::ResetTxStat()
|
||||
{
|
||||
m_txStat->ResetStatistics();
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/traced-value.h"
|
||||
#include "ns3/tx-statistics.h"
|
||||
#include "wifi-mode.h"
|
||||
|
||||
namespace ns3 {
|
||||
@@ -257,6 +258,8 @@ public:
|
||||
* handshake.
|
||||
*/
|
||||
WifiMode GetAckMode (WifiMode dataMode);
|
||||
WifiTxStatistics::TX_STATISTICS GetTxStat();
|
||||
void ResetTxStat();
|
||||
|
||||
private:
|
||||
typedef std::vector<WifiMode> SupportedModes;
|
||||
@@ -286,6 +289,7 @@ private:
|
||||
SupportedModes m_modes;
|
||||
TracedValue<uint32_t> m_ssrc;
|
||||
TracedValue<uint32_t> m_slrc;
|
||||
Ptr<WifiTxStatistics> m_txStat;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
def build(bld):
|
||||
obj = bld.create_ns3_module('wifi', ['node'])
|
||||
obj.source = [
|
||||
'tx-statistics.cc',
|
||||
'propagation-delay-model.cc',
|
||||
'propagation-loss-model.cc',
|
||||
'jakes-propagation-loss-model.cc',
|
||||
@@ -35,6 +36,16 @@ def build(bld):
|
||||
'adhoc-wifi-mac.cc',
|
||||
'nqap-wifi-mac.cc',
|
||||
'nqsta-wifi-mac.cc',
|
||||
'mesh-wifi-mac.cc',
|
||||
'mesh-configuration-element.cc',
|
||||
'mesh-wifi-beacon-timing-element.cc',
|
||||
'dot11s-peer-management-element.cc',
|
||||
'mesh-mgt-headers.cc',
|
||||
'mesh-wifi-peer-manager.cc',
|
||||
'mesh-wifi-rann-information-element.cc',
|
||||
'mesh-wifi-preq-information-element.cc',
|
||||
'mesh-wifi-perr-information-element.cc',
|
||||
'mesh-wifi-prep-information-element.cc',
|
||||
'wifi-net-device.cc',
|
||||
'arf-wifi-manager.cc',
|
||||
'aarf-wifi-manager.cc',
|
||||
@@ -44,10 +55,12 @@ def build(bld):
|
||||
'rraa-wifi-manager.cc',
|
||||
'constant-rate-wifi-manager.cc',
|
||||
'wifi-test.cc',
|
||||
'dot11s-parameters.cc',
|
||||
]
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers.module = 'wifi'
|
||||
headers.source = [
|
||||
'tx-statistics.h',
|
||||
'propagation-delay-model.h',
|
||||
'propagation-loss-model.h',
|
||||
'jakes-propagation-loss-model.h',
|
||||
@@ -73,10 +86,25 @@ def build(bld):
|
||||
'adhoc-wifi-mac.h',
|
||||
'nqsta-wifi-mac.h',
|
||||
'nqap-wifi-mac.h',
|
||||
'mesh-wifi-mac.h',
|
||||
'wifi-phy.h',
|
||||
'supported-rates.h',
|
||||
'mgt-headers.h',
|
||||
'status-code.h',
|
||||
'capability-information.h',
|
||||
'mesh-configuration-element.h',
|
||||
'mesh-wifi-beacon-timing-element.h',
|
||||
'dot11s-peer-management-element.h',
|
||||
'mesh-mgt-headers.h',
|
||||
'mesh-wifi-peer-manager.h',
|
||||
'mesh-wifi-rann-information-element.h',
|
||||
'mesh-wifi-preq-information-element.h',
|
||||
'mesh-wifi-perr-information-element.h',
|
||||
'mesh-wifi-prep-information-element.h',
|
||||
'error-rate-model.h',
|
||||
'yans-error-rate-model.h',
|
||||
'dot11s-codes.h',
|
||||
'dot11s-parameters.h',
|
||||
]
|
||||
|
||||
obj = bld.create_ns3_program('wifi-phy-test',
|
||||
|
||||
21
src/helper/hwmp-helper.cc
Normal file
21
src/helper/hwmp-helper.cc
Normal file
@@ -0,0 +1,21 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
21
src/helper/hwmp-helper.h
Normal file
21
src/helper/hwmp-helper.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
220
src/helper/mesh-wifi-helper.cc
Normal file
220
src/helper/mesh-wifi-helper.cc
Normal file
@@ -0,0 +1,220 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Evgeny Khorov <horov@frtk.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "mesh-wifi-helper.h"
|
||||
#include "ns3/wifi-net-device.h"
|
||||
#include "ns3/wifi-mac.h"
|
||||
#include "ns3/wifi-phy.h"
|
||||
#include "ns3/wifi-remote-station-manager.h"
|
||||
#include "ns3/wifi-channel.h"
|
||||
#include "ns3/yans-wifi-channel.h"
|
||||
#include "ns3/propagation-delay-model.h"
|
||||
#include "ns3/propagation-loss-model.h"
|
||||
#include "ns3/mobility-model.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/pcap-writer.h"
|
||||
#include "ns3/config.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/hwmp.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("MeshWifiHelper");
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
MeshWifiHelper::MeshWifiHelper ()
|
||||
{
|
||||
//m_deviceFactory.SetTypeId ("ns3::L2RoutingNetDevice");
|
||||
}
|
||||
|
||||
MeshWifiHelper::~MeshWifiHelper ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiHelper::SetRemoteStationManager (std::string type,
|
||||
std::string n0, const AttributeValue &v0,
|
||||
std::string n1, const AttributeValue &v1,
|
||||
std::string n2, const AttributeValue &v2,
|
||||
std::string n3, const AttributeValue &v3,
|
||||
std::string n4, const AttributeValue &v4,
|
||||
std::string n5, const AttributeValue &v5,
|
||||
std::string n6, const AttributeValue &v6,
|
||||
std::string n7, const AttributeValue &v7)
|
||||
{
|
||||
m_stationManager = ObjectFactory ();
|
||||
m_stationManager.SetTypeId (type);
|
||||
m_stationManager.Set (n0, v0);
|
||||
m_stationManager.Set (n1, v1);
|
||||
m_stationManager.Set (n2, v2);
|
||||
m_stationManager.Set (n3, v3);
|
||||
m_stationManager.Set (n4, v4);
|
||||
m_stationManager.Set (n5, v5);
|
||||
m_stationManager.Set (n6, v6);
|
||||
m_stationManager.Set (n7, v7);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiHelper::SetMac (std::string type,
|
||||
std::string n0, const AttributeValue &v0,
|
||||
std::string n1, const AttributeValue &v1,
|
||||
std::string n2, const AttributeValue &v2,
|
||||
std::string n3, const AttributeValue &v3,
|
||||
std::string n4, const AttributeValue &v4,
|
||||
std::string n5, const AttributeValue &v5,
|
||||
std::string n6, const AttributeValue &v6,
|
||||
std::string n7, const AttributeValue &v7)
|
||||
{
|
||||
m_meshMac = ObjectFactory ();
|
||||
m_meshMac.SetTypeId (type);
|
||||
m_meshMac.Set (n0, v0);
|
||||
m_meshMac.Set (n1, v1);
|
||||
m_meshMac.Set (n2, v2);
|
||||
m_meshMac.Set (n3, v3);
|
||||
m_meshMac.Set (n4, v4);
|
||||
m_meshMac.Set (n5, v5);
|
||||
m_meshMac.Set (n6, v6);
|
||||
m_meshMac.Set (n7, v7);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiHelper::SetL2RoutingProtocol(std::string type,
|
||||
std::string n0, const AttributeValue &v0,
|
||||
std::string n1, const AttributeValue &v1,
|
||||
std::string n2, const AttributeValue &v2,
|
||||
std::string n3, const AttributeValue &v3,
|
||||
std::string n4, const AttributeValue &v4,
|
||||
std::string n5, const AttributeValue &v5,
|
||||
std::string n6, const AttributeValue &v6,
|
||||
std::string n7, const AttributeValue &v7,
|
||||
std::string n8, const AttributeValue &v8,
|
||||
std::string n9, const AttributeValue &v9)
|
||||
{
|
||||
m_routingProtocol = ObjectFactory ();
|
||||
m_routingProtocol.SetTypeId (type);
|
||||
m_routingProtocol.Set (n0, v0);
|
||||
m_routingProtocol.Set (n1, v1);
|
||||
m_routingProtocol.Set (n2, v2);
|
||||
m_routingProtocol.Set (n3, v3);
|
||||
m_routingProtocol.Set (n4, v4);
|
||||
m_routingProtocol.Set (n5, v5);
|
||||
m_routingProtocol.Set (n6, v6);
|
||||
m_routingProtocol.Set (n7, v7);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiHelper::SetL2RoutingNetDevice(std::string type,
|
||||
std::string n0, const AttributeValue &v0,
|
||||
std::string n1, const AttributeValue &v1,
|
||||
std::string n2, const AttributeValue &v2,
|
||||
std::string n3, const AttributeValue &v3,
|
||||
std::string n4, const AttributeValue &v4,
|
||||
std::string n5, const AttributeValue &v5,
|
||||
std::string n6, const AttributeValue &v6,
|
||||
std::string n7, const AttributeValue &v7,
|
||||
std::string n8, const AttributeValue &v8,
|
||||
std::string n9, const AttributeValue &v9)
|
||||
{
|
||||
m_deviceFactory = ObjectFactory ();
|
||||
m_deviceFactory.SetTypeId (type);
|
||||
m_deviceFactory.Set (n0, v0);
|
||||
m_deviceFactory.Set (n1, v1);
|
||||
m_deviceFactory.Set (n2, v2);
|
||||
m_deviceFactory.Set (n3, v3);
|
||||
m_deviceFactory.Set (n4, v4);
|
||||
m_deviceFactory.Set (n5, v5);
|
||||
m_deviceFactory.Set (n6, v6);
|
||||
m_deviceFactory.Set (n7, v7);
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiHelper::SetPeerLinkManager (std::string type,
|
||||
std::string n0, const AttributeValue &v0,
|
||||
std::string n1, const AttributeValue &v1,
|
||||
std::string n2, const AttributeValue &v2,
|
||||
std::string n3, const AttributeValue &v3,
|
||||
std::string n4, const AttributeValue &v4,
|
||||
std::string n5, const AttributeValue &v5,
|
||||
std::string n6, const AttributeValue &v6,
|
||||
std::string n7, const AttributeValue &v7,
|
||||
std::string n8, const AttributeValue &v8,
|
||||
std::string n9, const AttributeValue &v9)
|
||||
{
|
||||
m_peerManager = ObjectFactory ();
|
||||
m_peerManager.SetTypeId (type);
|
||||
m_peerManager.Set (n0, v0);
|
||||
m_peerManager.Set (n1, v1);
|
||||
m_peerManager.Set (n2, v2);
|
||||
m_peerManager.Set (n3, v3);
|
||||
m_peerManager.Set (n4, v4);
|
||||
m_peerManager.Set (n5, v5);
|
||||
m_peerManager.Set (n6, v6);
|
||||
m_peerManager.Set (n7, v7);
|
||||
m_peerManager.Set (n8, v8);
|
||||
m_peerManager.Set (n9, v9);
|
||||
}
|
||||
|
||||
NetDeviceContainer
|
||||
MeshWifiHelper::Install (const WifiPhyHelper &phyHelper, NodeContainer c, uint8_t numOfPorts) const
|
||||
{
|
||||
NetDeviceContainer devices;
|
||||
for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
|
||||
{
|
||||
Ptr<Node> node = *i;
|
||||
Ptr<L2RoutingNetDevice> virtualDevice = m_deviceFactory.Create<L2RoutingNetDevice> ();
|
||||
Ptr<WifiPeerManager>pPeer = m_peerManager.Create<WifiPeerManager > ();
|
||||
devices.Add (virtualDevice);
|
||||
std::vector<Ptr<WifiNetDevice> > nodeDevices;
|
||||
for (uint8_t k=0; k<numOfPorts; k++)
|
||||
{
|
||||
Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> ();
|
||||
Ptr<MeshWifiMac> mac = m_meshMac.Create<MeshWifiMac> ();
|
||||
Ptr<WifiRemoteStationManager> manager = m_stationManager.Create<WifiRemoteStationManager> ();
|
||||
Ptr<WifiPhy> phy = phyHelper.Create (node, device);
|
||||
mac->SetAddress (Mac48Address::Allocate ());
|
||||
device->SetMac (mac);
|
||||
device->SetPhy (phy);
|
||||
device->SetRemoteStationManager (manager);
|
||||
//mac ->SetPeerLinkManager (pPeer);
|
||||
//create L2RoutingNetDevice and add WifiNetDevice to it
|
||||
node->AddDevice(device);
|
||||
nodeDevices.push_back(device);
|
||||
}
|
||||
node -> AddDevice(virtualDevice);
|
||||
for (std::vector<Ptr<WifiNetDevice> > ::iterator iter=nodeDevices.begin();iter!=nodeDevices.end(); ++iter)
|
||||
virtualDevice->AddPort(*iter);
|
||||
// nodeDevice.pop_back()
|
||||
pPeer->AttachPorts(nodeDevices);
|
||||
Ptr<L2RoutingProtocol> routingProtocol = m_routingProtocol.Create <L2RoutingProtocol>();
|
||||
virtualDevice->AttachProtocol(routingProtocol);
|
||||
//hwmp->SetRoot(device->GetIfIndex(), Seconds(5));
|
||||
nodeDevices.clear();
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
NetDeviceContainer
|
||||
MeshWifiHelper::Install (const WifiPhyHelper &phy, Ptr<Node> node, uint8_t numOfPorts) const
|
||||
{
|
||||
return Install (phy, NodeContainer (node), numOfPorts);
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
124
src/helper/mesh-wifi-helper.h
Normal file
124
src/helper/mesh-wifi-helper.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Kirill Andreev <andreev@iitp.ru>
|
||||
* Evgeny Khorov <horov@frtk.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MESHWIFIHELPER_H
|
||||
#define _MESHWIFIHELPER_H
|
||||
|
||||
#include "ns3/wifi-net-device.h"
|
||||
#include "ns3/l2-routing-net-device.h"
|
||||
#include "ns3/mesh-wifi-mac.h"
|
||||
#include "ns3/wifi-channel.h"
|
||||
#include "ns3/mesh-wifi-peer-manager.h"
|
||||
#include "wifi-helper.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
class WifiChannel;
|
||||
|
||||
class MeshWifiHelper
|
||||
{
|
||||
public:
|
||||
MeshWifiHelper ();
|
||||
virtual ~MeshWifiHelper ();
|
||||
|
||||
/**
|
||||
* \param type the type of peer manager to use.
|
||||
* \param n0 the name of the attribute to set in the peer manager.
|
||||
* \param v0 the value of the attribute to set in the peer manager.
|
||||
* etc.
|
||||
*
|
||||
*/
|
||||
void SetRemoteStationManager (std::string type,
|
||||
std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
|
||||
std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
|
||||
std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
|
||||
std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
|
||||
std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
|
||||
std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
|
||||
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
|
||||
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
|
||||
|
||||
/**
|
||||
* \param type the type of ns3::WifiMac to create.
|
||||
* \param n0 the name of the attribute to set
|
||||
* \param v0 the value of the attribute to set
|
||||
*
|
||||
* All the attributes specified in this method should exist
|
||||
* in the requested mac.
|
||||
*/
|
||||
void SetMac (std::string type,
|
||||
std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
|
||||
std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
|
||||
std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
|
||||
std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
|
||||
std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
|
||||
std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
|
||||
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
|
||||
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
|
||||
|
||||
void SetPeerLinkManager (std::string type,
|
||||
std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
|
||||
std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
|
||||
std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
|
||||
std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
|
||||
std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
|
||||
std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
|
||||
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
|
||||
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (),
|
||||
std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (),
|
||||
std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ());
|
||||
void SetL2RoutingProtocol(std::string type,
|
||||
std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
|
||||
std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
|
||||
std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
|
||||
std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
|
||||
std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
|
||||
std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
|
||||
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
|
||||
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (),
|
||||
std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (),
|
||||
std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ());
|
||||
|
||||
void SetL2RoutingNetDevice(std::string type,
|
||||
std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
|
||||
std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
|
||||
std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
|
||||
std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
|
||||
std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
|
||||
std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
|
||||
std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
|
||||
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue (),
|
||||
std::string n8 = "", const AttributeValue &v8 = EmptyAttributeValue (),
|
||||
std::string n9 = "", const AttributeValue &v9 = EmptyAttributeValue ());
|
||||
NetDeviceContainer Install (const WifiPhyHelper &phyHelper, NodeContainer c, uint8_t numOfPorts) const;
|
||||
NetDeviceContainer Install (const WifiPhyHelper &phy, Ptr<Node> node, uint8_t numOfPorts) const;
|
||||
private:
|
||||
ObjectFactory m_stationManager;
|
||||
ObjectFactory m_meshMac;
|
||||
ObjectFactory m_peerManager;
|
||||
//L2routing:
|
||||
ObjectFactory m_deviceFactory;
|
||||
ObjectFactory m_routingProtocol;
|
||||
};
|
||||
}//namespace ns3
|
||||
#endif /* _MESHWIFIHELPER_H */
|
||||
|
||||
@@ -23,6 +23,8 @@ def build(bld):
|
||||
'bridge-helper.cc',
|
||||
'yans-wifi-helper.cc',
|
||||
'v4ping-helper.cc',
|
||||
'mesh-wifi-helper.cc',
|
||||
'hwmp-helper.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
@@ -48,6 +50,8 @@ def build(bld):
|
||||
'bridge-helper.h',
|
||||
'yans-wifi-helper.h',
|
||||
'v4ping-helper.h',
|
||||
'mesh-wifi-helper.h',
|
||||
'hwmp-helper.h',
|
||||
]
|
||||
|
||||
env = bld.env_of_name('default')
|
||||
|
||||
43
src/node/l2-routing-protocol.cc
Normal file
43
src/node/l2-routing-protocol.cc
Normal file
@@ -0,0 +1,43 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/log.h"
|
||||
#include "l2-routing-protocol.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("L2RoutingProtocol");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (L2RoutingProtocol);
|
||||
|
||||
TypeId
|
||||
L2RoutingProtocol::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::L2RoutingProtocol")
|
||||
.SetParent<Object> ();
|
||||
return tid;
|
||||
}
|
||||
|
||||
L2RoutingProtocol::~L2RoutingProtocol ()
|
||||
{}
|
||||
|
||||
} // namespace ns3
|
||||
166
src/node/l2-routing-protocol.h
Normal file
166
src/node/l2-routing-protocol.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2008,2009 IITP RAS
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Kirill Andreev <andreev@iitp.ru>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef L2_ROUTING_PROTOCOL_H
|
||||
#define L2_ROUTING_PROTOCOL_H
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/ptr.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Packet;
|
||||
/**
|
||||
* \ingroup node
|
||||
* \defgroup L2RoutingProtocol L2routingProtocol
|
||||
*/
|
||||
/**
|
||||
* \ingroup L2RoutingProtocol
|
||||
*
|
||||
* \brief Base class for Layer 2 routing protocols
|
||||
*
|
||||
* \details Yhis class is an internal part of L2RoutingNetDevice class
|
||||
* and this class implements interface between L2RoutingNetDevice and
|
||||
* any protocol of MAC layer. This interface is similar to ipv4
|
||||
* routiong protocol base class.
|
||||
*/
|
||||
class L2RoutingProtocol : public Object
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId();
|
||||
virtual ~L2RoutingProtocol();
|
||||
/**
|
||||
* \brief Callback to be invoked when route discovery
|
||||
* procedure is completed
|
||||
* \param bool flag indicating whether a route was
|
||||
* actually found and all needed information is added
|
||||
* to the packet succesfully
|
||||
* \param Ptr<Packet> is packet, for which the route
|
||||
* was resolved
|
||||
* \attention All needed information for MAC layer
|
||||
* must be stored in proper tags (like in case of
|
||||
* HWMP, when WifiMacHeader needs address of next
|
||||
* hop), or must be added as a packet header(if MAC
|
||||
* does not need any additional information). So, the
|
||||
* packet is returned back to L2RoutingNetDevice looks
|
||||
* like a pure packet with ethernet header (i.e data
|
||||
* +src +dst + protocol). All information needed to
|
||||
* L2RoutingNetDevice is outgoing port ID.
|
||||
* \param Mac48Address Source address of the packet
|
||||
* \param Mac48Address Destiation address of the
|
||||
* packet
|
||||
* \param uint16_t Ethernet 'Protocol' field - stored
|
||||
* in protocol, needed to form a proper MAC-layer
|
||||
* header.
|
||||
* \param uint32_t Output port
|
||||
*/
|
||||
typedef Callback<
|
||||
void,
|
||||
bool,
|
||||
Ptr<Packet>,
|
||||
Mac48Address,
|
||||
Mac48Address,
|
||||
uint16_t,
|
||||
uint32_t
|
||||
>
|
||||
RouteReplyCallback;
|
||||
/**
|
||||
* \brief All packets must go through RequestRoute
|
||||
* \returns Can the route be discovered or not
|
||||
* \param sourceIface The incoming interface of the
|
||||
* packet
|
||||
* \param source Source address of the packet
|
||||
* \param destination Destination address of the
|
||||
* packet
|
||||
* \param packet The packet to be resolved (needed the
|
||||
* whole packet, because we can add tags or headers).
|
||||
* \param protocolType The protocol ID (must be stored
|
||||
* for route discovery time to form a proper MAC-layer
|
||||
* header).
|
||||
* \param routeReply Callback to be invoked after route
|
||||
* discovery procedure.
|
||||
*/
|
||||
virtual bool RequestRoute(
|
||||
uint32_t sourceIface,
|
||||
const Mac48Address source,
|
||||
const Mac48Address destination,
|
||||
Ptr<Packet> packet,
|
||||
uint16_t protocolType,
|
||||
RouteReplyCallback routeReply
|
||||
) = 0;
|
||||
/**
|
||||
* \brief Attaches ports to the L2RoutingProtocols,
|
||||
* \returns False if there are not proper devices (like
|
||||
* HWMP, which requires only WifiNetDevice and works
|
||||
* only above MeshWifiMac).
|
||||
* \param ports The array of ports.
|
||||
*/
|
||||
virtual bool AttachPorts(std::vector<Ptr<NetDevice> > ports) = 0;
|
||||
/**
|
||||
* \brief L2Routing protocol must know the
|
||||
* L2RoutingNetDevice ID to determine packets as 'came
|
||||
* from upper layer' and 'received from network' (for
|
||||
* example, to manage TTL).
|
||||
* \param interface The interface ID of
|
||||
* L2RoutingNetDevice
|
||||
*/
|
||||
virtual void SetIfIndex(uint32_t interface) = 0;
|
||||
protected:
|
||||
struct QueuedPacket {
|
||||
Ptr<Packet> pkt;
|
||||
Mac48Address dst;
|
||||
Mac48Address src;
|
||||
uint16_t protocol;
|
||||
uint32_t inPort;
|
||||
RouteReplyCallback reply;
|
||||
};
|
||||
/**
|
||||
* \brief Set Max queue size per destinztion
|
||||
* \details Routing Queue is implemented inside the
|
||||
* routing protocol and keeps one queue per
|
||||
* destination (to make it easier to find resolved and
|
||||
* timed out packets).
|
||||
* \param maxPacketsPerDestination Packets per
|
||||
* destination that can be stored inside protocol.
|
||||
*/
|
||||
virtual void SetMaxQueueSize(int maxPacketsPerDestination) = 0;
|
||||
/**
|
||||
* \brief Queue packet with 'Ethernet header'
|
||||
* \returns false if the queue is full.
|
||||
*/
|
||||
virtual bool QueuePacket(struct QueuedPacket packet) = 0;
|
||||
/**
|
||||
* \brief Deques packet with 'Ethernet header'
|
||||
* \returns Ptr<packet> (NULL if queue is empty), src,
|
||||
* dst, protocol ID, incoming port ID, and reply
|
||||
* callback
|
||||
* \param destination The destination address, which
|
||||
* identifyes queue.
|
||||
*/
|
||||
virtual struct QueuedPacket DequeuePacket(Mac48Address destination) = 0;
|
||||
};
|
||||
}//namespace ns3
|
||||
#endif
|
||||
@@ -38,6 +38,7 @@ def build(bld):
|
||||
'ipv6-address.cc',
|
||||
'ipv6-header.cc',
|
||||
'ipv4-raw-socket-factory.cc',
|
||||
'l2-routing-protocol.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
@@ -77,4 +78,5 @@ def build(bld):
|
||||
'ipv6-address.h',
|
||||
'ipv6-header.h',
|
||||
'ipv4-raw-socket-factory.h',
|
||||
'l2-routing-protocol.h',
|
||||
]
|
||||
|
||||
@@ -34,6 +34,8 @@ all_modules = (
|
||||
'helper',
|
||||
'contrib/stats',
|
||||
'applications/v4ping',
|
||||
'devices/l2-routing/l2-routing-main',
|
||||
'devices/l2-routing/l2-routing-hwmp',
|
||||
)
|
||||
|
||||
def set_options(opt):
|
||||
|
||||
Reference in New Issue
Block a user