--- a/samples/main-adhoc-wifi.cc Sat Mar 01 20:41:08 2008 +0100
+++ b/samples/main-adhoc-wifi.cc Sat Mar 01 21:21:53 2008 +0100
@@ -19,6 +19,9 @@
*/
#include "ns3/wifi-net-device.h"
+#include "ns3/arf-wifi-manager.h"
+#include "ns3/adhoc-wifi-mac.h"
+#include "ns3/wifi-phy.h"
#include "ns3/wifi-channel.h"
#include "ns3/simulator.h"
#include "ns3/callback.h"
@@ -34,50 +37,67 @@
#include "ns3/command-line.h"
#include "ns3/gnuplot.h"
#include "ns3/uinteger.h"
+#include "ns3/string.h"
+#include "ns3/config.h"
+#include "ns3/wifi-helper.h"
+#include "ns3/mobility-helper.h"
+#include "ns3/log.h"
#include <iostream>
-using namespace ns3;
-static uint32_t g_bytesTotal = 0;
-static GnuplotDataset *g_output = 0;
+NS_LOG_COMPONENT_DEFINE ("Main");
-static Ptr<Node>
-CreateAdhocNode (Ptr<WifiChannel> channel,
- Vector position, const char *address)
+using namespace ns3;
+
+class Experiment
{
- Ptr<Node> node = CreateObject<Node> ();
- Ptr<AdhocWifiNetDevice> device = CreateObject<AdhocWifiNetDevice> (node, Mac48Address (address));
- node->AddDevice (device);
- device->Attach (channel);
- Ptr<MobilityModel> mobility = CreateObject<StaticMobilityModel> ();
- mobility->SetPosition (position);
- node->AggregateObject (mobility);
-
- return node;
+public:
+ Experiment ();
+ Experiment (std::string name);
+ GnuplotDataset Run (const WifiHelper &wifi);
+private:
+ void ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &address);
+ void SetPosition (Ptr<Node> node, Vector position);
+ Vector GetPosition (Ptr<Node> node);
+ void AdvancePosition (Ptr<Node> node);
+ Ptr<Socket> SetupPacketReceive (Ptr<Node> node);
+
+ uint32_t m_bytesTotal;
+ GnuplotDataset m_output;
+};
+
+Experiment::Experiment ()
+ : m_output ()
+{}
+
+Experiment::Experiment (std::string name)
+ : m_output (name)
+{
+ m_output.SetStyle (GnuplotDataset::LINES);
}
-static void
-SetPosition (Ptr<Node> node, Vector position)
+void
+Experiment::SetPosition (Ptr<Node> node, Vector position)
{
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
mobility->SetPosition (position);
}
-static Vector
-GetPosition (Ptr<Node> node)
+Vector
+Experiment::GetPosition (Ptr<Node> node)
{
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
return mobility->GetPosition ();
}
-static void
-AdvancePosition (Ptr<Node> node)
+void
+Experiment::AdvancePosition (Ptr<Node> node)
{
Vector pos = GetPosition (node);
- double mbs = ((g_bytesTotal * 8.0) / 1000000);
- g_bytesTotal = 0;
- g_output->Add (pos.x, mbs);
+ double mbs = ((m_bytesTotal * 8.0) / 1000000);
+ m_bytesTotal = 0;
+ m_output.Add (pos.x, mbs);
pos.x += 1.0;
if (pos.x >= 210.0)
{
@@ -85,63 +105,70 @@
}
SetPosition (node, pos);
//std::cout << "x="<<pos.x << std::endl;
- Simulator::Schedule (Seconds (1.0), &AdvancePosition, node);
+ Simulator::Schedule (Seconds (1.0), &Experiment::AdvancePosition, this, node);
}
-static void
-ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &address)
+void
+Experiment::ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &address)
{
- g_bytesTotal += packet->GetSize ();
+ m_bytesTotal += packet->GetSize ();
}
-static Ptr<Socket>
-SetupPacketReceive (Ptr<Node> node, uint16_t port)
+Ptr<Socket>
+Experiment::SetupPacketReceive (Ptr<Node> node)
{
TypeId tid = TypeId::LookupByName ("Packet");
Ptr<SocketFactory> socketFactory = node->GetObject<SocketFactory> (tid);
Ptr<Socket> sink = socketFactory->CreateSocket ();
sink->Bind ();
- sink->SetRecvCallback (MakeCallback (&ReceivePacket));
+ sink->SetRecvCallback (MakeCallback (&Experiment::ReceivePacket, this));
return sink;
}
-static void
-RunOneExperiment (void)
+GnuplotDataset
+Experiment::Run (const WifiHelper &wifi)
{
- g_bytesTotal = 0;
+ m_bytesTotal = 0;
- Ptr<WifiChannel> channel = CreateObject<WifiChannel> ();
+ NodeContainer c;
+ c.Create (2);
- Ptr<Node> a = CreateAdhocNode (channel,
- Vector (5.0,0.0,0.0),
- "00:00:00:00:00:01");
- Ptr<Node> b = CreateAdhocNode (channel,
- Vector (0.0, 0.0, 0.0),
- "00:00:00:00:00:02");
+ NetDeviceContainer devices = wifi.Build (c);
+
+ MobilityHelper mobility;
+ Ptr<ListPositionAllocator> positionAlloc = CreateObjectWith<ListPositionAllocator> ();
+ positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+ positionAlloc->Add (Vector (5.0, 0.0, 0.0));
+ mobility.SetPositionAllocator (positionAlloc);
+ mobility.SetMobilityModel ("StaticMobilityModel");
+
+ mobility.Layout (c.Begin (), c.End ());
PacketSocketAddress destination = PacketSocketAddress ();
destination.SetProtocol (1);
destination.SetSingleDevice (0);
- destination.SetPhysicalAddress (Mac48Address ("00:00:00:00:00:02"));
+ destination.SetPhysicalAddress (devices.Get (1)->GetAddress ());
Ptr<Application> app =
- CreateObjectWith<OnOffApplication> ("Node", a,
+ CreateObjectWith<OnOffApplication> ("Node", c.Get (0),
"Remote", Address (destination),
"Protocol", TypeId::LookupByName ("Packet"),
"OnTime", ConstantVariable (250),
"OffTime", ConstantVariable (0),
"DataRate", DataRate (60000000),
"PacketSize", Uinteger (2000));
- a->AddApplication (app);
+ c.Get (0)->AddApplication (app);
app->Start (Seconds (0.5));
app->Stop (Seconds (250.0));
- Simulator::Schedule (Seconds (1.5), &AdvancePosition, b);
- Ptr<Socket> recvSink = SetupPacketReceive (b, 10);
+ Simulator::Schedule (Seconds (1.5), &Experiment::AdvancePosition, this, c.Get (1));
+ Ptr<Socket> recvSink = SetupPacketReceive (c.Get (1));
Simulator::Run ();
Simulator::Destroy ();
+
+ return m_output;
}
int main (int argc, char *argv[])
@@ -149,106 +176,101 @@
Simulator::SetLinkedList ();
// disable fragmentation
- DefaultValue::Bind ("WifiFragmentationThreshold", "2200");
+ Config::SetDefault ("WifiRemoteStationManager::FragmentationThreshold", String ("2200"));
+ Config::SetDefault ("WifiRemoteStationManager::RtsCtsThreshold", String ("2200"));
+
CommandLine::Parse (argc, argv);
Gnuplot gnuplot = Gnuplot ("reference-rates.png");
- DefaultValue::Bind ("WifiRtsCtsThreshold", "2200");
+ Experiment experiment;
+ WifiHelper wifi;
+ GnuplotDataset dataset;
+
+ wifi.SetMac ("AdhocWifiMac");
+ wifi.SetPhy ("WifiPhy");
- g_output = new GnuplotDataset ("54mb");
- g_output->SetStyle (GnuplotDataset::LINES);
- DefaultValue::Bind ("WifiRateControlAlgorithm", "ConstantRate");
- DefaultValue::Bind ("WifiConstantDataRate", "54mb");
- RunOneExperiment ();
- gnuplot.AddDataset (*g_output);
- delete g_output;
+ NS_LOG_DEBUG ("54");
+ experiment = Experiment ("54mb");
+ wifi.SetRemoteStationManager ("ConstantRateWifiManager",
+ "DataMode", String ("wifia-54mbs"));
+ dataset = experiment.Run (wifi);
+ gnuplot.AddDataset (dataset);
- g_output = new GnuplotDataset ("48mb");
- g_output->SetStyle (GnuplotDataset::LINES);
- DefaultValue::Bind ("WifiRateControlAlgorithm", "ConstantRate");
- DefaultValue::Bind ("WifiConstantDataRate", "48mb");
- RunOneExperiment ();
- gnuplot.AddDataset (*g_output);
- delete g_output;
+ NS_LOG_DEBUG ("48");
+ experiment = Experiment ("48mb");
+ wifi.SetRemoteStationManager ("ConstantRateWifiManager",
+ "DataMode", String ("wifia-48mbs"));
+ dataset = experiment.Run (wifi);
+ gnuplot.AddDataset (dataset);
- g_output = new GnuplotDataset ("36mb");
- g_output->SetStyle (GnuplotDataset::LINES);
- DefaultValue::Bind ("WifiRateControlAlgorithm", "ConstantRate");
- DefaultValue::Bind ("WifiConstantDataRate", "36mb");
- RunOneExperiment ();
- gnuplot.AddDataset (*g_output);
- delete g_output;
+ NS_LOG_DEBUG ("36");
+ experiment = Experiment ("36mb");
+ wifi.SetRemoteStationManager ("ConstantRateWifiManager",
+ "DataMode", String ("wifia-36mbs"));
+ dataset = experiment.Run (wifi);
+ gnuplot.AddDataset (dataset);
- g_output = new GnuplotDataset ("24mb");
- g_output->SetStyle (GnuplotDataset::LINES);
- DefaultValue::Bind ("WifiRateControlAlgorithm", "ConstantRate");
- DefaultValue::Bind ("WifiConstantDataRate", "24mb");
- RunOneExperiment ();
- gnuplot.AddDataset (*g_output);
- delete g_output;
+ NS_LOG_DEBUG ("24");
+ experiment = Experiment ("24mb");
+ wifi.SetRemoteStationManager ("ConstantRateWifiManager",
+ "DataMode", String ("wifia-24mbs"));
+ dataset = experiment.Run (wifi);
+ gnuplot.AddDataset (dataset);
- g_output = new GnuplotDataset ("18mb");
- g_output->SetStyle (GnuplotDataset::LINES);
- DefaultValue::Bind ("WifiRateControlAlgorithm", "ConstantRate");
- DefaultValue::Bind ("WifiConstantDataRate", "18mb");
- RunOneExperiment ();
- gnuplot.AddDataset (*g_output);
- delete g_output;
+ NS_LOG_DEBUG ("18");
+ experiment = Experiment ("18mb");
+ wifi.SetRemoteStationManager ("ConstantRateWifiManager",
+ "DataMode", String ("wifia-18mbs"));
+ dataset = experiment.Run (wifi);
+ gnuplot.AddDataset (dataset);
- g_output = new GnuplotDataset ("12mb");
- g_output->SetStyle (GnuplotDataset::LINES);
- DefaultValue::Bind ("WifiRateControlAlgorithm", "ConstantRate");
- DefaultValue::Bind ("WifiConstantDataRate", "12mb");
- RunOneExperiment ();
- gnuplot.AddDataset (*g_output);
- delete g_output;
+ NS_LOG_DEBUG ("12");
+ experiment = Experiment ("12mb");
+ wifi.SetRemoteStationManager ("ConstantRateWifiManager",
+ "DataMode", String ("wifia-12mbs"));
+ dataset = experiment.Run (wifi);
+ gnuplot.AddDataset (dataset);
- g_output = new GnuplotDataset ("9mb");
- g_output->SetStyle (GnuplotDataset::LINES);
- DefaultValue::Bind ("WifiRateControlAlgorithm", "ConstantRate");
- DefaultValue::Bind ("WifiConstantDataRate", "9mb");
- RunOneExperiment ();
- gnuplot.AddDataset (*g_output);
- delete g_output;
+ NS_LOG_DEBUG ("9");
+ experiment = Experiment ("9mb");
+ wifi.SetRemoteStationManager ("ConstantRateWifiManager",
+ "DataMode", String ("wifia-9mbs"));
+ dataset = experiment.Run (wifi);
+ gnuplot.AddDataset (dataset);
- g_output = new GnuplotDataset ("6mb");
- g_output->SetStyle (GnuplotDataset::LINES);
- DefaultValue::Bind ("WifiRateControlAlgorithm", "ConstantRate");
- DefaultValue::Bind ("WifiConstantDataRate", "6mb");
- RunOneExperiment ();
- gnuplot.AddDataset (*g_output);
- delete g_output;
+ NS_LOG_DEBUG ("6");
+ experiment = Experiment ("6mb");
+ wifi.SetRemoteStationManager ("ConstantRateWifiManager",
+ "DataMode", String ("wifia-6mbs"));
+ dataset = experiment.Run (wifi);
+ gnuplot.AddDataset (dataset);
gnuplot.GenerateOutput (std::cout);
- gnuplot = Gnuplot ("rate-control.png");
+
- DefaultValue::Bind ("WifiPhyStandard", "holland");
+ gnuplot = Gnuplot ("rate-control.png");
+ Config::SetDefault ("WifiPhy::Standard", String ("holland"));
+
- g_output = new GnuplotDataset ("arf");
- g_output->SetStyle (GnuplotDataset::LINES);
- DefaultValue::Bind ("WifiRtsCtsThreshold", "2200");
- DefaultValue::Bind ("WifiRateControlAlgorithm", "Arf");
- RunOneExperiment ();
- gnuplot.AddDataset (*g_output);
- delete g_output;
+ NS_LOG_DEBUG ("arf");
+ experiment = Experiment ("arf");
+ wifi.SetRemoteStationManager ("ArfWifiManager");
+ dataset = experiment.Run (wifi);
+ gnuplot.AddDataset (dataset);
- g_output = new GnuplotDataset ("aarf");
- g_output->SetStyle (GnuplotDataset::LINES);
- DefaultValue::Bind ("WifiRtsCtsThreshold", "2200");
- DefaultValue::Bind ("WifiRateControlAlgorithm", "Aarf");
- RunOneExperiment ();
- gnuplot.AddDataset (*g_output);
- delete g_output;
+ NS_LOG_DEBUG ("aarf");
+ experiment = Experiment ("aarf");
+ wifi.SetRemoteStationManager ("AarfWifiManager");
+ dataset = experiment.Run (wifi);
+ gnuplot.AddDataset (dataset);
- g_output = new GnuplotDataset ("ideal");
- g_output->SetStyle (GnuplotDataset::LINES);
- DefaultValue::Bind ("WifiRtsCtsThreshold", "2200");
- DefaultValue::Bind ("WifiRateControlAlgorithm", "Ideal");
- RunOneExperiment ();
- gnuplot.AddDataset (*g_output);
- delete g_output;
+ NS_LOG_DEBUG ("ideal");
+ experiment = Experiment ("ideal");
+ wifi.SetRemoteStationManager ("IdealWifiManager");
+ dataset = experiment.Run (wifi);
+ gnuplot.AddDataset (dataset);
gnuplot.GenerateOutput (std::cout);
--- a/samples/wscript Sat Mar 01 20:41:08 2008 +0100
+++ b/samples/wscript Sat Mar 01 21:21:53 2008 +0100
@@ -39,9 +39,9 @@
['core', 'simulator', 'mobility', 'wifi'])
obj.source = 'main-adhoc-wifi.cc'
- obj = bld.create_ns3_program('main-ap-wifi',
- ['core', 'simulator', 'mobility', 'wifi'])
- obj.source = 'main-ap-wifi.cc'
+# obj = bld.create_ns3_program('main-ap-wifi',
+# ['core', 'simulator', 'mobility', 'wifi'])
+# obj.source = 'main-ap-wifi.cc'
obj = bld.create_ns3_program('main-random-walk',
['core', 'simulator', 'mobility'])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/aarf-wifi-manager.cc Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2004,2005,2006 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "aarf-wifi-manager.h"
+
+#include "ns3/double.h"
+#include "ns3/uinteger.h"
+
+#define Min(a,b) ((a<b)?a:b)
+#define Max(a,b) ((a>b)?a:b)
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (AarfWifiManager);
+
+TypeId
+AarfWifiManager::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("AarfWifiManager")
+ .SetParent<ArfWifiManager> ()
+ .AddConstructor<AarfWifiManager> ()
+ .AddAttribute ("SuccessK", "Multiplication factor for the success threshold in the AARF algorithm.",
+ Double (2.0),
+ MakeDoubleAccessor (&AarfWifiManager::m_successK),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TimerK",
+ "Multiplication factor for the timer threshold in the AARF algorithm.",
+ Double (2.0),
+ MakeDoubleAccessor (&AarfWifiManager::m_timerK),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("MaxSuccessThreshold",
+ "Maximum value of the success threshold in the AARF algorithm.",
+ Uinteger (60),
+ MakeUintegerAccessor (&AarfWifiManager::m_maxSuccessThreshold),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("MinTimerThreshold",
+ "The minimum value for the 'timer' threshold in the AARF algorithm.",
+ Uinteger (15),
+ MakeUintegerAccessor (&AarfWifiManager::m_minTimerThreshold),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("MinSuccessThreshold",
+ "The minimum value for the success threshold in the AARF algorithm.",
+ Uinteger (10),
+ MakeUintegerAccessor (&AarfWifiManager::m_minSuccessThreshold),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+ return tid;
+}
+
+AarfWifiManager::AarfWifiManager ()
+{}
+AarfWifiManager::~AarfWifiManager ()
+{}
+WifiRemoteStation *
+AarfWifiManager::CreateStation (void)
+{
+ return new AarfWifiRemoteStation (this, m_minTimerThreshold,
+ m_minSuccessThreshold,
+ m_successK,
+ m_maxSuccessThreshold,
+ m_timerK);
+}
+
+
+
+
+AarfWifiRemoteStation::AarfWifiRemoteStation (Ptr<AarfWifiManager> stations,
+ uint32_t minTimerThreshold,
+ uint32_t minSuccessThreshold,
+ double successK,
+ uint32_t maxSuccessThreshold,
+ double timerK)
+ : ArfWifiRemoteStation (stations, minTimerThreshold, minSuccessThreshold),
+ m_successK (successK),
+ m_maxSuccessThreshold (maxSuccessThreshold),
+ m_timerK (timerK)
+{}
+
+
+AarfWifiRemoteStation::~AarfWifiRemoteStation ()
+{}
+
+void
+AarfWifiRemoteStation::ReportRecoveryFailure (void)
+{
+ SetSuccessThreshold ((int)(Min (GetSuccessThreshold () * m_successK,
+ m_maxSuccessThreshold)));
+ SetTimerTimeout ((int)(Max (GetMinTimerTimeout (),
+ GetSuccessThreshold () * m_timerK)));
+}
+
+void
+AarfWifiRemoteStation::ReportFailure (void)
+{
+ SetTimerTimeout (GetMinTimerTimeout ());
+ SetSuccessThreshold (GetMinSuccessThreshold ());
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/aarf-wifi-manager.h Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef AARF_MAC_STATIONS_H
+#define AARF_MAC_STATIONS_H
+
+#include "arf-wifi-manager.h"
+
+namespace ns3 {
+
+/**
+ * \brief AARF Rate control algorithm
+ *
+ * This class implements the AARF rate control algorithm which
+ * was initially described in <i>IEEE 802.11 Rate Adaptation:
+ * A Practical Approach</i>, by M. Lacage, M.H. Manshaei, and
+ * T. Turletti.
+ */
+class AarfWifiManager : public ArfWifiManager
+{
+public:
+ static TypeId GetTypeId (void);
+ AarfWifiManager ();
+ virtual ~AarfWifiManager ();
+private:
+ virtual class WifiRemoteStation *CreateStation (void);
+ uint32_t m_minTimerThreshold;
+ uint32_t m_minSuccessThreshold;
+ double m_successK;
+ uint32_t m_maxSuccessThreshold;
+ double m_timerK;
+};
+
+class AarfWifiRemoteStation : public ArfWifiRemoteStation
+{
+public:
+ AarfWifiRemoteStation (Ptr<AarfWifiManager> stations,
+ uint32_t minTimerThreshold,
+ uint32_t minSuccessThreshold,
+ double successK,
+ uint32_t maxSuccessThreshold,
+ double timerK);
+ virtual ~AarfWifiRemoteStation ();
+
+private:
+ virtual void ReportRecoveryFailure (void);
+ virtual void ReportFailure (void);
+
+ double m_successK;
+ uint32_t m_maxSuccessThreshold;
+ double m_timerK;
+};
+
+} // namespace ns3
+
+
+#endif /* AARF_MAC_STATIONS_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/adhoc-wifi-mac.cc Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,191 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "adhoc-wifi-mac.h"
+#include "dca-txop.h"
+#include "mac-low.h"
+#include "mac-rx-middle.h"
+#include "wifi-phy.h"
+#include "dcf-manager.h"
+#include "ns3/packet.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("AdhocWifiMac");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (AdhocWifiMac);
+
+TypeId
+AdhocWifiMac::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("AdhocWifiMac")
+ .SetParent<WifiMac> ()
+ .AddConstructor<AdhocWifiMac> ()
+ ;
+ return tid;
+}
+
+AdhocWifiMac::AdhocWifiMac ()
+{
+ m_rxMiddle = new MacRxMiddle ();
+ m_rxMiddle->SetForwardCallback (MakeCallback (&AdhocWifiMac::ForwardUp, this));
+
+ m_low = new MacLow ();
+ m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
+ m_low->SetMac (this);
+
+ m_dcfManager = new DcfManager ();
+ m_dcfManager->SetupLowListener (m_low);
+
+ m_dca = CreateObject<DcaTxop> ();
+ m_dca->SetLow (m_low);
+ m_dca->SetManager (m_dcfManager);
+}
+AdhocWifiMac::~AdhocWifiMac ()
+{}
+
+void
+AdhocWifiMac::DoDispose (void)
+{
+ delete m_rxMiddle;
+ delete m_low;
+ m_rxMiddle = 0;
+ m_low = 0;
+ m_phy = 0;
+ WifiMac::DoDispose ();
+}
+
+void
+AdhocWifiMac::SetSlot (Time slotTime)
+{
+ m_dcfManager->SetSlot (slotTime);
+ WifiMac::SetSlot (slotTime);
+}
+void
+AdhocWifiMac::SetSifs (Time sifs)
+{
+ m_dcfManager->SetSifs (sifs);
+ WifiMac::SetSifs (sifs);
+}
+void
+AdhocWifiMac::SetEifsNoDifs (Time eifsNoDifs)
+{
+ m_dcfManager->SetEifsNoDifs (eifsNoDifs);
+ WifiMac::SetEifsNoDifs (eifsNoDifs);
+}
+
+void
+AdhocWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
+{
+ m_phy = phy;
+ m_dcfManager->SetupPhyListener (phy);
+ m_low->SetPhy (phy);
+}
+void
+AdhocWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
+{
+ m_stationManager = stationManager;
+ m_dca->SetWifiRemoteStationManager (stationManager);
+ m_low->SetWifiRemoteStationManager (stationManager);
+}
+void
+AdhocWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, const Mac48Address &> upCallback)
+{
+ m_upCallback = upCallback;
+}
+void
+AdhocWifiMac::SetLinkUpCallback (Callback<void> linkUp)
+{
+ // an Adhoc network is always UP.
+ linkUp ();
+}
+void
+AdhocWifiMac::SetLinkDownCallback (Callback<void> linkDown)
+{
+ //XXX
+}
+Mac48Address
+AdhocWifiMac::GetAddress (void) const
+{
+ return m_address;
+}
+Ssid
+AdhocWifiMac::GetSsid (void) const
+{
+ return m_ssid;
+}
+Mac48Address
+AdhocWifiMac::GetBssid (void) const
+{
+ // XXX the bssid should be generated by the procedure
+ // described in ieee802.11 section 11.1.3
+ return Mac48Address::GetBroadcast ();
+}
+void
+AdhocWifiMac::SetAddress (Mac48Address address)
+{
+ m_address = address;
+}
+void
+AdhocWifiMac::SetSsid (Ssid ssid)
+{
+ // XXX: here, we should start a special adhoc network
+ m_ssid = ssid;
+}
+
+void
+AdhocWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
+{
+ NS_LOG_DEBUG ("enqueue size="<<packet->GetSize ()<<", to="<<to);
+ WifiMacHeader hdr;
+ hdr.SetType (WIFI_MAC_DATA);
+ hdr.SetAddr1 (to);
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetBssid ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+
+ WifiRemoteStation *destination = m_stationManager->Lookup (to);
+ if (destination->IsBrandNew ())
+ {
+ // in adhoc mode, we assume that every destination
+ // supports all the rates we support.
+ for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+ {
+ destination->AddSupportedMode (m_phy->GetMode (i));
+ }
+ destination->RecordDisassociated ();
+ }
+
+ m_dca->Queue (packet, hdr);
+}
+
+void
+AdhocWifiMac::ForwardUp (Ptr<Packet> packet, WifiMacHeader const *hdr)
+{
+ NS_LOG_DEBUG ("received size="<<packet->GetSize ()<<", from="<<hdr->GetAddr2 ());
+ if (hdr->GetAddr1 ().IsBroadcast () || hdr->GetAddr1 () == GetAddress ())
+ {
+ m_upCallback (packet, hdr->GetAddr2 ());
+ }
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/adhoc-wifi-mac.h Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef ADHOC_WIFI_MAC_H
+#define ADHOC_WIFI_MAC_H
+
+#include "ns3/mac48-address.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+#include "wifi-mac.h"
+
+namespace ns3 {
+
+class DcaTxop;
+class Packet;
+class WifiMacHeader;
+class WifiPhy;
+class DcfManager;
+class MacLow;
+class MacRxMiddle;
+
+/**
+ * \brief the Adhoc state machine
+ *
+ * For now, this class is really empty but it should contain
+ * the code for the distributed generation of beacons in an adhoc
+ * network.
+ */
+class AdhocWifiMac : public WifiMac
+{
+public:
+ typedef Callback<void, Ptr<Packet>, const Mac48Address &> ForwardCallback;
+
+ static TypeId GetTypeId (void);
+
+ AdhocWifiMac ();
+ ~AdhocWifiMac ();
+
+ virtual void SetSlot (Time slotTime);
+ virtual void SetSifs (Time sifs);
+ virtual void SetEifsNoDifs (Time eifsNoDifs);
+ virtual void SetWifiPhy (Ptr<WifiPhy> phy);
+ virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
+ virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
+ virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, const Mac48Address &> upCallback);
+ virtual void SetLinkUpCallback (Callback<void> linkUp);
+ virtual void SetLinkDownCallback (Callback<void> linkDown);
+ virtual Mac48Address GetAddress (void) const;
+ virtual Ssid GetSsid (void) const;
+ virtual Mac48Address GetBssid (void) const;
+ virtual void SetAddress (Mac48Address address);
+ virtual void SetSsid (Ssid ssid);
+
+
+private:
+ virtual void DoDispose (void);
+ /* invoked by the MacLows. */
+ void ForwardUp (Ptr<Packet> packet, WifiMacHeader const*hdr);
+
+ Ptr<DcaTxop> m_dca;
+ Callback<void,Ptr<Packet>,const Mac48Address &> m_upCallback;
+ Ptr<WifiRemoteStationManager> m_stationManager;
+ Ptr<WifiPhy> m_phy;
+ DcfManager *m_dcfManager;
+ MacRxMiddle *m_rxMiddle;
+ MacLow *m_low;
+ Mac48Address m_address;
+ Ssid m_ssid;
+};
+
+} // namespace ns3
+
+#endif /* ADHOC_WIFI_MAC_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/arf-wifi-manager.cc Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,254 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2004,2005,2006 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "mac-stations.h"
+#include "arf-wifi-manager.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/uinteger.h"
+
+NS_LOG_COMPONENT_DEFINE ("ArfWifiManager");
+
+
+namespace ns3 {
+
+ArfWifiRemoteStation::ArfWifiRemoteStation (Ptr<ArfWifiManager> stations,
+ int minTimerTimeout,
+ int minSuccessThreshold)
+ : m_stations (stations)
+{
+ m_minTimerTimeout = minTimerTimeout;
+ m_minSuccessThreshold = minSuccessThreshold;
+ m_successThreshold = m_minSuccessThreshold;
+ m_timerTimeout = m_minTimerTimeout;
+ m_rate = GetMinRate ();
+
+ m_success = 0;
+ m_failed = 0;
+ m_recovery = false;
+ m_retry = 0;
+ m_timer = 0;
+}
+ArfWifiRemoteStation::~ArfWifiRemoteStation ()
+{}
+
+uint32_t
+ArfWifiRemoteStation::GetMaxRate (void)
+{
+ return GetNSupportedModes ();
+}
+uint32_t
+ArfWifiRemoteStation::GetMinRate (void)
+{
+ return 0;
+}
+
+bool
+ArfWifiRemoteStation::NeedRecoveryFallback (void)
+{
+ if (m_retry == 1)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+bool
+ArfWifiRemoteStation::NeedNormalFallback (void)
+{
+ int retryMod = (m_retry - 1) % 2;
+ if (retryMod == 1)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+
+void
+ArfWifiRemoteStation::ReportRtsFailed (void)
+{}
+/**
+ * It is important to realize that "recovery" mode starts after failure of
+ * the first transmission after a rate increase and ends at the first successful
+ * transmission. Specifically, recovery mode transcends retransmissions boundaries.
+ * Fundamentally, ARF handles each data transmission independently, whether it
+ * is the initial transmission of a packet or the retransmission of a packet.
+ * The fundamental reason for this is that there is a backoff between each data
+ * transmission, be it an initial transmission or a retransmission.
+ */
+void
+ArfWifiRemoteStation::ReportDataFailed (void)
+{
+ m_timer++;
+ m_failed++;
+ m_retry++;
+ m_success = 0;
+
+ if (m_recovery)
+ {
+ NS_ASSERT (m_retry >= 1);
+ if (NeedRecoveryFallback ())
+ {
+ ReportRecoveryFailure ();
+ if (m_rate != GetMinRate ())
+ {
+ m_rate--;
+ }
+ }
+ m_timer = 0;
+ }
+ else
+ {
+ NS_ASSERT (m_retry >= 1);
+ if (NeedNormalFallback ())
+ {
+ ReportFailure ();
+ if (m_rate != GetMinRate ())
+ {
+ m_rate--;
+ }
+ }
+ if (m_retry >= 2)
+ {
+ m_timer = 0;
+ }
+ }
+}
+void
+ArfWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+{}
+void ArfWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+{
+ NS_LOG_DEBUG ("self="<<this<<" rts ok");
+}
+void ArfWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+{
+ m_timer++;
+ m_success++;
+ m_failed = 0;
+ m_recovery = false;
+ m_retry = 0;
+ NS_LOG_DEBUG ("self="<<this<<" data ok success="<<m_success<<", timer="<<m_timer);
+ if ((m_success == GetSuccessThreshold () ||
+ m_timer == GetTimerTimeout ()) &&
+ (m_rate < (GetMaxRate () - 1)))
+ {
+ NS_LOG_DEBUG ("self="<<this<<" inc rate");
+ m_rate++;
+ m_timer = 0;
+ m_success = 0;
+ m_recovery = true;
+ }
+}
+void
+ArfWifiRemoteStation::ReportFinalRtsFailed (void)
+{}
+void
+ArfWifiRemoteStation::ReportFinalDataFailed (void)
+{}
+
+WifiMode
+ArfWifiRemoteStation::DoGetDataMode (uint32_t size)
+{
+ return GetSupportedMode (m_rate);
+}
+WifiMode
+ArfWifiRemoteStation::DoGetRtsMode (void)
+{
+ // XXX: we could/should implement the Arf algorithm for
+ // RTS only by picking a single rate within the BasicRateSet.
+ return GetSupportedMode (0);
+}
+
+void ArfWifiRemoteStation::ReportRecoveryFailure (void)
+{}
+void ArfWifiRemoteStation::ReportFailure (void)
+{}
+uint32_t ArfWifiRemoteStation::GetMinTimerTimeout (void)
+{
+ return m_minTimerTimeout;
+}
+uint32_t ArfWifiRemoteStation::GetMinSuccessThreshold (void)
+{
+ return m_minSuccessThreshold;
+}
+uint32_t ArfWifiRemoteStation::GetTimerTimeout (void)
+{
+ return m_timerTimeout;
+}
+uint32_t ArfWifiRemoteStation::GetSuccessThreshold (void)
+{
+ return m_successThreshold;
+}
+void ArfWifiRemoteStation::SetTimerTimeout (uint32_t timerTimeout)
+{
+ NS_ASSERT (timerTimeout >= m_minTimerTimeout);
+ m_timerTimeout = timerTimeout;
+}
+void ArfWifiRemoteStation::SetSuccessThreshold (uint32_t successThreshold)
+{
+ NS_ASSERT (successThreshold >= m_minSuccessThreshold);
+ m_successThreshold = successThreshold;
+}
+Ptr<WifiRemoteStationManager>
+ArfWifiRemoteStation::GetManager (void) const
+{
+ return m_stations;
+}
+
+NS_OBJECT_ENSURE_REGISTERED (ArfWifiManager);
+
+TypeId
+ArfWifiManager::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ArfWifiManager")
+ .SetParent<WifiRemoteStationManager> ()
+ .AddConstructor<ArfWifiManager> ()
+ .AddAttribute ("TimerThreshold", "The 'timer' threshold in the ARF algorithm.",
+ Uinteger (15),
+ MakeUintegerAccessor (&ArfWifiManager::m_timerThreshold),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("SuccessThreshold",
+ "The minimum number of sucessfull transmissions to try a new rate.",
+ Uinteger (10),
+ MakeUintegerAccessor (&ArfWifiManager::m_successThreshold),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+ return tid;
+}
+
+ArfWifiManager::ArfWifiManager ()
+{}
+ArfWifiManager::~ArfWifiManager ()
+{}
+WifiRemoteStation *
+ArfWifiManager::CreateStation (void)
+{
+ return new ArfWifiRemoteStation (this, m_timerThreshold, m_successThreshold);
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/arf-wifi-manager.h Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef ARF_WIFI_MANAGER_H
+#define ARF_WIFI_MANAGER_H
+
+#include "wifi-remote-station-manager.h"
+
+namespace ns3 {
+
+/**
+ * \brief ARF Rate control algorithm
+ *
+ * This class implements the so-called ARF algorithm which was
+ * initially described in <i>WaveLAN-II: A High-performance wireless
+ * LAN for the unlicensed band</i>, by A. Kamerman and L. Monteban. in
+ * Bell Lab Technical Journal, pages 118-133, Summer 1997.
+ *
+ * This implementation differs from the initial description in that it
+ * uses a packet-based timer rather than a time-based timer as described
+ * in XXX (I cannot find back the original paper which described how
+ * the time-based timer could be easily replaced with a packet-based
+ * timer.)
+ */
+class ArfWifiManager : public WifiRemoteStationManager
+{
+public:
+ static TypeId GetTypeId (void);
+ ArfWifiManager ();
+ virtual ~ArfWifiManager ();
+
+private:
+ virtual class WifiRemoteStation *CreateStation (void);
+ uint32_t m_timerThreshold;
+ uint32_t m_successThreshold;
+};
+
+
+class ArfWifiRemoteStation : public WifiRemoteStation
+{
+public:
+ ArfWifiRemoteStation (Ptr<ArfWifiManager> stations,
+ int minTimerTimeout,
+ int minSuccessThreshold);
+ virtual ~ArfWifiRemoteStation ();
+
+ virtual void ReportRxOk (double rxSnr, WifiMode txMode);
+ virtual void ReportRtsFailed (void);
+ virtual void ReportDataFailed (void);
+ virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+ virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+ virtual void ReportFinalRtsFailed (void);
+ virtual void ReportFinalDataFailed (void);
+
+private:
+ virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
+ virtual WifiMode DoGetDataMode (uint32_t size);
+ virtual WifiMode DoGetRtsMode (void);
+
+ uint32_t m_timer;
+ uint32_t m_success;
+ uint32_t m_failed;
+ bool m_recovery;
+ uint32_t m_retry;
+
+ uint32_t m_timerTimeout;
+ uint32_t m_successThreshold;
+
+ uint32_t m_rate;
+
+ uint32_t m_minTimerTimeout;
+ uint32_t m_minSuccessThreshold;
+
+ Ptr<ArfWifiManager> m_stations;
+
+private:
+ // overriden by AarfMacStation.
+ virtual void ReportRecoveryFailure (void);
+ virtual void ReportFailure (void);
+
+ uint32_t GetMaxRate (void);
+ uint32_t GetMinRate (void);
+
+ bool NeedRecoveryFallback (void);
+ bool NeedNormalFallback (void);
+
+protected:
+ // called by AarfMacStation.
+ uint32_t GetMinTimerTimeout (void);
+ uint32_t GetMinSuccessThreshold (void);
+
+ uint32_t GetTimerTimeout (void);
+ uint32_t GetSuccessThreshold (void);
+
+ void SetTimerTimeout (uint32_t timerTimeout);
+ void SetSuccessThreshold (uint32_t successThreshold);
+};
+
+} // namespace ns3
+
+#endif /* ARF_WIFI_MANAGER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/constant-rate-wifi-manager.cc Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2004,2005 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "constant-rate-wifi-manager.h"
+
+#include "ns3/string.h"
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+ConstantRateWifiRemoteStation::ConstantRateWifiRemoteStation (Ptr<ConstantRateWifiManager> manager)
+ : m_manager (manager)
+{}
+ConstantRateWifiRemoteStation::~ConstantRateWifiRemoteStation ()
+{}
+
+void
+ConstantRateWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+{}
+void
+ConstantRateWifiRemoteStation::ReportRtsFailed (void)
+{}
+void
+ConstantRateWifiRemoteStation::ReportDataFailed (void)
+{}
+void
+ConstantRateWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+{}
+void
+ConstantRateWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+{}
+void
+ConstantRateWifiRemoteStation::ReportFinalRtsFailed (void)
+{}
+void
+ConstantRateWifiRemoteStation::ReportFinalDataFailed (void)
+{}
+
+WifiMode
+ConstantRateWifiRemoteStation::DoGetDataMode (uint32_t size)
+{
+ return m_manager->GetDataMode ();
+}
+WifiMode
+ConstantRateWifiRemoteStation::DoGetRtsMode (void)
+{
+ return m_manager->GetCtlMode ();
+}
+Ptr<WifiRemoteStationManager>
+ConstantRateWifiRemoteStation::GetManager (void) const
+{
+ return m_manager;
+}
+
+NS_OBJECT_ENSURE_REGISTERED (ConstantRateWifiManager);
+
+TypeId
+ConstantRateWifiManager::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ConstantRateWifiManager")
+ .SetParent<WifiRemoteStationManager> ()
+ .AddConstructor<ConstantRateWifiManager> ()
+ .AddAttribute ("DataMode", "XXX",
+ String ("wifia-6mbs"),
+ MakeWifiModeAccessor (&ConstantRateWifiManager::m_dataMode),
+ MakeWifiModeChecker ())
+ .AddAttribute ("ControlMode", "XXX",
+ String ("wifia-6mbs"),
+ MakeWifiModeAccessor (&ConstantRateWifiManager::m_ctlMode),
+ MakeWifiModeChecker ())
+ ;
+ return tid;
+}
+
+ConstantRateWifiManager::ConstantRateWifiManager ()
+{}
+ConstantRateWifiManager::~ConstantRateWifiManager ()
+{}
+
+WifiMode
+ConstantRateWifiManager::GetDataMode (void) const
+{
+ return m_dataMode;
+}
+WifiMode
+ConstantRateWifiManager::GetCtlMode (void) const
+{
+ return m_ctlMode;
+}
+
+
+WifiRemoteStation *
+ConstantRateWifiManager::CreateStation (void)
+{
+ return new ConstantRateWifiRemoteStation (this);
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/constant-rate-wifi-manager.h Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef CONSTANT_RATE_WIFI_MANAGER_H
+#define CONSTANT_RATE_WIFI_MANAGER_H
+
+#include <stdint.h>
+
+#include "wifi-remote-station-manager.h"
+
+namespace ns3 {
+
+/**
+ * \brief use constant rates for data and control transmissions
+ *
+ * This class uses always the same transmission rate for every
+ * packet sent.
+ */
+class ConstantRateWifiManager : public WifiRemoteStationManager
+{
+public:
+ static TypeId GetTypeId (void);
+ ConstantRateWifiManager ();
+ virtual ~ConstantRateWifiManager ();
+
+ WifiMode GetDataMode (void) const;
+ WifiMode GetCtlMode (void) const;
+private:
+ virtual class WifiRemoteStation *CreateStation (void);
+
+ WifiMode m_dataMode;
+ WifiMode m_ctlMode;
+};
+
+
+class ConstantRateWifiRemoteStation : public WifiRemoteStation
+{
+public:
+ ConstantRateWifiRemoteStation (Ptr<ConstantRateWifiManager> stations);
+ virtual ~ConstantRateWifiRemoteStation ();
+
+ virtual void ReportRxOk (double rxSnr, WifiMode txMode);
+ virtual void ReportRtsFailed (void);
+ virtual void ReportDataFailed (void);
+ virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+ virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+ virtual void ReportFinalRtsFailed (void);
+ virtual void ReportFinalDataFailed (void);
+
+private:
+ virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
+ virtual WifiMode DoGetDataMode (uint32_t size);
+ virtual WifiMode DoGetRtsMode (void);
+ Ptr<ConstantRateWifiManager> m_manager;
+};
+
+} // namespace ns3
+
+
+
+#endif /* CONSTANT_RATE_WIFI_MANAGER_H */
--- a/src/devices/wifi/dca-txop.cc Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/dca-txop.cc Sat Mar 01 21:21:53 2008 +0100
@@ -22,26 +22,23 @@
#include "ns3/packet.h"
#include "ns3/log.h"
#include "ns3/simulator.h"
-#include "ns3/net-device.h"
#include "ns3/node.h"
+#include "ns3/uinteger.h"
+#include "ns3/trace-source-accessor.h"
#include "dca-txop.h"
#include "dcf-manager.h"
-#include "wifi-mac-parameters.h"
#include "mac-low.h"
#include "wifi-mac-queue.h"
#include "mac-tx-middle.h"
#include "wifi-mac-trailer.h"
-#include "mac-stations.h"
-#include "wifi-phy.h"
+#include "wifi-mac.h"
#include "random-stream.h"
-#include "ns3/composite-trace-resolver.h"
NS_LOG_COMPONENT_DEFINE ("DcaTxop");
#define MY_DEBUG(x) \
- NS_LOG_DEBUG (Simulator::Now () << " " << m_low->GetDevice ()->GetNode ()->GetId () << ":" << \
- m_low->GetDevice ()->GetIfIndex () << " " << x)
+ NS_LOG_DEBUG (Simulator::Now () << " " << m_low->GetMac ()->GetAddress () << " " << x)
namespace ns3 {
@@ -97,8 +94,37 @@
DcaTxop *m_txop;
};
-DcaTxop::DcaTxop (uint32_t minCw, uint32_t maxCw, uint32_t aifsn, DcfManager *manager)
- : m_manager (manager),
+TypeId
+DcaTxop::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("DcaTxop")
+ .SetParent<Object> ()
+ .AddConstructor<DcaTxop> ()
+ .AddAttribute ("MinCw", "XXX",
+ Uinteger (15),
+ MakeUintegerAccessor (&DcaTxop::SetMinCw,
+ &DcaTxop::GetMinCw),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("MaxCw", "XXX",
+ Uinteger (1023),
+ MakeUintegerAccessor (&DcaTxop::SetMaxCw,
+ &DcaTxop::GetMaxCw),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("Aifsn", "XXX",
+ Uinteger (2),
+ MakeUintegerAccessor (&DcaTxop::SetAifsn,
+ &DcaTxop::GetAifsn),
+ MakeUintegerChecker<uint32_t> ())
+ .AddTraceSource ("Ssrc", "XXX",
+ MakeTraceSourceAccessor (&DcaTxop::m_ssrc))
+ .AddTraceSource ("Slrc", "XXX",
+ MakeTraceSourceAccessor (&DcaTxop::m_slrc))
+ ;
+ return tid;
+}
+
+DcaTxop::DcaTxop ()
+ : m_manager (0),
m_currentPacket (0),
m_ssrc (0),
m_slrc (0)
@@ -106,23 +132,29 @@
{
m_transmissionListener = new DcaTxop::TransmissionListener (this);
m_dcf = new DcaTxop::Dcf (this);
- m_dcf->SetCwBounds (minCw, maxCw);
- m_dcf->SetAifsn (aifsn);
- m_manager->Add (m_dcf);
- m_queue = new WifiMacQueue ();
+ m_queue = CreateObjectWith<WifiMacQueue> ();
m_rng = new RealRandomStream ();
+ m_txMiddle = new MacTxMiddle ();
}
DcaTxop::~DcaTxop ()
{
delete m_transmissionListener;
- delete m_queue;
delete m_dcf;
delete m_rng;
+ delete m_txMiddle;
m_transmissionListener = 0;
m_queue = 0;
m_dcf = 0;
m_rng = 0;
+ m_txMiddle = 0;
+}
+
+void
+DcaTxop::SetManager (DcfManager *manager)
+{
+ m_manager = manager;
+ m_manager->Add (m_dcf);
}
void
@@ -131,19 +163,9 @@
m_low = low;
}
void
-DcaTxop::SetParameters (WifiMacParameters *parameters)
-{
- m_parameters = parameters;
-}
-void
-DcaTxop::SetStations (MacStations *stations)
+DcaTxop::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> remoteManager)
{
- m_stations = stations;
-}
-void
-DcaTxop::SetTxMiddle (MacTxMiddle *txMiddle)
-{
- m_txMiddle = txMiddle;
+ m_stationManager = remoteManager;
}
void
DcaTxop::SetTxOkCallback (TxOk callback)
@@ -166,22 +188,52 @@
{
m_queue->SetMaxDelay (delay);
}
+void
+DcaTxop::SetMinCw (uint32_t minCw)
+{
+ m_dcf->SetCwMin (minCw);
+}
+void
+DcaTxop::SetMaxCw (uint32_t maxCw)
+{
+ m_dcf->SetCwMax (maxCw);
+}
+void
+DcaTxop::SetAifsn (uint32_t aifsn)
+{
+ m_dcf->SetAifsn (aifsn);
+}
+uint32_t
+DcaTxop::GetMinCw (void) const
+{
+ return m_dcf->GetCwMin ();
+}
+uint32_t
+DcaTxop::GetMaxCw (void) const
+{
+ return m_dcf->GetCwMax ();
+}
+uint32_t
+DcaTxop::GetAifsn (void) const
+{
+ return m_dcf->GetAifsn ();
+}
void
DcaTxop::Queue (Ptr<const Packet> packet, WifiMacHeader const &hdr)
{
WifiMacTrailer fcs;
uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
- MacStation *station = m_stations->Lookup (hdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (hdr.GetAddr1 ());
station->PrepareForQueue (packet, fullPacketSize);
m_queue->Enqueue (packet, hdr);
StartAccessIfNeeded ();
}
-MacStation *
+WifiRemoteStation *
DcaTxop::GetStation (Mac48Address ad) const
{
- return m_stations->Lookup (ad);
+ return m_stationManager->Lookup (ad);
}
void
@@ -213,31 +265,24 @@
return m_low;
}
-WifiMacParameters *
-DcaTxop::Parameters (void)
-{
- return m_parameters;
-}
-
-
bool
DcaTxop::NeedRts (void)
{
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->NeedRts (m_currentPacket);
}
bool
DcaTxop::NeedFragmentation (void)
{
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->NeedFragmentation (m_currentPacket);
}
uint32_t
DcaTxop::GetNFragments (void)
{
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->GetNFragments (m_currentPacket);
}
void
@@ -249,20 +294,20 @@
uint32_t
DcaTxop::GetFragmentSize (void)
{
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->GetFragmentSize (m_currentPacket, m_fragmentNumber);
}
bool
DcaTxop::IsLastFragment (void)
{
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->IsLastFragment (m_currentPacket, m_fragmentNumber);
}
uint32_t
DcaTxop::GetNextFragmentSize (void)
{
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->GetFragmentSize (m_currentPacket, m_fragmentNumber + 1);
}
@@ -289,13 +334,13 @@
uint32_t
DcaTxop::GetMaxSsrc (void) const
{
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->GetMaxSsrc (m_currentPacket);
}
uint32_t
DcaTxop::GetMaxSlrc (void) const
{
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
return station->GetMaxSlrc (m_currentPacket);
}
@@ -409,10 +454,9 @@
{
MY_DEBUG ("missed cts");
m_ssrc++;
- m_ctstimeoutTrace (m_ssrc);
if (m_ssrc > GetMaxSsrc ())
{
- MacStation *station = m_stations->Lookup (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportFinalRtsFailed ();
// to reset the dcf.
m_currentPacket = 0;
@@ -456,10 +500,9 @@
{
MY_DEBUG ("missed ack");
m_slrc++;
- m_acktimeoutTrace (m_slrc);
if (m_slrc > GetMaxSlrc ())
{
- MacStation *station = m_stations->Lookup (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportFinalDataFailed ();
// to reset the dcf.
m_currentPacket = 0;
@@ -531,21 +574,4 @@
*/
}
-Ptr<TraceResolver>
-DcaTxop::GetTraceResolver (void) const
-{
- Ptr<CompositeTraceResolver> resolver =
- Create<CompositeTraceResolver> ();
- resolver->AddSource ("ackTimeout",
- TraceDoc ("ACK timeout",
- "uint32_t", "Number of transmission attemps"),
- m_acktimeoutTrace);
- resolver->AddSource ("ctsTimeout",
- TraceDoc ("CTS timeout",
- "uint32_t", "Number of transmission attemps"),
- m_ctstimeoutTrace);
- resolver->SetParentResolver (Object::GetTraceResolver ());
- return resolver;
-}
-
} // namespace ns3
--- a/src/devices/wifi/dca-txop.h Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/dca-txop.h Sat Mar 01 21:21:53 2008 +0100
@@ -24,11 +24,12 @@
#include <stdint.h>
#include "ns3/callback.h"
#include "ns3/packet.h"
-#include "ns3/callback-trace-source.h"
#include "ns3/nstime.h"
#include "ns3/object.h"
+#include "ns3/traced-value.h"
#include "wifi-mac-header.h"
#include "wifi-mode.h"
+#include "wifi-remote-station-manager.h"
namespace ns3 {
@@ -65,26 +66,18 @@
class DcaTxop : public Object
{
public:
+ static TypeId GetTypeId (void);
+
typedef Callback <void, WifiMacHeader const&> TxOk;
typedef Callback <void, WifiMacHeader const&> TxFailed;
- /**
- * \param cwMin forwarded to ns3::DcfState constructor
- * \param cwMax forwarded to ns3::DcfState constructor
- * \param aifsn forwarded to ns3::DcfState constructor
- * \param manager the manager which will be responsible
- * for controlling access to this DcaTxop.
- *
- * Initialized from \valueref{WifiMaxSsrc}, \valueref{WifiMaxSlrc},
- * \valueref{WifiRtsCtsThreshold}, and, \valueref{WifiFragmentationThreshold}.
- */
- DcaTxop (uint32_t cwMin, uint32_t cwMax, uint32_t aifsn, DcfManager *manager);
+ DcaTxop ();
~DcaTxop ();
void SetLow (Ptr<MacLow> low);
- void SetParameters (WifiMacParameters *parameters);
- void SetStations (MacStations *stations);
- void SetTxMiddle (MacTxMiddle *txMiddle);
+ void SetManager (DcfManager *manager);
+ void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> remoteManager);
+
/**
* \param callback the callback to invoke when a
* packet transmission was completed successfully.
@@ -98,6 +91,12 @@
void SetMaxQueueSize (uint32_t size);
void SetMaxQueueDelay (Time delay);
+ void SetMinCw (uint32_t minCw);
+ void SetMaxCw (uint32_t maxCw);
+ void SetAifsn (uint32_t aifsn);
+ uint32_t GetMinCw (void) const;
+ uint32_t GetMaxCw (void) const;
+ uint32_t GetAifsn (void) const;
/**
* \param packet packet to send
@@ -117,9 +116,7 @@
friend class TransmissionListener;
// Inherited from ns3::Object
- virtual Ptr<TraceResolver> GetTraceResolver (void) const;
Ptr<MacLow> Low (void);
- WifiMacParameters *Parameters (void);
/* dcf notifications forwarded here */
bool NeedsAccess (void) const;
@@ -141,7 +138,7 @@
uint32_t GetNFragments (void);
uint32_t GetNextFragmentSize (void);
uint32_t GetFragmentSize (void);
- MacStation *GetStation (Mac48Address to) const;
+ WifiRemoteStation *GetStation (Mac48Address to) const;
uint32_t GetMaxSsrc (void) const;
uint32_t GetMaxSlrc (void) const;
bool IsLastFragment (void);
@@ -152,11 +149,10 @@
DcfManager *m_manager;
TxOk m_txOkCallback;
TxFailed m_txFailedCallback;
- WifiMacQueue *m_queue;
+ Ptr<WifiMacQueue> m_queue;
MacTxMiddle *m_txMiddle;
Ptr <MacLow> m_low;
- MacStations *m_stations;
- WifiMacParameters *m_parameters;
+ Ptr<WifiRemoteStationManager> m_stationManager;
TransmissionListener *m_transmissionListener;
RandomStream *m_rng;
@@ -164,18 +160,9 @@
bool m_accessOngoing;
Ptr<const Packet> m_currentPacket;
WifiMacHeader m_currentHdr;
- uint32_t m_ssrc;
- uint32_t m_slrc;
+ TracedValue<uint32_t> m_ssrc;
+ TracedValue<uint32_t> m_slrc;
uint8_t m_fragmentNumber;
-
- /* 80211-dca-acktimeout
- * param1: slrc
- */
- CallbackTraceSource<uint32_t> m_acktimeoutTrace;
- /* 80211-dca-ctstimeout
- * param1: ssrc
- */
- CallbackTraceSource<uint32_t> m_ctstimeoutTrace;
};
} //namespace ns3
--- a/src/devices/wifi/dcf-manager-test.cc Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/dcf-manager-test.cc Sat Mar 01 21:21:53 2008 +0100
@@ -51,7 +51,7 @@
private:
- void StartTest (uint64_t slotTime, uint64_t sifs, uint64_t ackTxDuration);
+ void StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs);
void AddDcfState (uint32_t aifsn);
void EndTest (void);
void ExpectInternalCollision (uint64_t time, uint32_t from, uint32_t nSlots);
@@ -171,12 +171,12 @@
}
void
-DcfManagerTest::StartTest (uint64_t slotTime, uint64_t sifs, uint64_t ackTxDuration)
+DcfManagerTest::StartTest (uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs)
{
m_dcfManager = new DcfManager ();
- m_dcfManager->SetSlotTime (MicroSeconds (slotTime));
+ m_dcfManager->SetSlot (MicroSeconds (slotTime));
m_dcfManager->SetSifs (MicroSeconds (sifs));
- m_dcfManager->SetAckTxDuration (MicroSeconds (ackTxDuration));
+ m_dcfManager->SetEifsNoDifs (MicroSeconds (eifsNoDifsNoSifs+sifs));
}
void
--- a/src/devices/wifi/dcf-manager.cc Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/dcf-manager.cc Sat Mar 01 21:21:53 2008 +0100
@@ -6,7 +6,9 @@
#include <math.h>
#include "dcf-manager.h"
-#include "wifi-mac-parameters.h"
+#include "wifi-phy.h"
+#include "wifi-mac.h"
+#include "mac-low.h"
NS_LOG_COMPONENT_DEFINE ("DcfManager");
@@ -22,6 +24,9 @@
DcfState::DcfState ()
: m_backoffSlots (0),
m_backoffStart (Seconds (0.0)),
+ m_cwMin (0),
+ m_cwMax (0),
+ m_cw (0),
m_accessRequested (false)
{}
@@ -33,14 +38,33 @@
{
m_aifsn = aifsn;
}
-
void
-DcfState::SetCwBounds (uint32_t minCw, uint32_t maxCw)
+DcfState::SetCwMin (uint32_t minCw)
{
m_cwMin = minCw;
+ ResetCw ();
+}
+void
+DcfState::SetCwMax (uint32_t maxCw)
+{
m_cwMax = maxCw;
ResetCw ();
}
+uint32_t
+DcfState::GetAifsn (void) const
+{
+ return m_aifsn;
+}
+uint32_t
+DcfState::GetCwMin (void) const
+{
+ return m_cwMin;
+}
+uint32_t
+DcfState::GetCwMax (void) const
+{
+ return m_cwMax;
+}
void
DcfState::ResetCw (void)
@@ -72,11 +96,6 @@
m_backoffStart = Simulator::Now ();
}
-uint32_t
-DcfState::GetAifsn (void) const
-{
- return m_aifsn;
-}
uint32_t
DcfState::GetCw (void) const
{
@@ -121,6 +140,53 @@
}
+/***************************************************************
+ * Listener for Nav events. Forwards to DcfManager
+ ***************************************************************/
+
+class LowNavListener : public ns3::MacLowNavListener {
+public:
+ LowNavListener (ns3::DcfManager *dcf)
+ : m_dcf (dcf) {}
+ virtual ~LowNavListener () {}
+ virtual void NavStart (Time duration) {
+ m_dcf->NotifyNavStartNow (duration);
+ }
+ virtual void NavReset (Time duration) {
+ m_dcf->NotifyNavResetNow (duration);
+ }
+private:
+ ns3::DcfManager *m_dcf;
+};
+
+/***************************************************************
+ * Listener for PHY events. Forwards to DcfManager
+ ***************************************************************/
+
+class PhyListener : public ns3::WifiPhyListener {
+public:
+ PhyListener (ns3::DcfManager *dcf)
+ : m_dcf (dcf) {}
+ virtual ~PhyListener () {}
+ virtual void NotifyRxStart (Time duration) {
+ m_dcf->NotifyRxStartNow (duration);
+ }
+ virtual void NotifyRxEndOk (void) {
+ m_dcf->NotifyRxEndOkNow ();
+ }
+ virtual void NotifyRxEndError (void) {
+ m_dcf->NotifyRxEndErrorNow ();
+ }
+ virtual void NotifyTxStart (Time duration) {
+ m_dcf->NotifyTxStartNow (duration);
+ }
+ virtual void NotifyCcaBusyStart (Time duration) {
+ m_dcf->NotifyCcaBusyStartNow (duration);
+ }
+private:
+ ns3::DcfManager *m_dcf;
+};
+
/****************************************************************
* Implement the DCF manager of all DCF state holders
****************************************************************/
@@ -138,11 +204,34 @@
m_lastBusyDuration (MicroSeconds (0)),
m_rxing (false),
m_slotTime (Seconds (0.0)),
- m_sifs (Seconds (0.0))
+ m_sifs (Seconds (0.0)),
+ m_phyListener (0),
+ m_lowListener (0)
{}
+DcfManager::~DcfManager ()
+{
+ delete m_phyListener;
+ delete m_lowListener;
+ m_phyListener = 0;
+ m_lowListener = 0;
+}
+
void
-DcfManager::SetSlotTime (Time slotTime)
+DcfManager::SetupPhyListener (Ptr<WifiPhy> phy)
+{
+ m_phyListener = new PhyListener (this);
+ phy->RegisterListener (m_phyListener);
+}
+void
+DcfManager::SetupLowListener (Ptr<MacLow> low)
+{
+ m_lowListener = new LowNavListener (this);
+ low->RegisterNavListener (m_lowListener);
+}
+
+void
+DcfManager::SetSlot (Time slotTime)
{
m_slotTime = slotTime;
}
@@ -151,11 +240,10 @@
{
m_sifs = sifs;
}
-
void
-DcfManager::SetAckTxDuration (Time ackTxDuration)
+DcfManager::SetEifsNoDifs (Time eifsNoDifs)
{
- m_ackTxTime = ackTxDuration;
+ m_eifsNoDifs = eifsNoDifs;
}
void
@@ -302,12 +390,15 @@
Time rxAccessStart;
if (m_lastRxEnd >= m_lastRxStart)
{
- rxAccessStart = m_lastRxEnd + m_sifs;
+ rxAccessStart = m_lastRxEnd;
if (!m_lastRxReceivedOk)
{
- /* to handle EIFS */
- rxAccessStart += m_ackTxTime;
- }
+ rxAccessStart += m_eifsNoDifs;
+ }
+ else
+ {
+ rxAccessStart += m_sifs;
+ }
}
else
{
--- a/src/devices/wifi/dcf-manager.h Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/dcf-manager.h Sat Mar 01 21:21:53 2008 +0100
@@ -6,6 +6,10 @@
namespace ns3 {
+class WifiPhy;
+class WifiMac;
+class MacLow;
+
/**
* \brief keep track of the state needed for a single DCF
* function.
@@ -29,13 +33,11 @@
* Calling this method after DcfManager::Add has been called is not recommended.
*/
void SetAifsn (uint32_t aifsn);
- /**
- * \param minCw the minimum value for the CW variable.
- * \param maxCw the maximum value for the CW variable.
- *
- * Calling this method after DcfManager::Add has been called is not recommended.
- */
- void SetCwBounds (uint32_t minCw, uint32_t maxCw);
+ void SetCwMin (uint32_t minCw);
+ void SetCwMax (uint32_t maxCw);
+ uint32_t GetAifsn (void) const;
+ uint32_t GetCwMin (void) const;
+ uint32_t GetCwMax (void) const;
/**
* Update the value of the CW variable to take into account
* a transmission success or a transmission abort (stop transmission
@@ -70,7 +72,6 @@
private:
friend class DcfManager;
- uint32_t GetAifsn (void) const;
uint32_t GetBackoffSlots (void) const;
Time GetBackoffStart (void) const;
void UpdateBackoffSlotsNow (uint32_t nSlots, Time backoffUpdateBound);
@@ -139,6 +140,10 @@
{
public:
DcfManager ();
+ ~DcfManager ();
+
+ void SetupPhyListener (Ptr<WifiPhy> phy);
+ void SetupLowListener (Ptr<MacLow> low);
/**
* \param slotTime the duration of a slot.
@@ -146,7 +151,7 @@
* It is a bad idea to call this method after RequestAccess or
* one of the Notify methods has been invoked.
*/
- void SetSlotTime (Time slotTime);
+ void SetSlot (Time slotTime);
/**
* \param sifs the duration of a SIFS.
*
@@ -156,13 +161,12 @@
void SetSifs (Time sifs);
/**
- * \param ackTxDuration time to transmit an ACK at the lowest mandatory rate
+ * \param eifsNoDifs the duration of a EIFS minus the duration of DIFS.
*
- * This value is used for the calculation of the EIFS duration.
* It is a bad idea to call this method after RequestAccess or
* one of the Notify methods has been invoked.
*/
- void SetAckTxDuration (Time ackTxDuration);
+ void SetEifsNoDifs (Time eifsNoDifs);
/**
* \param dcf a new DcfState.
@@ -265,10 +269,12 @@
Time m_lastBusyDuration;
bool m_rxing;
bool m_sleeping;
- Time m_ackTxTime;
+ Time m_eifsNoDifs;
EventId m_accessTimeout;
Time m_slotTime;
Time m_sifs;
+ class PhyListener *m_phyListener;
+ class LowNavListener *m_lowListener;
};
} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/ideal-wifi-manager.cc Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,182 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ideal-wifi-manager.h"
+#include "wifi-phy.h"
+#include "ns3/assert.h"
+#include "ns3/double.h"
+#include <math.h>
+
+#define noIDEAL_DEBUG 1
+
+#ifdef IDEAL_DEBUG
+#include <iostream>
+# define TRACE(x) \
+std::cout << "IDEAL TRACE " << x << std::endl;
+#else
+# define TRACE(x)
+#endif
+
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (IdealWifiManager);
+
+TypeId
+IdealWifiManager::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("IdealWifiManager")
+ .SetParent<WifiRemoteStationManager> ()
+ .AddConstructor<IdealWifiManager> ()
+ .AddAttribute ("BerThreshold",
+ "The maximum Bit Error Rate acceptable at any transmission mode",
+ Double (10e-6),
+ MakeDoubleAccessor (&IdealWifiManager::m_ber),
+ MakeDoubleChecker<double> ())
+ ;
+ return tid;
+}
+
+IdealWifiManager::IdealWifiManager ()
+{}
+IdealWifiManager::~IdealWifiManager ()
+{}
+
+void
+IdealWifiManager::SetupPhy (Ptr<WifiPhy> phy)
+{
+ uint32_t nModes = phy->GetNModes ();
+ for (uint32_t i = 0; i < nModes; i++)
+ {
+ WifiMode mode = phy->GetMode (i);
+ AddModeSnrThreshold (mode, phy->CalculateSnr (mode, m_ber));
+ }
+
+ WifiRemoteStationManager::SetupPhy (phy);
+}
+
+WifiRemoteStation *
+IdealWifiManager::CreateStation (void)
+{
+ return new IdealWifiRemoteStation (this);
+}
+
+double
+IdealWifiManager::GetSnrThreshold (WifiMode mode) const
+{
+ for (Thresholds::const_iterator i = m_thresholds.begin (); i != m_thresholds.end (); i++)
+ {
+ if (mode == i->second)
+ {
+ return i->first;
+ }
+ }
+ NS_ASSERT (false);
+ return 0.0;
+}
+
+void
+IdealWifiManager::AddModeSnrThreshold (WifiMode mode, double snr)
+{
+ m_thresholds.push_back (std::make_pair (snr,mode));
+}
+
+IdealWifiRemoteStation::IdealWifiRemoteStation (Ptr<IdealWifiManager> manager)
+ : m_manager (manager),
+ m_lastSnr (0.0)
+{}
+IdealWifiRemoteStation::~IdealWifiRemoteStation ()
+{}
+void
+IdealWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+{}
+void
+IdealWifiRemoteStation::ReportRtsFailed (void)
+{}
+void
+IdealWifiRemoteStation::ReportDataFailed (void)
+{}
+void
+IdealWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+{
+ TRACE ("got cts for rts snr="<<rtsSnr);
+ m_lastSnr = rtsSnr;
+}
+void
+IdealWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+{
+ TRACE ("got cts for rts snr="<<dataSnr);
+ m_lastSnr = dataSnr;
+}
+void
+IdealWifiRemoteStation::ReportFinalRtsFailed (void)
+{}
+void
+IdealWifiRemoteStation::ReportFinalDataFailed (void)
+{}
+
+WifiMode
+IdealWifiRemoteStation::DoGetDataMode (uint32_t size)
+{
+ // We search within the Supported rate set the mode with the
+ // highest snr threshold possible which is smaller than m_lastSnr
+ // to ensure correct packet delivery.
+ double maxThreshold = 0.0;
+ WifiMode maxMode = m_manager->GetDefaultMode ();
+ for (uint32_t i = 0; i < GetNSupportedModes (); i++)
+ {
+ WifiMode mode = GetSupportedMode (i);
+ double threshold = m_manager->GetSnrThreshold (mode);
+ if (threshold > maxThreshold &&
+ threshold < m_lastSnr)
+ {
+ maxThreshold = threshold;
+ maxMode = mode;
+ }
+ }
+ return maxMode;
+}
+WifiMode
+IdealWifiRemoteStation::DoGetRtsMode (void)
+{
+ // We search within the Basic rate set the mode with the highest
+ // snr threshold possible which is smaller than m_lastSnr to
+ // ensure correct packet delivery.
+ double maxThreshold = 0.0;
+ WifiMode maxMode = m_manager->GetDefaultMode ();
+ for (uint32_t i = 0; i < m_manager->GetNBasicModes (); i++)
+ {
+ WifiMode mode = m_manager->GetBasicMode (i);
+ double threshold = m_manager->GetSnrThreshold (mode);
+ if (threshold > maxThreshold &&
+ threshold < m_lastSnr)
+ {
+ maxThreshold = threshold;
+ maxMode = mode;
+ }
+ }
+ return maxMode;
+}
+Ptr<WifiRemoteStationManager>
+IdealWifiRemoteStation::GetManager (void) const
+{
+ return m_manager;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/ideal-wifi-manager.h Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IDEAL_MAC_STATIONS_H
+#define IDEAL_MAC_STATIONS_H
+
+#include <stdint.h>
+#include <vector>
+#include "wifi-mode.h"
+#include "wifi-remote-station-manager.h"
+
+namespace ns3 {
+
+/**
+ * \brief Ideal rate control algorithm
+ *
+ * This class implements an 'ideal' rate control algorithm
+ * similar to RBAR in spirit (see <i>A rate-adaptive MAC
+ * protocol for multihop wireless networks</i> by G. Holland,
+ * N. Vaidya, and P. Bahl.): every station keeps track of the
+ * snr of every packet received and sends back this snr to the
+ * original transmitter by an out-of-band mechanism. Each
+ * transmitter keeps track of the last snr sent back by a receiver
+ * and uses it to pick a transmission mode based on a set
+ * of snr thresholds built from a target ber and transmission
+ * mode-specific snr/ber curves.
+ */
+class IdealWifiManager : public WifiRemoteStationManager
+{
+public:
+ static TypeId GetTypeId (void);
+ IdealWifiManager ();
+ virtual ~IdealWifiManager ();
+
+ virtual void SetupPhy (Ptr<WifiPhy> phy);
+
+ WifiMode GetMode (double snr) const;
+ // return the min snr needed to successfully transmit
+ // data with this mode at the specified ber.
+ double GetSnrThreshold (WifiMode mode) const;
+ void AddModeSnrThreshold (WifiMode mode, double ber);
+private:
+ virtual class WifiRemoteStation *CreateStation (void);
+
+ typedef std::vector<std::pair<double,WifiMode> > Thresholds;
+
+ double m_ber;
+ Thresholds m_thresholds;
+ double m_minSnr;
+ double m_maxSnr;
+};
+
+class IdealWifiRemoteStation : public WifiRemoteStation
+{
+public:
+ IdealWifiRemoteStation (Ptr<IdealWifiManager> stations);
+
+ virtual ~IdealWifiRemoteStation ();
+
+ virtual void ReportRxOk (double rxSnr, WifiMode txMode);
+ virtual void ReportRtsFailed (void);
+ virtual void ReportDataFailed (void);
+ virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+ virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+ virtual void ReportFinalRtsFailed (void);
+ virtual void ReportFinalDataFailed (void);
+
+private:
+ virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
+ virtual WifiMode DoGetDataMode (uint32_t size);
+ virtual WifiMode DoGetRtsMode (void);
+
+ Ptr<IdealWifiManager> m_manager;
+ double m_lastSnr;
+};
+
+} // namespace ns3
+
+#endif /* MAC_STA_H */
--- a/src/devices/wifi/mac-low.cc Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/mac-low.cc Sat Mar 01 21:21:53 2008 +0100
@@ -28,7 +28,7 @@
#include "mac-low.h"
#include "wifi-phy.h"
#include "wifi-mac-trailer.h"
-#include "wifi-net-device.h"
+#include "wifi-mac.h"
#include "mac-stations.h"
#include "wifi-mac-parameters.h"
#include "ns3/composite-trace-resolver.h"
@@ -36,8 +36,7 @@
NS_LOG_COMPONENT_DEFINE ("MacLow");
#define MY_DEBUG(x) \
- NS_LOG_DEBUG (Simulator::Now () << " " << m_device->GetNode ()->GetId () << ":" << \
- m_device->GetIfIndex () << " " << x)
+ NS_LOG_DEBUG (Simulator::Now () << " " << m_mac->GetAddress () << " " << x)
namespace ns3 {
@@ -300,37 +299,30 @@
}
}
-/****************************************************************************
- * API methods below.
- ****************************************************************************/
-
-void
-MacLow::SetDevice (Ptr<WifiNetDevice> device)
-{
- m_device = device;
-}
-Ptr<NetDevice>
-MacLow::GetDevice (void) const
-{
- return m_device;
-}
void
MacLow::SetPhy (Ptr<WifiPhy> phy)
{
m_phy = phy;
+ m_phy->SetReceiveOkCallback (MakeCallback (&MacLow::ReceiveOk, this));
+ m_phy->SetReceiveErrorCallback (MakeCallback (&MacLow::ReceiveError, this));
}
-void
-MacLow::SetParameters (WifiMacParameters *parameters)
+void
+MacLow::SetMac (Ptr<WifiMac> mac)
{
- m_parameters = parameters;
+ m_mac = mac;
}
void
-MacLow::SetStations (MacStations *stations)
+MacLow::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> manager)
{
- m_stations = stations;
+ m_stationManager = manager;
+}
+Ptr<WifiMac>
+MacLow::GetMac (void)
+{
+ return m_mac;
}
void
-MacLow::SetRxCallback (MacLowRxCallback callback)
+MacLow::SetRxCallback (Callback<void,Ptr<Packet>,const WifiMacHeader *> callback)
{
m_rxCallback = callback;
}
@@ -389,7 +381,6 @@
MacLow::ReceiveError (Ptr<Packet> packet, double rxSnr)
{
MY_DEBUG ("rx failed ");
- m_dropError (packet);
if (m_txParams.MustWaitFastAck ())
{
NS_ASSERT (m_fastAckFailedTimeoutEvent.IsExpired ());
@@ -422,11 +413,11 @@
* that STA shall not respond to the RTS frame.
*/
if (isPrevNavZero &&
- hdr.GetAddr1 () == m_device->GetSelfAddress ())
+ hdr.GetAddr1 () == m_mac->GetAddress ())
{
MY_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
NS_ASSERT (m_sendCtsEvent.IsExpired ());
- MacStation *station = m_stations->Lookup (hdr.GetAddr2 ());
+ WifiRemoteStation *station = GetStation (hdr.GetAddr2 ());
station->ReportRxOk (rxSnr, txMode);
m_sendCtsEvent = Simulator::Schedule (GetSifs (),
&MacLow::SendCtsAfterRts, this,
@@ -441,14 +432,14 @@
}
}
else if (hdr.IsCts () &&
- hdr.GetAddr1 () == m_device->GetSelfAddress () &&
+ hdr.GetAddr1 () == m_mac->GetAddress () &&
m_ctsTimeoutEvent.IsRunning () &&
m_currentPacket != 0)
{
MY_DEBUG ("receive cts from="<<m_currentHdr.GetAddr1 ());
SnrTag tag;
packet->PeekTag (tag);
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportRxOk (rxSnr, txMode);
station->ReportRtsOk (rxSnr, txMode, tag.Get ());
@@ -462,7 +453,7 @@
txMode);
}
else if (hdr.IsAck () &&
- hdr.GetAddr1 () == m_device->GetSelfAddress () &&
+ hdr.GetAddr1 () == m_mac->GetAddress () &&
(m_normalAckTimeoutEvent.IsRunning () ||
m_fastAckTimeoutEvent.IsRunning () ||
m_superFastAckTimeoutEvent.IsRunning ()) &&
@@ -471,7 +462,7 @@
MY_DEBUG ("receive ack from="<<m_currentHdr.GetAddr1 ());
SnrTag tag;
packet->PeekTag (tag);
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportRxOk (rxSnr, txMode);
station->ReportDataOk (rxSnr, txMode, tag.Get ());
bool gotAck = false;
@@ -501,9 +492,9 @@
{
MY_DEBUG ("rx drop " << hdr.GetTypeString ());
}
- else if (hdr.GetAddr1 () == m_device->GetSelfAddress ())
+ else if (hdr.GetAddr1 () == m_mac->GetAddress ())
{
- MacStation *station = GetStation (hdr.GetAddr2 ());
+ WifiRemoteStation *station = GetStation (hdr.GetAddr2 ());
station->ReportRxOk (rxSnr, txMode);
if (hdr.IsQosData () && hdr.IsQosNoAck ())
@@ -583,22 +574,27 @@
Time
MacLow::GetSifs (void) const
{
- return m_parameters->GetSifs ();
+ return m_mac->GetSifs ();
+}
+Time
+MacLow::GetSlotTime (void) const
+{
+ return m_mac->GetSlot ();
}
Time
MacLow::GetPifs (void) const
{
- return m_parameters->GetPifs ();
+ return m_mac->GetPifs ();
}
Time
MacLow::GetAckTimeout (void) const
{
- return m_parameters->GetAckTimeout ();
+ return m_mac->GetAckTimeout ();
}
Time
MacLow::GetCtsTimeout (void) const
{
- return m_parameters->GetCtsTimeout ();
+ return m_mac->GetCtsTimeout ();
}
uint32_t
MacLow::GetSize (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
@@ -680,7 +676,7 @@
Time duration = hdr.GetDuration ();
if (hdr.IsCfpoll () &&
- hdr.GetAddr2 () == m_device->GetBssid ())
+ hdr.GetAddr2 () == m_mac->GetBssid ())
{
// see section 9.3.2.2 802.11-1999
DoNavResetNow (duration);
@@ -688,7 +684,7 @@
}
// XXX Note that we should also handle CF_END specially here
// but we don't for now because we do not generate them.
- else if (hdr.GetAddr1 () != m_device->GetSelfAddress ())
+ else if (hdr.GetAddr1 () != m_mac->GetAddress ())
{
// see section 9.2.5.4 802.11-1999
bool navUpdated = DoNavStartNow (duration);
@@ -706,7 +702,7 @@
cts.SetType (WIFI_MAC_CTL_CTS);
Time navCounterResetCtsMissedDelay =
m_phy->CalculateTxDuration (cts.GetSerializedSize (), txMode, preamble) +
- Scalar (2) * m_parameters->GetSifs () + Scalar (2) * m_parameters->GetSlotTime ();
+ Scalar (2) * GetSifs () + Scalar (2) * GetSlotTime ();
m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
&MacLow::NavCounterResetCtsMissed, this,
Simulator::Now ());
@@ -778,7 +774,7 @@
// XXX: should check that there was no rx start before now.
// we should restart a new cts timeout now until the expected
// end of rx if there was a rx start before now.
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportRtsFailed ();
m_currentPacket = 0;
MacLowTransmissionListener *listener = m_listener;
@@ -792,7 +788,7 @@
// XXX: should check that there was no rx start before now.
// we should restart a new ack timeout now until the expected
// end of rx if there was a rx start before now.
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportDataFailed ();
MacLowTransmissionListener *listener = m_listener;
m_listener = 0;
@@ -801,7 +797,7 @@
void
MacLow::FastAckTimeout (void)
{
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportDataFailed ();
MacLowTransmissionListener *listener = m_listener;
m_listener = 0;
@@ -818,7 +814,7 @@
void
MacLow::SuperFastAckTimeout ()
{
- MacStation *station = GetStation (m_currentHdr.GetAddr1 ());
+ WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
station->ReportDataFailed ();
MacLowTransmissionListener *listener = m_listener;
m_listener = 0;
@@ -843,7 +839,7 @@
rts.SetDsNotFrom ();
rts.SetDsNotTo ();
rts.SetAddr1 (m_currentHdr.GetAddr1 ());
- rts.SetAddr2 (m_device->GetSelfAddress ());
+ rts.SetAddr2 (m_mac->GetAddress ());
WifiMode rtsTxMode = GetRtsTxMode (m_currentPacket, &m_currentHdr);
Time duration = Seconds (0);
if (m_txParams.HasDurationId ())
@@ -968,10 +964,10 @@
}
}
-MacStation *
+WifiRemoteStation *
MacLow::GetStation (Mac48Address ad) const
{
- return m_stations->Lookup (ad);
+ return m_stationManager->Lookup (ad);
}
void
@@ -1077,17 +1073,4 @@
ForwardDown (packet, &ack, ackTxMode);
}
-Ptr<TraceResolver>
-MacLow::GetTraceResolver (void) const
-{
- Ptr<CompositeTraceResolver> resolver =
- Create<CompositeTraceResolver> ();
- resolver->AddSource ("error",
- TraceDoc ("Receive a packet with errors",
- "Packet", "the packet received"),
- m_dropError);
- resolver->SetParentResolver (Object::GetTraceResolver ());
- return resolver;
-}
-
} // namespace ns3
--- a/src/devices/wifi/mac-low.h Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/mac-low.h Sat Mar 01 21:21:53 2008 +0100
@@ -26,9 +26,9 @@
#include "wifi-mac-header.h"
#include "wifi-mode.h"
#include "wifi-preamble.h"
+#include "wifi-remote-station-manager.h"
#include "ns3/mac48-address.h"
#include "ns3/callback.h"
-#include "ns3/callback-trace-source.h"
#include "ns3/event-id.h"
#include "ns3/packet.h"
#include "ns3/nstime.h"
@@ -37,10 +37,7 @@
class WifiNetDevice;
class WifiPhy;
-class PacketLogger;
-class MacStations;
-class MacStation;
-class WifiMacParameters;
+class WifiMac;
/**
* \brief listen to events coming from ns3::MacLow.
@@ -277,18 +274,19 @@
MacLow ();
virtual ~MacLow ();
- void SetDevice (Ptr<WifiNetDevice> device);
void SetPhy (Ptr<WifiPhy> phy);
- void SetStations (MacStations *stations);
- void SetParameters (WifiMacParameters *parameters);
- Ptr<NetDevice> GetDevice (void) const;
+ void SetMac (Ptr<WifiMac> mac);
+ void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> manager);
+
+ Ptr<WifiMac> GetMac (void);
+
/**
* \param callback the callback which receives every incoming packet.
*
* This callback typically forwards incoming packets to
* an instance of ns3::MacRxMiddle.
*/
- void SetRxCallback (MacLowRxCallback callback);
+ void SetRxCallback (Callback<void,Ptr<Packet>,const WifiMacHeader *> callback);
/**
* \param listener listen to NAV events for every incoming
* and outgoing packet.
@@ -340,19 +338,18 @@
*/
void ReceiveError (Ptr<Packet> packet, double rxSnr);
private:
- // Inherited from ns3::Object.
- virtual Ptr<TraceResolver> GetTraceResolver (void) const;
void CancelAllEvents (void);
uint32_t GetAckSize (void) const;
uint32_t GetRtsSize (void) const;
uint32_t GetCtsSize (void) const;
Time GetSifs (void) const;
Time GetPifs (void) const;
+ Time GetSlotTime (void) const;
Time GetAckTimeout (void) const;
Time GetCtsTimeout (void) const;
uint32_t GetSize (Ptr<const Packet> packet, const WifiMacHeader *hdr) const;
Time NowUs (void) const;
- MacStation *GetStation (Mac48Address to) const;
+ WifiRemoteStation *GetStation (Mac48Address to) const;
void ForwardDown (Ptr<const Packet> packet, WifiMacHeader const *hdr,
WifiMode txMode);
Time CalculateOverallTxTime (Ptr<const Packet> packet,
@@ -386,10 +383,9 @@
void SendCurrentTxPacket (void);
void StartDataTxTimers (void);
- Ptr<WifiNetDevice> m_device;
Ptr<WifiPhy> m_phy;
- MacStations *m_stations;
- WifiMacParameters *m_parameters;
+ Ptr<WifiMac> m_mac;
+ Ptr<WifiRemoteStationManager> m_stationManager;
MacLowRxCallback m_rxCallback;
typedef std::vector<MacLowNavListener *>::const_iterator NavListenersCI;
typedef std::vector<MacLowNavListener *> NavListeners;
@@ -413,8 +409,6 @@
Time m_lastNavStart;
Time m_lastNavDuration;
-
- CallbackTraceSource<Ptr<const Packet> > m_dropError;
};
} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/nqap-wifi-mac.cc Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,408 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/node.h"
+
+#include "nqap-wifi-mac.h"
+#include "dca-txop.h"
+#include "wifi-mac-header.h"
+#include "mgt-headers.h"
+#include "wifi-phy.h"
+#include "dcf-manager.h"
+#include "mac-rx-middle.h"
+#include "mac-low.h"
+
+NS_LOG_COMPONENT_DEFINE ("NqapWifiMac");
+
+#define TRACE(x) \
+ NS_LOG_DEBUG(Simulator::Now () << " " << GetAddress () << " " << x);
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (NqapWifiMac);
+
+TypeId
+NqapWifiMac::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("NqapWifiMac")
+ .SetParent<WifiMac> ()
+ .AddConstructor<NqapWifiMac> ()
+ .AddAttribute ("BeaconInterval", "Delay between two beacons",
+ Seconds (1.0),
+ MakeTimeAccessor (&NqapWifiMac::m_beaconInterval),
+ MakeTimeChecker ())
+ ;
+ return tid;
+}
+
+NqapWifiMac::NqapWifiMac ()
+{
+ m_dcfManager = new DcfManager ();
+
+ m_rxMiddle = new MacRxMiddle ();
+ m_rxMiddle->SetForwardCallback (MakeCallback (&NqapWifiMac::Receive, this));
+
+ m_low = new MacLow ();
+ m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
+
+ m_dca = CreateObject<DcaTxop> ();
+ m_dca->SetLow (m_low);
+ m_dca->SetManager (m_dcfManager);
+ m_dca->SetTxOkCallback (MakeCallback (&NqapWifiMac::TxOk, this));
+ m_dca->SetTxFailedCallback (MakeCallback (&NqapWifiMac::TxFailed, this));
+
+ m_beaconDca = CreateObject<DcaTxop> ();
+ m_beaconDca->SetLow (m_low);
+ m_beaconDca->SetManager (m_dcfManager);
+}
+NqapWifiMac::~NqapWifiMac ()
+{}
+
+void
+NqapWifiMac::DoDispose (void)
+{
+ delete m_rxMiddle;
+ delete m_low;
+ m_rxMiddle = 0;
+ m_low = 0;
+ m_phy = 0;
+ m_dca = 0;
+ m_beaconDca = 0;
+ WifiMac::DoDispose ();
+}
+
+
+void
+NqapWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
+{
+ m_phy = phy;
+}
+void
+NqapWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
+{
+ m_stationManager = stationManager;
+}
+void
+NqapWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, const Mac48Address &> upCallback)
+{
+ m_upCallback = upCallback;
+}
+void
+NqapWifiMac::SetLinkUpCallback (Callback<void> linkUp)
+{
+
+}
+void
+NqapWifiMac::SetLinkDownCallback (Callback<void> linkDown)
+{
+
+}
+Mac48Address
+NqapWifiMac::GetAddress (void) const
+{
+ return m_address;
+}
+Ssid
+NqapWifiMac::GetSsid (void) const
+{
+ return m_ssid;
+}
+Mac48Address
+NqapWifiMac::GetBssid (void) const
+{
+ return m_address;
+}
+void
+NqapWifiMac::SetAddress (Mac48Address address)
+{
+ m_address = address;
+}
+void
+NqapWifiMac::SetSsid (Ssid ssid)
+{
+ m_ssid = ssid;
+}
+
+
+void
+NqapWifiMac::SetBeaconInterval (Time interval)
+{
+ m_beaconInterval = interval;
+}
+void
+NqapWifiMac::StartBeaconing (void)
+{
+ SendOneBeacon ();
+}
+void
+NqapWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from)
+{
+ m_upCallback (packet, from);
+}
+void
+NqapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
+{
+ WifiMacHeader hdr;
+ hdr.SetTypeData ();
+ hdr.SetAddr1 (to);
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (from);
+ hdr.SetDsFrom ();
+ hdr.SetDsNotTo ();
+ m_dca->Queue (packet, hdr);
+}
+void
+NqapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
+{
+ ForwardDown (packet, GetAddress (), to);
+}
+SupportedRates
+NqapWifiMac::GetSupportedRates (void) const
+{
+ // send the set of supported rates and make sure that we indicate
+ // the Basic Rate set in this set of supported rates.
+ SupportedRates rates;
+ for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+ {
+ WifiMode mode = m_phy->GetMode (i);
+ rates.AddSupportedRate (mode.GetDataRate ());
+ }
+ // set the basic rates
+ for (uint32_t j = 0; j < m_stationManager->GetNBasicModes (); j++)
+ {
+ WifiMode mode = m_stationManager->GetBasicMode (j);
+ rates.SetBasicRate (mode.GetDataRate ());
+ }
+ return rates;
+}
+void
+NqapWifiMac::SendProbeResp (Mac48Address to)
+{
+ TRACE ("send probe response to="<<to);
+ WifiMacHeader hdr;
+ hdr.SetProbeResp ();
+ hdr.SetAddr1 (to);
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetAddress ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Ptr<Packet> packet = Create<Packet> ();
+ MgtProbeResponseHeader probe;
+ probe.SetSsid (GetSsid ());
+ probe.SetSupportedRates (GetSupportedRates ());
+ probe.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
+ packet->AddHeader (probe);
+
+ m_dca->Queue (packet, hdr);
+}
+void
+NqapWifiMac::SendAssocResp (Mac48Address to, bool success)
+{
+ TRACE ("send assoc response to="<<to);
+ WifiMacHeader hdr;
+ hdr.SetAssocResp ();
+ hdr.SetAddr1 (to);
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetAddress ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Ptr<Packet> packet = Create<Packet> ();
+ MgtAssocResponseHeader assoc;
+ StatusCode code;
+ if (success)
+ {
+ code.SetSuccess ();
+ }
+ else
+ {
+ code.SetFailure ();
+ }
+ assoc.SetSupportedRates (GetSupportedRates ());
+ assoc.SetStatusCode (code);
+ packet->AddHeader (assoc);
+
+ m_dca->Queue (packet, hdr);
+}
+void
+NqapWifiMac::SendOneBeacon (void)
+{
+ TRACE ("send beacon to="<<Mac48Address::GetBroadcast ());
+ WifiMacHeader hdr;
+ hdr.SetBeacon ();
+ hdr.SetAddr1 (Mac48Address::GetBroadcast ());
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetAddress ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Ptr<Packet> packet = Create<Packet> ();
+ MgtBeaconHeader beacon;
+ beacon.SetSsid (GetSsid ());
+ beacon.SetSupportedRates (GetSupportedRates ());
+ beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
+ packet->AddHeader (beacon);
+
+ m_beaconDca->Queue (packet, hdr);
+ Simulator::Schedule (m_beaconInterval, &NqapWifiMac::SendOneBeacon, this);
+}
+void
+NqapWifiMac::TxOk (WifiMacHeader const &hdr)
+{
+ WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
+ if (hdr.IsAssocResp () &&
+ station->IsWaitAssocTxOk ())
+ {
+ TRACE ("associated with sta="<<hdr.GetAddr1 ());
+ station->RecordGotAssocTxOk ();
+ }
+}
+void
+NqapWifiMac::TxFailed (WifiMacHeader const &hdr)
+{
+ WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ());
+ if (hdr.IsAssocResp () &&
+ station->IsWaitAssocTxOk ())
+ {
+ TRACE ("assoc failed with sta="<<hdr.GetAddr1 ());
+ station->RecordGotAssocTxFailed ();
+ }
+}
+void
+NqapWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
+{
+ WifiRemoteStation *station = m_stationManager->Lookup (hdr->GetAddr2 ());
+
+ if (hdr->IsData ())
+ {
+ if (!hdr->IsFromDs () &&
+ hdr->IsToDs () &&
+ hdr->GetAddr1 () == GetAddress () &&
+ station->IsAssociated ())
+ {
+ if (hdr->GetAddr3 () == GetAddress ())
+ {
+ TRACE ("frame for me from="<<hdr->GetAddr2 ());
+ ForwardUp (packet, hdr->GetAddr2 ());
+ }
+ else
+ {
+ TRACE ("forwarding frame from="<<hdr->GetAddr2 ()<<", to="<<hdr->GetAddr3 ());
+ Ptr<Packet> copy = packet->Copy ();
+ ForwardDown (packet,
+ hdr->GetAddr2 (),
+ hdr->GetAddr3 ());
+ ForwardUp (copy, hdr->GetAddr2 ());
+ }
+ }
+ else if (hdr->IsFromDs () &&
+ hdr->IsToDs ())
+ {
+ // this is an AP-to-AP frame
+ // we ignore for now.
+ }
+ else
+ {
+ // we can ignore these frames since
+ // they are not targeted at the AP
+ }
+ }
+ else if (hdr->IsMgt ())
+ {
+ if (hdr->IsProbeReq ())
+ {
+ NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ());
+ SendProbeResp (hdr->GetAddr2 ());
+ }
+ else if (hdr->GetAddr1 () == GetAddress ())
+ {
+ if (hdr->IsAssocReq ())
+ {
+ // first, verify that the the station's supported
+ // rate set is compatible with our Basic Rate set
+ MgtAssocRequestHeader assocReq;
+ packet->RemoveHeader (assocReq);
+ SupportedRates rates = assocReq.GetSupportedRates ();
+ bool problem = false;
+ for (uint32_t i = 0; i < m_stationManager->GetNBasicModes (); i++)
+ {
+ WifiMode mode = m_stationManager->GetBasicMode (i);
+ if (!rates.IsSupportedRate (mode.GetDataRate ()))
+ {
+ problem = true;
+ break;
+ }
+ }
+ if (problem)
+ {
+ // one of the Basic Rate set mode is not
+ // supported by the station. So, we return an assoc
+ // response with an error status.
+ SendAssocResp (hdr->GetAddr2 (), false);
+ }
+ else
+ {
+ // station supports all rates in Basic Rate Set.
+ // record all its supported modes in its associated WifiRemoteStation
+ for (uint32_t j = 0; j < m_phy->GetNModes (); j++)
+ {
+ WifiMode mode = m_phy->GetMode (j);
+ if (rates.IsSupportedRate (mode.GetDataRate ()))
+ {
+ station->AddSupportedMode (mode);
+ }
+ }
+ station->RecordWaitAssocTxOk ();
+ // send assoc response with success status.
+ SendAssocResp (hdr->GetAddr2 (), true);
+ }
+ }
+ else if (hdr->IsDisassociation ())
+ {
+ station->RecordDisassociated ();
+ }
+ else if (hdr->IsReassocReq ())
+ {
+ /* we don't support reassoc frames for now */
+ }
+ else if (hdr->IsAuthentication () ||
+ hdr->IsDeauthentication ())
+ {
+ /*
+ */
+ }
+ else
+ {
+ /* unknown mgt frame
+ */
+ }
+ }
+ }
+ else
+ {
+ /* damn, what could this be ? a control frame ?
+ * control frames should never reach the MacHigh so,
+ * this is likely to be a bug. assert.
+ */
+ NS_ASSERT (false);
+ }
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/nqap-wifi-mac.h Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef MAC_HIGH_NQAP_H
+#define MAC_HIGH_NQAP_H
+
+#include <stdint.h>
+#include "ns3/mac48-address.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "supported-rates.h"
+#include "wifi-remote-station-manager.h"
+#include "wifi-mac.h"
+
+namespace ns3 {
+
+class WifiMacHeader;
+class DcaTxop;
+class WifiPhy;
+class DcfManager;
+class MacRxMiddle;
+class MacLow;
+
+/**
+ * \brief non-QoS AP state machine
+ *
+ * Handle association, dis-association and authentication,
+ * of STAs within an IBSS.
+ * This class uses two output queues, each of which is server by
+ * a single DCF
+ * - the highest priority DCF serves the queue which contains
+ * only beacons.
+ * - the lowest priority DCF serves the queue which contains all
+ * other frames, including user data frames.
+ */
+class NqapWifiMac : public WifiMac
+{
+public:
+ static TypeId GetTypeId (void);
+
+ NqapWifiMac ();
+ ~NqapWifiMac ();
+
+ virtual void SetWifiPhy (Ptr<WifiPhy> phy);
+ virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
+ virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
+ virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, const Mac48Address &> upCallback);
+ virtual void SetLinkUpCallback (Callback<void> linkUp);
+ virtual void SetLinkDownCallback (Callback<void> linkDown);
+ virtual Mac48Address GetAddress (void) const;
+ virtual Ssid GetSsid (void) const;
+ virtual Mac48Address GetBssid (void) const;
+ virtual void SetAddress (Mac48Address address);
+ virtual void SetSsid (Ssid ssid);
+
+
+ void SetBeaconInterval (Time interval);
+ Time GetBeaconInterval (void) const;
+ /**
+ * Start beacon transmission immediately.
+ */
+ void StartBeaconing (void);
+
+private:
+ void Receive (Ptr<Packet> packet, WifiMacHeader const *hdr);
+ void ForwardUp (Ptr<Packet> packet, Mac48Address from);
+ void ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to);
+ void TxOk (WifiMacHeader const &hdr);
+ void TxFailed (WifiMacHeader const &hdr);
+ void SendProbeResp (Mac48Address to);
+ void SendAssocResp (Mac48Address to, bool success);
+ void SendOneBeacon (void);
+ SupportedRates GetSupportedRates (void) const;
+ virtual void DoDispose (void);
+
+ Ptr<DcaTxop> m_dca;
+ Ptr<DcaTxop> m_beaconDca;
+ Ptr<WifiRemoteStationManager> m_stationManager;
+ Ptr<WifiPhy> m_phy;
+ Callback<void, Ptr<Packet>,const Mac48Address &> m_upCallback;
+ Time m_beaconInterval;
+
+ DcfManager *m_dcfManager;
+ MacRxMiddle *m_rxMiddle;
+ MacLow *m_low;
+ Mac48Address m_address;
+ Ssid m_ssid;
+};
+
+} // namespace ns3
+
+
+#endif /* MAC_HIGH_NQAP_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/nqsta-wifi-mac.cc Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,471 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ns3/packet.h"
+#include "ns3/simulator.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/uinteger.h"
+
+#include "nqsta-wifi-mac.h"
+#include "wifi-mac-header.h"
+#include "mgt-headers.h"
+#include "wifi-phy.h"
+#include "dca-txop.h"
+#include "mac-low.h"
+#include "dcf-manager.h"
+#include "mac-rx-middle.h"
+
+NS_LOG_COMPONENT_DEFINE ("NqstaWifiMac");
+
+#define TRACE(x) \
+ NS_LOG_DEBUG (Simulator::Now () << " " << GetAddress () << " " << x);
+
+/*
+ * The state machine for this NQSTA is:
+ -------------- -----------
+ | Associated | <-------------------- -------> | Refused |
+ -------------- \ / -----------
+ \ \ /
+ \ ----------------- -----------------------------
+ \-> | Beacon Missed | --> | Wait Association Response |
+ ----------------- -----------------------------
+ \ ^
+ \ |
+ \ -----------------------
+ \-> | Wait Probe Response |
+ -----------------------
+ */
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (NqstaWifiMac);
+
+TypeId
+NqstaWifiMac::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("NqstaWifiMac")
+ .SetParent<WifiMac> ()
+ .AddConstructor<NqstaWifiMac> ()
+ .AddAttribute ("ProbeRequestTimeout", "XXX",
+ Seconds (0.5),
+ MakeTimeAccessor (&NqstaWifiMac::m_probeRequestTimeout),
+ MakeTimeChecker ())
+ .AddAttribute ("AssocRequestTimeout", "XXX",
+ Seconds (0.5),
+ MakeTimeAccessor (&NqstaWifiMac::m_assocRequestTimeout),
+ MakeTimeChecker ())
+ .AddAttribute ("MaxMissedBeacons",
+ "Number of beacons which much be consecutively missed before "
+ "we attempt to restart association.",
+ Uinteger (10),
+ MakeUintegerAccessor (&NqstaWifiMac::m_maxMissedBeacons),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+ return tid;
+}
+
+
+NqstaWifiMac::NqstaWifiMac ()
+ : m_state (BEACON_MISSED),
+ m_probeRequestEvent (),
+ m_assocRequestEvent (),
+ m_beaconWatchdogEnd (Seconds (0.0))
+{
+ m_dcfManager = new DcfManager ();
+
+ m_rxMiddle = new MacRxMiddle ();
+ m_rxMiddle->SetForwardCallback (MakeCallback (&NqstaWifiMac::Receive, this));
+
+ m_low = new MacLow ();
+ m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
+
+ m_dca = CreateObject<DcaTxop> ();
+ m_dca->SetLow (m_low);
+ m_dca->SetManager (m_dcfManager);
+}
+
+NqstaWifiMac::~NqstaWifiMac ()
+{}
+
+void
+NqstaWifiMac::DoDispose (void)
+{
+ delete m_rxMiddle;
+ delete m_low;
+ m_rxMiddle = 0;
+ m_low = 0;
+ m_phy = 0;
+ m_dca = 0;
+ WifiMac::DoDispose ();
+}
+
+void
+NqstaWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
+{
+ m_phy = phy;
+}
+void
+NqstaWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
+{
+ m_stationManager = stationManager;
+}
+void
+NqstaWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, const Mac48Address &> upCallback)
+{
+ m_forwardUp = upCallback;
+}
+void
+NqstaWifiMac::SetLinkUpCallback (Callback<void> linkUp)
+{
+ m_linkUp = linkUp;
+}
+void
+NqstaWifiMac::SetLinkDownCallback (Callback<void> linkDown)
+{
+ m_linkDown = linkDown;
+}
+Mac48Address
+NqstaWifiMac::GetAddress (void) const
+{
+ return m_address;
+}
+Ssid
+NqstaWifiMac::GetSsid (void) const
+{
+ return m_ssid;
+}
+Mac48Address
+NqstaWifiMac::GetBssid (void) const
+{
+ return m_bssid;
+}
+void
+NqstaWifiMac::SetAddress (Mac48Address address)
+{
+ m_address = address;
+}
+void
+NqstaWifiMac::SetSsid (Ssid ssid)
+{
+ m_ssid = ssid;
+}
+
+void
+NqstaWifiMac::SetMaxMissedBeacons (uint32_t missed)
+{
+ m_maxMissedBeacons = missed;
+}
+void
+NqstaWifiMac::SetProbeRequestTimeout (Time timeout)
+{
+ m_probeRequestTimeout = timeout;
+}
+void
+NqstaWifiMac::SetAssocRequestTimeout (Time timeout)
+{
+ m_assocRequestTimeout = timeout;
+}
+
+void
+NqstaWifiMac::StartActiveAssociation (void)
+{
+ TryToEnsureAssociated ();
+}
+
+Mac48Address
+NqstaWifiMac::GetBroadcastBssid (void)
+{
+ return Mac48Address::GetBroadcast ();
+}
+
+void
+NqstaWifiMac::SetBssid (Mac48Address bssid)
+{
+ m_bssid = bssid;
+}
+void
+NqstaWifiMac::ForwardUp (Ptr<Packet> packet, const Mac48Address &address)
+{
+ m_forwardUp (packet, address);
+}
+void
+NqstaWifiMac::SendProbeRequest (void)
+{
+ TRACE ("send probe request");
+ WifiMacHeader hdr;
+ hdr.SetProbeReq ();
+ hdr.SetAddr1 (GetBroadcastBssid ());
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetBroadcastBssid ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Ptr<Packet> packet = Create<Packet> ();
+ MgtProbeRequestHeader probe;
+ probe.SetSsid (GetSsid ());
+ probe.SetSupportedRates (GetSupportedRates ());
+ packet->AddHeader (probe);
+
+ m_dca->Queue (packet, hdr);
+
+ m_probeRequestEvent = Simulator::Schedule (m_probeRequestTimeout,
+ &NqstaWifiMac::ProbeRequestTimeout, this);
+}
+
+void
+NqstaWifiMac::SendAssociationRequest (void)
+{
+ TRACE ("send assoc request to=" << GetBssid ());
+ WifiMacHeader hdr;
+ hdr.SetAssocReq ();
+ hdr.SetAddr1 (GetBssid ());
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetBssid ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Ptr<Packet> packet = Create<Packet> ();
+ MgtAssocRequestHeader assoc;
+ assoc.SetSsid (GetSsid ());
+ assoc.SetSupportedRates (GetSupportedRates ());
+ packet->AddHeader (assoc);
+
+ m_dca->Queue (packet, hdr);
+
+ m_assocRequestEvent = Simulator::Schedule (m_assocRequestTimeout,
+ &NqstaWifiMac::AssocRequestTimeout, this);
+}
+void
+NqstaWifiMac::TryToEnsureAssociated (void)
+{
+ switch (m_state) {
+ case ASSOCIATED:
+ return;
+ break;
+ case WAIT_PROBE_RESP:
+ /* we have sent a probe request earlier so we
+ do not need to re-send a probe request immediately.
+ We just need to wait until probe-request-timeout
+ or until we get a probe response
+ */
+ break;
+ case BEACON_MISSED:
+ /* we were associated but we missed a bunch of beacons
+ * so we should assume we are not associated anymore.
+ * We try to initiate a probe request now.
+ */
+ m_linkDown ();
+ m_state = WAIT_PROBE_RESP;
+ SendProbeRequest ();
+ break;
+ case WAIT_ASSOC_RESP:
+ /* we have sent an assoc request so we do not need to
+ re-send an assoc request right now. We just need to
+ wait until either assoc-request-timeout or until
+ we get an assoc response.
+ */
+ break;
+ case REFUSED:
+ /* we have sent an assoc request and received a negative
+ assoc resp. We wait until someone restarts an
+ association with a given ssid.
+ */
+ break;
+ }
+}
+
+void
+NqstaWifiMac::AssocRequestTimeout (void)
+{
+ TRACE ("assoc request timeout");
+ m_state = WAIT_ASSOC_RESP;
+ SendAssociationRequest ();
+}
+void
+NqstaWifiMac::ProbeRequestTimeout (void)
+{
+ TRACE ("probe request timeout");
+ m_state = WAIT_PROBE_RESP;
+ SendProbeRequest ();
+}
+void
+NqstaWifiMac::MissedBeacons (void)
+{
+ if (m_beaconWatchdogEnd > Simulator::Now ())
+ {
+ m_beaconWatchdog = Simulator::Schedule (m_beaconWatchdogEnd - Simulator::Now (),
+ &NqstaWifiMac::MissedBeacons, this);
+ return;
+ }
+ TRACE ("beacon missed");
+ m_state = BEACON_MISSED;
+ TryToEnsureAssociated ();
+}
+void
+NqstaWifiMac::RestartBeaconWatchdog (Time delay)
+{
+ m_beaconWatchdogEnd = std::max (Simulator::Now () + delay, m_beaconWatchdogEnd);
+ if (Simulator::GetDelayLeft (m_beaconWatchdog) < delay &&
+ m_beaconWatchdog.IsExpired ())
+ {
+ m_beaconWatchdog = Simulator::Schedule (delay, &NqstaWifiMac::MissedBeacons, this);
+ }
+}
+bool
+NqstaWifiMac::IsAssociated (void)
+{
+ return (m_state == ASSOCIATED)?true:false;
+}
+
+void
+NqstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
+{
+ if (!IsAssociated ())
+ {
+ TryToEnsureAssociated ();
+ return;
+ }
+ //TRACE ("enqueue size="<<packet->GetSize ()<<", to="<<to);
+ WifiMacHeader hdr;
+ hdr.SetTypeData ();
+ hdr.SetAddr1 (GetBssid ());
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (to);
+ hdr.SetDsNotFrom ();
+ hdr.SetDsTo ();
+ m_dca->Queue (packet, hdr);
+}
+
+void
+NqstaWifiMac::Receive (Ptr<Packet> packet, WifiMacHeader const *hdr)
+{
+ NS_ASSERT (!hdr->IsCtl ());
+ if (hdr->GetAddr1 () != GetAddress () &&
+ !hdr->GetAddr1 ().IsBroadcast ())
+ {
+ // packet is not for us
+ }
+ else if (hdr->IsData ())
+ {
+ ForwardUp (packet, hdr->GetAddr2 ());
+ }
+ else if (hdr->IsProbeReq () ||
+ hdr->IsAssocReq ())
+ {
+ /* this is a frame aimed at an AP.
+ * so we can safely ignore it.
+ */
+ }
+ else if (hdr->IsBeacon ())
+ {
+ MgtBeaconHeader beacon;
+ packet->RemoveHeader (beacon);
+ bool goodBeacon = false;
+ if (GetSsid ().IsBroadcast () ||
+ beacon.GetSsid ().IsEqual (GetSsid ()))
+ {
+ Time delay = MicroSeconds (beacon.GetBeaconIntervalUs () * m_maxMissedBeacons);
+ RestartBeaconWatchdog (delay);
+ goodBeacon = true;
+ }
+ if (goodBeacon)
+ {
+ SetBssid (hdr->GetAddr3 ());
+ }
+ if (goodBeacon && m_state == BEACON_MISSED)
+ {
+ m_state = WAIT_ASSOC_RESP;
+ SendAssociationRequest ();
+ }
+ }
+ else if (hdr->IsProbeResp ())
+ {
+ if (m_state == WAIT_PROBE_RESP)
+ {
+ MgtProbeResponseHeader probeResp;
+ packet->RemoveHeader (probeResp);
+ if (!probeResp.GetSsid ().IsEqual (GetSsid ()))
+ {
+ //not a probe resp for our ssid.
+ return;
+ }
+ SetBssid (hdr->GetAddr3 ());
+ Time delay = MicroSeconds (probeResp.GetBeaconIntervalUs () * m_maxMissedBeacons);
+ RestartBeaconWatchdog (delay);
+ if (m_probeRequestEvent.IsRunning ())
+ {
+ m_probeRequestEvent.Cancel ();
+ }
+ m_state = WAIT_ASSOC_RESP;
+ SendAssociationRequest ();
+ }
+ }
+ else if (hdr->IsAssocResp ())
+ {
+ if (m_state == WAIT_ASSOC_RESP)
+ {
+ MgtAssocResponseHeader assocResp;
+ packet->RemoveHeader (assocResp);
+ if (m_assocRequestEvent.IsRunning ())
+ {
+ m_assocRequestEvent.Cancel ();
+ }
+ if (assocResp.GetStatusCode ().IsSuccess ())
+ {
+ m_state = ASSOCIATED;
+ TRACE ("assoc completed");
+ SupportedRates rates = assocResp.GetSupportedRates ();
+ WifiRemoteStation *ap = m_stationManager->Lookup (hdr->GetAddr2 ());
+ for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+ {
+ WifiMode mode = m_phy->GetMode (i);
+ if (rates.IsSupportedRate (mode.GetDataRate ()))
+ {
+ ap->AddSupportedMode (mode);
+ if (rates.IsBasicRate (mode.GetDataRate ()))
+ {
+ m_stationManager->AddBasicMode (mode);
+ }
+ }
+ }
+ m_linkUp ();
+ }
+ else
+ {
+ TRACE ("assoc refused");
+ m_state = REFUSED;
+ }
+ }
+ }
+}
+
+SupportedRates
+NqstaWifiMac::GetSupportedRates (void) const
+{
+ SupportedRates rates;
+ for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+ {
+ WifiMode mode = m_phy->GetMode (i);
+ rates.AddSupportedRate (mode.GetDataRate ());
+ }
+ return rates;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/nqsta-wifi-mac.h Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef NQSTA_WIFI_MAC_H
+#define NQSTA_WIFI_MAC_H
+
+#include <stdint.h>
+
+#include "ns3/mac48-address.h"
+#include "ns3/callback.h"
+#include "ns3/event-id.h"
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+
+#include "wifi-mac.h"
+#include "supported-rates.h"
+
+namespace ns3 {
+
+class WifiMacHeader;
+class DcaTxop;
+class WifiPhy;
+class DcfManager;
+class MacLow;
+class MacRxMiddle;
+
+/**
+ * \brief a non-QoS STA state machine
+ *
+ * This state machine handles association, disassociation,
+ * authentication and beacon monitoring. It does not perform
+ * channel scanning.
+ * If the station detects a certain number of missed beacons
+ * while associated, it automatically attempts a new association
+ * sequence.
+ */
+class NqstaWifiMac : public WifiMac
+{
+public:
+ static TypeId GetTypeId (void);
+
+ NqstaWifiMac ();
+ ~NqstaWifiMac ();
+
+ virtual void SetWifiPhy (Ptr<WifiPhy> phy);
+ virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
+ virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
+ virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, const Mac48Address &> upCallback);
+ virtual void SetLinkUpCallback (Callback<void> linkUp);
+ virtual void SetLinkDownCallback (Callback<void> linkDown);
+ virtual Mac48Address GetAddress (void) const;
+ virtual Ssid GetSsid (void) const;
+ virtual Mac48Address GetBssid (void) const;
+ virtual void SetAddress (Mac48Address address);
+ virtual void SetSsid (Ssid ssid);
+
+
+ /**
+ * \param missed the number of beacons which must be missed
+ * before a new association sequence is started.
+ */
+ void SetMaxMissedBeacons (uint32_t missed);
+ /**
+ * \param timeout
+ *
+ * If no probe response is received within the specified
+ * timeout, the station sends a new probe request.
+ */
+ void SetProbeRequestTimeout (Time timeout);
+ /**
+ * \param timeout
+ *
+ * If no association response is received within the specified
+ * timeout, the station sends a new association request.
+ */
+ void SetAssocRequestTimeout (Time timeout);
+
+ /**
+ * Start an active association sequence immediately.
+ */
+ void StartActiveAssociation (void);
+
+private:
+ void SetBssid (Mac48Address bssid);
+ void ForwardUp (Ptr<Packet> packet, const Mac48Address &address);
+ void Receive (Ptr<Packet> packet, WifiMacHeader const *hdr);
+ Mac48Address GetBroadcastBssid (void);
+ void SendProbeRequest (void);
+ void SendAssociationRequest (void);
+ void TryToEnsureAssociated (void);
+ void AssocRequestTimeout (void);
+ void ProbeRequestTimeout (void);
+ bool IsAssociated (void);
+ void MissedBeacons (void);
+ void RestartBeaconWatchdog (Time delay);
+ SupportedRates GetSupportedRates (void) const;
+ virtual void DoDispose (void);
+
+ enum {
+ ASSOCIATED,
+ WAIT_PROBE_RESP,
+ WAIT_ASSOC_RESP,
+ BEACON_MISSED,
+ REFUSED
+ } m_state;
+ Time m_probeRequestTimeout;
+ Time m_assocRequestTimeout;
+ EventId m_probeRequestEvent;
+ EventId m_assocRequestEvent;
+ Callback<void, Ptr<Packet>,const Mac48Address &> m_forwardUp;
+ Callback<void> m_linkUp;
+ Callback<void> m_linkDown;
+ Ptr<DcaTxop> m_dca;
+ EventId m_beaconWatchdog;
+ Time m_beaconWatchdogEnd;
+ Mac48Address m_bssid;
+ uint32_t m_maxMissedBeacons;
+
+ Ptr<WifiPhy> m_phy;
+ Ptr<WifiRemoteStationManager> m_stationManager;
+ DcfManager *m_dcfManager;
+ MacRxMiddle *m_rxMiddle;
+ MacLow *m_low;
+ Mac48Address m_address;
+ Ssid m_ssid;
+};
+
+} // namespace ns3
+
+
+#endif /* NQSTA_WIFI_MAC_H */
--- a/src/devices/wifi/wifi-channel.cc Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/wifi-channel.cc Sat Mar 01 21:21:53 2008 +0100
@@ -52,19 +52,28 @@
}
void
-WifiChannel::Add (Ptr<NetDevice> device, ReceiveCallback callback)
+WifiChannel::Add (Ptr<NetDevice> device, Ptr<WifiPhy> phy)
{
- m_deviceList.push_back (std::make_pair (device, callback));
+ m_deviceList.push_back (std::make_pair (device, phy));
}
void
-WifiChannel::Send (Ptr<NetDevice> sender, Ptr<const Packet> packet, double txPowerDbm,
+WifiChannel::Send (Ptr<WifiPhy> sender, Ptr<const Packet> packet, double txPowerDbm,
WifiMode wifiMode, WifiPreamble preamble) const
{
- Ptr<MobilityModel> senderMobility = sender->GetNode ()->GetObject<MobilityModel> ();
+ Ptr<MobilityModel> senderMobility = 0;
+ for (DeviceList::const_iterator i = m_deviceList.begin (); i != m_deviceList.end (); i++)
+ {
+ if (sender == i->second)
+ {
+ senderMobility = i->first->GetNode ()->GetObject<MobilityModel> ();
+ break;
+ }
+ }
+ NS_ASSERT (senderMobility != 0);
uint32_t j = 0;
for (DeviceList::const_iterator i = m_deviceList.begin (); i != m_deviceList.end (); i++)
{
- if (sender != i->first)
+ if (sender != i->second)
{
Ptr<MobilityModel> receiverMobility = i->first->GetNode ()->GetObject<MobilityModel> ();
Time delay = m_delay->GetDelay (senderMobility, receiverMobility);
@@ -83,7 +92,7 @@
WifiChannel::Receive (uint32_t i, Ptr<Packet> packet, double rxPowerDbm,
WifiMode txMode, WifiPreamble preamble) const
{
- m_deviceList[i].second (packet, rxPowerDbm, txMode, preamble);
+ m_deviceList[i].second->StartReceivePacket (packet, rxPowerDbm, txMode, preamble);
}
uint32_t
--- a/src/devices/wifi/wifi-channel.h Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/wifi-channel.h Sat Mar 01 21:21:53 2008 +0100
@@ -26,6 +26,7 @@
#include "ns3/channel.h"
#include "wifi-mode.h"
#include "wifi-preamble.h"
+#include "wifi-phy.h"
namespace ns3 {
@@ -83,7 +84,7 @@
* This method should not be invoked by normal users. It is
* currently invoked only from WifiPhy::SetChannel.
*/
- void Add (Ptr<NetDevice> device, ReceiveCallback callback);
+ void Add (Ptr<NetDevice> device, Ptr<WifiPhy> phy);
/**
* \param sender the device from which the packet is originating.
* \param packet the packet to send
@@ -94,11 +95,11 @@
* This method should not be invoked by normal users. It is
* currently invoked only from WifiPhy::Send.
*/
- void Send (Ptr<NetDevice> sender, Ptr<const Packet> packet, double txPowerDbm,
+ void Send (Ptr<WifiPhy> sender, Ptr<const Packet> packet, double txPowerDbm,
WifiMode wifiMode, WifiPreamble preamble) const;
private:
- typedef std::vector<std::pair<Ptr<NetDevice>, ReceiveCallback> > DeviceList;
+ typedef std::vector<std::pair<Ptr<NetDevice>, Ptr<WifiPhy> > > DeviceList;
void Receive (uint32_t i, Ptr<Packet> packet, double rxPowerDbm,
WifiMode txMode, WifiPreamble preamble) const;
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/wifi-helper.cc Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,114 @@
+#include "wifi-helper.h"
+#include "wifi-net-device.h"
+#include "wifi-mac.h"
+#include "wifi-phy.h"
+#include "wifi-remote-station-manager.h"
+#include "wifi-channel.h"
+#include "ns3/mobility-model.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("WifiHelper");
+
+namespace ns3 {
+
+WifiHelper::WifiHelper ()
+{
+ m_stationManager.SetTypeId ("ArfWifiManager");
+ m_phy.SetTypeId ("WifiPhy");
+ m_mac.SetTypeId ("AdhocWifiMac");
+}
+
+void
+WifiHelper::SetRemoteStationManager (std::string type,
+ std::string n0, Attribute v0,
+ std::string n1, Attribute v1,
+ std::string n2, Attribute v2,
+ std::string n3, Attribute v3,
+ std::string n4, Attribute v4,
+ std::string n5, Attribute v5,
+ std::string n6, Attribute v6,
+ std::string n7, Attribute v7)
+{
+ m_stationManager = ObjectFactory ();
+ m_stationManager.SetTypeId (type);
+ m_stationManager.Set (n0, v0);
+ m_stationManager.Set (n1, v1);
+ m_stationManager.Set (n2, v2);
+ m_stationManager.Set (n3, v3);
+ m_stationManager.Set (n4, v4);
+ m_stationManager.Set (n5, v5);
+ m_stationManager.Set (n6, v6);
+ m_stationManager.Set (n7, v7);
+}
+
+void
+WifiHelper::SetMac (std::string type,
+ std::string n0, Attribute v0,
+ std::string n1, Attribute v1,
+ std::string n2, Attribute v2,
+ std::string n3, Attribute v3,
+ std::string n4, Attribute v4,
+ std::string n5, Attribute v5,
+ std::string n6, Attribute v6,
+ std::string n7, Attribute v7)
+{
+ m_mac = ObjectFactory ();
+ m_mac.SetTypeId (type);
+ m_mac.Set (n0, v0);
+ m_mac.Set (n1, v1);
+ m_mac.Set (n2, v2);
+ m_mac.Set (n3, v3);
+ m_mac.Set (n4, v4);
+ m_mac.Set (n5, v5);
+ m_mac.Set (n6, v6);
+ m_mac.Set (n7, v7);
+}
+
+void
+WifiHelper::SetPhy (std::string type,
+ std::string n0, Attribute v0,
+ std::string n1, Attribute v1,
+ std::string n2, Attribute v2,
+ std::string n3, Attribute v3,
+ std::string n4, Attribute v4,
+ std::string n5, Attribute v5,
+ std::string n6, Attribute v6,
+ std::string n7, Attribute v7)
+{
+ m_phy = ObjectFactory ();
+ m_phy.SetTypeId (type);
+ m_phy.Set (n0, v0);
+ m_phy.Set (n1, v1);
+ m_phy.Set (n2, v2);
+ m_phy.Set (n3, v3);
+ m_phy.Set (n4, v4);
+ m_phy.Set (n5, v5);
+ m_phy.Set (n6, v6);
+ m_phy.Set (n7, v7);
+}
+
+NetDeviceContainer
+WifiHelper::Build (NodeContainer c) const
+{
+ Ptr<WifiChannel> channel = CreateObjectWith<WifiChannel> ();
+ return Build (c, channel);
+}
+NetDeviceContainer
+WifiHelper::Build (NodeContainer c, Ptr<WifiChannel> channel) const
+{
+ NetDeviceContainer devices;
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
+ {
+ Ptr<Node> node = *i;
+ Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> ();
+ Ptr<WifiRemoteStationManager> manager = m_stationManager.Create<WifiRemoteStationManager> ();
+ Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
+ Ptr<WifiPhy> phy = m_phy.Create<WifiPhy> ();
+ device->Setup (node, mac, phy, manager, channel);
+ node->AddDevice (device);
+ devices.Add (device);
+ NS_LOG_DEBUG ("node="<<node<<", mob="<<node->GetObject<MobilityModel> ());
+ }
+ return devices;
+}
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/wifi-helper.h Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,60 @@
+#ifndef WIFI_HELPER_H
+#define WIFI_HELPER_H
+
+#include <string>
+#include "ns3/attribute.h"
+#include "ns3/object-factory.h"
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+
+namespace ns3 {
+
+class WifiChannel;
+
+class WifiHelper
+{
+public:
+ WifiHelper ();
+
+ void SetRemoteStationManager (std::string type,
+ std::string n0 = "", Attribute v0 = Attribute (),
+ std::string n1 = "", Attribute v1 = Attribute (),
+ std::string n2 = "", Attribute v2 = Attribute (),
+ std::string n3 = "", Attribute v3 = Attribute (),
+ std::string n4 = "", Attribute v4 = Attribute (),
+ std::string n5 = "", Attribute v5 = Attribute (),
+ std::string n6 = "", Attribute v6 = Attribute (),
+ std::string n7 = "", Attribute v7 = Attribute ());
+
+ void SetMac (std::string type,
+ std::string n0 = "", Attribute v0 = Attribute (),
+ std::string n1 = "", Attribute v1 = Attribute (),
+ std::string n2 = "", Attribute v2 = Attribute (),
+ std::string n3 = "", Attribute v3 = Attribute (),
+ std::string n4 = "", Attribute v4 = Attribute (),
+ std::string n5 = "", Attribute v5 = Attribute (),
+ std::string n6 = "", Attribute v6 = Attribute (),
+ std::string n7 = "", Attribute v7 = Attribute ());
+
+ void SetPhy (std::string phyType,
+ std::string n0 = "", Attribute v0 = Attribute (),
+ std::string n1 = "", Attribute v1 = Attribute (),
+ std::string n2 = "", Attribute v2 = Attribute (),
+ std::string n3 = "", Attribute v3 = Attribute (),
+ std::string n4 = "", Attribute v4 = Attribute (),
+ std::string n5 = "", Attribute v5 = Attribute (),
+ std::string n6 = "", Attribute v6 = Attribute (),
+ std::string n7 = "", Attribute v7 = Attribute ());
+
+ NetDeviceContainer Build (NodeContainer c) const;
+ NetDeviceContainer Build (NodeContainer c, Ptr<WifiChannel> channel) const;
+
+private:
+ ObjectFactory m_stationManager;
+ ObjectFactory m_mac;
+ ObjectFactory m_phy;
+};
+
+} // namespace ns3
+
+#endif /* WIFI_HELPER_H */
--- a/src/devices/wifi/wifi-mac-queue.cc Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/wifi-mac-queue.cc Sat Mar 01 21:21:53 2008 +0100
@@ -20,6 +20,7 @@
#include "ns3/simulator.h"
#include "ns3/packet.h"
+#include "ns3/uinteger.h"
#include "wifi-mac-queue.h"
@@ -33,6 +34,24 @@
: packet (packet), hdr (hdr), tstamp (tstamp)
{}
+TypeId
+WifiMacQueue::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("WifiMacQueue")
+ .SetParent<Object> ()
+ .AddConstructor<WifiMacQueue> ()
+ .AddAttribute ("MaxPacketNumber", "XXX",
+ Uinteger (400),
+ MakeUintegerAccessor (&WifiMacQueue::m_maxSize),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("MaxDelay", "XXX",
+ Seconds (10.0),
+ MakeTimeAccessor (&WifiMacQueue::m_maxDelay),
+ MakeTimeChecker ())
+ ;
+ return tid;
+}
+
WifiMacQueue::WifiMacQueue ()
: m_size (0)
{}
@@ -52,6 +71,17 @@
{
m_maxDelay = delay;
}
+uint32_t
+WifiMacQueue::GetMaxSize (void) const
+{
+ return m_maxSize;
+}
+Time
+WifiMacQueue::GetMaxDelay (void) const
+{
+ return m_maxDelay;
+}
+
void
WifiMacQueue::Enqueue (Ptr<const Packet> packet, WifiMacHeader const &hdr)
{
--- a/src/devices/wifi/wifi-mac-queue.h Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/wifi-mac-queue.h Sat Mar 01 21:21:53 2008 +0100
@@ -24,6 +24,7 @@
#include <utility>
#include "ns3/packet.h"
#include "ns3/nstime.h"
+#include "ns3/object.h"
#include "wifi-mac-header.h"
namespace ns3 {
@@ -45,13 +46,17 @@
* dot11EDCATableMSDULifetime has elapsed, it is dropped.
* Otherwise, it is returned to the caller.
*/
-class WifiMacQueue {
+class WifiMacQueue : public Object
+{
public:
+ static TypeId GetTypeId (void);
WifiMacQueue ();
~WifiMacQueue ();
void SetMaxSize (uint32_t maxSize);
void SetMaxDelay (Time delay);
+ uint32_t GetMaxSize (void) const;
+ Time GetMaxDelay (void) const;
void Enqueue (Ptr<const Packet> packet, WifiMacHeader const &hdr);
Ptr<const Packet> Dequeue (WifiMacHeader *hdr);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/wifi-mac.cc Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,180 @@
+#include "wifi-mac.h"
+#include "ns3/uinteger.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (WifiMac);
+
+Time
+WifiMac::GetDefaultMaxPropagationDelay (void)
+{
+ // 1000m
+ return Seconds (1000.0 / 300000000.0);
+}
+Time
+WifiMac::GetDefaultSlot (void)
+{
+ // 802.11-a specific
+ return MicroSeconds (9);
+}
+Time
+WifiMac::GetDefaultSifs (void)
+{
+ // 802.11-a specific
+ return MicroSeconds (16);
+}
+Time
+WifiMac::GetDefaultEifsNoDifs (void)
+{
+ return GetDefaultSifs () + GetDefaultCtsAckDelay ();
+}
+Time
+WifiMac::GetDefaultCtsAckDelay (void)
+{
+ // 802.11-a specific: 6mb/s
+ return MicroSeconds (44);
+}
+Time
+WifiMac::GetDefaultCtsAckTimeout (void)
+{
+ /* Cts_Timeout and Ack_Timeout are specified in the Annex C
+ (Formal description of MAC operation, see details on the
+ Trsp timer setting at page 346)
+ */
+ Time ctsTimeout = GetDefaultSifs ();
+ ctsTimeout += GetDefaultCtsAckDelay ();
+ ctsTimeout += GetDefaultMaxPropagationDelay () * Scalar (2);
+ ctsTimeout += GetDefaultSlot ();
+ return ctsTimeout;
+}
+
+
+TypeId
+WifiMac::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("WifiMac")
+ .SetParent<Object> ()
+ .AddAttribute ("CtsTimeout", "XXX",
+ GetDefaultCtsAckTimeout (),
+ MakeTimeAccessor (&WifiMac::m_ctsTimeout),
+ MakeTimeChecker ())
+ .AddAttribute ("AckTimeout", "XXX",
+ GetDefaultCtsAckTimeout (),
+ MakeTimeAccessor (&WifiMac::m_ackTimeout),
+ MakeTimeChecker ())
+ .AddAttribute ("Sifs", "XXX",
+ GetDefaultSifs (),
+ MakeTimeAccessor (&WifiMac::SetSifs,
+ &WifiMac::GetSifs),
+ MakeTimeChecker ())
+ .AddAttribute ("EifsNoDifs", "XXX",
+ GetDefaultEifsNoDifs (),
+ MakeTimeAccessor (&WifiMac::SetEifsNoDifs,
+ &WifiMac::GetEifsNoDifs),
+ MakeTimeChecker ())
+ .AddAttribute ("Slot", "XXX",
+ GetDefaultSlot (),
+ MakeTimeAccessor (&WifiMac::SetSlot,
+ &WifiMac::GetSlot),
+ MakeTimeChecker ())
+ .AddAttribute ("Pifs", "XXX",
+ GetDefaultSifs () + GetDefaultSlot (),
+ MakeTimeAccessor (&WifiMac::m_pifs),
+ MakeTimeChecker ())
+ .AddAttribute ("MaxPropagationDelay", "XXX",
+ GetDefaultMaxPropagationDelay (),
+ MakeTimeAccessor (&WifiMac::m_maxPropagationDelay),
+ MakeTimeChecker ())
+ .AddAttribute ("MaxMsduSize", "XXX",
+ Uinteger (2304),
+ MakeUintegerAccessor (&WifiMac::GetMaxMsduSize),
+ MakeUintegerChecker (1,2304))
+ ;
+ return tid;
+}
+
+void
+WifiMac::SetSlot (Time slotTime)
+{
+ m_slot = slotTime;
+}
+void
+WifiMac::SetEifsNoDifs (Time eifsNoDifs)
+{
+ m_eifsNoDifs = eifsNoDifs;
+}
+void
+WifiMac::SetSifs (Time sifs)
+{
+ m_sifs = sifs;
+}
+void
+WifiMac::SetPifs (Time pifs)
+{
+ m_pifs = pifs;
+}
+void
+WifiMac::SetCtsTimeout (Time ctsTimeout)
+{
+ m_ctsTimeout = ctsTimeout;
+}
+void
+WifiMac::SetAckTimeout (Time ackTimeout)
+{
+ m_ackTimeout = ackTimeout;
+}
+void
+WifiMac::SetMaxPropagationDelay (Time delay)
+{
+ m_maxPropagationDelay = delay;
+}
+Time
+WifiMac::GetPifs (void) const
+{
+ return m_pifs;
+}
+Time
+WifiMac::GetSifs (void) const
+{
+ return m_sifs;
+}
+Time
+WifiMac::GetSlot (void) const
+{
+ return m_slot;
+}
+Time
+WifiMac::GetEifsNoDifs (void) const
+{
+ return m_eifsNoDifs;
+}
+Time
+WifiMac::GetCtsTimeout (void) const
+{
+ return m_ctsTimeout;
+}
+Time
+WifiMac::GetAckTimeout (void) const
+{
+ return m_ackTimeout;
+}
+
+Time
+WifiMac::GetMsduLifetime (void) const
+{
+ return Seconds (10);
+}
+Time
+WifiMac::GetMaxPropagationDelay (void) const
+{
+ return m_maxPropagationDelay;
+}
+
+uint32_t
+WifiMac::GetMaxMsduSize (void) const
+{
+ return m_maxMsduSize;
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/wifi-mac.h Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,72 @@
+#ifndef WIFI_MAC_H
+#define WIFI_MAC_H
+
+#include "ns3/packet.h"
+#include "ns3/mac48-address.h"
+
+#include "wifi-phy.h"
+#include "wifi-remote-station-manager.h"
+#include "ssid.h"
+
+namespace ns3 {
+
+class WifiMac : public Object
+{
+public:
+ static TypeId GetTypeId (void);
+
+ virtual void SetSlot (Time slotTime);
+ virtual void SetSifs (Time sifs);
+ virtual void SetEifsNoDifs (Time eifsNoDifs);
+ void SetPifs (Time pifs);
+ void SetCtsTimeout (Time ctsTimeout);
+ void SetAckTimeout (Time ackTimeout);
+ void SetMsduLifetime (Time msduLifetime);
+ void SetMaxPropagationDelay (Time delay);
+
+ Time GetPifs (void) const;
+ Time GetSifs (void) const;
+ Time GetSlot (void) const;
+ Time GetEifsNoDifs (void) const;
+ Time GetCtsTimeout (void) const;
+ Time GetAckTimeout (void) const;
+ Time GetMsduLifetime (void) const;
+ Time GetMaxPropagationDelay (void) const;
+ uint32_t GetMaxMsduSize (void) const;
+
+ virtual Mac48Address GetAddress (void) const = 0;
+ virtual Ssid GetSsid (void) const = 0;
+ virtual Mac48Address GetBssid (void) const = 0;
+ virtual void SetAddress (Mac48Address address) = 0;
+ virtual void SetSsid (Ssid ssid) = 0;
+
+private:
+ friend class WifiNetDevice;
+ virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to) = 0;
+ virtual void SetWifiPhy (Ptr<WifiPhy> phy) = 0;
+ virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager) = 0;
+ virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, const Mac48Address &> upCallback) = 0;
+ virtual void SetLinkUpCallback (Callback<void> linkUp) = 0;
+ virtual void SetLinkDownCallback (Callback<void> linkDown) = 0;
+
+
+ static Time GetDefaultMaxPropagationDelay (void);
+ static Time GetDefaultSlot (void);
+ static Time GetDefaultSifs (void);
+ static Time GetDefaultEifsNoDifs (void);
+ static Time GetDefaultCtsAckDelay (void);
+ static Time GetDefaultCtsAckTimeout (void);
+
+ Time m_slot;
+ Time m_pifs;
+ Time m_sifs;
+ Time m_eifsNoDifs;
+ Time m_ctsTimeout;
+ Time m_ackTimeout;
+ Time m_maxPropagationDelay;
+ uint32_t m_maxMsduSize;
+};
+
+} // namespace ns3
+
+#endif /* WIFI_MAC_H */
--- a/src/devices/wifi/wifi-mode.cc Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/wifi-mode.cc Sat Mar 01 21:21:53 2008 +0100
@@ -31,6 +31,16 @@
os << mode.GetUniqueName ();
return os;
}
+std::istream & operator >> (std::istream &is, WifiMode &mode)
+{
+ std::string str;
+ is >> str;
+ if (!WifiModeFactory::GetFactory ()->Search (str, &mode))
+ {
+ is.setstate (std::ios_base::badbit);
+ }
+ return is;
+}
uint32_t
WifiMode::GetBandwidth (void) const
@@ -98,6 +108,8 @@
: m_uid (uid)
{}
+VALUE_HELPER_CPP (WifiMode);
+
WifiModeFactory::WifiModeFactory ()
{}
@@ -141,6 +153,23 @@
return WifiMode (uid);
}
+bool
+WifiModeFactory::Search (std::string name, WifiMode *mode)
+{
+ uint32_t j = 0;
+ for (WifiModeItemList::const_iterator i = m_itemList.begin ();
+ i != m_itemList.end (); i++)
+ {
+ if (i->uniqueUid == name)
+ {
+ *mode = WifiMode (j);
+ return true;
+ }
+ j++;
+ }
+ return false;
+}
+
uint32_t
WifiModeFactory::AllocateUid (std::string uniqueUid)
{
@@ -169,7 +198,13 @@
WifiModeFactory *
WifiModeFactory::GetFactory (void)
{
+ static bool isFirstTime = true;
static WifiModeFactory factory;
+ if (isFirstTime)
+ {
+ factory.AllocateUid ("Invalid-WifiMode");
+ isFirstTime = false;
+ }
return &factory;
}
--- a/src/devices/wifi/wifi-mode.h Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/wifi-mode.h Sat Mar 01 21:21:53 2008 +0100
@@ -24,6 +24,7 @@
#include <string>
#include <vector>
#include <ostream>
+#include "ns3/attribute-helper.h"
namespace ns3 {
@@ -105,6 +106,8 @@
* its initialization.
*/
WifiMode ();
+
+ VALUE_HELPER_HEADER_1 (WifiMode);
private:
friend class WifiModeFactory;
WifiMode (uint32_t uid);
@@ -113,6 +116,9 @@
bool operator == (const WifiMode &a, const WifiMode &b);
std::ostream & operator << (std::ostream & os, const WifiMode &mode);
+std::istream & operator >> (std::istream &is, WifiMode &mode);
+
+VALUE_HELPER_HEADER_2 (WifiMode);
/**
* \brief create WifiMode class instances and keep track of them.
@@ -159,8 +165,10 @@
uint32_t dataRate,
uint32_t phyRate,
uint8_t constellationSize);
+
private:
friend class WifiMode;
+ friend std::istream & operator >> (std::istream &is, WifiMode &mode);
static WifiModeFactory *GetFactory ();
WifiModeFactory ();
@@ -179,6 +187,7 @@
bool isMandatory;
};
+ bool Search (std::string name, WifiMode *mode);
uint32_t AllocateUid (std::string uniqueName);
WifiModeItem *Get (uint32_t uid);
--- a/src/devices/wifi/wifi-net-device.cc Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/wifi-net-device.cc Sat Mar 01 21:21:53 2008 +0100
@@ -17,345 +17,74 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
-#include "ns3/packet.h"
-#include "ns3/llc-snap-header.h"
-#include "ns3/node.h"
-#include "ns3/composite-trace-resolver.h"
-
#include "wifi-net-device.h"
+#include "wifi-mac.h"
#include "wifi-phy.h"
+#include "wifi-remote-station-manager.h"
#include "wifi-channel.h"
-#include "mac-stations.h"
-#include "mac-low.h"
-#include "wifi-mac-parameters.h"
-#include "mac-rx-middle.h"
-#include "mac-tx-middle.h"
-#include "mac-high-adhoc.h"
-#include "mac-high-nqsta.h"
-#include "mac-high-nqap.h"
-#include "dca-txop.h"
-#include "dcf-manager.h"
-#include "wifi-default-parameters.h"
-#include "arf-mac-stations.h"
-#include "aarf-mac-stations.h"
-#include "ideal-mac-stations.h"
-#include "cr-mac-stations.h"
-#include "onoe-mac-stations.h"
-#include "amrr-mac-stations.h"
-#include "rraa-mac-stations.h"
+#include "ns3/llc-snap-header.h"
+#include "ns3/packet.h"
+#include "ns3/uinteger.h"
+#include "ns3/node.h"
+#include "ns3/trace-source-accessor.h"
namespace ns3 {
-/***************************************************************
- * hold an enumeration of the trace types
- ***************************************************************/
-
-WifiNetDeviceTraceType::WifiNetDeviceTraceType ()
- : m_type (RX)
-{}
-
-WifiNetDeviceTraceType::WifiNetDeviceTraceType (enum Type type)
- : m_type (type)
-{}
-enum WifiNetDeviceTraceType::Type
-WifiNetDeviceTraceType::Get (void) const
-{
- return m_type;
-}
-uint16_t
-WifiNetDeviceTraceType::GetUid (void)
-{
- static uint16_t uid = AllocateUid<WifiNetDeviceTraceType> ("ns3::WifiNetDeviceTraceType");
- return uid;
-}
-void
-WifiNetDeviceTraceType::Print (std::ostream &os) const
+TypeId
+WifiNetDevice::GetTypeId (void)
{
- os << "event=";
- switch (m_type) {
- case RX:
- os << "rx";
- break;
- case TX:
- os << "tx";
- break;
- }
-}
-std::string
-WifiNetDeviceTraceType::GetTypeName (void) const
-{
- return "ns3::WifiNetDeviceTraceType";
-}
-
-/***************************************************************
- * a static helper
- ***************************************************************/
-
-static WifiMode
-GetWifiModeForPhyMode (Ptr<WifiPhy> phy, enum WifiDefaultParameters::PhyModeParameter mode)
-{
- uint32_t phyRate = (uint32_t)mode;
- for (uint32_t i= 0; i < phy->GetNModes (); i++)
- {
- WifiMode mode = phy->GetMode (i);
- if (mode.GetDataRate () == phyRate)
- {
- return mode;
- }
- }
- NS_ASSERT (false);
- return WifiMode ();
+ static TypeId tid = TypeId ("WifiNetDevice")
+ .SetParent<NetDevice> ()
+ .AddTraceSource ("Rx", "XXX",
+ MakeTraceSourceAccessor (&WifiNetDevice::m_rxLogger))
+ .AddTraceSource ("Tx", "XXX",
+ MakeTraceSourceAccessor (&WifiNetDevice::m_txLogger))
+ ;
+ return tid;
}
-/***************************************************************
- * Listener for Nav events. Forwards to DcfManager
- ***************************************************************/
-
-class WifiNetDevice::NavListener : public ns3::MacLowNavListener {
-public:
- NavListener (ns3::DcfManager *dcf)
- : m_dcf (dcf) {}
- virtual ~NavListener () {}
- virtual void NavStart (Time duration) {
- m_dcf->NotifyNavStartNow (duration);
- }
- virtual void NavReset (Time duration) {
- m_dcf->NotifyNavResetNow (duration);
- }
-private:
- ns3::DcfManager *m_dcf;
-};
-
-/***************************************************************
- * Listener for PHY events. Forwards to DcfManager
- ***************************************************************/
-
-class WifiNetDevice::PhyListener : public ns3::WifiPhyListener {
-public:
- PhyListener (ns3::DcfManager *dcf)
- : m_dcf (dcf) {}
- virtual ~PhyListener () {}
- virtual void NotifyRxStart (Time duration) {
- m_dcf->NotifyRxStartNow (duration);
- }
- virtual void NotifyRxEndOk (void) {
- m_dcf->NotifyRxEndOkNow ();
- }
- virtual void NotifyRxEndError (void) {
- m_dcf->NotifyRxEndErrorNow ();
- }
- virtual void NotifyTxStart (Time duration) {
- m_dcf->NotifyTxStartNow (duration);
- }
- virtual void NotifyCcaBusyStart (Time duration) {
- m_dcf->NotifyCcaBusyStartNow (duration);
- }
-private:
- ns3::DcfManager *m_dcf;
-};
-
-/***************************************************************
- * The NetDevice itself
- ***************************************************************/
-
-
-
-WifiNetDevice::WifiNetDevice (Ptr<Node> node, Mac48Address self)
- : m_node (node),
- m_address (self),
- m_name (""),
- m_linkUp (false)
-{
- Construct ();
-}
-
+WifiNetDevice::WifiNetDevice ()
+{}
WifiNetDevice::~WifiNetDevice ()
{}
-
-void
-WifiNetDevice::Construct (void)
-{
- m_mtu = 2300;
- // the physical layer.
- m_phy = Create<WifiPhy> (this);
-
- // the rate control algorithm
- switch (WifiDefaultParameters::GetRateControlAlgorithm ()) {
- case WifiDefaultParameters::ARF:
- m_stations = new ArfMacStations (m_phy->GetMode (0),
- WifiDefaultParameters::GetArfRateControlTimerThreshold (),
- WifiDefaultParameters::GetArfRateControlSuccessThreshold ());
- break;
- case WifiDefaultParameters::AARF:
- m_stations = new AarfMacStations (m_phy->GetMode (0),
- WifiDefaultParameters::GetAarfRateControlMinTimerThreshold (),
- WifiDefaultParameters::GetAarfRateControlMinSuccessThreshold (),
- WifiDefaultParameters::GetAarfRateControlSuccessK (),
- WifiDefaultParameters::GetAarfRateControlMaxSuccessThreshold (),
- WifiDefaultParameters::GetAarfRateControlTimerK ());
- break;
- case WifiDefaultParameters::CONSTANT_RATE: {
- WifiMode dataRate = GetWifiModeForPhyMode (m_phy, WifiDefaultParameters::GetConstantDataRate ());
- WifiMode ctlRate = GetWifiModeForPhyMode (m_phy, WifiDefaultParameters::GetConstantCtlRate ());
- m_stations = new CrMacStations (dataRate, ctlRate);
- } break;
- case WifiDefaultParameters::IDEAL: {
- double ber = WifiDefaultParameters::GetIdealRateControlBer ();
- IdealMacStations *ideal = new IdealMacStations (m_phy->GetMode (0));
- uint32_t nModes = m_phy->GetNModes ();
- for (uint32_t i = 0; i < nModes; i++)
- {
- WifiMode mode = m_phy->GetMode (i);
- ideal->AddModeSnrThreshold (mode, m_phy->CalculateSnr (mode, ber));
- }
- m_stations = ideal;
- } break;
- case WifiDefaultParameters::ONOE: {
- m_stations = new OnoeMacStations (m_phy->GetMode (0));
- } break;
- case WifiDefaultParameters::AMRR: {
- m_stations = new AmrrMacStations (m_phy->GetMode (0));
- } break;
- case WifiDefaultParameters::RRAA: {
- m_stations = new RraaMacStations (m_phy->GetMode (0));
- } break;
- default:
- // NOTREACHED
- NS_ASSERT (false);
- break;
- }
-
- // WifiMacParameters
- WifiMacParameters *parameters = new WifiMacParameters ();
- m_parameters = parameters;
- m_stations->SetParameters (m_parameters);
-
- // the MacLow
- Ptr<MacLow> low = CreateObject<MacLow> ();
- low->SetDevice (this);
- low->SetPhy (m_phy);
- low->SetStations (m_stations);
- low->SetParameters (m_parameters);
- m_phy->SetReceiveOkCallback (MakeCallback (&MacLow::ReceiveOk, low));
- m_phy->SetReceiveErrorCallback (MakeCallback (&MacLow::ReceiveError, low));
- m_low = low;
-
- // the 'middle' rx
- MacRxMiddle *rxMiddle = new MacRxMiddle ();
- low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, rxMiddle));
- m_rxMiddle = rxMiddle;
-
- // the 'middle' tx
- MacTxMiddle *txMiddle = new MacTxMiddle ();
- m_txMiddle = txMiddle;
-
- m_manager = new DcfManager ();
- Time ackTxDuration = m_phy->CalculateTxDuration (8 * (2+2+6+4), m_phy->GetMode (0), WIFI_PREAMBLE_LONG);
- m_manager->SetAckTxDuration (ackTxDuration);
- m_manager->SetSlotTime (m_parameters->GetSlotTime ());
- m_manager->SetSifs (m_parameters->GetSifs ());
- m_phyListener = new WifiNetDevice::PhyListener (m_manager);
- m_phy->RegisterListener (m_phyListener);
- m_navListener = new WifiNetDevice::NavListener (m_manager);
- m_low->RegisterNavListener (m_navListener);
-}
-
-Ptr<DcaTxop>
-WifiNetDevice::CreateDca (uint32_t minCw, uint32_t maxCw, uint32_t aifsn) const
+
+void
+WifiNetDevice::Setup (Ptr<Node> node, Ptr<WifiMac> mac, Ptr<WifiPhy> phy,
+ Ptr<WifiRemoteStationManager> manager,
+ Ptr<WifiChannel> channel)
{
- Ptr<DcaTxop> dca = CreateObject<DcaTxop> (minCw, maxCw, aifsn, m_manager);
- dca->SetParameters (m_parameters);
- dca->SetTxMiddle (m_txMiddle);
- dca->SetLow (m_low);
- dca->SetStations (m_stations);
- dca->SetMaxQueueSize (400);
- dca->SetMaxQueueDelay (Seconds (10));
- return dca;
-}
+ m_node = node;
+ m_mac = mac;
+ m_phy = phy;
+ m_stationManager = manager;
+
+ manager->SetupPhy (phy);
-Ptr<TraceResolver>
-WifiNetDevice::GetTraceResolver (void) const
-{
- Ptr<CompositeTraceResolver> resolver =
- Create<CompositeTraceResolver> ();
- resolver->AddSource ("rx",
- TraceDoc ("Receive a packet",
- "Packet", "the packet received",
- "Mac48Address", "the sender of the packet"),
- m_rxLogger,
- WifiNetDeviceTraceType (WifiNetDeviceTraceType::RX));
- resolver->AddSource ("tx",
- TraceDoc ("Send a packet",
- "Packet", "the packet to send",
- "Mac48Address", "the destination of the packet"),
- m_txLogger,
- WifiNetDeviceTraceType (WifiNetDeviceTraceType::TX));
- resolver->AddComposite ("phy", m_phy);
- resolver->AddComposite ("maclow", m_low);
- resolver->SetParentResolver (NetDevice::GetTraceResolver ());
- return resolver;
-}
-
-void
-WifiNetDevice::Attach (Ptr<WifiChannel> channel)
-{
- m_channel = channel;
- m_phy->SetChannel (channel);
- NotifyAttached ();
-}
-void
-WifiNetDevice::DoForwardUp (Ptr<Packet> packet, const Mac48Address &from)
-{
- m_rxLogger (packet, from);
+ m_mac->SetWifiRemoteStationManager (manager);
+ m_mac->SetWifiPhy (m_phy);
+ m_mac->SetForwardUpCallback (MakeCallback (&WifiNetDevice::ForwardUp, this));
+ m_mac->SetLinkUpCallback (MakeCallback (&WifiNetDevice::LinkUp, this));
+ m_mac->SetLinkDownCallback (MakeCallback (&WifiNetDevice::LinkDown, this));
+ channel->Add (this, m_phy);
- LlcSnapHeader llc;
- packet->RemoveHeader (llc);
- m_rxCallback (this, packet, llc.GetType (), from);
+ m_phy->SetChannel (channel);
+ //XXX
+ //m_stationManager->
}
-Mac48Address
-WifiNetDevice::GetSelfAddress (void) const
-{
- NS_ASSERT (Mac48Address::IsMatchingType (GetAddress ()));
- Mac48Address self = Mac48Address::ConvertFrom (GetAddress ());
- return self;
-}
-void
-WifiNetDevice::DoDispose (void)
+Ptr<WifiMac>
+WifiNetDevice::GetMac (void) const
{
- // cleanup local
- m_node = 0;
- m_channel = 0;
- delete m_stations;
- delete m_rxMiddle;
- delete m_txMiddle;
- delete m_parameters;
- delete m_manager;
- delete m_phyListener;
- delete m_navListener;
- m_phy = 0;
- m_stations = 0;
- m_low = 0;
- m_rxMiddle = 0;
- m_txMiddle = 0;
- m_parameters = 0;
- // chain up.
- NetDevice::DoDispose ();
+ return m_mac;
}
-
-void
-WifiNetDevice::NotifyLinkUp (void)
+Ptr<WifiPhy>
+WifiNetDevice::GetPhy (void) const
{
- m_linkUp = true;
- if (!m_linkChangeCallback.IsNull ())
- {
- m_linkChangeCallback ();
- }
+ return m_phy;
}
-void
-WifiNetDevice::NotifyLinkDown (void)
+Ptr<WifiRemoteStationManager>
+WifiNetDevice::GetRemoteStationManager (void) const
{
- m_linkUp = false;
- m_linkChangeCallback ();
+ return m_stationManager;
}
void
@@ -381,43 +110,53 @@
Ptr<Channel>
WifiNetDevice::GetChannel (void) const
{
- return m_channel;
+ return m_phy->GetChannel ();
}
Address
WifiNetDevice::GetAddress (void) const
{
- return m_address;
+ return m_mac->GetAddress ();
}
bool
WifiNetDevice::SetMtu (const uint16_t mtu)
{
+ Uinteger maxMsduSize = m_mac->GetAttribute ("MaxMsduSize");
+ if (mtu > maxMsduSize && mtu > 0)
+ {
+ return false;
+ }
m_mtu = mtu;
return true;
}
uint16_t
WifiNetDevice::GetMtu (void) const
{
+ if (m_mtu == 0)
+ {
+ Uinteger maxMsduSize = m_mac->GetAttribute ("MaxMsduSize");
+ m_mtu = maxMsduSize;
+ }
return m_mtu;
}
bool
WifiNetDevice::IsLinkUp (void) const
{
- return m_linkUp;
+ return m_phy != 0 && m_linkUp;
}
void
WifiNetDevice::SetLinkChangeCallback (Callback<void> callback)
{
- m_linkChangeCallback = callback;
+ m_linkChange = callback;
}
bool
WifiNetDevice::IsBroadcast (void) const
{
return true;
}
-Address
+Address
WifiNetDevice::GetBroadcast (void) const
{
- return Mac48Address ("ff:ff:ff:ff:ff:ff");
+ return Mac48Address::GetBroadcast ();
}
bool
WifiNetDevice::IsMulticast (void) const
@@ -432,7 +171,7 @@
Address
WifiNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const
{
- return Mac48Address ("01:00:5e:00:00:00");
+ return GetMulticast ();
}
bool
WifiNetDevice::IsPointToPoint (void) const
@@ -440,11 +179,11 @@
return false;
}
bool
-WifiNetDevice::Send(Ptr<Packet> packet, const Address& to, uint16_t protocolNumber)
+WifiNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
{
- NS_ASSERT (Mac48Address::IsMatchingType (to));
+ NS_ASSERT (Mac48Address::IsMatchingType (dest));
- Mac48Address realTo = Mac48Address::ConvertFrom (to);
+ Mac48Address realTo = Mac48Address::ConvertFrom (dest);
LlcSnapHeader llc;
llc.SetType (protocolNumber);
@@ -452,7 +191,8 @@
m_txLogger (packet, realTo);
- return DoSendTo (packet, realTo);
+ m_mac->Enqueue (packet, realTo);
+ return true;
}
Ptr<Node>
WifiNetDevice::GetNode (void) const
@@ -467,276 +207,35 @@
void
WifiNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
{
- m_rxCallback = cb;
-}
-
-
-/*****************************************************
- * Adhoc code
- *****************************************************/
-
-AdhocWifiNetDevice::AdhocWifiNetDevice (Ptr<Node> node, Mac48Address self)
- : WifiNetDevice (node, self)
-{
- DoConstruct ();
-}
-void
-AdhocWifiNetDevice::DoConstruct (void)
-{
- m_ssid = WifiDefaultParameters::GetSsid ();
- m_dca = CreateDca (15, 1023, 2);
-
- MacHighAdhoc *high = new MacHighAdhoc ();
- high->SetDevice (this);
- high->SetDcaTxop (m_dca);
- high->SetForwardCallback (MakeCallback (&AdhocWifiNetDevice::DoForwardUp,
- static_cast<WifiNetDevice *> (this)));
- high->SetPhy (m_phy);
- high->SetStations (m_stations);
- m_rxMiddle->SetForwardCallback (MakeCallback (&MacHighAdhoc::Receive, high));
- m_high = high;
+ m_forwardUp = cb;
}
-AdhocWifiNetDevice::~AdhocWifiNetDevice ()
-{}
-Mac48Address
-AdhocWifiNetDevice::GetBssid (void) const
-{
- return m_high->GetBssid ();
-}
-Ssid
-AdhocWifiNetDevice::GetSsid (void) const
-{
- return m_ssid;
-}
-void
-AdhocWifiNetDevice::SetSsid (Ssid ssid)
-{
- // XXX restart adhoc network join.
- m_ssid = ssid;
-}
-bool
-AdhocWifiNetDevice::DoSendTo (Ptr<const Packet> packet, Mac48Address const &to)
+void
+WifiNetDevice::ForwardUp (Ptr<Packet> packet, const Mac48Address &from)
{
- m_high->Enqueue (packet, to);
- return true;
-}
-void
-AdhocWifiNetDevice::NotifyAttached (void)
-{
- NotifyLinkUp ();
-}
-void
-AdhocWifiNetDevice::DoDispose (void)
-{
- // chain up.
- WifiNetDevice::DoDispose ();
- // local cleanup
- delete m_high;
- m_dca = 0;
- m_high = 0;
-}
-Ptr<TraceResolver>
-AdhocWifiNetDevice::GetTraceResolver (void) const
-{
- Ptr<CompositeTraceResolver> resolver =
- Create<CompositeTraceResolver> ();
- resolver->AddComposite ("dca", m_dca);
- resolver->SetParentResolver (WifiNetDevice::GetTraceResolver ());
- return resolver;
+ LlcSnapHeader llc;
+ packet->RemoveHeader (llc);
+ m_forwardUp (this, packet, llc.GetType (), from);
+ m_rxLogger (packet, from);
}
-
-/*****************************************************
- * STA code
- *****************************************************/
-
-NqstaWifiNetDevice::NqstaWifiNetDevice (Ptr<Node> node, Mac48Address self)
- : WifiNetDevice (node, self)
-{
- DoConstruct ();
-}
void
-NqstaWifiNetDevice::DoConstruct (void)
+WifiNetDevice::LinkUp (void)
{
- m_ssid = WifiDefaultParameters::GetSsid ();
- m_dca = CreateDca (15, 1023, 2);
-
- MacHighNqsta *high = new MacHighNqsta ();
- high->SetDevice (this);
- high->SetDcaTxop (m_dca);
- high->SetForwardCallback (MakeCallback (&NqstaWifiNetDevice::DoForwardUp,
- this));
- high->SetAssociatedCallback (MakeCallback (&NqstaWifiNetDevice::Associated,
- this));
- high->SetDisAssociatedCallback (MakeCallback (&NqstaWifiNetDevice::DisAssociated,
- this));
- high->SetStations (m_stations);
- high->SetPhy (m_phy);
- m_rxMiddle->SetForwardCallback (MakeCallback (&MacHighNqsta::Receive, high));
- m_high = high;
-}
-
-NqstaWifiNetDevice::~NqstaWifiNetDevice ()
-{}
-Mac48Address
-NqstaWifiNetDevice::GetBssid (void) const
-{
- return m_high->GetBssid ();
-}
-Ssid
-NqstaWifiNetDevice::GetSsid (void) const
-{
- return m_ssid;
-}
-void
-NqstaWifiNetDevice::StartActiveAssociation (Ssid ssid)
-{
- m_ssid = ssid;
- m_high->StartActiveAssociation ();
-}
-bool
-NqstaWifiNetDevice::DoSendTo (Ptr<const Packet> packet, Mac48Address const &to)
-{
- m_high->Queue (packet, to);
- return true;
+ m_linkUp = true;
+ if (!m_linkChange.IsNull ())
+ {
+ m_linkChange ();
+ }
}
void
-NqstaWifiNetDevice::NotifyAttached (void)
-{
- // do nothing because link status is kept track of in
- // ::Associated and ::Disassociated
-}
-void
-NqstaWifiNetDevice::Associated (void)
-{
- WifiNetDevice::NotifyLinkUp ();
-}
-
-void
-NqstaWifiNetDevice::DisAssociated (void)
-{
- WifiNetDevice::NotifyLinkDown ();
-}
-void
-NqstaWifiNetDevice::DoDispose (void)
-{
- // chain up.
- WifiNetDevice::DoDispose ();
- // local cleanup
- delete m_high;
- m_dca = 0;
- m_high = 0;
-}
-
-Ptr<TraceResolver>
-NqstaWifiNetDevice::GetTraceResolver (void) const
+WifiNetDevice::LinkDown (void)
{
- Ptr<CompositeTraceResolver> resolver =
- Create<CompositeTraceResolver> ();
- resolver->AddComposite ("dca", m_dca);
- resolver->SetParentResolver (WifiNetDevice::GetTraceResolver ());
- return resolver;
-}
-
-/*****************************************************
- * AP code
- *****************************************************/
-
-
-NqapWifiNetDevice::NqapWifiNetDevice (Ptr<Node> node, Mac48Address self)
- : WifiNetDevice (node, self)
-{
- DoConstruct ();
-
-}
-void
-NqapWifiNetDevice::DoConstruct (void)
-{
- m_ssid = WifiDefaultParameters::GetSsid ();
-
- // The Beacon DCA is higher priority than
- // the normal DCA so, we create it first.
- m_beaconDca = CreateDca (0, 0, 1);
- m_dca = CreateDca (15, 1023, 2);
-
- // By default, we configure the Basic Rate Set to be the set
- // of rates we support which are mandatory.
- // This could be trivially made user-configurable
- for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+ m_linkUp = false;
+ if (!m_linkChange.IsNull ())
{
- WifiMode mode = m_phy->GetMode (i);
- if (mode.IsMandatory ())
- {
- m_stations->AddBasicMode (mode);
- }
- }
-
- MacHighNqap *high = new MacHighNqap ();
- high->SetDevice (this);
- high->SetDcaTxop (m_dca);
- high->SetBeaconDcaTxop (m_beaconDca);
- high->SetStations (m_stations);
- high->SetPhy (m_phy);
- high->SetForwardCallback (MakeCallback (&NqapWifiNetDevice::DoForwardUp,
- this));
- m_rxMiddle->SetForwardCallback (MakeCallback (&MacHighNqap::Receive, high));
- m_high = high;
-}
-NqapWifiNetDevice::~NqapWifiNetDevice ()
-{}
-Mac48Address
-NqapWifiNetDevice::GetBssid (void) const
-{
- return GetSelfAddress ();
-}
-Ssid
-NqapWifiNetDevice::GetSsid (void) const
-{
- return m_ssid;
-}
-void
-NqapWifiNetDevice::SetSsid (Ssid ssid)
-{
- m_ssid = ssid;
-}
-void
-NqapWifiNetDevice::StartBeaconing (void)
-{
- m_high->StartBeaconing ();
-}
-bool
-NqapWifiNetDevice::DoSendTo (Ptr<const Packet> packet, Mac48Address const & to)
-{
- m_high->Queue (packet, to);
- return true;
-}
-void
-NqapWifiNetDevice::NotifyAttached (void)
-{
- NotifyLinkUp ();
-}
-void
-NqapWifiNetDevice::DoDispose (void)
-{
- // chain up.
- WifiNetDevice::DoDispose ();
- // local cleanup
- delete m_high;
- m_dca = 0;
- m_high = 0;
- m_beaconDca = 0;
-}
-
-Ptr<TraceResolver>
-NqapWifiNetDevice::GetTraceResolver (void) const
-{
- Ptr<CompositeTraceResolver> resolver =
- Create<CompositeTraceResolver> ();
- resolver->AddComposite ("dca", m_dca);
- resolver->AddComposite ("beaconDca", m_beaconDca);
- resolver->SetParentResolver (WifiNetDevice::GetTraceResolver ());
- return resolver;
+ m_linkChange ();
+ }
}
} // namespace ns3
--- a/src/devices/wifi/wifi-net-device.h Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/wifi-net-device.h Sat Mar 01 21:21:53 2008 +0100
@@ -23,80 +23,37 @@
#include "ns3/net-device.h"
#include "ns3/packet.h"
-#include "ns3/callback-trace-source.h"
+#include "ns3/traced-callback.h"
#include "ns3/mac48-address.h"
-#include "ssid.h"
+#include "wifi-remote-station-manager.h"
#include <string>
namespace ns3 {
class WifiChannel;
class WifiPhy;
-class MacStations;
-class MacLow;
-class MacRxMiddle;
-class MacTxMiddle;
-class WifiMacParameters;
-class DcaTxop;
-class MacHighAdhoc;
-class MacHighNqsta;
-class MacHighNqap;
-class DcfManager;
-
-/**
- * \brief hold the type of trace event generated by
- * a WifiNetDevice.
- */
-class WifiNetDeviceTraceType : public TraceContextElement
-{
-public:
- enum Type {
- RX,
- TX
- };
- WifiNetDeviceTraceType ();
- WifiNetDeviceTraceType (enum Type type);
- /**
- * \returns the type of event
- */
- enum Type Get (void) const;
-
- static uint16_t GetUid (void);
- void Print (std::ostream &os) const;
- std::string GetTypeName (void) const;
-private:
- enum Type m_type;
-};
+class WifiMac;
/**
* \brief the base class for 802.11 network interfaces
*
*/
-class WifiNetDevice : public NetDevice {
+class WifiNetDevice : public NetDevice
+{
public:
+ static TypeId GetTypeId (void);
+
+ WifiNetDevice ();
virtual ~WifiNetDevice ();
- /**
- * \param channel the channel to connect this 802.11
- * interface to.
- */
- void Attach (Ptr<WifiChannel> channel);
+
+ void Setup (Ptr<Node> node, Ptr<WifiMac> mac, Ptr<WifiPhy> phy,
+ Ptr<WifiRemoteStationManager> manager,
+ Ptr<WifiChannel> channel);
+ Ptr<WifiMac> GetMac (void) const;
+ Ptr<WifiPhy> GetPhy (void) const;
+ Ptr<WifiRemoteStationManager> GetRemoteStationManager (void) const;
- /**
- * \returns the Mac48Address of this 802.11 interface.
- *
- * This method is equivalent to NetDevice::GetAddress. The only
- * difference is its return type.
- */
- Mac48Address GetSelfAddress (void) const;
- /**
- * \returns the bssid of this 802.11 interface.
- */
- virtual Mac48Address GetBssid (void) const = 0;
- /**
- * \returns the ssid of this 802.11 interface.
- */
- virtual Ssid GetSsid (void) const = 0;
// inherited from NetDevice base class.
virtual void SetName(const std::string name);
@@ -121,162 +78,21 @@
virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
private:
- class PhyListener;
- class NavListener;
-
- // defined for children
- virtual void NotifyAttached (void) = 0;
- virtual bool DoSendTo (Ptr<const Packet> packet, const Mac48Address &to) = 0;
- // private helper
- void Construct (void);
-
- CallbackTraceSource<Ptr<const Packet>, Mac48Address> m_rxLogger;
- CallbackTraceSource<Ptr<const Packet>, Mac48Address> m_txLogger;
-protected:
- WifiNetDevice (Ptr<Node> node, Mac48Address self);
- void DoForwardUp (Ptr<Packet> packet, const Mac48Address &from);
- Ptr<DcaTxop> CreateDca (uint32_t minCw, uint32_t maxCw, uint32_t aifsn) const;
- void NotifyLinkUp (void);
- void NotifyLinkDown (void);
- // inherited from Object
- virtual void DoDispose (void);
- // inherited from Object
- virtual Ptr<TraceResolver> GetTraceResolver (void) const;
-
- Ptr<WifiChannel> m_channel;
+ void ForwardUp (Ptr<Packet> packet, const Mac48Address &from);
+ void LinkUp (void);
+ void LinkDown (void);
+ Ptr<Node> m_node;
Ptr<WifiPhy> m_phy;
- MacStations *m_stations;
- Ptr<MacLow> m_low;
- MacRxMiddle *m_rxMiddle;
- MacTxMiddle *m_txMiddle;
- WifiMacParameters *m_parameters;
- DcfManager *m_manager;
- PhyListener *m_phyListener;
- NavListener *m_navListener;
-
- Ptr<Node> m_node;
- Mac48Address m_address;
- NetDevice::ReceiveCallback m_rxCallback;
+ Ptr<WifiMac> m_mac;
+ Ptr<WifiRemoteStationManager> m_stationManager;
+ Callback <bool,Ptr<NetDevice>,Ptr<Packet>,uint16_t,const Address &> m_forwardUp;
+ TracedCallback<Ptr<const Packet>, Mac48Address> m_rxLogger;
+ TracedCallback<Ptr<const Packet>, Mac48Address> m_txLogger;
uint32_t m_ifIndex;
std::string m_name;
bool m_linkUp;
- Callback<void> m_linkChangeCallback;
- uint16_t m_mtu;
-};
-
-/**
- * \brief a 802.11 adhoc network interface
- *
- * This network interface is a very simple pass-through
- * from the higher layers down to the MAC DCF layer.
- */
-class AdhocWifiNetDevice : public WifiNetDevice {
-public:
- AdhocWifiNetDevice (Ptr<Node> node, Mac48Address self);
- virtual ~AdhocWifiNetDevice ();
-
- virtual Mac48Address GetBssid (void) const;
- virtual Ssid GetSsid (void) const;
- void SetSsid (Ssid ssid);
-
-protected:
- // inherited from Object
- virtual void DoDispose (void);
-private:
- void DoConstruct (void);
- void ForwardUp (void);
- // inherited from WifiNetDefice
- virtual bool DoSendTo (Ptr<const Packet> packet, Mac48Address const & to);
- virtual void NotifyAttached (void);
- virtual Ptr<TraceResolver> GetTraceResolver (void) const;
-
- Ssid m_ssid;
- Ptr<DcaTxop> m_dca;
- MacHighAdhoc *m_high;
-};
-
-/**
- * \brief a 802.11 STA network interface
- *
- * This network interface implements the MAC-level STA
- * active probing, association, and disassociation prototols.
- *
- * By default, it starts a new probing phase whenever a new
- * data packet must be sent and the STA is not yet associated
- * to the AP.
- */
-class NqstaWifiNetDevice : public WifiNetDevice
-{
-public:
- /**
- * The ssid is initialized from \valueref{WifiSsid}.
- */
- NqstaWifiNetDevice (Ptr<Node> node, Mac48Address self);
- virtual ~NqstaWifiNetDevice ();
-
- virtual Mac48Address GetBssid (void) const;
- virtual Ssid GetSsid (void) const;
-
- /**
- * \param ssid the ssid we want to associate with
- *
- * Start a new active probing phase with the specified
- * ssid.
- */
- void StartActiveAssociation (Ssid ssid);
-protected:
- // inherited from Object
- virtual void DoDispose (void);
-private:
- void DoConstruct (void);
- void Associated (void);
- void DisAssociated (void);
- // inherited from WifiNetDefice
- virtual bool DoSendTo (Ptr<const Packet> packet, Mac48Address const & to);
- virtual void NotifyAttached (void);
- virtual Ptr<TraceResolver> GetTraceResolver (void) const;
-
- Ssid m_ssid;
- Ptr<DcaTxop> m_dca;
- MacHighNqsta *m_high;
-};
-
-/**
- * \brief a 802.11 AP network interface
- *
- * This network interface implements the MAC-level
- * AP-side of the beacon, probing, and, association
- * protocols. By default, every STA which tries
- * to associate is accepted.
- */
-class NqapWifiNetDevice : public WifiNetDevice
-{
-public:
- /**
- * The ssid is initialized from \valueref{WifiSsid}.
- */
- NqapWifiNetDevice (Ptr<Node> node);
- NqapWifiNetDevice (Ptr<Node> node, Mac48Address self);
- virtual ~NqapWifiNetDevice ();
-
- virtual Mac48Address GetBssid (void) const;
- virtual Ssid GetSsid (void) const;
- void SetSsid (Ssid ssid);
- void StartBeaconing (void);
-protected:
- // inherited from Object
- virtual void DoDispose (void);
-private:
- void DoConstruct (void);
- // inherited from WifiNetDefice
- virtual bool DoSendTo (Ptr<const Packet> packet, Mac48Address const & to);
- virtual void NotifyAttached (void);
- virtual Ptr<TraceResolver> GetTraceResolver (void) const;
-
- Ssid m_ssid;
- Ptr<DcaTxop> m_dca;
- Ptr<DcaTxop> m_beaconDca;
- MacHighNqap *m_high;
+ Callback<void> m_linkChange;
+ mutable uint16_t m_mtu;
};
} // namespace ns3
--- a/src/devices/wifi/wifi-phy.cc Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/wifi-phy.cc Sat Mar 01 21:21:53 2008 +0100
@@ -21,16 +21,17 @@
#include "wifi-phy.h"
#include "wifi-mode.h"
#include "wifi-channel.h"
-#include "wifi-net-device.h"
#include "wifi-preamble.h"
-#include "wifi-default-parameters.h"
#include "ns3/simulator.h"
#include "ns3/packet.h"
#include "ns3/random-variable.h"
#include "ns3/assert.h"
#include "ns3/log.h"
-#include "ns3/composite-trace-resolver.h"
#include "ns3/object-base.h"
+#include "ns3/double.h"
+#include "ns3/uinteger.h"
+#include "ns3/enum.h"
+#include "ns3/trace-source-accessor.h"
#include <math.h>
NS_LOG_COMPONENT_DEFINE ("WifiPhy");
@@ -176,15 +177,71 @@
* The actual WifiPhy class
****************************************************************/
-WifiPhy::WifiPhy (Ptr<WifiNetDevice> device)
- : m_edThresholdW (DbmToW (WifiDefaultParameters::GetPhyEnergyDetectionThresholdDbm ())),
- m_txGainDb (WifiDefaultParameters::GetPhyTxGainDb ()),
- m_rxGainDb (WifiDefaultParameters::GetPhyRxGainDb ()),
- m_rxNoiseRatio (DbToRatio (WifiDefaultParameters::GetPhyRxNoiseDb ())),
- m_txPowerBaseDbm (WifiDefaultParameters::GetPhyTxPowerBaseDbm ()),
- m_txPowerEndDbm (WifiDefaultParameters::GetPhyTxPowerEndDbm ()),
- m_nTxPower (WifiDefaultParameters::GetPhyTxPowerLevels ()),
- m_syncing (false),
+NS_OBJECT_ENSURE_REGISTERED (WifiPhy);
+
+TypeId
+WifiPhy::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("WifiPhy")
+ .SetParent<Object> ()
+ .AddConstructor<WifiPhy> ()
+ .AddAttribute ("EnergyDetectionThreshold",
+ "The energy of a received signal should be higher than "
+ "this threshold (dbm) to allow the PHY layer to detect the signal.",
+ Double (-140.0),
+ MakeDoubleAccessor (&WifiPhy::SetEdThreshold,
+ &WifiPhy::GetEdThreshold),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxGain",
+ "Transmission gain (dB).",
+ Double (1.0),
+ MakeDoubleAccessor (&WifiPhy::SetTxGain,
+ &WifiPhy::GetTxGain),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("RxGain",
+ "Reception gain (dB).",
+ Double (1.0),
+ MakeDoubleAccessor (&WifiPhy::SetRxGain,
+ &WifiPhy::GetRxGain),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxPowerLevels",
+ "Number of transmission power levels available between "
+ "TxPowerBase and TxPowerEnd included.",
+ Uinteger (1),
+ MakeUintegerAccessor (&WifiPhy::m_nTxPower),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("TxPowerEnd",
+ "Maximum available transmission level (dbm).",
+ Double (16.0206),
+ MakeDoubleAccessor (&WifiPhy::SetTxPowerEnd,
+ &WifiPhy::GetTxPowerEnd),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxPowerStart",
+ "Minimum available transmission level (dbm).",
+ Double (16.0206),
+ MakeDoubleAccessor (&WifiPhy::SetTxPowerStart,
+ &WifiPhy::GetTxPowerStart),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("RxNoise",
+ "Ratio of energy lost by receiver (dB).",
+ Double (7),
+ MakeDoubleAccessor (&WifiPhy::SetRxNoise,
+ &WifiPhy::GetRxNoise),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("Standard", "XXX",
+ Enum (WIFI_PHY_STANDARD_80211a),
+ MakeEnumAccessor (&WifiPhy::SetStandard),
+ MakeEnumChecker (WIFI_PHY_STANDARD_80211a, "802.11a",
+ WIFI_PHY_STANDARD_holland, "holland"))
+ .AddTraceSource ("State",
+ "The WifiPhy state",
+ MakeTraceSourceAccessor (&WifiPhy::m_stateLogger))
+ ;
+ return tid;
+}
+
+WifiPhy::WifiPhy ()
+ : m_syncing (false),
m_endTx (Seconds (0)),
m_endSync (Seconds (0)),
m_endCcaBusy (Seconds (0)),
@@ -192,12 +249,22 @@
m_startSync (Seconds (0)),
m_startCcaBusy (Seconds (0)),
m_previousStateChangeTime (Seconds (0)),
- m_device (device),
m_endSyncEvent (),
- m_random (0.0, 1.0),
- m_standard (WifiDefaultParameters::GetPhyStandard ())
+ m_random (0.0, 1.0)
+{}
+
+WifiPhy::~WifiPhy ()
{
- switch (m_standard) {
+ m_channel = 0;
+ m_events.clear ();
+ m_modes.clear ();
+}
+
+void
+WifiPhy::SetStandard (enum WifiPhyStandard standard)
+{
+ m_standard = standard;
+ switch (standard) {
case WIFI_PHY_STANDARD_80211a:
Configure80211a ();
break;
@@ -210,40 +277,84 @@
}
}
-WifiPhy::~WifiPhy ()
+
+void
+WifiPhy::SetRxNoise (double db)
+{
+ m_rxNoiseRatio = DbToRatio (db);
+}
+void
+WifiPhy::SetTxPowerStart (double start)
{
- m_channel = 0;
- m_events.clear ();
- m_modes.clear ();
+ m_txPowerBaseDbm = start;
+}
+void
+WifiPhy::SetTxPowerEnd (double end)
+{
+ m_txPowerEndDbm = end;
+}
+void
+WifiPhy::SetNTxPower (uint32_t n)
+{
+ m_nTxPower = n;
+}
+void
+WifiPhy::SetTxGain (double gain)
+{
+ m_txGainDb = gain;
}
-
-Ptr<WifiNetDevice>
-WifiPhy::GetDevice (void) const
+void
+WifiPhy::SetRxGain (double gain)
+{
+ m_rxGainDb = gain;
+}
+void
+WifiPhy::SetEdThreshold (double threshold)
+{
+ m_edThresholdW = DbmToW (threshold);
+}
+double
+WifiPhy::GetRxNoise (void) const
{
- return m_device;
+ return RatioToDb (m_rxNoiseRatio);
+}
+double
+WifiPhy::GetTxPowerStart (void) const
+{
+ return m_txPowerBaseDbm;
+}
+double
+WifiPhy::GetTxPowerEnd (void) const
+{
+ return m_txPowerEndDbm;
+}
+double
+WifiPhy::GetTxGain (void) const
+{
+ return m_txGainDb;
+}
+double
+WifiPhy::GetRxGain (void) const
+{
+ return m_rxGainDb;
}
-Ptr<TraceResolver>
-WifiPhy::GetTraceResolver (void) const
+double
+WifiPhy::GetEdThreshold (void) const
{
- Ptr<CompositeTraceResolver> resolver =
- Create<CompositeTraceResolver> ();
- resolver->AddSource ("state",
- TraceDoc ("The WifiPhy state",
- "Time", "start time",
- "Time", "duration",
- "enum WifiPhy::State", "the state of the PHY layer."),
- m_stateLogger);
- resolver->SetParentResolver (Object::GetTraceResolver ());
- return resolver;
+ return WToDbm (m_edThresholdW);
}
+Ptr<WifiChannel>
+WifiPhy::GetChannel (void) const
+{
+ return m_channel;
+}
void
WifiPhy::SetChannel (Ptr<WifiChannel> channel)
{
m_channel = channel;
- m_channel->Add (m_device, MakeCallback (&WifiPhy::ReceivePacket, this));
}
void
@@ -257,10 +368,10 @@
m_syncErrorCallback = callback;
}
void
-WifiPhy::ReceivePacket (Ptr<Packet> packet,
- double rxPowerDbm,
- WifiMode txMode,
- enum WifiPreamble preamble)
+WifiPhy::StartReceivePacket (Ptr<Packet> packet,
+ double rxPowerDbm,
+ WifiMode txMode,
+ enum WifiPreamble preamble)
{
rxPowerDbm += m_rxGainDb;
double rxPowerW = DbmToW (rxPowerDbm);
@@ -361,7 +472,7 @@
Time txDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
NotifyTxStart (txDuration);
SwitchToTx (txDuration);
- m_channel->Send (m_device, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble);
+ m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble);
}
uint32_t
@@ -375,7 +486,7 @@
return m_modes[mode];
}
uint32_t
-WifiPhy::GetNTxpower (void) const
+WifiPhy::GetNTxPower (void) const
{
return m_nTxPower;
}
@@ -611,6 +722,18 @@
}
double
+WifiPhy::WToDbm (double w) const
+{
+ return 10.0 * log10(w * 1000.0);
+}
+
+double
+WifiPhy::RatioToDb (double ratio) const
+{
+ return 10.0 * log10(ratio);
+}
+
+double
WifiPhy::GetEdThresholdW (void) const
{
return m_edThresholdW;
@@ -1113,7 +1236,7 @@
}
Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (plcpPreambleDelayUs);
Time plcpPayloadStart = plcpHeaderStart +
- Seconds (m_plcpHeaderLength / headerMode.GetDataRate ());
+ Seconds ((m_plcpHeaderLength + 0.0) / headerMode.GetDataRate ());
double noiseInterferenceW = (*j).GetDelta ();
double powerW = event->GetRxPowerW ();
--- a/src/devices/wifi/wifi-phy.h Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/wifi-phy.h Sat Mar 01 21:21:53 2008 +0100
@@ -28,7 +28,7 @@
#include "ns3/event-id.h"
#include "ns3/packet.h"
#include "ns3/object.h"
-#include "ns3/callback-trace-source.h"
+#include "ns3/traced-callback.h"
#include "ns3/nstime.h"
#include "ns3/ptr.h"
#include "ns3/random-variable.h"
@@ -120,17 +120,30 @@
*/
typedef Callback<void,Ptr<Packet>, double> SyncErrorCallback;
+ static TypeId GetTypeId (void);
+
+ WifiPhy ();
+ virtual ~WifiPhy ();
+
+ void SetStandard (enum WifiPhyStandard standard);
+ void SetRxNoise (double ratio);
+ void SetTxPowerStart (double start);
+ void SetTxPowerEnd (double end);
+ void SetNTxPower (uint32_t n);
+ void SetTxGain (double gain);
+ void SetRxGain (double gain);
+ void SetEdThreshold (double threshold);
+ double GetRxNoise (void) const;
+ double GetTxPowerStart (void) const;
+ double GetTxPowerEnd (void) const;
/**
- * \param device the device which contains this PHY.
- *
- * Create a new PHY layer instance initialized with values
- * coming from \valueref{WifiPhyEnergyDetectionThreshold},
- * \valueref{WifiPhyRxNoise}, \valueref{WifiPhyTxPowerBase},
- * \valueref{WifiPhyTxPowerEnd}, \valueref{WifiPhyTxPowerLevels},
- * \valueref{WifiPhyTxGain}, and, \valueref{WifiPhyRxGain}
+ * \returns the number of tx power levels available for this PHY.
*/
- WifiPhy (Ptr<WifiNetDevice> device);
- virtual ~WifiPhy ();
+ uint32_t GetNTxPower (void) const;
+ double GetTxGain (void) const;
+ double GetRxGain (void) const;
+ double GetEdThreshold (void) const;
+
Ptr<WifiNetDevice> GetDevice (void) const;
@@ -219,10 +232,6 @@
* \returns the mode whose index is specified.
*/
WifiMode GetMode (uint32_t mode) const;
- /**
- * \returns the number of tx power levels available for this PHY.
- */
- uint32_t GetNTxpower (void) const;
/* return snr: W/W */
/**
* \param txMode the transmission mode
@@ -232,6 +241,14 @@
*/
double CalculateSnr (WifiMode txMode, double ber) const;
+ /* rxPower unit is Watt */
+ void StartReceivePacket (Ptr<Packet> packet,
+ double rxPowerDbm,
+ WifiMode mode,
+ WifiPreamble preamble);
+
+ Ptr<WifiChannel> GetChannel (void) const;
+
private:
class NiChange {
public:
@@ -249,8 +266,6 @@
typedef std::vector <NiChange> NiChanges;
private:
- // inherited from ns3::Object.
- virtual Ptr<TraceResolver> GetTraceResolver (void) const;
void Configure80211aParameters (void);
void PrintModes (void) const;
void Configure80211a (void);
@@ -260,6 +275,8 @@
double GetEdThresholdW (void) const;
double DbmToW (double dbm) const;
double DbToRatio (double db) const;
+ double WToDbm (double w) const;
+ double RatioToDb (double ratio) const;
Time GetMaxPacketDuration (void) const;
void CancelRx (void);
double GetPowerDbm (uint8_t power) const;
@@ -297,11 +314,6 @@
uint32_t m, uint32_t dfree,
uint32_t adFree, uint32_t adFreePlusOne) const;
double GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const;
- /* rxPower unit is Watt */
- void ReceivePacket (Ptr<Packet> packet,
- double rxPowerDbm,
- WifiMode mode,
- WifiPreamble preamble);
private:
uint64_t m_txPrepareDelayUs;
uint64_t m_plcpLongPreambleDelayUs;
@@ -330,7 +342,6 @@
Time m_previousStateChangeTime;
Ptr<WifiChannel> m_channel;
- Ptr<WifiNetDevice> m_device;
SyncOkCallback m_syncOkCallback;
SyncErrorCallback m_syncErrorCallback;
Modes m_modes;
@@ -338,7 +349,7 @@
EventId m_endSyncEvent;
Events m_events;
UniformVariable m_random;
- CallbackTraceSource<Time,Time,enum WifiPhy::State> m_stateLogger;
+ TracedCallback<Time,Time,enum WifiPhy::State> m_stateLogger;
WifiPhyStandard m_standard;
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/wifi-remote-station-manager.cc Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,623 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "wifi-remote-station-manager.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/tag.h"
+#include "ns3/boolean.h"
+#include "ns3/uinteger.h"
+#include "ns3/wifi-phy.h"
+
+NS_LOG_COMPONENT_DEFINE ("WifiRemoteStationManager");
+
+namespace ns3 {
+
+/**
+ * _all_ broadcast and multicast frames are transmitted
+ * at the same constant default rate because since we don't
+ * have any kind of feedback from their transmission,
+ * we cannot adjust the rate, so, we pick one which ensures
+ * that all frames reach destination.
+ */
+class NonUnicastWifiRemoteStation : public WifiRemoteStation
+{
+public:
+ NonUnicastWifiRemoteStation (Ptr<WifiRemoteStationManager> stations);
+ virtual void ReportRxOk (double rxSnr, WifiMode txMode);
+ virtual void ReportRtsFailed (void);
+ virtual void ReportDataFailed (void);
+ virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+ virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+ virtual void ReportFinalRtsFailed (void);
+ virtual void ReportFinalDataFailed (void);
+
+private:
+ virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
+ virtual WifiMode DoGetDataMode (uint32_t size);
+ virtual WifiMode DoGetRtsMode (void);
+ Ptr<WifiRemoteStationManager> m_stations;
+};
+
+NonUnicastWifiRemoteStation::NonUnicastWifiRemoteStation (Ptr<WifiRemoteStationManager> stations)
+ : m_stations (stations)
+{
+ RecordDisassociated ();
+}
+void
+NonUnicastWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+{
+ NS_ASSERT (false);
+}
+void
+NonUnicastWifiRemoteStation::ReportRtsFailed (void)
+{
+ NS_ASSERT (false);
+}
+void
+NonUnicastWifiRemoteStation::ReportDataFailed (void)
+{
+ NS_ASSERT (false);
+}
+void
+NonUnicastWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+{
+ NS_ASSERT (false);
+}
+void
+NonUnicastWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+{
+ NS_ASSERT (false);
+}
+void
+NonUnicastWifiRemoteStation::ReportFinalRtsFailed (void)
+{}
+void
+NonUnicastWifiRemoteStation::ReportFinalDataFailed (void)
+{}
+
+WifiMode
+NonUnicastWifiRemoteStation::DoGetDataMode (uint32_t size)
+{
+ WifiMode mode = m_stations->GetBasicMode (0);
+ NS_LOG_DEBUG ("non-unicast size="<<size<<", mode="<<mode);
+ return mode;
+}
+WifiMode
+NonUnicastWifiRemoteStation::DoGetRtsMode (void)
+{
+ NS_ASSERT (false);
+ // theoretically, no rts for broadcast/multicast packets.
+ return m_stations->GetBasicMode (0);
+}
+Ptr<WifiRemoteStationManager>
+NonUnicastWifiRemoteStation::GetManager (void) const
+{
+ return m_stations;
+}
+
+
+} // namespace ns3
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (WifiRemoteStationManager);
+
+TypeId
+WifiRemoteStationManager::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("WifiRemoteStationManager")
+ .SetParent<Object> ()
+ .AddAttribute ("IsLowLatency", "XXX",
+ Boolean (true),
+ MakeBooleanAccessor (&WifiRemoteStationManager::m_isLowLatency),
+ MakeBooleanChecker ())
+ .AddAttribute ("MaxSsrc", "XXX",
+ Uinteger (7),
+ MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSsrc),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("MaxSlrc", "XXX",
+ Uinteger (7),
+ MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSlrc),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("RtsCtsThreshold", "XXX",
+ Uinteger (1500),
+ MakeUintegerAccessor (&WifiRemoteStationManager::m_rtsCtsThreshold),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("FragmentationThreshold", "XXX",
+ Uinteger (1500),
+ MakeUintegerAccessor (&WifiRemoteStationManager::m_fragmentationThreshold),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+ return tid;
+}
+
+WifiRemoteStationManager::WifiRemoteStationManager ()
+ : m_nonUnicast (new NonUnicastWifiRemoteStation (this))
+{}
+
+WifiRemoteStationManager::~WifiRemoteStationManager ()
+{
+ for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++)
+ {
+ delete (*i).second;
+ }
+ m_stations.clear ();
+ delete m_nonUnicast;
+}
+void
+WifiRemoteStationManager::SetupPhy (Ptr<WifiPhy> phy)
+{
+ m_defaultTxMode = phy->GetMode (0);
+ Reset ();
+}
+
+uint32_t
+WifiRemoteStationManager::GetMaxSsrc (void) const
+{
+ return m_maxSsrc;
+}
+uint32_t
+WifiRemoteStationManager::GetMaxSlrc (void) const
+{
+ return m_maxSlrc;
+}
+uint32_t
+WifiRemoteStationManager::GetRtsCtsThreshold (void) const
+{
+ return m_rtsCtsThreshold;
+}
+uint32_t
+WifiRemoteStationManager::GetFragmentationThreshold (void) const
+{
+ return m_fragmentationThreshold;
+}
+void
+WifiRemoteStationManager::SetMaxSsrc (uint32_t maxSsrc)
+{
+ m_maxSsrc = maxSsrc;
+}
+void
+WifiRemoteStationManager::SetMaxSlrc (uint32_t maxSlrc)
+{
+ m_maxSlrc = maxSlrc;
+}
+void
+WifiRemoteStationManager::SetRtsCtsThreshold (uint32_t threshold)
+{
+ m_rtsCtsThreshold = threshold;
+}
+void
+WifiRemoteStationManager::SetFragmentationThreshold (uint32_t threshold)
+{
+ m_fragmentationThreshold = threshold;
+}
+
+WifiRemoteStation *
+WifiRemoteStationManager::Lookup (Mac48Address address)
+{
+ if (address.IsBroadcast () ||
+ address.IsMulticast ())
+ {
+ return m_nonUnicast;
+ }
+ for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++)
+ {
+ if ((*i).first == address)
+ {
+ return (*i).second;
+ }
+ }
+ WifiRemoteStation *station = CreateStation ();
+ station->Reset ();
+ m_stations.push_back (std::make_pair (address, station));
+ return station;
+}
+
+WifiRemoteStation *
+WifiRemoteStationManager::LookupNonUnicast (void)
+{
+ return m_nonUnicast;
+}
+
+WifiMode
+WifiRemoteStationManager::GetDefaultMode (void) const
+{
+ return m_defaultTxMode;
+}
+void
+WifiRemoteStationManager::Reset (void)
+{
+ for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++)
+ {
+ delete i->second;
+ }
+ m_stations.clear ();
+ m_basicModes.clear ();
+ m_basicModes.push_back (m_defaultTxMode);
+ NS_ASSERT (m_defaultTxMode.IsMandatory ());
+}
+void
+WifiRemoteStationManager::AddBasicMode (WifiMode mode)
+{
+ for (uint32_t i = 0; i < GetNBasicModes (); i++)
+ {
+ if (GetBasicMode (i) == mode)
+ {
+ return;
+ }
+ }
+ m_basicModes.push_back (mode);
+}
+uint32_t
+WifiRemoteStationManager::GetNBasicModes (void) const
+{
+ return m_basicModes.size ();
+}
+WifiMode
+WifiRemoteStationManager::GetBasicMode (uint32_t i) const
+{
+ NS_ASSERT (i < m_basicModes.size ());
+ return m_basicModes[i];
+}
+WifiRemoteStationManager::BasicModesIterator
+WifiRemoteStationManager::BeginBasicModes (void) const
+{
+ return m_basicModes.begin ();
+}
+WifiRemoteStationManager::BasicModesIterator
+WifiRemoteStationManager::EndBasicModes (void) const
+{
+ return m_basicModes.end ();
+}
+bool
+WifiRemoteStationManager::IsLowLatency (void) const
+{
+ return m_isLowLatency;
+}
+
+} // namespace ns3
+
+/***************************************************************
+ * Packet Mode Tagger
+ ***************************************************************/
+
+namespace ns3 {
+
+class TxModeTag : public Tag
+{
+public:
+ TxModeTag ();
+ TxModeTag (WifiMode rtsMode, WifiMode dataMode);
+ WifiMode GetRtsMode (void) const;
+ WifiMode GetDataMode (void) const;
+
+ static uint32_t GetUid (void);
+ void Print (std::ostream &os) const;
+ void Serialize (ns3::Buffer::Iterator start) const;
+ uint32_t Deserialize (ns3::Buffer::Iterator start);
+ uint32_t GetSerializedSize (void) const;
+private:
+ WifiMode m_rtsMode;
+ WifiMode m_dataMode;
+};
+
+TxModeTag::TxModeTag ()
+{}
+TxModeTag::TxModeTag (WifiMode rtsMode, WifiMode dataMode)
+ : m_rtsMode (rtsMode),
+ m_dataMode (dataMode)
+{}
+WifiMode
+TxModeTag::GetRtsMode (void) const
+{
+ return m_rtsMode;
+}
+WifiMode
+TxModeTag::GetDataMode (void) const
+{
+ return m_dataMode;
+}
+
+uint32_t
+TxModeTag::GetUid (void)
+{
+ static uint32_t uid = Tag::AllocateUid<TxModeTag> ("ns3.wifi.TxModeTag");
+ return uid;
+}
+void
+TxModeTag::Print (std::ostream &os) const
+{
+ os << "rts="<<m_rtsMode<<" data="<<m_dataMode;
+}
+void
+TxModeTag::Serialize (ns3::Buffer::Iterator start) const
+{}
+uint32_t
+TxModeTag::Deserialize (ns3::Buffer::Iterator start)
+{
+ return 0;
+}
+uint32_t
+TxModeTag::GetSerializedSize (void) const
+{
+ return 0;
+}
+
+} // namespace ns3
+
+
+/***************************************************************
+ * WifiRemoteStation below.
+ ***************************************************************/
+
+namespace ns3 {
+
+WifiRemoteStation::WifiRemoteStation ()
+ : m_state (BRAND_NEW)
+{}
+WifiRemoteStation::~WifiRemoteStation ()
+{}
+
+bool
+WifiRemoteStation::IsBrandNew (void) const
+{
+ return m_state == BRAND_NEW;
+}
+
+bool
+WifiRemoteStation::IsAssociated (void) const
+{
+ return m_state == GOT_ASSOC_TX_OK;
+}
+bool
+WifiRemoteStation::IsWaitAssocTxOk (void) const
+{
+ return m_state == WAIT_ASSOC_TX_OK;
+}
+void
+WifiRemoteStation::RecordWaitAssocTxOk (void)
+{
+ m_state = WAIT_ASSOC_TX_OK;
+}
+void
+WifiRemoteStation::RecordGotAssocTxOk (void)
+{
+ m_state = GOT_ASSOC_TX_OK;
+}
+void
+WifiRemoteStation::RecordGotAssocTxFailed (void)
+{
+ m_state = DISASSOC;
+}
+void
+WifiRemoteStation::RecordDisassociated (void)
+{
+ m_state = DISASSOC;
+}
+
+void
+WifiRemoteStation::Reset (void)
+{
+ m_modes.clear ();
+ AddSupportedMode (GetManager ()->GetDefaultMode ());
+}
+void
+WifiRemoteStation::AddSupportedMode (WifiMode mode)
+{
+ if (IsIn (mode))
+ {
+ return;
+ }
+ m_modes.push_back (mode);
+}
+
+bool
+WifiRemoteStation::IsIn (WifiMode mode) const
+{
+ for (SupportedModes::const_iterator i = m_modes.begin (); i != m_modes.end (); i++)
+ {
+ if ((*i) == mode)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+WifiMode
+WifiRemoteStation::GetControlAnswerMode (WifiMode reqMode)
+{
+ /**
+ * see ieee 802.11e, section 9.6:
+ *
+ * To allow the transmitting STA to calculate the contents of
+ * the Duration/ID field, a STA responding to a received frame
+ * shall transmit its Control Response frame (either CTS or ACK)
+ * frames, other than the Block-Ack control frame, at the highest
+ * rate in the BSSBasicRateSet parameter that is less than or equal
+ * to the rate of the immediately previous frame in the frame
+ * exchange sequence (as defined in 9.79.12) and that is of the
+ * same modulation type as the received frame. If no rate in the
+ * basic rate set meets these conditions, then the control frame
+ * sent in response to a received frame shall be transmitted at
+ * the highest mandatory rate of the PHY that is less than or equal
+ * to the rate of the received frame, and that is of the same
+ * modulation type as the received frame. In addition, the Control
+ * Response frame shall be sent using the same PHY options as the
+ * received frame, unless they conflict with the requirement to use
+ * the BSSBasicRateSet parameter.
+ */
+ WifiMode mode = GetManager ()->GetDefaultMode ();
+ bool found = false;
+
+ // First, search the BSS Basic Rate set
+ for (WifiRemoteStationManager::BasicModesIterator i = GetManager ()->BeginBasicModes ();
+ i != GetManager ()->EndBasicModes (); i++)
+ {
+ if (i->GetPhyRate () > mode.GetPhyRate () &&
+ i->GetPhyRate () <= reqMode.GetPhyRate () &&
+ i->GetModulationType () == reqMode.GetModulationType ())
+ {
+ mode = *i;
+ found = true;
+ }
+ }
+ // no need to search Mandatory rate set because it is included
+ // within the Basic rate set.
+ return mode;
+}
+
+WifiMode
+WifiRemoteStation::GetCtsMode (WifiMode rtsMode)
+{
+ return GetControlAnswerMode (rtsMode);
+}
+WifiMode
+WifiRemoteStation::GetAckMode (WifiMode dataMode)
+{
+ return GetControlAnswerMode (dataMode);
+}
+
+uint32_t
+WifiRemoteStation::GetNSupportedModes (void) const
+{
+ return m_modes.size ();
+}
+WifiMode
+WifiRemoteStation::GetSupportedMode (uint32_t i) const
+{
+ NS_ASSERT (i < m_modes.size ());
+ return m_modes[i];
+}
+void
+WifiRemoteStation::PrepareForQueue (Ptr<const Packet> packet, uint32_t fullPacketSize)
+{
+ if (GetManager ()->IsLowLatency ())
+ {
+ return;
+ }
+ TxModeTag tag = TxModeTag (DoGetRtsMode (), DoGetDataMode (fullPacketSize));
+ packet->AddTag (tag);
+}
+WifiMode
+WifiRemoteStation::GetDataMode (Ptr<const Packet> packet, uint32_t fullPacketSize)
+{
+ if (GetManager ()->IsLowLatency ())
+ {
+ return DoGetDataMode (fullPacketSize);
+ }
+ TxModeTag tag;
+ bool found;
+ found = packet->PeekTag (tag);
+ NS_ASSERT (found);
+ return tag.GetDataMode ();
+}
+WifiMode
+WifiRemoteStation::GetRtsMode (Ptr<const Packet> packet)
+{
+ if (GetManager ()->IsLowLatency ())
+ {
+ return DoGetRtsMode ();
+ }
+ TxModeTag tag;
+ bool found;
+ found = packet->PeekTag (tag);
+ NS_ASSERT (found);
+ return tag.GetRtsMode ();
+}
+
+bool
+WifiRemoteStation::NeedRts (Ptr<const Packet> packet)
+{
+ if (packet->GetSize () > GetManager ()->GetRtsCtsThreshold ())
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+uint32_t
+WifiRemoteStation::GetMaxSsrc (Ptr<const Packet> packet)
+{
+ return GetManager ()->GetMaxSsrc ();
+}
+
+uint32_t
+WifiRemoteStation::GetMaxSlrc (Ptr<const Packet> packet)
+{
+ return GetManager ()->GetMaxSlrc ();
+}
+
+bool
+WifiRemoteStation::NeedFragmentation (Ptr<const Packet> packet)
+{
+ if (packet->GetSize () > GetManager ()->GetFragmentationThreshold ())
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+uint32_t
+WifiRemoteStation::GetNFragments (Ptr<const Packet> packet)
+{
+ uint32_t nFragments = packet->GetSize () / GetManager ()->GetFragmentationThreshold () + 1;
+ return nFragments;
+}
+
+uint32_t
+WifiRemoteStation::GetFragmentSize (Ptr<const Packet> packet, uint32_t fragmentNumber)
+{
+ uint32_t nFragment = GetNFragments (packet);
+ if (fragmentNumber >= nFragment)
+ {
+ return 0;
+ }
+ if (fragmentNumber == nFragment - 1)
+ {
+ uint32_t lastFragmentSize = packet->GetSize () % GetManager ()->GetFragmentationThreshold ();
+ return lastFragmentSize;
+ }
+ else
+ {
+ return GetManager ()->GetFragmentationThreshold ();
+ }
+}
+
+bool
+WifiRemoteStation::IsLastFragment (Ptr<const Packet> packet, uint32_t fragmentNumber)
+{
+ if (fragmentNumber == (GetNFragments (packet) - 1))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+} // namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/wifi-remote-station-manager.h Sat Mar 01 21:21:53 2008 +0100
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef WIFI_REMOTE_STATION_MANAGER_H
+#define WIFI_REMOTE_STATION_MANAGER_H
+
+#include <vector>
+#include <utility>
+#include "ns3/mac48-address.h"
+#include "ns3/packet.h"
+#include "ns3/object.h"
+#include "wifi-mode.h"
+
+namespace ns3 {
+
+class WifiRemoteStation;
+class NonUnicastWifiRemoteStation;
+class WifiPhy;
+
+class WifiRemoteStationManager : public Object
+{
+private:
+ typedef std::vector<WifiMode> BasicModes;
+public:
+ typedef BasicModes::const_iterator BasicModesIterator;
+
+ static TypeId GetTypeId (void);
+
+ WifiRemoteStationManager ();
+ virtual ~WifiRemoteStationManager ();
+
+ virtual void SetupPhy (Ptr<WifiPhy> phy);
+
+ uint32_t GetMaxSsrc (void) const;
+ uint32_t GetMaxSlrc (void) const;
+ uint32_t GetRtsCtsThreshold (void) const;
+ uint32_t GetFragmentationThreshold (void) const;
+ void SetMaxSsrc (uint32_t maxSsrc);
+ void SetMaxSlrc (uint32_t maxSlrc);
+ void SetRtsCtsThreshold (uint32_t threshold);
+ void SetFragmentationThreshold (uint32_t threshold);
+
+ // Invoked in a STA upon dis-association
+ // or in an AP upon reboot
+ void Reset (void);
+ // Invoked in a STA upon association to store
+ // the set of rates which belong to the
+ // BSSBasicRateSet of the associated AP
+ // and which are supported locally.
+ // Invoked in an AP to configure the BSSBasicRateSet
+ void AddBasicMode (WifiMode mode);
+
+ WifiMode GetDefaultMode (void) const;
+ uint32_t GetNBasicModes (void) const;
+ WifiMode GetBasicMode (uint32_t i) const;
+ BasicModesIterator BeginBasicModes (void) const;
+ BasicModesIterator EndBasicModes (void) const;
+
+ bool IsLowLatency (void) const;
+
+ WifiRemoteStation *Lookup (Mac48Address address);
+ WifiRemoteStation *LookupNonUnicast (void);
+private:
+ typedef std::vector <std::pair<Mac48Address, WifiRemoteStation *> > Stations;
+ virtual class WifiRemoteStation *CreateStation (void) = 0;
+ Stations m_stations;
+ WifiMode m_defaultTxMode;
+ NonUnicastWifiRemoteStation *m_nonUnicast;
+ BasicModes m_basicModes;
+ bool m_isLowLatency;
+ uint32_t m_maxSsrc;
+ uint32_t m_maxSlrc;
+ uint32_t m_rtsCtsThreshold;
+ uint32_t m_fragmentationThreshold;
+};
+
+} // namespace ns3
+
+namespace ns3 {
+
+class WifiRemoteStation {
+public:
+ WifiRemoteStation ();
+ virtual ~WifiRemoteStation ();
+
+ // Invoked in an AP upon disassociation of a
+ // specific STA.
+ void Reset (void);
+ // Invoked in a STA or AP to store the set of
+ // modes supported by a destination which is
+ // also supported locally.
+ // The set of supported modes includes
+ // the BSSBasicRateSet.
+ void AddSupportedMode (WifiMode mode);
+
+ bool IsBrandNew (void) const;
+ bool IsAssociated (void) const;
+ bool IsWaitAssocTxOk (void) const;
+ void RecordWaitAssocTxOk (void);
+ void RecordGotAssocTxOk (void);
+ void RecordGotAssocTxFailed (void);
+ void RecordDisassociated (void);
+
+ void PrepareForQueue (Ptr<const Packet> packet, uint32_t fullPacketSize);
+ WifiMode GetDataMode (Ptr<const Packet> packet, uint32_t fullPacketSize);
+ WifiMode GetRtsMode (Ptr<const Packet> packet);
+
+ // reception-related method
+ virtual void ReportRxOk (double rxSnr, WifiMode txMode) = 0;
+
+ // transmission-related methods
+ virtual void ReportRtsFailed (void) = 0;
+ virtual void ReportDataFailed (void) = 0;
+ virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr) = 0;
+ virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr) = 0;
+ virtual void ReportFinalRtsFailed (void) = 0;
+ virtual void ReportFinalDataFailed (void) = 0;
+ virtual bool NeedRts (Ptr<const Packet> packet);
+ virtual uint32_t GetMaxSsrc (Ptr<const Packet> packet);
+ virtual uint32_t GetMaxSlrc (Ptr<const Packet> packet);
+ virtual bool NeedFragmentation (Ptr<const Packet> packet);
+ virtual uint32_t GetNFragments (Ptr<const Packet> packet);
+ virtual uint32_t GetFragmentSize (Ptr<const Packet> packet, uint32_t fragmentNumber);
+ virtual bool IsLastFragment (Ptr<const Packet> packet, uint32_t fragmentNumber);
+
+ WifiMode GetCtsMode (WifiMode rtsMode);
+ WifiMode GetAckMode (WifiMode dataMode);
+
+private:
+ typedef std::vector<WifiMode> SupportedModes;
+ virtual Ptr<WifiRemoteStationManager> GetManager (void) const = 0;
+ virtual WifiMode DoGetDataMode (uint32_t size) = 0;
+ virtual WifiMode DoGetRtsMode (void) = 0;
+protected:
+ uint32_t GetNSupportedModes (void) const;
+ WifiMode GetSupportedMode (uint32_t i) const;
+private:
+ bool IsIn (WifiMode mode) const;
+ WifiMode GetControlAnswerMode (WifiMode reqMode);
+ enum {
+ BRAND_NEW,
+ DISASSOC,
+ WAIT_ASSOC_TX_OK,
+ GOT_ASSOC_TX_OK
+ } m_state;
+ SupportedModes m_modes;
+};
+
+} // namespace ns3
+
+#endif /* MAC_STATIONS_H */
--- a/src/devices/wifi/wscript Sat Mar 01 20:41:08 2008 +0100
+++ b/src/devices/wifi/wscript Sat Mar 01 21:21:53 2008 +0100
@@ -9,35 +9,31 @@
'wifi-mode.cc',
'ssid.cc',
'wifi-phy.cc',
- 'mac-stations.cc',
- 'cr-mac-stations.cc',
- 'arf-mac-stations.cc',
- 'aarf-mac-stations.cc',
'wifi-mac-header.cc',
'wifi-mac-trailer.cc',
- 'wifi-mac-parameters.cc',
'mac-low.cc',
'wifi-mac-queue.cc',
'mac-tx-middle.cc',
'mac-rx-middle.cc',
'dca-txop.cc',
- 'ideal-mac-stations.cc',
- 'mac-high-adhoc.cc',
'supported-rates.cc',
'capability-information.cc',
'status-code.cc',
'mgt-headers.cc',
- 'mac-high-nqap.cc',
- 'mac-high-nqsta.cc',
- 'wifi-net-device.cc',
- 'wifi-default-parameters.cc',
'random-stream.cc',
'dcf-manager.cc',
'dcf-manager-test.cc',
- 'onoe-mac-stations.cc',
- 'amrr-mac-stations.cc',
- 'rraa-mac-stations.cc',
- 'wifi-trace.cc',
+ 'wifi-mac.cc',
+ 'wifi-remote-station-manager.cc',
+ 'adhoc-wifi-mac.cc',
+ 'nqap-wifi-mac.cc',
+ 'nqsta-wifi-mac.cc',
+ 'wifi-net-device.cc',
+ 'arf-wifi-manager.cc',
+ 'aarf-wifi-manager.cc',
+ 'ideal-wifi-manager.cc',
+ 'constant-rate-wifi-manager.cc',
+ 'wifi-helper.cc',
]
headers = bld.create_obj('ns3header')
headers.source = [
@@ -50,4 +46,15 @@
'wifi-phy-standard.h',
'wifi-phy.h',
'wifi-trace.h',
+ 'wifi-remote-station-manager.h',
+ 'arf-wifi-manager.h',
+ 'aarf-wifi-manager.h',
+ 'constant-rate-wifi-manager.h',
+ 'ideal-wifi-manager.h',
+ 'wifi-mac.h',
+ 'adhoc-wifi-mac.h',
+ 'nqsta-wifi-mac.h',
+ 'nqap-wifi-mac.h',
+ 'wifi-phy.h',
+ 'wifi-helper.h',
]