wifi: add RRPAA wifi rate control (patch from Matias Richart)
This commit is contained in:
@@ -67,6 +67,7 @@ us a note on ns-developers mailing list.</p>
|
||||
<li>A new information element has been added: HeCapabilities. This information element is added to the MAC frame header if the node is a HE node. This HeCapabilites information element is used to advertise the HE capabilites of the node to other nodes in the network.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li> A new class were added for the RRPAA WiFi rate control mechanism.</li>
|
||||
<li>Included carrier aggregation feature in LTE module</li>
|
||||
<ul>
|
||||
<li>LTE model is extended to support carrier aggregation feature according to 3GPP Release 10, for up to 5 component
|
||||
|
||||
@@ -434,7 +434,7 @@ LOOKUP_CACHE_SIZE = 1
|
||||
# normally produced when WARNINGS is set to YES.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_ALL = no
|
||||
|
||||
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
|
||||
# be included in the documentation.
|
||||
@@ -732,7 +732,7 @@ QUIET = NO
|
||||
# Tip: Turn warnings on while writing the documentation.
|
||||
# The default value is: YES.
|
||||
|
||||
WARNINGS = YES
|
||||
WARNINGS = no
|
||||
|
||||
# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
|
||||
# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
|
||||
@@ -2205,7 +2205,7 @@ HIDE_UNDOC_RELATIONS = YES
|
||||
# set to NO
|
||||
# The default value is: NO.
|
||||
|
||||
HAVE_DOT = YES
|
||||
HAVE_DOT = no
|
||||
|
||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
||||
# to run in parallel. When set to 0 doxygen will base this on the number of
|
||||
|
||||
@@ -26,6 +26,7 @@ cpp_examples = [
|
||||
("wifi-wired-bridging", "True", "True"),
|
||||
("power-adaptation-distance --manager=ns3::ParfWifiManager --outputFileName=parf --steps=5 --stepsSize=10", "True", "True"),
|
||||
("power-adaptation-distance --manager=ns3::AparfWifiManager --outputFileName=aparf --steps=5 --stepsSize=10", "True", "True"),
|
||||
("power-adaptation-distance --manager=ns3::RrpaaWifiManager --outputFileName=rrpaa --steps=5 --stepsSize=10", "True", "True"),
|
||||
("ofdm-ht-validation", "True", "True"),
|
||||
("ofdm-validation", "True", "True"),
|
||||
("ofdm-vht-validation", "True", "True"),
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* This example program is designed to illustrate the behavior of two
|
||||
* power/rate-adaptive WiFi rate controls; namely, ns3::ParfWifiManager
|
||||
* and ns3::AparfWifiManager.
|
||||
* This example program is designed to illustrate the behavior of three
|
||||
* power/rate-adaptive WiFi rate controls; namely, ns3::ParfWifiManager,
|
||||
* ns3::AparfWifiManager and ns3::RrpaaWifiManager.
|
||||
*
|
||||
* The output of this is typically two plot files, named throughput-parf.plt
|
||||
* (or throughput-aparf.plt, if Aparf is used) and power-parf.plt If
|
||||
* (or throughput-aparf.plt, if Aparf is used) and power-parf.plt. If
|
||||
* Gnuplot program is available, one can use it to convert the plt file
|
||||
* into an eps file, by running:
|
||||
* \code{.sh}
|
||||
@@ -59,7 +59,7 @@
|
||||
* and converted from dbm to milliwatt units, and this average is
|
||||
* plotted against time.
|
||||
*
|
||||
* When neither Parf nor Aparf is selected as the rate control, the
|
||||
* When neither Parf, Aparf or Rrpaa is selected as the rate control, the
|
||||
* generation of the plot of average transmit power vs distance is suppressed
|
||||
* since the other Wifi rate controls do not support the necessary callbacks
|
||||
* for computing the average power.
|
||||
@@ -97,7 +97,7 @@ using namespace std;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("PowerAdaptationDistance");
|
||||
|
||||
// packet size generated at the AP
|
||||
//packet size generated at the AP
|
||||
static const uint32_t packetSize = 1420;
|
||||
|
||||
class NodeStatistics
|
||||
@@ -107,8 +107,8 @@ public:
|
||||
|
||||
void PhyCallback (std::string path, Ptr<const Packet> packet);
|
||||
void RxCallback (std::string path, Ptr<const Packet> packet, const Address &from);
|
||||
void PowerCallback (std::string path, uint8_t power, Mac48Address dest);
|
||||
void RateCallback (std::string path, uint32_t rate, Mac48Address dest);
|
||||
void PowerCallback (std::string path, double oldPower, double newPower, Mac48Address dest);
|
||||
void RateCallback (std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest);
|
||||
void SetPosition (Ptr<Node> node, Vector position);
|
||||
void AdvancePosition (Ptr<Node> node, int stepsSize, int stepsTime);
|
||||
Vector GetPosition (Ptr<Node> node);
|
||||
@@ -116,13 +116,14 @@ public:
|
||||
Gnuplot2dDataset GetDatafile ();
|
||||
Gnuplot2dDataset GetPowerDatafile ();
|
||||
|
||||
private:
|
||||
typedef std::vector<std::pair<Time,WifiMode> > TxTime;
|
||||
void SetupPhy (Ptr<WifiPhy> phy);
|
||||
Time GetCalcTxTime (WifiMode mode);
|
||||
|
||||
std::map<Mac48Address, double> actualPower;
|
||||
std::map<Mac48Address, WifiMode> actualMode;
|
||||
private:
|
||||
typedef std::vector<std::pair<Time, DataRate> > TxTime;
|
||||
void SetupPhy (Ptr<WifiPhy> phy);
|
||||
Time GetCalcTxTime (DataRate rate);
|
||||
|
||||
std::map<Mac48Address, double> currentPower;
|
||||
std::map<Mac48Address, DataRate> currentRate;
|
||||
uint32_t m_bytesTotal;
|
||||
double totalEnergy;
|
||||
double totalTime;
|
||||
@@ -139,15 +140,17 @@ NodeStatistics::NodeStatistics (NetDeviceContainer aps, NetDeviceContainer stas)
|
||||
Ptr<WifiPhy> phy = wifiDevice->GetPhy ();
|
||||
myPhy = phy;
|
||||
SetupPhy (phy);
|
||||
DataRate dataRate = DataRate (phy->GetMode (0).GetDataRate (phy->GetChannelWidth ()));
|
||||
double power = phy->GetTxPowerEnd ();
|
||||
for (uint32_t j = 0; j < stas.GetN (); j++)
|
||||
{
|
||||
Ptr<NetDevice> staDevice = stas.Get (j);
|
||||
Ptr<WifiNetDevice> wifiStaDevice = DynamicCast<WifiNetDevice> (staDevice);
|
||||
Mac48Address addr = wifiStaDevice->GetMac ()->GetAddress ();
|
||||
actualPower[addr] = 17;
|
||||
actualMode[addr] = phy->GetMode (0);
|
||||
currentPower[addr] = power;
|
||||
currentRate[addr] = dataRate;
|
||||
}
|
||||
actualMode[Mac48Address ("ff:ff:ff:ff:ff:ff")] = phy->GetMode (0);
|
||||
currentRate[Mac48Address ("ff:ff:ff:ff:ff:ff")] = dataRate;
|
||||
totalEnergy = 0;
|
||||
totalTime = 0;
|
||||
m_bytesTotal = 0;
|
||||
@@ -165,16 +168,20 @@ NodeStatistics::SetupPhy (Ptr<WifiPhy> phy)
|
||||
WifiTxVector txVector;
|
||||
txVector.SetMode (mode);
|
||||
txVector.SetPreambleType (WIFI_PREAMBLE_LONG);
|
||||
timeTable.push_back (std::make_pair (phy->CalculateTxDuration (packetSize, txVector, phy->GetFrequency ()), mode));
|
||||
txVector.SetChannelWidth (phy->GetChannelWidth ());
|
||||
DataRate dataRate = DataRate (mode.GetDataRate (phy->GetChannelWidth ()));
|
||||
Time time = phy->CalculateTxDuration (packetSize, txVector, phy->GetFrequency ());
|
||||
NS_LOG_DEBUG (i << " " << time.GetSeconds () << " " << dataRate);
|
||||
timeTable.push_back (std::make_pair (time, dataRate));
|
||||
}
|
||||
}
|
||||
|
||||
Time
|
||||
NodeStatistics::GetCalcTxTime (WifiMode mode)
|
||||
NodeStatistics::GetCalcTxTime (DataRate rate)
|
||||
{
|
||||
for (TxTime::const_iterator i = timeTable.begin (); i != timeTable.end (); i++)
|
||||
{
|
||||
if (mode == i->second)
|
||||
if (rate == i->second)
|
||||
{
|
||||
return i->first;
|
||||
}
|
||||
@@ -192,34 +199,21 @@ NodeStatistics::PhyCallback (std::string path, Ptr<const Packet> packet)
|
||||
|
||||
if (head.GetType () == WIFI_MAC_DATA)
|
||||
{
|
||||
totalEnergy += pow (10.0, actualPower[dest] / 10.0) * GetCalcTxTime (actualMode[dest]).GetSeconds ();
|
||||
totalTime += GetCalcTxTime (actualMode[dest]).GetSeconds ();
|
||||
totalEnergy += pow (10.0, currentPower[dest] / 10.0) * GetCalcTxTime (currentRate[dest]).GetSeconds ();
|
||||
totalTime += GetCalcTxTime (currentRate[dest]).GetSeconds ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NodeStatistics::PowerCallback (std::string path, uint8_t power, Mac48Address dest)
|
||||
NodeStatistics::PowerCallback (std::string path, double oldPower, double newPower, Mac48Address dest)
|
||||
{
|
||||
double txPowerBaseDbm = myPhy->GetTxPowerStart ();
|
||||
double txPowerEndDbm = myPhy->GetTxPowerEnd ();
|
||||
uint32_t nTxPower = myPhy->GetNTxPower ();
|
||||
double dbm;
|
||||
if (nTxPower > 1)
|
||||
{
|
||||
dbm = txPowerBaseDbm + power * (txPowerEndDbm - txPowerBaseDbm) / (nTxPower - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT_MSG (txPowerBaseDbm == txPowerEndDbm, "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
|
||||
dbm = txPowerBaseDbm;
|
||||
}
|
||||
actualPower[dest] = dbm;
|
||||
currentPower[dest] = newPower;
|
||||
}
|
||||
|
||||
void
|
||||
NodeStatistics::RateCallback (std::string path, uint32_t rate, Mac48Address dest)
|
||||
NodeStatistics::RateCallback (std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest)
|
||||
{
|
||||
actualMode[dest] = myPhy->GetMode (rate);
|
||||
currentRate[dest] = newRate;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -271,14 +265,14 @@ NodeStatistics::GetPowerDatafile ()
|
||||
return m_output_power;
|
||||
}
|
||||
|
||||
void PowerCallback (std::string path, uint8_t power, Mac48Address dest)
|
||||
void PowerCallback (std::string path, double oldPower, double newPower, Mac48Address dest)
|
||||
{
|
||||
NS_LOG_INFO ((Simulator::Now ()).GetSeconds () << " " << dest << " Power " << (int)power);
|
||||
NS_LOG_INFO ((Simulator::Now ()).GetSeconds () << " " << dest << " Old power=" << oldPower << " New power=" << newPower);
|
||||
}
|
||||
|
||||
void RateCallback (std::string path, uint32_t rate, Mac48Address dest)
|
||||
void RateCallback (std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest)
|
||||
{
|
||||
NS_LOG_INFO ((Simulator::Now ()).GetSeconds () << " " << dest << " Rate " << rate);
|
||||
NS_LOG_INFO ((Simulator::Now ()).GetSeconds () << " " << dest << " Old rate=" << oldRate << " New rate=" << newRate);
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
@@ -322,7 +316,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
uint32_t simuTime = (steps + 1) * stepsTime;
|
||||
|
||||
// Define the APs
|
||||
//Define the APs
|
||||
NodeContainer wifiApNodes;
|
||||
wifiApNodes.Create (1);
|
||||
|
||||
@@ -366,7 +360,7 @@ int main (int argc, char *argv[])
|
||||
wifiDevices.Add (wifiStaDevices);
|
||||
wifiDevices.Add (wifiApDevices);
|
||||
|
||||
// Configure the mobility.
|
||||
//Configure the mobility.
|
||||
MobilityHelper mobility;
|
||||
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
|
||||
//Initial position of AP and STA
|
||||
@@ -443,7 +437,8 @@ int main (int argc, char *argv[])
|
||||
gnuplot.GenerateOutput (outfile);
|
||||
|
||||
if (manager.compare ("ns3::ParfWifiManager") == 0
|
||||
|| manager.compare ("ns3::AparfWifiManager") == 0)
|
||||
|| manager.compare ("ns3::AparfWifiManager") == 0
|
||||
|| manager.compare ("ns3::RrpaaWifiManager") == 0)
|
||||
{
|
||||
std::ofstream outfile2 (("power-" + outputFileName + ".plt").c_str ());
|
||||
gnuplot = Gnuplot (("power-" + outputFileName + ".eps").c_str (), "Average Transmit Power");
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* This example program is designed to illustrate the behavior of two
|
||||
* power/rate-adaptive WiFi rate controls; namely, ns3::ParfWifiManager
|
||||
* and ns3::AparfWifiManager.
|
||||
* This example program is designed to illustrate the behavior of three
|
||||
* power/rate-adaptive WiFi rate controls; namely, ns3::ParfWifiManager,
|
||||
* ns3::AparfWifiManager and ns3::RrpaaWifiManager.
|
||||
*
|
||||
* This simulation consist of 4 nodes, two APs and two STAs.
|
||||
* The APs generates UDP traffic with a CBR of 54 Mbps to the STAs.
|
||||
@@ -68,7 +68,7 @@ using namespace std;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("PowerAdaptationInterference");
|
||||
|
||||
// packet size generated at the AP
|
||||
//Packet size generated at the AP.
|
||||
static const uint32_t packetSize = 1420;
|
||||
|
||||
class NodeStatistics
|
||||
@@ -80,8 +80,8 @@ public:
|
||||
|
||||
void PhyCallback (std::string path, Ptr<const Packet> packet);
|
||||
void RxCallback (std::string path, Ptr<const Packet> packet, const Address &from);
|
||||
void PowerCallback (std::string path, uint8_t power, Mac48Address dest);
|
||||
void RateCallback (std::string path, uint32_t rate, Mac48Address dest);
|
||||
void PowerCallback (std::string path, double oldPower, double newPower, Mac48Address dest);
|
||||
void RateCallback (std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest);
|
||||
void StateCallback (std::string path, Time init, Time duration, enum WifiPhy::State state);
|
||||
|
||||
Gnuplot2dDataset GetDatafile ();
|
||||
@@ -94,12 +94,12 @@ public:
|
||||
double GetBusyTime ();
|
||||
|
||||
private:
|
||||
typedef std::vector<std::pair<Time,WifiMode> > TxTime;
|
||||
typedef std::vector<std::pair<Time, DataRate> > TxTime;
|
||||
void SetupPhy (Ptr<WifiPhy> phy);
|
||||
Time GetCalcTxTime (WifiMode mode);
|
||||
Time GetCalcTxTime (DataRate rate);
|
||||
|
||||
std::map<Mac48Address, double> actualPower;
|
||||
std::map<Mac48Address, WifiMode> actualMode;
|
||||
std::map<Mac48Address, double> currentPower;
|
||||
std::map<Mac48Address, DataRate> currentRate;
|
||||
uint32_t m_bytesTotal;
|
||||
double totalEnergy;
|
||||
double totalTime;
|
||||
@@ -128,15 +128,17 @@ NodeStatistics::NodeStatistics (NetDeviceContainer aps, NetDeviceContainer stas)
|
||||
Ptr<WifiPhy> phy = wifiDevice->GetPhy ();
|
||||
myPhy = phy;
|
||||
SetupPhy (phy);
|
||||
DataRate dataRate = DataRate (phy->GetMode (0).GetDataRate (phy->GetChannelWidth ()));
|
||||
double power = phy->GetTxPowerEnd ();
|
||||
for (uint32_t j = 0; j < stas.GetN (); j++)
|
||||
{
|
||||
Ptr<NetDevice> staDevice = stas.Get (j);
|
||||
Ptr<WifiNetDevice> wifiStaDevice = DynamicCast<WifiNetDevice> (staDevice);
|
||||
Mac48Address addr = wifiStaDevice->GetMac ()->GetAddress ();
|
||||
actualPower[addr] = 17;
|
||||
actualMode[addr] = phy->GetMode (0);
|
||||
currentPower[addr] = power;
|
||||
currentRate[addr] = dataRate;
|
||||
}
|
||||
actualMode[Mac48Address ("ff:ff:ff:ff:ff:ff")] = phy->GetMode (0);
|
||||
currentRate[Mac48Address ("ff:ff:ff:ff:ff:ff")] = dataRate;
|
||||
totalEnergy = 0;
|
||||
totalTime = 0;
|
||||
busyTime = 0;
|
||||
@@ -165,16 +167,20 @@ NodeStatistics::SetupPhy (Ptr<WifiPhy> phy)
|
||||
WifiTxVector txVector;
|
||||
txVector.SetMode (mode);
|
||||
txVector.SetPreambleType (WIFI_PREAMBLE_LONG);
|
||||
timeTable.push_back (std::make_pair (phy->CalculateTxDuration (packetSize, txVector, phy->GetFrequency ()), mode));
|
||||
txVector.SetChannelWidth (phy->GetChannelWidth ());
|
||||
DataRate dataRate = DataRate (mode.GetDataRate (phy->GetChannelWidth ()));
|
||||
Time time = phy->CalculateTxDuration (packetSize, txVector, phy->GetFrequency ());
|
||||
NS_LOG_DEBUG (i << " " << time.GetSeconds () << " " << dataRate);
|
||||
timeTable.push_back (std::make_pair (time, dataRate));
|
||||
}
|
||||
}
|
||||
|
||||
Time
|
||||
NodeStatistics::GetCalcTxTime (WifiMode mode)
|
||||
NodeStatistics::GetCalcTxTime (DataRate rate)
|
||||
{
|
||||
for (TxTime::const_iterator i = timeTable.begin (); i != timeTable.end (); i++)
|
||||
{
|
||||
if (mode == i->second)
|
||||
if (rate == i->second)
|
||||
{
|
||||
return i->first;
|
||||
}
|
||||
@@ -192,34 +198,21 @@ NodeStatistics::PhyCallback (std::string path, Ptr<const Packet> packet)
|
||||
|
||||
if (head.GetType () == WIFI_MAC_DATA)
|
||||
{
|
||||
totalEnergy += pow (10.0, actualPower[dest] / 10.0) * GetCalcTxTime (actualMode[dest]).GetSeconds ();
|
||||
totalTime += GetCalcTxTime (actualMode[dest]).GetSeconds ();
|
||||
totalEnergy += pow (10.0, currentPower[dest] / 10.0) * GetCalcTxTime (currentRate[dest]).GetSeconds ();
|
||||
totalTime += GetCalcTxTime (currentRate[dest]).GetSeconds ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NodeStatistics::PowerCallback (std::string path, uint8_t power, Mac48Address dest)
|
||||
NodeStatistics::PowerCallback (std::string path, double oldPower, double newPower, Mac48Address dest)
|
||||
{
|
||||
double txPowerBaseDbm = myPhy->GetTxPowerStart ();
|
||||
double txPowerEndDbm = myPhy->GetTxPowerEnd ();
|
||||
uint32_t nTxPower = myPhy->GetNTxPower ();
|
||||
double dbm;
|
||||
if (nTxPower > 1)
|
||||
{
|
||||
dbm = txPowerBaseDbm + power * (txPowerEndDbm - txPowerBaseDbm) / (nTxPower - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT_MSG (txPowerBaseDbm == txPowerEndDbm, "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
|
||||
dbm = txPowerBaseDbm;
|
||||
}
|
||||
actualPower[dest] = dbm;
|
||||
currentPower[dest] = newPower;
|
||||
}
|
||||
|
||||
void
|
||||
NodeStatistics::RateCallback (std::string path, uint32_t rate, Mac48Address dest)
|
||||
NodeStatistics::RateCallback (std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest)
|
||||
{
|
||||
actualMode[dest] = myPhy->GetMode (rate);
|
||||
currentRate[dest] = newRate;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -318,16 +311,14 @@ NodeStatistics::GetBusyTime ()
|
||||
return totalBusyTime + totalRxTime;
|
||||
}
|
||||
|
||||
void PowerCallback (std::string path, uint8_t power, Mac48Address dest)
|
||||
void PowerCallback (std::string path, double oldPower, double newPower, Mac48Address dest)
|
||||
{
|
||||
NS_LOG_INFO ((Simulator::Now ()).GetSeconds () << " " << dest << " Power " << (int)power);
|
||||
// end PowerCallback
|
||||
NS_LOG_INFO ((Simulator::Now ()).GetSeconds () << " " << dest << " Old power=" << oldPower << " New power=" << newPower);
|
||||
}
|
||||
|
||||
void RateCallback (std::string path, uint32_t rate, Mac48Address dest)
|
||||
void RateCallback (std::string path, DataRate oldRate, DataRate newRate, Mac48Address dest)
|
||||
{
|
||||
NS_LOG_INFO ((Simulator::Now ()).GetSeconds () << " " << dest << " Rate " << rate);
|
||||
// end PowerCallback
|
||||
NS_LOG_INFO ((Simulator::Now ()).GetSeconds () << " " << dest << " Old rate=" << oldRate << " New rate=" << newRate);
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
@@ -370,7 +361,7 @@ int main (int argc, char *argv[])
|
||||
cmd.AddValue ("STA2_y", "Position of STA2 in y coordinate", sta2_y);
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
// Define the APs
|
||||
//Define the APs
|
||||
NodeContainer wifiApNodes;
|
||||
wifiApNodes.Create (2);
|
||||
|
||||
@@ -427,7 +418,7 @@ int main (int argc, char *argv[])
|
||||
wifiDevices.Add (wifiStaDevices);
|
||||
wifiDevices.Add (wifiApDevices);
|
||||
|
||||
// Configure the mobility.
|
||||
//Configure the mobility.
|
||||
MobilityHelper mobility;
|
||||
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
|
||||
positionAlloc->Add (Vector (ap1_x, ap1_y, 0.0));
|
||||
@@ -520,8 +511,7 @@ int main (int argc, char *argv[])
|
||||
MakeCallback (RateCallback));
|
||||
|
||||
|
||||
// Calculate Throughput using Flowmonitor
|
||||
//
|
||||
//Calculate Throughput using Flowmonitor
|
||||
|
||||
FlowMonitorHelper flowmon;
|
||||
Ptr<FlowMonitor> monitor = flowmon.InstallAll ();
|
||||
@@ -566,7 +556,8 @@ int main (int argc, char *argv[])
|
||||
gnuplot.GenerateOutput (outfileTh0);
|
||||
|
||||
if (manager.compare ("ns3::ParfWifiManager") == 0
|
||||
|| manager.compare ("ns3::AparfWifiManager") == 0)
|
||||
|| manager.compare ("ns3::AparfWifiManager") == 0
|
||||
|| manager.compare ("ns3::RrpaaWifiManager") == 0)
|
||||
{
|
||||
std::ofstream outfilePower0 (("power-" + outputFileName + "-0.plt").c_str ());
|
||||
gnuplot = Gnuplot (("power-" + outputFileName + "-0.eps").c_str (), "Average Transmit Power");
|
||||
@@ -619,7 +610,8 @@ int main (int argc, char *argv[])
|
||||
gnuplot.GenerateOutput (outfileTh1);
|
||||
|
||||
if (manager.compare ("ns3::ParfWifiManager") == 0
|
||||
|| manager.compare ("ns3::AparfWifiManager") == 0)
|
||||
|| manager.compare ("ns3::AparfWifiManager") == 0
|
||||
|| manager.compare ("ns3::RrpaaWifiManager") == 0)
|
||||
{
|
||||
std::ofstream outfilePower1 (("power-" + outputFileName + "-1.plt").c_str ());
|
||||
gnuplot = Gnuplot (("power-" + outputFileName + "-1.eps").c_str (), "Average Transmit Power");
|
||||
|
||||
@@ -50,7 +50,9 @@ class TracedCallbackTypedefTestCase : public TestCase
|
||||
{
|
||||
public:
|
||||
TracedCallbackTypedefTestCase ();
|
||||
virtual ~TracedCallbackTypedefTestCase () {}
|
||||
virtual ~TracedCallbackTypedefTestCase ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of arguments passed to callback.
|
||||
@@ -61,24 +63,23 @@ public:
|
||||
* in the CheckType() method.
|
||||
*/
|
||||
static int m_nArgs;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/** Invoker boilerplate. */
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class CheckerBase;
|
||||
|
||||
|
||||
/** Callback checkers. */
|
||||
template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class Checker;
|
||||
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
class Checker<T1, T2, T3, T4, empty>;
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
class Checker<T1, T2, T3, empty, empty>;
|
||||
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
class Checker<T1, T2, empty, empty, empty>;
|
||||
|
||||
@@ -111,13 +112,13 @@ Duplicates (void)
|
||||
|
||||
return dupes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Container for duplicate types.
|
||||
*/
|
||||
std::set<std::string> g_dupes = Duplicates ();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Stringify the known TracedCallback type names.
|
||||
*
|
||||
@@ -125,16 +126,21 @@ std::set<std::string> g_dupes = Duplicates ();
|
||||
* \param [in] N The number of arguments expected.
|
||||
* \returns The \c TracedCallback type name.
|
||||
*/
|
||||
template <typename T> inline
|
||||
std::string TypeName (int N) { return "unknown"; }
|
||||
template <typename T>
|
||||
inline
|
||||
std::string TypeName (int N)
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
#define TYPENAME(T) \
|
||||
template <> inline std::string \
|
||||
TypeName < T > (int N) \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
#define TYPENAME(T) \
|
||||
template <> \
|
||||
inline std::string \
|
||||
TypeName < T > (int N) \
|
||||
{ \
|
||||
std::stringstream ss; \
|
||||
ss << # T << "(" << N << ")"; \
|
||||
return ss.str (); \
|
||||
return ss.str (); \
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,12 +166,12 @@ TYPENAME (LteEnbRrc::ConnectionHandoverTracedCallback);
|
||||
TYPENAME (LteEnbRrc::HandoverStartTracedCallback);
|
||||
TYPENAME (LteEnbRrc::NewUeContextTracedCallback);
|
||||
TYPENAME (LteEnbRrc::ReceiveReportTracedCallback);
|
||||
TYPENAME (LtePdcp::PduRxTracedCallback);
|
||||
TYPENAME (LtePdcp::PduRxTracedCallback);
|
||||
TYPENAME (LtePdcp::PduTxTracedCallback);
|
||||
TYPENAME (LteUePhy::StateTracedCallback);
|
||||
TYPENAME (LteUePhy::RsrpSinrTracedCallback);
|
||||
TYPENAME (LteUePhy::RsrpSinrTracedCallback);
|
||||
TYPENAME (LteUeRrc::CellSelectionTracedCallback);
|
||||
TYPENAME (LteUeRrc::StateTracedCallback);
|
||||
TYPENAME (LteUeRrc::StateTracedCallback);
|
||||
TYPENAME (Mac48Address::TracedCallback);
|
||||
TYPENAME (MobilityModel::TracedCallback);
|
||||
TYPENAME (olsr::RoutingProtocol::PacketTxRxTracedCallback);
|
||||
@@ -222,35 +228,50 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class TracedCbSink
|
||||
{
|
||||
public:
|
||||
static void Sink (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) { SinkIt (5); }
|
||||
static void Sink (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
|
||||
{
|
||||
SinkIt (5);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
class TracedCbSink<T1, T2, T3, T4, empty>
|
||||
{
|
||||
public:
|
||||
static void Sink (T1 a1, T2 a2, T3 a3, T4 a4) { SinkIt (4); }
|
||||
static void Sink (T1 a1, T2 a2, T3 a3, T4 a4)
|
||||
{
|
||||
SinkIt (4);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
class TracedCbSink<T1, T2, T3, empty, empty>
|
||||
{
|
||||
public:
|
||||
static void Sink (T1 a1, T2 a2, T3 a3) { SinkIt (3); }
|
||||
static void Sink (T1 a1, T2 a2, T3 a3)
|
||||
{
|
||||
SinkIt (3);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
class TracedCbSink<T1, T2, empty, empty, empty>
|
||||
{
|
||||
public:
|
||||
static void Sink (T1 a1, T2 a2) { SinkIt (2); }
|
||||
static void Sink (T1 a1, T2 a2)
|
||||
{
|
||||
SinkIt (2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T1>
|
||||
class TracedCbSink< T1, empty, empty, empty, empty>
|
||||
{
|
||||
public:
|
||||
static void Sink (T1 a1) { SinkIt (1); }
|
||||
static void Sink (T1 a1)
|
||||
{
|
||||
SinkIt (1);
|
||||
}
|
||||
};
|
||||
/** @} */
|
||||
|
||||
@@ -278,10 +299,13 @@ public:
|
||||
typename TypeTraits<T3>::BaseType m3;
|
||||
typename TypeTraits<T4>::BaseType m4;
|
||||
typename TypeTraits<T5>::BaseType m5;
|
||||
|
||||
|
||||
void Cleanup (int N)
|
||||
{
|
||||
if (m_nArgs == 0) std::cout << std::endl;
|
||||
if (m_nArgs == 0)
|
||||
{
|
||||
std::cout << std::endl;
|
||||
}
|
||||
NS_ASSERT_MSG (m_nArgs && m_nArgs == N, "failed.");
|
||||
m_nArgs = 0;
|
||||
}
|
||||
@@ -291,7 +315,7 @@ template <typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
class TracedCallbackTypedefTestCase::Checker : public CheckerBase<T1, T2, T3, T4, T5>
|
||||
{
|
||||
TracedCallback<T1, T2, T3, T4, T5> m_cb;
|
||||
|
||||
|
||||
public:
|
||||
template <typename U>
|
||||
void Invoke (void)
|
||||
@@ -299,7 +323,7 @@ public:
|
||||
const int N = 5;
|
||||
U sink = TracedCbSink<T1, T2, T3, T4, T5>::Sink;
|
||||
Callback<void, T1, T2, T3, T4, T5> cb = MakeCallback (sink);
|
||||
|
||||
|
||||
std::cout << TypeName<U> (N) << " invoked ";
|
||||
m_cb.ConnectWithoutContext (cb);
|
||||
m_cb (this->m1, this->m2, this->m3, this->m4, this->m5);
|
||||
@@ -312,7 +336,7 @@ class TracedCallbackTypedefTestCase::Checker<T1, T2, T3, T4, empty>
|
||||
: public CheckerBase<T1, T2, T3, T4, empty>
|
||||
{
|
||||
TracedCallback<T1, T2, T3, T4> m_cb;
|
||||
|
||||
|
||||
public:
|
||||
template <typename U>
|
||||
void Invoke (void)
|
||||
@@ -320,20 +344,20 @@ public:
|
||||
const int N = 4;
|
||||
U sink = TracedCbSink<T1, T2, T3, T4, empty>::Sink;
|
||||
Callback<void, T1, T2, T3, T4> cb = MakeCallback (sink);
|
||||
|
||||
|
||||
std::cout << TypeName<U> (N) << " invoked ";
|
||||
m_cb.ConnectWithoutContext (cb);
|
||||
m_cb (this->m1, this->m2, this->m3, this->m4);
|
||||
this->Cleanup (N);
|
||||
}
|
||||
}; // Checker <4>
|
||||
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
class TracedCallbackTypedefTestCase::Checker<T1, T2, T3, empty, empty>
|
||||
: public CheckerBase<T1, T2, T3, empty, empty>
|
||||
{
|
||||
TracedCallback<T1, T2, T3> m_cb;
|
||||
|
||||
|
||||
public:
|
||||
template <typename U>
|
||||
void Invoke (void)
|
||||
@@ -341,7 +365,7 @@ public:
|
||||
const int N = 3;
|
||||
U sink = TracedCbSink<T1, T2, T3, empty, empty>::Sink;
|
||||
Callback<void, T1, T2, T3> cb = MakeCallback (sink);
|
||||
|
||||
|
||||
std::cout << TypeName<U> (N) << " invoked ";
|
||||
m_cb.ConnectWithoutContext (cb);
|
||||
m_cb (this->m1, this->m2, this->m3);
|
||||
@@ -354,7 +378,7 @@ class TracedCallbackTypedefTestCase::Checker<T1, T2, empty, empty, empty>
|
||||
: public CheckerBase<T1, T2, empty, empty, empty>
|
||||
{
|
||||
TracedCallback<T1, T2> m_cb;
|
||||
|
||||
|
||||
public:
|
||||
template <typename U>
|
||||
void Invoke (void)
|
||||
@@ -362,7 +386,7 @@ public:
|
||||
const int N = 2;
|
||||
U sink = TracedCbSink<T1, T2, empty, empty, empty>::Sink;
|
||||
Callback<void, T1, T2> cb = MakeCallback (sink);
|
||||
|
||||
|
||||
std::cout << TypeName<U> (N) << " invoked ";
|
||||
m_cb.ConnectWithoutContext (cb);
|
||||
m_cb (this->m1, this->m2);
|
||||
@@ -375,7 +399,7 @@ class TracedCallbackTypedefTestCase::Checker<T1, empty, empty, empty, empty>
|
||||
: public CheckerBase<T1, empty, empty, empty, empty>
|
||||
{
|
||||
TracedCallback<T1> m_cb;
|
||||
|
||||
|
||||
public:
|
||||
template <typename U>
|
||||
void Invoke (void)
|
||||
@@ -383,7 +407,7 @@ public:
|
||||
const int N = 1;
|
||||
U sink = TracedCbSink<T1, empty, empty, empty, empty>::Sink;
|
||||
Callback<void, T1> cb = MakeCallback (sink);
|
||||
|
||||
|
||||
std::cout << TypeName<U> (N) << " invoked ";
|
||||
m_cb.ConnectWithoutContext (cb);
|
||||
m_cb (this->m1);
|
||||
@@ -401,20 +425,20 @@ TracedCallbackTypedefTestCase::DoRun (void)
|
||||
{
|
||||
|
||||
#define DUPE(U, T1) \
|
||||
if (g_dupes.find ( # U ) == g_dupes.end ()) \
|
||||
NS_TEST_ASSERT_MSG_NE (0, 1, \
|
||||
"expected to find " << # U << " in dupes."); \
|
||||
if (TypeName<U> (0) == TypeName<T1> (0)) \
|
||||
std::cout << # U << " matches " << # T1 << std::endl; \
|
||||
if (g_dupes.find ( # U ) == g_dupes.end ()) { \
|
||||
NS_TEST_ASSERT_MSG_NE (0, 1, \
|
||||
"expected to find " << # U << " in dupes."); } \
|
||||
if (TypeName<U> (0) == TypeName<T1> (0)) { \
|
||||
std::cout << # U << " matches " << # T1 << std::endl; } \
|
||||
else \
|
||||
NS_TEST_ASSERT_MSG_EQ \
|
||||
(TypeName<U> (0), TypeName<T1> (0), \
|
||||
"the typedef " << # U << \
|
||||
" used to match the typedef " << # T1 << \
|
||||
" but no longer does. Please add a new CHECK call.")
|
||||
"the typedef " << # U << \
|
||||
" used to match the typedef " << # T1 << \
|
||||
" but no longer does. Please add a new CHECK call.")
|
||||
|
||||
#define CHECK(U, T1, T2, T3, T4, T5) \
|
||||
CreateObject< Checker<T1, T2, T3, T4, T5> > () -> Invoke<U> ()
|
||||
CreateObject< Checker<T1, T2, T3, T4, T5> > ()->Invoke<U> ()
|
||||
|
||||
CHECK (dsr::DsrOptionSRHeader::TracedCallback,
|
||||
const dsr::DsrOptionSRHeader &,
|
||||
@@ -435,11 +459,11 @@ TracedCallbackTypedefTestCase::DoRun (void)
|
||||
CHECK (Ipv4L3Protocol::TxRxTracedCallback,
|
||||
Ptr<const Packet>, Ptr<Ipv4>, uint32_t,
|
||||
empty, empty);
|
||||
|
||||
|
||||
CHECK (Ipv6L3Protocol::DropTracedCallback,
|
||||
const Ipv6Header &, Ptr<const Packet>,
|
||||
Ipv6L3Protocol::DropReason, Ptr<Ipv6>, uint32_t
|
||||
);
|
||||
);
|
||||
|
||||
CHECK (Ipv6L3Protocol::SentTracedCallback,
|
||||
const Ipv6Header &, Ptr<const Packet>, uint32_t,
|
||||
@@ -461,7 +485,7 @@ TracedCallbackTypedefTestCase::DoRun (void)
|
||||
Time, LrWpanPhyEnumeration, LrWpanPhyEnumeration,
|
||||
empty, empty);
|
||||
|
||||
|
||||
|
||||
/* Too many args :(
|
||||
CHECK (LteEnbMac::DlSchedulingTracedCallback,
|
||||
uint32_t, uint32_t, uint16_t,
|
||||
@@ -486,7 +510,7 @@ TracedCallbackTypedefTestCase::DoRun (void)
|
||||
CHECK (LteEnbRrc::HandoverStartTracedCallback,
|
||||
uint64_t, uint16_t, uint16_t, uint16_t,
|
||||
empty);
|
||||
|
||||
|
||||
CHECK (LteEnbRrc::NewUeContextTracedCallback,
|
||||
uint16_t, uint16_t,
|
||||
empty, empty, empty);
|
||||
@@ -524,7 +548,7 @@ TracedCallbackTypedefTestCase::DoRun (void)
|
||||
|
||||
CHECK (LteUeRrc::StateTracedCallback,
|
||||
uint64_t, uint16_t, uint16_t, LteUeRrc::State, LteUeRrc::State);
|
||||
|
||||
|
||||
CHECK (Mac48Address::TracedCallback,
|
||||
Mac48Address,
|
||||
empty, empty, empty, empty);
|
||||
@@ -568,7 +592,7 @@ TracedCallbackTypedefTestCase::DoRun (void)
|
||||
CHECK (dot11s::PeerManagementProtocol::LinkOpenCloseTracedCallback,
|
||||
Mac48Address, Mac48Address,
|
||||
empty, empty, empty);
|
||||
|
||||
|
||||
CHECK (PhyReceptionStatParameters::TracedCallback,
|
||||
PhyReceptionStatParameters,
|
||||
empty, empty, empty, empty);
|
||||
@@ -589,7 +613,7 @@ TracedCallbackTypedefTestCase::DoRun (void)
|
||||
CHECK (SpectrumChannel::LossTracedCallback,
|
||||
Ptr<SpectrumPhy>, Ptr<SpectrumPhy>, double,
|
||||
empty, empty);
|
||||
|
||||
|
||||
CHECK (SpectrumValue::TracedCallback,
|
||||
Ptr<SpectrumValue>,
|
||||
empty, empty, empty, empty);
|
||||
@@ -601,11 +625,11 @@ TracedCallbackTypedefTestCase::DoRun (void)
|
||||
CHECK (UanMac::PacketModeTracedCallback,
|
||||
Ptr<const Packet>, UanTxMode,
|
||||
empty, empty, empty);
|
||||
|
||||
|
||||
CHECK (UanMacCw::QueueTracedCallback,
|
||||
Ptr<const Packet>, uint16_t,
|
||||
empty, empty, empty);
|
||||
|
||||
|
||||
CHECK (UanMacRc::QueueTracedCallback,
|
||||
Ptr<const Packet>, uint32_t,
|
||||
empty, empty, empty);
|
||||
@@ -613,14 +637,14 @@ TracedCallbackTypedefTestCase::DoRun (void)
|
||||
CHECK (UanNetDevice::RxTxTracedCallback,
|
||||
Ptr<const Packet>, UanAddress,
|
||||
empty, empty, empty);
|
||||
|
||||
|
||||
CHECK (UanPhy::TracedCallback,
|
||||
Ptr<const Packet>, double, UanTxMode,
|
||||
empty, empty);
|
||||
|
||||
CHECK (UeManager::StateTracedCallback,
|
||||
uint64_t, uint16_t, uint16_t, UeManager::State, UeManager::State);
|
||||
|
||||
|
||||
CHECK (WifiMacHeader::TracedCallback,
|
||||
const WifiMacHeader &,
|
||||
empty, empty, empty, empty);
|
||||
@@ -642,12 +666,12 @@ TracedCallbackTypedefTestCase::DoRun (void)
|
||||
empty);
|
||||
|
||||
CHECK (WifiRemoteStationManager::PowerChangeTracedCallback,
|
||||
uint8_t, Mac48Address,
|
||||
empty, empty, empty);
|
||||
double, double, Mac48Address,
|
||||
empty, empty);
|
||||
|
||||
CHECK (WifiRemoteStationManager::RateChangeTracedCallback,
|
||||
uint32_t, Mac48Address,
|
||||
empty, empty, empty);
|
||||
DataRate, DataRate, Mac48Address,
|
||||
empty, empty);
|
||||
}
|
||||
|
||||
class TracedCallbackTypedefTestSuite : public TestSuite
|
||||
|
||||
@@ -43,9 +43,11 @@ AparfWifiRemoteStation : public WifiRemoteStation
|
||||
uint32_t m_pCount; //!< Number of power changes.
|
||||
uint32_t m_successThreshold; //!< The minimum number of successful transmissions to try a new power or rate.
|
||||
uint32_t m_failThreshold; //!< The minimum number of failed transmissions to try a new power or rate.
|
||||
uint32_t m_rate; //!< Current rate.
|
||||
uint32_t m_rateCrit; //!< Critical rate.
|
||||
uint8_t m_power; //!< Current power.
|
||||
uint32_t m_prevRateIndex; //!< Rate index of the previous transmission.
|
||||
uint32_t m_rateIndex; //!< Current rate index.
|
||||
uint32_t m_critRateIndex; //!< Critical rate.
|
||||
uint8_t m_prevPowerLevel; //!< Power level of the previous transmission.
|
||||
uint8_t m_powerLevel; //!< Current power level.
|
||||
uint32_t m_nSupported; //!< Number of supported rates by the remote station.
|
||||
bool m_initialized; //!< For initializing variables.
|
||||
AparfWifiManager::State m_aparfState; //!< The estimated state of the channel.
|
||||
@@ -144,8 +146,8 @@ AparfWifiManager::DoCreateStation (void) const
|
||||
station->m_aparfState = AparfWifiManager::High;
|
||||
station->m_initialized = false;
|
||||
|
||||
NS_LOG_DEBUG ("create station=" << station << ", rate=" << station->m_rate
|
||||
<< ", power=" << (int)station->m_power);
|
||||
NS_LOG_DEBUG ("create station=" << station << ", rate=" << station->m_rateIndex
|
||||
<< ", power=" << (int)station->m_powerLevel);
|
||||
|
||||
return station;
|
||||
}
|
||||
@@ -156,11 +158,17 @@ AparfWifiManager::CheckInit (AparfWifiRemoteStation *station)
|
||||
if (!station->m_initialized)
|
||||
{
|
||||
station->m_nSupported = GetNSupported (station);
|
||||
station->m_rate = station->m_nSupported - 1;
|
||||
station->m_power = m_maxPower;
|
||||
station->m_rateCrit = 0;
|
||||
m_powerChange (station->m_power, station->m_state->m_address);
|
||||
m_rateChange (station->m_rate, station->m_state->m_address);
|
||||
station->m_rateIndex = station->m_nSupported - 1;
|
||||
station->m_prevRateIndex = station->m_nSupported - 1;
|
||||
station->m_powerLevel = m_maxPower;
|
||||
station->m_prevPowerLevel = m_maxPower;
|
||||
station->m_critRateIndex = 0;
|
||||
WifiMode mode = GetSupported (station, station->m_rateIndex);
|
||||
uint8_t channelWidth = GetChannelWidth (station);
|
||||
DataRate rate = DataRate (mode.GetDataRate (channelWidth));
|
||||
double power = GetPhy ()->GetPowerDbm (m_maxPower);
|
||||
m_powerChange (power, power, station->m_state->m_address);
|
||||
m_rateChange (rate, rate, station->m_state->m_address);
|
||||
station->m_initialized = true;
|
||||
}
|
||||
}
|
||||
@@ -177,8 +185,8 @@ void AparfWifiManager::DoReportDataFailed (WifiRemoteStation *st)
|
||||
CheckInit (station);
|
||||
station->m_nFailed++;
|
||||
station->m_nSuccess = 0;
|
||||
NS_LOG_DEBUG ("station=" << station << ", rate=" << station->m_rate
|
||||
<< ", power=" << (int)station->m_power);
|
||||
NS_LOG_DEBUG ("station=" << station << ", rate=" << station->m_rateIndex
|
||||
<< ", power=" << (int)station->m_powerLevel);
|
||||
|
||||
if (station->m_aparfState == AparfWifiManager::Low)
|
||||
{
|
||||
@@ -196,21 +204,19 @@ void AparfWifiManager::DoReportDataFailed (WifiRemoteStation *st)
|
||||
station->m_nFailed = 0;
|
||||
station->m_nSuccess = 0;
|
||||
station->m_pCount = 0;
|
||||
if (station->m_power == m_maxPower)
|
||||
if (station->m_powerLevel == m_maxPower)
|
||||
{
|
||||
station->m_rateCrit = station->m_rate;
|
||||
if (station->m_rate != 0)
|
||||
station->m_critRateIndex = station->m_rateIndex;
|
||||
if (station->m_rateIndex != 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("station=" << station << " dec rate");
|
||||
station->m_rate -= m_rateDec;
|
||||
m_rateChange (station->m_rate, station->m_state->m_address);
|
||||
station->m_rateIndex -= m_rateDec;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("station=" << station << " inc power");
|
||||
station->m_power += m_powerInc;
|
||||
m_powerChange (station->m_power, station->m_state->m_address);
|
||||
station->m_powerLevel += m_powerInc;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,7 +244,7 @@ AparfWifiManager::DoReportDataOk (WifiRemoteStation *st, double ackSnr,
|
||||
CheckInit (station);
|
||||
station->m_nSuccess++;
|
||||
station->m_nFailed = 0;
|
||||
NS_LOG_DEBUG ("station=" << station << " data ok success=" << station->m_nSuccess << ", rate=" << station->m_rate << ", power=" << (int)station->m_power);
|
||||
NS_LOG_DEBUG ("station=" << station << " data ok success=" << station->m_nSuccess << ", rate=" << station->m_rateIndex << ", power=" << (int)station->m_powerLevel);
|
||||
|
||||
if ((station->m_aparfState == AparfWifiManager::High) && (station->m_nSuccess >= station->m_successThreshold))
|
||||
{
|
||||
@@ -258,43 +264,38 @@ AparfWifiManager::DoReportDataOk (WifiRemoteStation *st, double ackSnr,
|
||||
{
|
||||
station->m_nSuccess = 0;
|
||||
station->m_nFailed = 0;
|
||||
if (station->m_rate == (station->m_state->m_operationalRateSet.size () - 1))
|
||||
if (station->m_rateIndex == (station->m_state->m_operationalRateSet.size () - 1))
|
||||
{
|
||||
if (station->m_power != m_minPower)
|
||||
if (station->m_powerLevel != m_minPower)
|
||||
{
|
||||
NS_LOG_DEBUG ("station=" << station << " dec power");
|
||||
station->m_power -= m_powerDec;
|
||||
m_powerChange (station->m_power, station->m_state->m_address);
|
||||
station->m_powerLevel -= m_powerDec;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (station->m_rateCrit == 0)
|
||||
if (station->m_critRateIndex == 0)
|
||||
{
|
||||
if (station->m_rate != (station->m_state->m_operationalRateSet.size () - 1))
|
||||
if (station->m_rateIndex != (station->m_state->m_operationalRateSet.size () - 1))
|
||||
{
|
||||
NS_LOG_DEBUG ("station=" << station << " inc rate");
|
||||
station->m_rate += m_rateInc;
|
||||
m_rateChange (station->m_rate, station->m_state->m_address);
|
||||
station->m_rateIndex += m_rateInc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (station->m_pCount == m_powerMax)
|
||||
{
|
||||
station->m_power = m_maxPower;
|
||||
m_powerChange (station->m_power, station->m_state->m_address);
|
||||
station->m_rate = station->m_rateCrit;
|
||||
m_rateChange (station->m_rate, station->m_state->m_address);
|
||||
station->m_powerLevel = m_maxPower;
|
||||
station->m_rateIndex = station->m_critRateIndex;
|
||||
station->m_pCount = 0;
|
||||
station->m_rateCrit = 0;
|
||||
station->m_critRateIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (station->m_power != m_minPower)
|
||||
if (station->m_powerLevel != m_minPower)
|
||||
{
|
||||
station->m_power -= m_powerDec;
|
||||
m_powerChange (station->m_power, station->m_state->m_address);
|
||||
station->m_powerLevel -= m_powerDec;
|
||||
station->m_pCount++;
|
||||
}
|
||||
}
|
||||
@@ -327,8 +328,22 @@ AparfWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
channelWidth = 20;
|
||||
}
|
||||
CheckInit (station);
|
||||
WifiMode mode = GetSupported (station, station->m_rate);
|
||||
return WifiTxVector (mode, station->m_power, GetLongRetryCount (station), GetPreambleForTransmission (mode, GetAddress (st)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
|
||||
WifiMode mode = GetSupported (station, station->m_rateIndex);
|
||||
DataRate rate = DataRate (mode.GetDataRate (channelWidth));
|
||||
DataRate prevRate = DataRate (GetSupported (station, station->m_prevRateIndex).GetDataRate (channelWidth));
|
||||
double power = GetPhy ()->GetPowerDbm (station->m_powerLevel);
|
||||
double prevPower = GetPhy ()->GetPowerDbm (station->m_prevPowerLevel);
|
||||
if (station->m_prevPowerLevel != station->m_powerLevel)
|
||||
{
|
||||
m_powerChange (prevPower, power, station->m_state->m_address);
|
||||
station->m_prevPowerLevel = station->m_powerLevel;
|
||||
}
|
||||
if (station->m_prevRateIndex != station->m_rateIndex)
|
||||
{
|
||||
m_rateChange (prevRate, rate, station->m_state->m_address);
|
||||
station->m_prevRateIndex = station->m_rateIndex;
|
||||
}
|
||||
return WifiTxVector (mode, station->m_powerLevel, GetLongRetryCount (station), GetPreambleForTransmission (mode, GetAddress (st)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
|
||||
}
|
||||
|
||||
WifiTxVector
|
||||
|
||||
@@ -115,13 +115,13 @@ private:
|
||||
uint32_t m_maxPower;
|
||||
|
||||
/**
|
||||
* The trace source fired when the transmission power change
|
||||
* The trace source fired when the transmission power changes.
|
||||
*/
|
||||
TracedCallback<uint8_t, Mac48Address> m_powerChange;
|
||||
TracedCallback<double, double, Mac48Address> m_powerChange;
|
||||
/**
|
||||
* The trace source fired when the transmission rate change
|
||||
* The trace source fired when the transmission rate changes.
|
||||
*/
|
||||
TracedCallback<uint32_t, Mac48Address> m_rateChange;
|
||||
TracedCallback<DataRate, DataRate, Mac48Address> m_rateChange;
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -43,8 +43,10 @@ struct ParfWifiRemoteStation : public WifiRemoteStation
|
||||
bool m_usingRecoveryRate; //!< If using recovery rate.
|
||||
bool m_usingRecoveryPower; //!< If using recovery power.
|
||||
uint32_t m_nRetry; //!< Number of transmission retries.
|
||||
uint32_t m_currentRate; //!< Current rate used by the remote station.
|
||||
uint8_t m_currentPower; //!< Current power used by the remote station.
|
||||
uint32_t m_prevRateIndex; //!< Rate index of the previous transmission.
|
||||
uint32_t m_rateIndex; //!< Current rate index used by the remote station.
|
||||
uint8_t m_prevPowerLevel; //!< Power level of the previous transmission.
|
||||
uint8_t m_powerLevel; //!< Current power level used by the remote station.
|
||||
uint32_t m_nSupported; //!< Number of supported rates by the remote station.
|
||||
bool m_initialized; //!< For initializing variables.
|
||||
};
|
||||
@@ -113,7 +115,7 @@ ParfWifiManager::DoCreateStation (void) const
|
||||
station->m_nAttempt = 0;
|
||||
|
||||
NS_LOG_DEBUG ("create station=" << station << ", timer=" << station->m_nAttempt
|
||||
<< ", rate=" << station->m_currentRate << ", power=" << (int)station->m_currentPower);
|
||||
<< ", rate=" << station->m_rateIndex << ", power=" << (int)station->m_powerLevel);
|
||||
|
||||
return station;
|
||||
}
|
||||
@@ -124,10 +126,16 @@ ParfWifiManager::CheckInit (ParfWifiRemoteStation *station)
|
||||
if (!station->m_initialized)
|
||||
{
|
||||
station->m_nSupported = GetNSupported (station);
|
||||
station->m_currentRate = station->m_nSupported - 1;
|
||||
station->m_currentPower = m_maxPower;
|
||||
m_powerChange (station->m_currentPower, station->m_state->m_address);
|
||||
m_rateChange (station->m_currentRate, station->m_state->m_address);
|
||||
station->m_rateIndex = station->m_nSupported - 1;
|
||||
station->m_prevRateIndex = station->m_nSupported - 1;
|
||||
station->m_powerLevel = m_maxPower;
|
||||
station->m_prevPowerLevel = m_maxPower;
|
||||
WifiMode mode = GetSupported (station, station->m_rateIndex);
|
||||
uint8_t channelWidth = GetChannelWidth (station);
|
||||
DataRate rate = DataRate (mode.GetDataRate (channelWidth));
|
||||
double power = GetPhy ()->GetPowerDbm (m_maxPower);
|
||||
m_powerChange (power, power, station->m_state->m_address);
|
||||
m_rateChange (rate, rate, station->m_state->m_address);
|
||||
station->m_initialized = true;
|
||||
}
|
||||
}
|
||||
@@ -159,18 +167,17 @@ ParfWifiManager::DoReportDataFailed (WifiRemoteStation *st)
|
||||
station->m_nSuccess = 0;
|
||||
|
||||
NS_LOG_DEBUG ("station=" << station << " data fail retry=" << station->m_nRetry << ", timer=" << station->m_nAttempt
|
||||
<< ", rate=" << station->m_currentRate << ", power=" << (int)station->m_currentPower);
|
||||
<< ", rate=" << station->m_rateIndex << ", power=" << (int)station->m_powerLevel);
|
||||
if (station->m_usingRecoveryRate)
|
||||
{
|
||||
NS_ASSERT (station->m_nRetry >= 1);
|
||||
if (station->m_nRetry == 1)
|
||||
{
|
||||
//need recovery fallback
|
||||
if (station->m_currentRate != 0)
|
||||
if (station->m_rateIndex != 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("station=" << station << " dec rate");
|
||||
station->m_currentRate--;
|
||||
m_rateChange (station->m_currentRate, station->m_state->m_address);
|
||||
station->m_rateIndex--;
|
||||
station->m_usingRecoveryRate = false;
|
||||
}
|
||||
}
|
||||
@@ -182,11 +189,10 @@ ParfWifiManager::DoReportDataFailed (WifiRemoteStation *st)
|
||||
if (station->m_nRetry == 1)
|
||||
{
|
||||
//need recovery fallback
|
||||
if (station->m_currentPower < m_maxPower)
|
||||
if (station->m_powerLevel < m_maxPower)
|
||||
{
|
||||
NS_LOG_DEBUG ("station=" << station << " inc power");
|
||||
station->m_currentPower++;
|
||||
m_powerChange (station->m_currentPower, station->m_state->m_address);
|
||||
station->m_powerLevel++;
|
||||
station->m_usingRecoveryPower = false;
|
||||
}
|
||||
}
|
||||
@@ -198,20 +204,18 @@ ParfWifiManager::DoReportDataFailed (WifiRemoteStation *st)
|
||||
if (((station->m_nRetry - 1) % 2) == 1)
|
||||
{
|
||||
//need normal fallback
|
||||
if (station->m_currentPower == m_maxPower)
|
||||
if (station->m_powerLevel == m_maxPower)
|
||||
{
|
||||
if (station->m_currentRate != 0)
|
||||
if (station->m_rateIndex != 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("station=" << station << " dec rate");
|
||||
station->m_currentRate--;
|
||||
m_rateChange (station->m_currentRate, station->m_state->m_address);
|
||||
station->m_rateIndex--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("station=" << station << " inc power");
|
||||
station->m_currentPower++;
|
||||
m_powerChange (station->m_currentPower, station->m_state->m_address);
|
||||
station->m_powerLevel++;
|
||||
}
|
||||
}
|
||||
if (station->m_nRetry >= 2)
|
||||
@@ -247,14 +251,13 @@ void ParfWifiManager::DoReportDataOk (WifiRemoteStation *st,
|
||||
station->m_usingRecoveryRate = false;
|
||||
station->m_usingRecoveryPower = false;
|
||||
station->m_nRetry = 0;
|
||||
NS_LOG_DEBUG ("station=" << station << " data ok success=" << station->m_nSuccess << ", timer=" << station->m_nAttempt << ", rate=" << station->m_currentRate << ", power=" << (int)station->m_currentPower);
|
||||
NS_LOG_DEBUG ("station=" << station << " data ok success=" << station->m_nSuccess << ", timer=" << station->m_nAttempt << ", rate=" << station->m_rateIndex << ", power=" << (int)station->m_powerLevel);
|
||||
if ((station->m_nSuccess == m_successThreshold
|
||||
|| station->m_nAttempt == m_attemptThreshold)
|
||||
&& (station->m_currentRate < (station->m_state->m_operationalRateSet.size () - 1)))
|
||||
&& (station->m_rateIndex < (station->m_state->m_operationalRateSet.size () - 1)))
|
||||
{
|
||||
NS_LOG_DEBUG ("station=" << station << " inc rate");
|
||||
station->m_currentRate++;
|
||||
m_rateChange (station->m_currentRate, station->m_state->m_address);
|
||||
station->m_rateIndex++;
|
||||
station->m_nAttempt = 0;
|
||||
station->m_nSuccess = 0;
|
||||
station->m_usingRecoveryRate = true;
|
||||
@@ -262,11 +265,10 @@ void ParfWifiManager::DoReportDataOk (WifiRemoteStation *st,
|
||||
else if (station->m_nSuccess == m_successThreshold || station->m_nAttempt == m_attemptThreshold)
|
||||
{
|
||||
//we are at the maximum rate, we decrease power
|
||||
if (station->m_currentPower != m_minPower)
|
||||
if (station->m_powerLevel != m_minPower)
|
||||
{
|
||||
NS_LOG_DEBUG ("station=" << station << " dec power");
|
||||
station->m_currentPower--;
|
||||
m_powerChange (station->m_currentPower, station->m_state->m_address);
|
||||
station->m_powerLevel--;
|
||||
}
|
||||
station->m_nAttempt = 0;
|
||||
station->m_nSuccess = 0;
|
||||
@@ -298,8 +300,22 @@ ParfWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
channelWidth = 20;
|
||||
}
|
||||
CheckInit (station);
|
||||
WifiMode mode = GetSupported (station, station->m_currentRate);
|
||||
return WifiTxVector (mode, station->m_currentPower, GetLongRetryCount (station), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
|
||||
WifiMode mode = GetSupported (station, station->m_rateIndex);
|
||||
DataRate rate = DataRate (mode.GetDataRate (channelWidth));
|
||||
DataRate prevRate = DataRate (GetSupported (station, station->m_prevRateIndex).GetDataRate (channelWidth));
|
||||
double power = GetPhy ()->GetPowerDbm (station->m_powerLevel);
|
||||
double prevPower = GetPhy ()->GetPowerDbm (station->m_prevPowerLevel);
|
||||
if (station->m_prevPowerLevel != station->m_powerLevel)
|
||||
{
|
||||
m_powerChange (prevPower, power, station->m_state->m_address);
|
||||
station->m_prevPowerLevel = station->m_powerLevel;
|
||||
}
|
||||
if (station->m_prevRateIndex != station->m_rateIndex)
|
||||
{
|
||||
m_rateChange (prevRate, rate, station->m_state->m_address);
|
||||
station->m_prevRateIndex = station->m_rateIndex;
|
||||
}
|
||||
return WifiTxVector (mode, station->m_powerLevel, GetLongRetryCount (station), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
|
||||
}
|
||||
|
||||
WifiTxVector
|
||||
|
||||
@@ -97,13 +97,13 @@ private:
|
||||
uint32_t m_maxPower;
|
||||
|
||||
/**
|
||||
* The trace source fired when the transmission power changes....
|
||||
* The trace source fired when the transmission power changes.
|
||||
*/
|
||||
TracedCallback<uint8_t, Mac48Address> m_powerChange;
|
||||
TracedCallback<double, double, Mac48Address> m_powerChange;
|
||||
/**
|
||||
* The trace source fired when the transmission rate changes.
|
||||
*/
|
||||
TracedCallback<uint32_t, Mac48Address> m_rateChange;
|
||||
TracedCallback<DataRate, DataRate, Mac48Address> m_rateChange;
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
644
src/wifi/model/rrpaa-wifi-manager.cc
Normal file
644
src/wifi/model/rrpaa-wifi-manager.cc
Normal file
@@ -0,0 +1,644 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2017 Universidad de la República - Uruguay
|
||||
*
|
||||
* 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: Matías Richart <mrichart@fing.edu.uy>
|
||||
*/
|
||||
|
||||
#include "rrpaa-wifi-manager.h"
|
||||
#include "yans-wifi-phy.h"
|
||||
#include "wifi-phy.h"
|
||||
#include "wifi-mac.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/double.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include <cmath>
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("RrpaaWifiManager");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* Hold per-remote-station state for RRPAA Wifi manager.
|
||||
*
|
||||
* This struct extends from WifiRemoteStation struct to hold additional
|
||||
* information required by the APARF Wifi manager
|
||||
*/
|
||||
struct RrpaaWifiRemoteStation : public WifiRemoteStation
|
||||
{
|
||||
uint32_t m_counter; //!< Counter for transmission attempts.
|
||||
uint32_t m_nFailed; //!< Number of failed transmission attempts.
|
||||
uint32_t m_adaptiveRtsWnd; //!< Window size for the Adaptive RTS mechanism.
|
||||
uint32_t m_rtsCounter; //!< Counter for RTS transmission attempts.
|
||||
Time m_lastReset; //!< Time of the last reset.
|
||||
bool m_adaptiveRtsOn; //!< Check if Adaptive RTS mechanism is on.
|
||||
bool m_lastFrameFail; //!< Flag if the last frame sent has failed.
|
||||
bool m_initialized; //!< For initializing variables.
|
||||
|
||||
uint32_t m_nRate; //!< Number of supported rates.
|
||||
|
||||
uint32_t m_prevRateIndex; //!< Rate index of the previous transmission.
|
||||
uint32_t m_rateIndex; //!< Current rate index.
|
||||
uint8_t m_prevPowerLevel; //!< Power level of the previous transmission.
|
||||
uint8_t m_powerLevel; //!< Current power level.
|
||||
|
||||
|
||||
RrpaaThresholdsTable m_thresholds; //!< Rrpaa thresholds for this station.
|
||||
|
||||
RrpaaProbabilitiesTable m_pdTable; //!< Probability table for power and rate changes.
|
||||
};
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (RrpaaWifiManager);
|
||||
|
||||
TypeId
|
||||
RrpaaWifiManager::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::RrpaaWifiManager")
|
||||
.SetParent<WifiRemoteStationManager> ()
|
||||
.SetGroupName ("Wifi")
|
||||
.AddConstructor<RrpaaWifiManager> ()
|
||||
.AddAttribute ("Basic",
|
||||
"If true the RRAA-BASIC algorithm will be used, otherwise the RRAA will be used.",
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (&RrpaaWifiManager::m_basic),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("Timeout",
|
||||
"Timeout for the RRAA-BASIC loss estimation block (s).",
|
||||
TimeValue (MilliSeconds (500)),
|
||||
MakeTimeAccessor (&RrpaaWifiManager::m_timeout),
|
||||
MakeTimeChecker ())
|
||||
.AddAttribute ("FrameLength",
|
||||
"The data frame length (in bytes) used for calculating mode TxTime.",
|
||||
UintegerValue (1420),
|
||||
MakeUintegerAccessor (&RrpaaWifiManager::m_frameLength),
|
||||
MakeUintegerChecker <uint32_t> ())
|
||||
.AddAttribute ("AckFrameLength",
|
||||
"The ACK frame length (in bytes) used for calculating mode TxTime.",
|
||||
UintegerValue (14),
|
||||
MakeUintegerAccessor (&RrpaaWifiManager::m_ackLength),
|
||||
MakeUintegerChecker <uint32_t> ())
|
||||
.AddAttribute ("Alpha",
|
||||
"Constant for calculating the MTL threshold.",
|
||||
DoubleValue (1.25),
|
||||
MakeDoubleAccessor (&RrpaaWifiManager::m_alpha),
|
||||
MakeDoubleChecker<double> (1))
|
||||
.AddAttribute ("Beta",
|
||||
"Constant for calculating the ORI threshold.",
|
||||
DoubleValue (2),
|
||||
MakeDoubleAccessor (&RrpaaWifiManager::m_beta),
|
||||
MakeDoubleChecker<double> (1))
|
||||
.AddAttribute ("Tau",
|
||||
"Constant for calculating the EWND size.",
|
||||
DoubleValue (0.015),
|
||||
MakeDoubleAccessor (&RrpaaWifiManager::m_tau),
|
||||
MakeDoubleChecker<double> (0))
|
||||
.AddAttribute ("Gamma",
|
||||
"Constant for Probabilistic Decision Table decrements.",
|
||||
DoubleValue (2),
|
||||
MakeDoubleAccessor (&RrpaaWifiManager::m_gamma),
|
||||
MakeDoubleChecker<double> (1))
|
||||
.AddAttribute ("Delta",
|
||||
"Constant for Probabilistic Decision Table increments.",
|
||||
DoubleValue (1.0905),
|
||||
MakeDoubleAccessor (&RrpaaWifiManager::m_delta),
|
||||
MakeDoubleChecker<double> (1))
|
||||
.AddTraceSource ("RateChange",
|
||||
"The transmission rate has change.",
|
||||
MakeTraceSourceAccessor (&RrpaaWifiManager::m_rateChange),
|
||||
"ns3::WifiRemoteStationManager::RateChangeTracedCallback")
|
||||
.AddTraceSource ("PowerChange",
|
||||
"The transmission power has change.",
|
||||
MakeTraceSourceAccessor (&RrpaaWifiManager::m_powerChange),
|
||||
"ns3::WifiRemoteStationManager::PowerChangeTracedCallback")
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
|
||||
RrpaaWifiManager::RrpaaWifiManager ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
|
||||
}
|
||||
|
||||
RrpaaWifiManager::~RrpaaWifiManager ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
int64_t
|
||||
RrpaaWifiManager::AssignStreams (int64_t stream)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << stream);
|
||||
m_uniformRandomVariable->SetStream (stream);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::SetupPhy (Ptr<WifiPhy> phy)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_minPower = phy->GetTxPowerStart ();
|
||||
m_maxPower = phy->GetTxPowerEnd ();
|
||||
m_nPower = m_maxPower - m_minPower + 1;
|
||||
uint32_t nModes = phy->GetNModes ();
|
||||
for (uint32_t i = 0; i < nModes; i++)
|
||||
{
|
||||
WifiMode mode = phy->GetMode (i);
|
||||
WifiTxVector txVector;
|
||||
txVector.SetMode (mode);
|
||||
txVector.SetPreambleType (WIFI_PREAMBLE_LONG);
|
||||
/* Calculate the TX Time of the data and the corresponding ACK*/
|
||||
Time dataTxTime = phy->CalculateTxDuration (m_frameLength, txVector, phy->GetFrequency ());
|
||||
Time ackTxTime = phy->CalculateTxDuration (m_ackLength, txVector, phy->GetFrequency ());
|
||||
NS_LOG_DEBUG ("Calculating TX times: Mode= " << mode << " DataTxTime= " << dataTxTime << " AckTxTime= " << ackTxTime);
|
||||
AddCalcTxTime (mode, dataTxTime + ackTxTime);
|
||||
}
|
||||
WifiRemoteStationManager::SetupPhy (phy);
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::SetupMac (Ptr<WifiMac> mac)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_sifs = mac->GetSifs ();
|
||||
m_difs = m_sifs + 2 * mac->GetSlot ();
|
||||
WifiRemoteStationManager::SetupMac (mac);
|
||||
}
|
||||
|
||||
Time
|
||||
RrpaaWifiManager::GetCalcTxTime (WifiMode mode) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << mode);
|
||||
for (TxTime::const_iterator i = m_calcTxTime.begin (); i != m_calcTxTime.end (); i++)
|
||||
{
|
||||
if (mode == i->second)
|
||||
{
|
||||
return i->first;
|
||||
}
|
||||
}
|
||||
NS_ASSERT (false);
|
||||
return Seconds (0);
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::AddCalcTxTime (WifiMode mode, Time t)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << mode << t);
|
||||
m_calcTxTime.push_back (std::make_pair (t, mode));
|
||||
}
|
||||
|
||||
Thresholds
|
||||
RrpaaWifiManager::GetThresholds (RrpaaWifiRemoteStation *station, WifiMode mode) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << station << mode);
|
||||
for (RrpaaThresholdsTable::const_iterator i = station->m_thresholds.begin (); i != station->m_thresholds.end (); i++)
|
||||
{
|
||||
if (mode == i->second)
|
||||
{
|
||||
return i->first;
|
||||
}
|
||||
}
|
||||
NS_ASSERT (false);
|
||||
}
|
||||
|
||||
WifiRemoteStation *
|
||||
RrpaaWifiManager::DoCreateStation (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
RrpaaWifiRemoteStation *station = new RrpaaWifiRemoteStation ();
|
||||
station->m_adaptiveRtsWnd = 0;
|
||||
station->m_rtsCounter = 0;
|
||||
station->m_adaptiveRtsOn = false;
|
||||
station->m_lastFrameFail = false;
|
||||
station->m_initialized = false;
|
||||
return station;
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::CheckInit (RrpaaWifiRemoteStation *station)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << station);
|
||||
if (!station->m_initialized)
|
||||
{
|
||||
//Note: we appear to be doing late initialization of the table
|
||||
//to make sure that the set of supported rates has been initialized
|
||||
//before we perform our own initialization.
|
||||
station->m_nRate = GetNSupported (station);
|
||||
//Initialize at minimal rate and maximal power.
|
||||
station->m_prevRateIndex = 0;
|
||||
station->m_rateIndex = 0;
|
||||
station->m_prevPowerLevel = m_maxPower;
|
||||
station->m_powerLevel = m_maxPower;
|
||||
WifiMode mode = GetSupported (station, 0);
|
||||
uint8_t channelWidth = GetChannelWidth (station);
|
||||
DataRate rate = DataRate (mode.GetDataRate (channelWidth));
|
||||
double power = GetPhy ()->GetPowerDbm (m_maxPower);
|
||||
m_rateChange (rate, rate, station->m_state->m_address);
|
||||
m_powerChange (power, power, station->m_state->m_address);
|
||||
|
||||
station->m_pdTable = RrpaaProbabilitiesTable (station->m_nRate, std::vector<double> (m_nPower));
|
||||
NS_LOG_DEBUG ("Initializing pdTable");
|
||||
for (uint32_t i = 0; i < station->m_nRate; i++)
|
||||
{
|
||||
for (uint8_t j = 0; j < m_nPower; j++)
|
||||
{
|
||||
station->m_pdTable[i][j] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
station->m_initialized = true;
|
||||
|
||||
station->m_thresholds = RrpaaThresholdsTable (station->m_nRate);
|
||||
InitThresholds (station);
|
||||
ResetCountersBasic (station);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::InitThresholds (RrpaaWifiRemoteStation *station)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << station);
|
||||
NS_LOG_DEBUG ("InitThresholds = " << station);
|
||||
|
||||
double nextCritical = 0;
|
||||
double nextMtl = 0;
|
||||
double mtl = 0;
|
||||
double ori = 0;
|
||||
for (uint32_t i = 0; i < station->m_nRate; i++)
|
||||
{
|
||||
WifiMode mode = GetSupported (station, i);
|
||||
Time totalTxTime = GetCalcTxTime (mode) + m_sifs + m_difs;
|
||||
if (i == station->m_nRate - 1)
|
||||
{
|
||||
ori = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
WifiMode nextMode = GetSupported (station, i + 1);
|
||||
Time nextTotalTxTime = GetCalcTxTime (nextMode) + m_sifs + m_difs;
|
||||
nextCritical = 1 - (nextTotalTxTime.GetSeconds () / totalTxTime.GetSeconds ());
|
||||
nextMtl = m_alpha * nextCritical;
|
||||
ori = nextMtl / m_beta;
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
mtl = nextMtl;
|
||||
}
|
||||
Thresholds th;
|
||||
th.m_ewnd = ceil (m_tau / totalTxTime.GetSeconds ());
|
||||
th.m_ori = ori;
|
||||
th.m_mtl = mtl;
|
||||
station->m_thresholds.push_back (std::make_pair (th, mode));
|
||||
mtl = nextMtl;
|
||||
NS_LOG_DEBUG (mode << " " << th.m_ewnd << " " << th.m_mtl << " " << th.m_ori);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::ResetCountersBasic (RrpaaWifiRemoteStation *station)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << station);
|
||||
station->m_nFailed = 0;
|
||||
station->m_counter = GetThresholds (station, station->m_rateIndex).m_ewnd;
|
||||
station->m_lastReset = Simulator::Now ();
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::DoReportRtsFailed (WifiRemoteStation *st)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << st);
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::DoReportDataFailed (WifiRemoteStation *st)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << st);
|
||||
RrpaaWifiRemoteStation *station = (RrpaaWifiRemoteStation *) st;
|
||||
CheckInit (station);
|
||||
station->m_lastFrameFail = true;
|
||||
CheckTimeout (station);
|
||||
station->m_counter--;
|
||||
station->m_nFailed++;
|
||||
RunBasicAlgorithm (station);
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::DoReportRxOk (WifiRemoteStation *st,
|
||||
double rxSnr, WifiMode txMode)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << st << rxSnr << txMode);
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::DoReportRtsOk (WifiRemoteStation *st,
|
||||
double ctsSnr, WifiMode ctsMode, double rtsSnr)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << st << ctsSnr << ctsMode << rtsSnr);
|
||||
NS_LOG_DEBUG ("self=" << st << " rts ok");
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::DoReportDataOk (WifiRemoteStation *st,
|
||||
double ackSnr, WifiMode ackMode, double dataSnr)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << st << ackSnr << ackMode << dataSnr);
|
||||
RrpaaWifiRemoteStation *station = (RrpaaWifiRemoteStation *) st;
|
||||
CheckInit (station);
|
||||
station->m_lastFrameFail = false;
|
||||
CheckTimeout (station);
|
||||
station->m_counter--;
|
||||
RunBasicAlgorithm (station);
|
||||
}
|
||||
void
|
||||
RrpaaWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *st)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << st);
|
||||
}
|
||||
void
|
||||
RrpaaWifiManager::DoReportFinalDataFailed (WifiRemoteStation *st)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << st);
|
||||
}
|
||||
|
||||
WifiTxVector
|
||||
RrpaaWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << st);
|
||||
RrpaaWifiRemoteStation *station = (RrpaaWifiRemoteStation *) st;
|
||||
uint32_t channelWidth = GetChannelWidth (station);
|
||||
if (channelWidth > 20 && channelWidth != 22)
|
||||
{
|
||||
//avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
|
||||
channelWidth = 20;
|
||||
}
|
||||
CheckInit (station);
|
||||
WifiMode mode = GetSupported (station, station->m_rateIndex);
|
||||
DataRate rate = DataRate (mode.GetDataRate (channelWidth));
|
||||
DataRate prevRate = DataRate (GetSupported (station, station->m_prevRateIndex).GetDataRate (channelWidth));
|
||||
double power = GetPhy ()->GetPowerDbm (station->m_powerLevel);
|
||||
double prevPower = GetPhy ()->GetPowerDbm (station->m_prevPowerLevel);
|
||||
if (station->m_prevRateIndex != station->m_rateIndex)
|
||||
{
|
||||
m_rateChange (prevRate, rate, station->m_state->m_address);
|
||||
station->m_prevRateIndex = station->m_rateIndex;
|
||||
}
|
||||
if (station->m_prevPowerLevel != station->m_powerLevel)
|
||||
{
|
||||
m_powerChange (prevPower, power, station->m_state->m_address);
|
||||
station->m_prevPowerLevel = station->m_powerLevel;
|
||||
}
|
||||
return WifiTxVector (mode, station->m_powerLevel, GetLongRetryCount (station), GetPreambleForTransmission (mode, GetAddress (station)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
|
||||
}
|
||||
WifiTxVector
|
||||
RrpaaWifiManager::DoGetRtsTxVector (WifiRemoteStation *st)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << st);
|
||||
RrpaaWifiRemoteStation *station = (RrpaaWifiRemoteStation *) st;
|
||||
uint32_t channelWidth = GetChannelWidth (station);
|
||||
if (channelWidth > 20 && channelWidth != 22)
|
||||
{
|
||||
//avoid to use legacy rate adaptation algorithms for IEEE 802.11n/ac
|
||||
channelWidth = 20;
|
||||
}
|
||||
WifiTxVector rtsTxVector;
|
||||
WifiMode mode;
|
||||
if (GetUseNonErpProtection () == false)
|
||||
{
|
||||
mode = GetSupported (station, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = GetNonErpSupported (station, 0);
|
||||
}
|
||||
rtsTxVector = WifiTxVector (mode, GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetPreambleForTransmission (mode, GetAddress (st)), 800, 1, 1, 0, channelWidth, GetAggregation (station), false);
|
||||
return rtsTxVector;
|
||||
}
|
||||
|
||||
bool
|
||||
RrpaaWifiManager::DoNeedRts (WifiRemoteStation *st,
|
||||
Ptr<const Packet> packet, bool normally)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << st << packet << normally);
|
||||
RrpaaWifiRemoteStation *station = (RrpaaWifiRemoteStation *) st;
|
||||
CheckInit (station);
|
||||
if (m_basic)
|
||||
{
|
||||
return normally;
|
||||
}
|
||||
RunAdaptiveRtsAlgorithm (station);
|
||||
return station->m_adaptiveRtsOn;
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::CheckTimeout (RrpaaWifiRemoteStation *station)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << station);
|
||||
Time d = Simulator::Now () - station->m_lastReset;
|
||||
if (station->m_counter == 0 || d > m_timeout)
|
||||
{
|
||||
ResetCountersBasic (station);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::RunBasicAlgorithm (RrpaaWifiRemoteStation *station)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << station);
|
||||
Thresholds thresholds = GetThresholds (station, station->m_rateIndex);
|
||||
double bploss = (double) station->m_nFailed / (double) thresholds.m_ewnd;
|
||||
double wploss = (double) (station->m_counter + station->m_nFailed) / (double) thresholds.m_ewnd;
|
||||
NS_LOG_DEBUG ("Best loss prob= " << bploss);
|
||||
NS_LOG_DEBUG ("Worst loss prob= " << wploss);
|
||||
if (bploss >= thresholds.m_mtl)
|
||||
{
|
||||
if (station->m_powerLevel < m_maxPower)
|
||||
{
|
||||
NS_LOG_DEBUG ("bploss >= MTL and power < maxPower => Increase Power");
|
||||
station->m_pdTable[station->m_rateIndex][station->m_powerLevel] /= m_gamma;
|
||||
NS_LOG_DEBUG ("pdTable[" << station->m_rateIndex << "][" << station->m_powerLevel << "] = " << station->m_pdTable[station->m_rateIndex][station->m_powerLevel]);
|
||||
station->m_powerLevel++;
|
||||
ResetCountersBasic (station);
|
||||
}
|
||||
else if (station->m_rateIndex != 0)
|
||||
{
|
||||
NS_LOG_DEBUG ("bploss >= MTL and power = maxPower => Decrease Rate");
|
||||
station->m_pdTable[station->m_rateIndex][station->m_powerLevel] /= m_gamma;
|
||||
NS_LOG_DEBUG ("pdTable[" << station->m_rateIndex << "][" << station->m_powerLevel << "] = " << station->m_pdTable[station->m_rateIndex][station->m_powerLevel]);
|
||||
station->m_rateIndex--;
|
||||
ResetCountersBasic (station);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("bploss >= MTL but already at maxPower and minRate");
|
||||
}
|
||||
}
|
||||
else if (wploss <= thresholds.m_ori)
|
||||
{
|
||||
if (station->m_rateIndex < station->m_nRate - 1)
|
||||
{
|
||||
NS_LOG_DEBUG ("wploss <= ORI and rate < maxRate => Probabilistic Rate Increase");
|
||||
|
||||
// Recalculate probabilities of lower rates.
|
||||
for (uint32_t i = 0; i <= station->m_rateIndex; i++)
|
||||
{
|
||||
station->m_pdTable[i][station->m_powerLevel] *= m_delta;
|
||||
if (station->m_pdTable[i][station->m_powerLevel] > 1)
|
||||
{
|
||||
station->m_pdTable[i][station->m_powerLevel] = 1;
|
||||
}
|
||||
NS_LOG_DEBUG ("pdTable[" << i << "][" << station->m_powerLevel << "] = " << station->m_pdTable[i][station->m_powerLevel]);
|
||||
}
|
||||
double rand = m_uniformRandomVariable->GetValue (0,1);
|
||||
if (rand < station->m_pdTable[station->m_rateIndex + 1][station->m_powerLevel])
|
||||
{
|
||||
NS_LOG_DEBUG ("Increase Rate");
|
||||
station->m_rateIndex++;
|
||||
}
|
||||
}
|
||||
else if (station->m_powerLevel > m_minPower)
|
||||
{
|
||||
NS_LOG_DEBUG ("wploss <= ORI and rate = maxRate => Probabilistic Power Decrease");
|
||||
|
||||
// Recalculate probabilities of higher powers.
|
||||
for (uint32_t i = m_maxPower; i > station->m_powerLevel; i--)
|
||||
{
|
||||
station->m_pdTable[station->m_rateIndex][i] *= m_delta;
|
||||
if (station->m_pdTable[station->m_rateIndex][i] > 1)
|
||||
{
|
||||
station->m_pdTable[station->m_rateIndex][i] = 1;
|
||||
}
|
||||
NS_LOG_DEBUG ("pdTable[" << station->m_rateIndex << "][" << i << "] = " << station->m_pdTable[station->m_rateIndex][i]);
|
||||
}
|
||||
double rand = m_uniformRandomVariable->GetValue (0,1);
|
||||
if (rand < station->m_pdTable[station->m_rateIndex][station->m_powerLevel - 1])
|
||||
{
|
||||
NS_LOG_DEBUG ("Decrease Power");
|
||||
station->m_powerLevel--;
|
||||
}
|
||||
}
|
||||
ResetCountersBasic (station);
|
||||
}
|
||||
else if (bploss > thresholds.m_ori && wploss < thresholds.m_mtl)
|
||||
{
|
||||
if (station->m_powerLevel > m_minPower)
|
||||
{
|
||||
NS_LOG_DEBUG ("loss between ORI and MTL and power > minPower => Probabilistic Power Decrease");
|
||||
|
||||
// Recalculate probabilities of higher powers.
|
||||
for (uint32_t i = m_maxPower; i >= station->m_powerLevel; i--)
|
||||
{
|
||||
station->m_pdTable[station->m_rateIndex][i] *= m_delta;
|
||||
if (station->m_pdTable[station->m_rateIndex][i] > 1)
|
||||
{
|
||||
station->m_pdTable[station->m_rateIndex][i] = 1;
|
||||
}
|
||||
NS_LOG_DEBUG ("pdTable[" << station->m_rateIndex << "][" << i << "] = " << station->m_pdTable[station->m_rateIndex][i]);
|
||||
}
|
||||
double rand = m_uniformRandomVariable->GetValue (0,1);
|
||||
if (rand < station->m_pdTable[station->m_rateIndex][station->m_powerLevel - 1])
|
||||
{
|
||||
NS_LOG_DEBUG ("Decrease Power");
|
||||
station->m_powerLevel--;
|
||||
}
|
||||
ResetCountersBasic (station);
|
||||
}
|
||||
}
|
||||
if (station->m_counter == 0)
|
||||
{
|
||||
ResetCountersBasic (station);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::RunAdaptiveRtsAlgorithm (RrpaaWifiRemoteStation *station)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << station);
|
||||
if (!station->m_adaptiveRtsOn
|
||||
&& station->m_lastFrameFail)
|
||||
{
|
||||
station->m_adaptiveRtsWnd += 2;
|
||||
station->m_rtsCounter = station->m_adaptiveRtsWnd;
|
||||
}
|
||||
else if ((station->m_adaptiveRtsOn && station->m_lastFrameFail)
|
||||
|| (!station->m_adaptiveRtsOn && !station->m_lastFrameFail))
|
||||
{
|
||||
station->m_adaptiveRtsWnd = station->m_adaptiveRtsWnd / 2;
|
||||
station->m_rtsCounter = station->m_adaptiveRtsWnd;
|
||||
}
|
||||
if (station->m_rtsCounter > 0)
|
||||
{
|
||||
station->m_adaptiveRtsOn = true;
|
||||
station->m_rtsCounter--;
|
||||
}
|
||||
else
|
||||
{
|
||||
station->m_adaptiveRtsOn = false;
|
||||
}
|
||||
}
|
||||
|
||||
Thresholds
|
||||
RrpaaWifiManager::GetThresholds (RrpaaWifiRemoteStation *station,
|
||||
uint32_t rate) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << station << rate);
|
||||
WifiMode mode = GetSupported (station, rate);
|
||||
return GetThresholds (station, mode);
|
||||
}
|
||||
|
||||
bool
|
||||
RrpaaWifiManager::IsLowLatency (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
RrpaaWifiManager::SetHtSupported (bool enable)
|
||||
{
|
||||
//HT is not supported by this algorithm.
|
||||
if (enable)
|
||||
{
|
||||
NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HT rates");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::SetVhtSupported (bool enable)
|
||||
{
|
||||
//VHT is not supported by this algorithm.
|
||||
if (enable)
|
||||
{
|
||||
NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support VHT rates");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RrpaaWifiManager::SetHeSupported (bool enable)
|
||||
{
|
||||
//HE is not supported by this algorithm.
|
||||
if (enable)
|
||||
{
|
||||
NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HE rates");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
239
src/wifi/model/rrpaa-wifi-manager.h
Normal file
239
src/wifi/model/rrpaa-wifi-manager.h
Normal file
@@ -0,0 +1,239 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2017 Universidad de la República - Uruguay
|
||||
*
|
||||
* 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: Matías Richart <mrichart@fing.edu.uy>
|
||||
*/
|
||||
|
||||
#ifndef RRPAA_WIFI_MANAGER_H
|
||||
#define RRPAA_WIFI_MANAGER_H
|
||||
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/random-variable-stream.h"
|
||||
#include "wifi-remote-station-manager.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
struct RrpaaWifiRemoteStation;
|
||||
|
||||
/**
|
||||
* \ingroup wifi
|
||||
* Robust Rate and Power Adaptation Algorithm
|
||||
*
|
||||
* This class implements the RRPAA algorithm as described in <i>Rate, Power and Carrier-Sense
|
||||
* Threshold Coordinated Management for High-Density IEEE 802.11 Networks</i>
|
||||
* by Matías Richart; Jorge Visca and Javier Baliosian in Integrated Network Management (IM),
|
||||
* 2015 IFIP/IEEE International Symposium on (pp. 139-146). IEEE.
|
||||
* http://dl.ifip.org/db/conf/im/im2015/137430.pdf
|
||||
*
|
||||
* RRPAA adds power control to the RRAA mechanism. RRAA is described in
|
||||
* <i>Robust rate adaptation for 802.11 wireless networks</i> by Starsky H. Y. Wong;
|
||||
* Hao Yang; Songwu Lu and Vaduvur Bharghavan in Proceedings of the 12th annual
|
||||
* international conference on Mobile computing and networking (pp. 146-157). ACM.
|
||||
* http://ocw.cs.pub.ro/courses/_media/isrm/articole/rrate_adapt_mobicom06.pdf
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* For each rate there is a Opportunistic Rate Increase threshold,
|
||||
* a Maximum Tolerable Loss threshold and an Evaluation Window.
|
||||
*/
|
||||
struct Thresholds
|
||||
{
|
||||
double m_ori; //!< The Oportunistic Rate Increase threshold.
|
||||
double m_mtl; //!< The Maximum Tolerable Loss threshold.
|
||||
uint32_t m_ewnd; //!< The Estimation Window size.
|
||||
};
|
||||
|
||||
/**
|
||||
* List of thresholds for each mode.
|
||||
*/
|
||||
typedef std::vector<std::pair<Thresholds,WifiMode> > RrpaaThresholdsTable;
|
||||
|
||||
/**
|
||||
* List of probabilities.
|
||||
*/
|
||||
typedef std::vector<std::vector<double> > RrpaaProbabilitiesTable;
|
||||
|
||||
class RrpaaWifiManager : public WifiRemoteStationManager
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Register this type.
|
||||
* \return The object TypeId.
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
RrpaaWifiManager ();
|
||||
virtual ~RrpaaWifiManager ();
|
||||
|
||||
// Inherited from WifiRemoteStationManager
|
||||
virtual void SetupPhy (Ptr<WifiPhy> phy);
|
||||
virtual void SetupMac (Ptr<WifiMac> mac);
|
||||
virtual void SetHtSupported (bool enable);
|
||||
virtual void SetVhtSupported (bool enable);
|
||||
virtual void SetHeSupported (bool enable);
|
||||
|
||||
/**
|
||||
* Assign a fixed random variable stream number to the random variables
|
||||
* used by this model. Return the number of streams (possibly zero) that
|
||||
* have been assigned.
|
||||
*
|
||||
* \param stream first stream index to use
|
||||
*
|
||||
* \return the number of stream indices assigned by this model
|
||||
*/
|
||||
int64_t AssignStreams (int64_t stream);
|
||||
|
||||
private:
|
||||
//overriden from base class
|
||||
virtual WifiRemoteStation * DoCreateStation (void) const;
|
||||
virtual void DoReportRxOk (WifiRemoteStation *station,
|
||||
double rxSnr, WifiMode txMode);
|
||||
virtual void DoReportRtsFailed (WifiRemoteStation *station);
|
||||
virtual void DoReportDataFailed (WifiRemoteStation *station);
|
||||
virtual void DoReportRtsOk (WifiRemoteStation *station,
|
||||
double ctsSnr, WifiMode ctsMode, double rtsSnr);
|
||||
virtual void DoReportDataOk (WifiRemoteStation *station,
|
||||
double ackSnr, WifiMode ackMode, double dataSnr);
|
||||
virtual void DoReportFinalRtsFailed (WifiRemoteStation *station);
|
||||
virtual void DoReportFinalDataFailed (WifiRemoteStation *station);
|
||||
virtual WifiTxVector DoGetDataTxVector (WifiRemoteStation *station);
|
||||
virtual WifiTxVector DoGetRtsTxVector (WifiRemoteStation *station);
|
||||
virtual bool DoNeedRts (WifiRemoteStation *st,
|
||||
Ptr<const Packet> packet, bool normally);
|
||||
virtual bool IsLowLatency (void) const;
|
||||
|
||||
/**
|
||||
* Check for initializations.
|
||||
* \param station The remote station.
|
||||
*/
|
||||
void CheckInit (RrpaaWifiRemoteStation *station);
|
||||
|
||||
/**
|
||||
* Check if the counter should be reseted.
|
||||
*
|
||||
* \param station
|
||||
*/
|
||||
void CheckTimeout (RrpaaWifiRemoteStation *station);
|
||||
/**
|
||||
* Find an appropriate rate and power for the given station, using
|
||||
* a basic algorithm.
|
||||
*
|
||||
* \param station
|
||||
*/
|
||||
void RunBasicAlgorithm (RrpaaWifiRemoteStation *station);
|
||||
/**
|
||||
* Run an enhanced algorithm which activates the use of RTS
|
||||
* for the given station if the conditions are met.
|
||||
*
|
||||
* \param station
|
||||
*/
|
||||
void RunAdaptiveRtsAlgorithm (RrpaaWifiRemoteStation *station);
|
||||
/**
|
||||
* Reset the counters of the given station.
|
||||
*
|
||||
* \param station
|
||||
*/
|
||||
void ResetCountersBasic (RrpaaWifiRemoteStation *station);
|
||||
|
||||
/**
|
||||
* Initialize the thresholds internal list for the given station.
|
||||
*
|
||||
* \param station
|
||||
*/
|
||||
void InitThresholds (RrpaaWifiRemoteStation *station);
|
||||
|
||||
/**
|
||||
* Get the thresholds for the given station and mode.
|
||||
*
|
||||
* \param station
|
||||
* \param mode
|
||||
*
|
||||
* \return threshold
|
||||
*/
|
||||
Thresholds GetThresholds (RrpaaWifiRemoteStation *station, WifiMode mode) const;
|
||||
|
||||
/**
|
||||
* Get the thresholds for the given station and mode index.
|
||||
*
|
||||
* \param station
|
||||
* \param rate
|
||||
*
|
||||
* \return threshold
|
||||
*/
|
||||
Thresholds GetThresholds (RrpaaWifiRemoteStation *station, uint32_t rate) const;
|
||||
|
||||
/**
|
||||
* Get the estimated TxTime of a packet with a given mode.
|
||||
*
|
||||
* \param mode
|
||||
*
|
||||
* \return time
|
||||
*/
|
||||
Time GetCalcTxTime (WifiMode mode) const;
|
||||
/**
|
||||
* Add transmission time for the given mode to an internal list.
|
||||
*
|
||||
* \param mode Wi-Fi mode
|
||||
* \param t transmission time
|
||||
*/
|
||||
void AddCalcTxTime (WifiMode mode, Time t);
|
||||
|
||||
/**
|
||||
* typedef for a vector of a pair of Time, WifiMode.
|
||||
* Essentially a list for WifiMode and its corresponding transmission time
|
||||
* to transmit a reference packet.
|
||||
*/
|
||||
typedef std::vector<std::pair<Time,WifiMode> > TxTime;
|
||||
|
||||
TxTime m_calcTxTime; //!< To hold all the calculated TxTime for all modes.
|
||||
Time m_sifs; //!< Value of SIFS configured in the device.
|
||||
Time m_difs; //!< Value of DIFS configured in the device.
|
||||
|
||||
uint32_t m_frameLength; //!< Data frame length used for calculate mode TxTime.
|
||||
uint32_t m_ackLength; //!< Ack frame length used for calculate mode TxTime.
|
||||
|
||||
bool m_basic; //!< If using the basic algorithm (without RTS/CTS).
|
||||
Time m_timeout; //!< Timeout for the RRAA BASIC loss estimation block.
|
||||
double m_alpha; //!< Alpha value for RRPAA (value for calculating MTL threshold)
|
||||
double m_beta; //!< Beta value for RRPAA (value for calculating ORI threshold).
|
||||
double m_tau; //!< Tau value for RRPAA (value for calculating EWND size).
|
||||
double m_gamma; //!< Gamma value for RRPAA (value for pdTable decrements).
|
||||
double m_delta; //!< Delta value for RRPAA (value for pdTable increments).
|
||||
|
||||
/**
|
||||
* Differently form rate, power levels do not depend on the remote station.
|
||||
* The levels depend only on the physical layer of the device.
|
||||
*/
|
||||
uint32_t m_minPower; //!< Minimal power level.
|
||||
uint32_t m_maxPower; //!< Maximal power level.
|
||||
uint32_t m_nPower; //!< Number of power levels.
|
||||
|
||||
/**
|
||||
* The trace source fired when the transmission power change
|
||||
*/
|
||||
TracedCallback<double, double, Mac48Address> m_powerChange;
|
||||
/**
|
||||
* The trace source fired when the transmission rate change
|
||||
*/
|
||||
TracedCallback<DataRate, DataRate, Mac48Address> m_rateChange;
|
||||
|
||||
Ptr<UniformRandomVariable> m_uniformRandomVariable; //!< Provides uniform random variables for probabilistic changes.
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
#endif /* RRPAA__WIFI_MANAGER_H */
|
||||
@@ -1625,6 +1625,16 @@ public:
|
||||
*/
|
||||
std::vector<uint8_t> GetSupportedChannelWidthSet (void) const;
|
||||
|
||||
/**
|
||||
* Get the power of the given power level in dBm.
|
||||
* In SpectrumWifiPhy implementation, the power levels are equally spaced (in dBm).
|
||||
*
|
||||
* \param power the power level
|
||||
*
|
||||
* \return the transmission power in dBm at the given power level
|
||||
*/
|
||||
double GetPowerDbm (uint8_t power) const;
|
||||
|
||||
|
||||
protected:
|
||||
// Inherited
|
||||
@@ -1652,16 +1662,6 @@ protected:
|
||||
*/
|
||||
bool DoFrequencySwitch (uint16_t frequency);
|
||||
|
||||
/**
|
||||
* Get the power of the given power level in dBm.
|
||||
* In SpectrumWifiPhy implementation, the power levels are equally spaced (in dBm).
|
||||
*
|
||||
* \param power the power level
|
||||
*
|
||||
* \return the transmission power in dBm at the given power level
|
||||
*/
|
||||
double GetPowerDbm (uint8_t power) const;
|
||||
|
||||
/**
|
||||
* Check if Phy state should move to CCA busy state based on current
|
||||
* state of interference tracker. In this model, CCA becomes busy when
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/data-rate.h"
|
||||
#include "wifi-tx-vector.h"
|
||||
#include "ht-capabilities.h"
|
||||
#include "vht-capabilities.h"
|
||||
@@ -864,18 +865,20 @@ public:
|
||||
/**
|
||||
* TracedCallback signature for power change events.
|
||||
*
|
||||
* \param [in] power The new power.
|
||||
* \param [in] oldPower The previous power (in dBm).
|
||||
* \param [in] newPower The new power (in dBm).
|
||||
* \param [in] address The remote station MAC address.
|
||||
*/
|
||||
typedef void (*PowerChangeTracedCallback)(uint8_t power, Mac48Address remoteAddress);
|
||||
typedef void (*PowerChangeTracedCallback)(double oldPower, double newPower, Mac48Address remoteAddress);
|
||||
|
||||
/**
|
||||
* TracedCallback signature for rate change events.
|
||||
*
|
||||
* \param [in] rate The new rate.
|
||||
* \param [in] oldRate The previous data rate.
|
||||
* \param [in] newRate The new data rate.
|
||||
* \param [in] address The remote station MAC address.
|
||||
*/
|
||||
typedef void (*RateChangeTracedCallback)(uint32_t rate, Mac48Address remoteAddress);
|
||||
typedef void (*RateChangeTracedCallback)(DataRate oldRate, DataRate newRate, Mac48Address remoteAddress);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "ns3/constant-position-mobility-model.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/double.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
@@ -44,6 +45,8 @@ private:
|
||||
void TestParf ();
|
||||
/// Test aparf function
|
||||
void TestAparf ();
|
||||
/// Test rrpaa function
|
||||
void TestRrpaa ();
|
||||
/**
|
||||
* Configure nde function
|
||||
* \returns the node
|
||||
@@ -566,12 +569,447 @@ PowerRateAdaptationTest::TestAparf ()
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
|
||||
void
|
||||
PowerRateAdaptationTest::TestRrpaa ()
|
||||
{
|
||||
m_manager.SetTypeId ("ns3::RrpaaWifiManager");
|
||||
Ptr<Node> node = ConfigureNode ();
|
||||
Ptr<WifiNetDevice> dev = DynamicCast<WifiNetDevice> (node->GetDevice (0));
|
||||
Ptr<WifiRemoteStationManager> manager = dev->GetRemoteStationManager ();
|
||||
|
||||
/*
|
||||
* Configure constants for rate and power control.
|
||||
*/
|
||||
manager->SetAttribute ("Basic", BooleanValue (true));
|
||||
manager->SetAttribute ("Alpha", DoubleValue (1.25));
|
||||
manager->SetAttribute ("Beta", DoubleValue (2));
|
||||
manager->SetAttribute ("Tau", DoubleValue (0.015));
|
||||
/*
|
||||
* Constants for the Probabilistic Decision Table.
|
||||
* We set both to 1 to avoid random behaviour in tests.
|
||||
*/
|
||||
manager->SetAttribute ("Gamma", DoubleValue (1));
|
||||
manager->SetAttribute ("Delta", DoubleValue (1));
|
||||
|
||||
/*
|
||||
* Create a dummy packet to simulate transmission.
|
||||
*/
|
||||
Mac48Address remoteAddress = Mac48Address::Allocate ();
|
||||
WifiMacHeader packetHeader;
|
||||
packetHeader.SetTypeData ();
|
||||
packetHeader.SetQosTid (0);
|
||||
Ptr<Packet> packet = Create<Packet> (10);
|
||||
WifiMode ackMode;
|
||||
|
||||
/*
|
||||
* To initialize the manager we need to generate a transmission.
|
||||
*/
|
||||
Ptr<Packet> p = Create<Packet> ();
|
||||
dev->Send (p, remoteAddress, 1);
|
||||
|
||||
/**
|
||||
* This will be the thresholds table.
|
||||
* The parameters of the table are:
|
||||
* - Estimation Window Size (EWND)
|
||||
* - Maximum Tolerable Loss Probability Threshold (MTL)
|
||||
* - Opportunistic Rate Increase (and Power Decrease) Probability Threshold (ORI)
|
||||
*
|
||||
* We also calculate the needed success and failures to generate
|
||||
* a rate or power change:
|
||||
* Rate Increase or Power Decrease limits (RI-PD)
|
||||
* Rate Decrease or Power Increase limits (RD-PI)
|
||||
* Power Decrease limits (PD)
|
||||
*
|
||||
* Mode EWND MTL ORI RI-PD RD-PI PD
|
||||
* succ fails succ fails
|
||||
* OfdmRate6Mbps 8 1 0.19861 7 8 2
|
||||
* OfdmRate9Mbps 11 0.397219 0.14556 10 5 7 2
|
||||
* OfdmRate12Mbps 15 0.291121 0.189753 13 5 11 3
|
||||
* OfdmRate18Mbps 21 0.379507 0.13624 19 8 14 3
|
||||
* OfdmRate24Mbps 27 0.27248 0.174216 23 8 20 5
|
||||
* OfdmRate36Mbps 37 0.348432 0.120773 33 13 25 5
|
||||
* OfdmRate48Mbps 45 0.241546 0.0523952 43 11 35 3
|
||||
* OfdmRate54Mbps 50 0.10479 0 50 6 45 5
|
||||
*
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* RRPAA initiates with minimal rate and maximal power.
|
||||
*/
|
||||
WifiTxVector txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
WifiMode mode = txVector.GetMode ();
|
||||
int power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 6000000, "RRPAA: Initial data rate wrong"); //802.11a minimal rate is 6Mbps
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Initial power level wrong");
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* As RRPAA starts with the 6Mbps rate, 7 successful transmissions are needed for RRPAA to increase rate.
|
||||
* 1/8 = 0.125
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test that 6 is not enough.
|
||||
*/
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 6000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
/**
|
||||
* Test that 7 is enough.
|
||||
*/
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 9000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* 5 failures are needed to make the rate decrease again.
|
||||
* 5/11 = 0.45
|
||||
*/
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
manager->ReportDataFailed (remoteAddress,&packetHeader);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 9000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
manager->ReportDataFailed (remoteAddress,&packetHeader);
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 6000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Increase rate until maximal rate.
|
||||
*/
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 9000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 12000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
for (int i = 0; i < 13; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 18000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
for (int i = 0; i < 19; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 24000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
for (int i = 0; i < 23; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 36000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
for (int i = 0; i < 33; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 48000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
for (int i = 0; i < 43; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 54000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Now we need more successful transmissions to make power decrease.
|
||||
* As we are at maximal rate, the power is decreased when it is sure that the failures
|
||||
* will not generate a rate decrease.
|
||||
*/
|
||||
|
||||
for (int i = 0; i < 49; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 54000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 54000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 16, "RRPAA: Incorrect value of power level");
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* As rate hasn't change the same amount of success are needed.
|
||||
* After 16*45 successful transmissions power is decreased to zero.
|
||||
*/
|
||||
|
||||
for (int i = 0; i < 16 * 50; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 54000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 0, "RRPAA: Incorrect value of power level");
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* After 6 failures the power should be increased.
|
||||
*/
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
manager->ReportDataFailed (remoteAddress,&packetHeader);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 54000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 1, "RRPAA: Incorrect value of power level");
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* After 16*6 failed transmissions power is increase to 17.
|
||||
*/
|
||||
|
||||
for (int i = 0; i < 16 * 6; i++)
|
||||
{
|
||||
manager->ReportDataFailed (remoteAddress,&packetHeader);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 54000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* After 6 more failures the rate should be decreased.
|
||||
*/
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
manager->ReportDataFailed (remoteAddress,&packetHeader);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 48000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
/*
|
||||
* Now 11 failures are needed to decrease rate again.
|
||||
*/
|
||||
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
manager->ReportDataFailed (remoteAddress,&packetHeader);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 36000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Test power decrement when loss probability is between MTL and ORI.
|
||||
* As we are at rate 36 Mbps we need at least 25 successful transmissions
|
||||
* and 5 failures.
|
||||
*/
|
||||
|
||||
for (int i = 0; i < 25; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 36000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 17, "RRPAA: Incorrect value of power level");
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
manager->ReportDataFailed (remoteAddress,&packetHeader);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 36000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 16, "RRPAA: Incorrect value of power level");
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
manager->ReportDataFailed (remoteAddress,&packetHeader);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 36000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 16, "RRPAA: Incorrect value of power level");
|
||||
|
||||
for (int i = 0; i < 25; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 36000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 15, "RRPAA: Incorrect value of power level");
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Repeat the previous test until power 0 is reached.
|
||||
*/
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
for (int i = 0; i < 25; i++)
|
||||
{
|
||||
manager->ReportDataOk (remoteAddress, &packetHeader, 0, ackMode, 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
manager->ReportDataFailed (remoteAddress,&packetHeader);
|
||||
}
|
||||
}
|
||||
|
||||
txVector = manager->GetDataTxVector (remoteAddress, &packetHeader, packet);
|
||||
mode = txVector.GetMode ();
|
||||
power = (int) txVector.GetTxPowerLevel ();
|
||||
|
||||
NS_TEST_ASSERT_MSG_EQ (mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), 1), 36000000, "RRPAA: Incorrect vale of data rate");
|
||||
NS_TEST_ASSERT_MSG_EQ (power, 0, "RRPAA: Incorrect value of power level");
|
||||
|
||||
Simulator::Stop (Seconds (10.0));
|
||||
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
PowerRateAdaptationTest::DoRun (void)
|
||||
{
|
||||
|
||||
TestParf ();
|
||||
TestAparf ();
|
||||
TestRrpaa ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -69,6 +69,7 @@ def build(bld):
|
||||
'model/wifi-tx-vector.cc',
|
||||
'model/parf-wifi-manager.cc',
|
||||
'model/aparf-wifi-manager.cc',
|
||||
'model/rrpaa-wifi-manager.cc',
|
||||
'model/ampdu-subframe-header.cc',
|
||||
'model/mpdu-aggregator.cc',
|
||||
'model/mpdu-standard-aggregator.cc',
|
||||
@@ -174,6 +175,7 @@ def build(bld):
|
||||
'model/ht-capabilities.h',
|
||||
'model/parf-wifi-manager.h',
|
||||
'model/aparf-wifi-manager.h',
|
||||
'model/rrpaa-wifi-manager.h',
|
||||
'model/wifi-tx-vector.h',
|
||||
'model/ampdu-subframe-header.h',
|
||||
'model/mpdu-aggregator.h',
|
||||
|
||||
Reference in New Issue
Block a user