# HG changeset patch # User Mathieu Lacage # Date 1204402913 -3600 # Node ID db72c0e7743e9c522be39d7ead18782ef9ba0691 # Parent 58182a1561cc69c8b475a9b16a02ea437762a565 port wifi model to Attributes diff -r 58182a1561cc -r db72c0e7743e samples/main-adhoc-wifi.cc --- 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 -using namespace ns3; -static uint32_t g_bytesTotal = 0; -static GnuplotDataset *g_output = 0; +NS_LOG_COMPONENT_DEFINE ("Main"); -static Ptr -CreateAdhocNode (Ptr channel, - Vector position, const char *address) +using namespace ns3; + +class Experiment { - Ptr node = CreateObject (); - Ptr device = CreateObject (node, Mac48Address (address)); - node->AddDevice (device); - device->Attach (channel); - Ptr mobility = CreateObject (); - mobility->SetPosition (position); - node->AggregateObject (mobility); - - return node; +public: + Experiment (); + Experiment (std::string name); + GnuplotDataset Run (const WifiHelper &wifi); +private: + void ReceivePacket (Ptr socket, Ptr packet, const Address &address); + void SetPosition (Ptr node, Vector position); + Vector GetPosition (Ptr node); + void AdvancePosition (Ptr node); + Ptr SetupPacketReceive (Ptr 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, Vector position) +void +Experiment::SetPosition (Ptr node, Vector position) { Ptr mobility = node->GetObject (); mobility->SetPosition (position); } -static Vector -GetPosition (Ptr node) +Vector +Experiment::GetPosition (Ptr node) { Ptr mobility = node->GetObject (); return mobility->GetPosition (); } -static void -AdvancePosition (Ptr node) +void +Experiment::AdvancePosition (Ptr 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="< socket, Ptr packet, const Address &address) +void +Experiment::ReceivePacket (Ptr socket, Ptr packet, const Address &address) { - g_bytesTotal += packet->GetSize (); + m_bytesTotal += packet->GetSize (); } -static Ptr -SetupPacketReceive (Ptr node, uint16_t port) +Ptr +Experiment::SetupPacketReceive (Ptr node) { TypeId tid = TypeId::LookupByName ("Packet"); Ptr socketFactory = node->GetObject (tid); Ptr 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 channel = CreateObject (); + NodeContainer c; + c.Create (2); - Ptr a = CreateAdhocNode (channel, - Vector (5.0,0.0,0.0), - "00:00:00:00:00:01"); - Ptr b = CreateAdhocNode (channel, - Vector (0.0, 0.0, 0.0), - "00:00:00:00:00:02"); + NetDeviceContainer devices = wifi.Build (c); + + MobilityHelper mobility; + Ptr positionAlloc = CreateObjectWith (); + 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 app = - CreateObjectWith ("Node", a, + CreateObjectWith ("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 recvSink = SetupPacketReceive (b, 10); + Simulator::Schedule (Seconds (1.5), &Experiment::AdvancePosition, this, c.Get (1)); + Ptr 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); diff -r 58182a1561cc -r db72c0e7743e samples/wscript --- 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']) diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/aarf-wifi-manager.cc --- /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 + */ + +#include "aarf-wifi-manager.h" + +#include "ns3/double.h" +#include "ns3/uinteger.h" + +#define Min(a,b) ((ab)?a:b) + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (AarfWifiManager); + +TypeId +AarfWifiManager::GetTypeId (void) +{ + static TypeId tid = TypeId ("AarfWifiManager") + .SetParent () + .AddConstructor () + .AddAttribute ("SuccessK", "Multiplication factor for the success threshold in the AARF algorithm.", + Double (2.0), + MakeDoubleAccessor (&AarfWifiManager::m_successK), + MakeDoubleChecker ()) + .AddAttribute ("TimerK", + "Multiplication factor for the timer threshold in the AARF algorithm.", + Double (2.0), + MakeDoubleAccessor (&AarfWifiManager::m_timerK), + MakeDoubleChecker ()) + .AddAttribute ("MaxSuccessThreshold", + "Maximum value of the success threshold in the AARF algorithm.", + Uinteger (60), + MakeUintegerAccessor (&AarfWifiManager::m_maxSuccessThreshold), + MakeUintegerChecker ()) + .AddAttribute ("MinTimerThreshold", + "The minimum value for the 'timer' threshold in the AARF algorithm.", + Uinteger (15), + MakeUintegerAccessor (&AarfWifiManager::m_minTimerThreshold), + MakeUintegerChecker ()) + .AddAttribute ("MinSuccessThreshold", + "The minimum value for the success threshold in the AARF algorithm.", + Uinteger (10), + MakeUintegerAccessor (&AarfWifiManager::m_minSuccessThreshold), + MakeUintegerChecker ()) + ; + 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 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 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/aarf-wifi-manager.h --- /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 + */ +#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 IEEE 802.11 Rate Adaptation: + * A Practical Approach, 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 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 */ diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/adhoc-wifi-mac.cc --- /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 + */ + +#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 () + .AddConstructor () + ; + 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 (); + 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 phy) +{ + m_phy = phy; + m_dcfManager->SetupPhyListener (phy); + m_low->SetPhy (phy); +} +void +AdhocWifiMac::SetWifiRemoteStationManager (Ptr stationManager) +{ + m_stationManager = stationManager; + m_dca->SetWifiRemoteStationManager (stationManager); + m_low->SetWifiRemoteStationManager (stationManager); +} +void +AdhocWifiMac::SetForwardUpCallback (Callback, const Mac48Address &> upCallback) +{ + m_upCallback = upCallback; +} +void +AdhocWifiMac::SetLinkUpCallback (Callback linkUp) +{ + // an Adhoc network is always UP. + linkUp (); +} +void +AdhocWifiMac::SetLinkDownCallback (Callback 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 packet, Mac48Address to) +{ + NS_LOG_DEBUG ("enqueue size="<GetSize ()<<", to="<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, WifiMacHeader const *hdr) +{ + NS_LOG_DEBUG ("received size="<GetSize ()<<", from="<GetAddr2 ()); + if (hdr->GetAddr1 ().IsBroadcast () || hdr->GetAddr1 () == GetAddress ()) + { + m_upCallback (packet, hdr->GetAddr2 ()); + } +} + +} // namespace ns3 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/adhoc-wifi-mac.h --- /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 + */ +#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, 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 phy); + virtual void SetWifiRemoteStationManager (Ptr stationManager); + virtual void Enqueue (Ptr packet, Mac48Address to); + virtual void SetForwardUpCallback (Callback, const Mac48Address &> upCallback); + virtual void SetLinkUpCallback (Callback linkUp); + virtual void SetLinkDownCallback (Callback 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, WifiMacHeader const*hdr); + + Ptr m_dca; + Callback,const Mac48Address &> m_upCallback; + Ptr m_stationManager; + Ptr m_phy; + DcfManager *m_dcfManager; + MacRxMiddle *m_rxMiddle; + MacLow *m_low; + Mac48Address m_address; + Ssid m_ssid; +}; + +} // namespace ns3 + +#endif /* ADHOC_WIFI_MAC_H */ diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/arf-wifi-manager.cc --- /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 + */ + +#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 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="<= m_minTimerTimeout); + m_timerTimeout = timerTimeout; +} +void ArfWifiRemoteStation::SetSuccessThreshold (uint32_t successThreshold) +{ + NS_ASSERT (successThreshold >= m_minSuccessThreshold); + m_successThreshold = successThreshold; +} +Ptr +ArfWifiRemoteStation::GetManager (void) const +{ + return m_stations; +} + +NS_OBJECT_ENSURE_REGISTERED (ArfWifiManager); + +TypeId +ArfWifiManager::GetTypeId (void) +{ + static TypeId tid = TypeId ("ArfWifiManager") + .SetParent () + .AddConstructor () + .AddAttribute ("TimerThreshold", "The 'timer' threshold in the ARF algorithm.", + Uinteger (15), + MakeUintegerAccessor (&ArfWifiManager::m_timerThreshold), + MakeUintegerChecker ()) + .AddAttribute ("SuccessThreshold", + "The minimum number of sucessfull transmissions to try a new rate.", + Uinteger (10), + MakeUintegerAccessor (&ArfWifiManager::m_successThreshold), + MakeUintegerChecker ()) + ; + return tid; +} + +ArfWifiManager::ArfWifiManager () +{} +ArfWifiManager::~ArfWifiManager () +{} +WifiRemoteStation * +ArfWifiManager::CreateStation (void) +{ + return new ArfWifiRemoteStation (this, m_timerThreshold, m_successThreshold); +} + +} // namespace ns3 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/arf-wifi-manager.h --- /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 + */ +#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 WaveLAN-II: A High-performance wireless + * LAN for the unlicensed band, 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 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 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 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 */ diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/constant-rate-wifi-manager.cc --- /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 + */ + +#include "constant-rate-wifi-manager.h" + +#include "ns3/string.h" +#include "ns3/assert.h" + +namespace ns3 { + +ConstantRateWifiRemoteStation::ConstantRateWifiRemoteStation (Ptr 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 +ConstantRateWifiRemoteStation::GetManager (void) const +{ + return m_manager; +} + +NS_OBJECT_ENSURE_REGISTERED (ConstantRateWifiManager); + +TypeId +ConstantRateWifiManager::GetTypeId (void) +{ + static TypeId tid = TypeId ("ConstantRateWifiManager") + .SetParent () + .AddConstructor () + .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 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/constant-rate-wifi-manager.h --- /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 + */ +#ifndef CONSTANT_RATE_WIFI_MANAGER_H +#define CONSTANT_RATE_WIFI_MANAGER_H + +#include + +#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 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 GetManager (void) const; + virtual WifiMode DoGetDataMode (uint32_t size); + virtual WifiMode DoGetRtsMode (void); + Ptr m_manager; +}; + +} // namespace ns3 + + + +#endif /* CONSTANT_RATE_WIFI_MANAGER_H */ diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/dca-txop.cc --- 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 () + .AddConstructor () + .AddAttribute ("MinCw", "XXX", + Uinteger (15), + MakeUintegerAccessor (&DcaTxop::SetMinCw, + &DcaTxop::GetMinCw), + MakeUintegerChecker ()) + .AddAttribute ("MaxCw", "XXX", + Uinteger (1023), + MakeUintegerAccessor (&DcaTxop::SetMaxCw, + &DcaTxop::GetMaxCw), + MakeUintegerChecker ()) + .AddAttribute ("Aifsn", "XXX", + Uinteger (2), + MakeUintegerAccessor (&DcaTxop::SetAifsn, + &DcaTxop::GetAifsn), + MakeUintegerChecker ()) + .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 (); 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 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 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 -DcaTxop::GetTraceResolver (void) const -{ - Ptr resolver = - Create (); - 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 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/dca-txop.h --- 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 #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 TxOk; typedef Callback 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 low); - void SetParameters (WifiMacParameters *parameters); - void SetStations (MacStations *stations); - void SetTxMiddle (MacTxMiddle *txMiddle); + void SetManager (DcfManager *manager); + void SetWifiRemoteStationManager (Ptr 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 GetTraceResolver (void) const; Ptr 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 m_queue; MacTxMiddle *m_txMiddle; Ptr m_low; - MacStations *m_stations; - WifiMacParameters *m_parameters; + Ptr m_stationManager; TransmissionListener *m_transmissionListener; RandomStream *m_rng; @@ -164,18 +160,9 @@ bool m_accessOngoing; Ptr m_currentPacket; WifiMacHeader m_currentHdr; - uint32_t m_ssrc; - uint32_t m_slrc; + TracedValue m_ssrc; + TracedValue m_slrc; uint8_t m_fragmentNumber; - - /* 80211-dca-acktimeout - * param1: slrc - */ - CallbackTraceSource m_acktimeoutTrace; - /* 80211-dca-ctstimeout - * param1: ssrc - */ - CallbackTraceSource m_ctstimeoutTrace; }; } //namespace ns3 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/dcf-manager-test.cc --- 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 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/dcf-manager.cc --- 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 #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 phy) +{ + m_phyListener = new PhyListener (this); + phy->RegisterListener (m_phyListener); +} +void +DcfManager::SetupLowListener (Ptr 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 { diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/dcf-manager.h --- 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 phy); + void SetupLowListener (Ptr 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 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/ideal-wifi-manager.cc --- /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 + */ +#include "ideal-wifi-manager.h" +#include "wifi-phy.h" +#include "ns3/assert.h" +#include "ns3/double.h" +#include + +#define noIDEAL_DEBUG 1 + +#ifdef IDEAL_DEBUG +#include +# 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 () + .AddConstructor () + .AddAttribute ("BerThreshold", + "The maximum Bit Error Rate acceptable at any transmission mode", + Double (10e-6), + MakeDoubleAccessor (&IdealWifiManager::m_ber), + MakeDoubleChecker ()) + ; + return tid; +} + +IdealWifiManager::IdealWifiManager () +{} +IdealWifiManager::~IdealWifiManager () +{} + +void +IdealWifiManager::SetupPhy (Ptr 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 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="< + */ +#ifndef IDEAL_MAC_STATIONS_H +#define IDEAL_MAC_STATIONS_H + +#include +#include +#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 A rate-adaptive MAC + * protocol for multihop wireless networks 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 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 > Thresholds; + + double m_ber; + Thresholds m_thresholds; + double m_minSnr; + double m_maxSnr; +}; + +class IdealWifiRemoteStation : public WifiRemoteStation +{ +public: + IdealWifiRemoteStation (Ptr 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 GetManager (void) const; + virtual WifiMode DoGetDataMode (uint32_t size); + virtual WifiMode DoGetRtsMode (void); + + Ptr m_manager; + double m_lastSnr; +}; + +} // namespace ns3 + +#endif /* MAC_STA_H */ diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/mac-low.cc --- 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 device) -{ - m_device = device; -} -Ptr -MacLow::GetDevice (void) const -{ - return m_device; -} void MacLow::SetPhy (Ptr 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 mac) { - m_parameters = parameters; + m_mac = mac; } void -MacLow::SetStations (MacStations *stations) +MacLow::SetWifiRemoteStationManager (Ptr manager) { - m_stations = stations; + m_stationManager = manager; +} +Ptr +MacLow::GetMac (void) +{ + return m_mac; } void -MacLow::SetRxCallback (MacLowRxCallback callback) +MacLow::SetRxCallback (Callback,const WifiMacHeader *> callback) { m_rxCallback = callback; } @@ -389,7 +381,6 @@ MacLow::ReceiveError (Ptr 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="<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="<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 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 -MacLow::GetTraceResolver (void) const -{ - Ptr resolver = - Create (); - resolver->AddSource ("error", - TraceDoc ("Receive a packet with errors", - "Packet", "the packet received"), - m_dropError); - resolver->SetParentResolver (Object::GetTraceResolver ()); - return resolver; -} - } // namespace ns3 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/mac-low.h --- 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 device); void SetPhy (Ptr phy); - void SetStations (MacStations *stations); - void SetParameters (WifiMacParameters *parameters); - Ptr GetDevice (void) const; + void SetMac (Ptr mac); + void SetWifiRemoteStationManager (Ptr manager); + + Ptr 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,const WifiMacHeader *> callback); /** * \param listener listen to NAV events for every incoming * and outgoing packet. @@ -340,19 +338,18 @@ */ void ReceiveError (Ptr packet, double rxSnr); private: - // Inherited from ns3::Object. - virtual Ptr 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 packet, const WifiMacHeader *hdr) const; Time NowUs (void) const; - MacStation *GetStation (Mac48Address to) const; + WifiRemoteStation *GetStation (Mac48Address to) const; void ForwardDown (Ptr packet, WifiMacHeader const *hdr, WifiMode txMode); Time CalculateOverallTxTime (Ptr packet, @@ -386,10 +383,9 @@ void SendCurrentTxPacket (void); void StartDataTxTimers (void); - Ptr m_device; Ptr m_phy; - MacStations *m_stations; - WifiMacParameters *m_parameters; + Ptr m_mac; + Ptr m_stationManager; MacLowRxCallback m_rxCallback; typedef std::vector::const_iterator NavListenersCI; typedef std::vector NavListeners; @@ -413,8 +409,6 @@ Time m_lastNavStart; Time m_lastNavDuration; - - CallbackTraceSource > m_dropError; }; } // namespace ns3 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/nqap-wifi-mac.cc --- /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 + */ +#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 () + .AddConstructor () + .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 (); + 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 (); + 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 phy) +{ + m_phy = phy; +} +void +NqapWifiMac::SetWifiRemoteStationManager (Ptr stationManager) +{ + m_stationManager = stationManager; +} +void +NqapWifiMac::SetForwardUpCallback (Callback, const Mac48Address &> upCallback) +{ + m_upCallback = upCallback; +} +void +NqapWifiMac::SetLinkUpCallback (Callback linkUp) +{ + +} +void +NqapWifiMac::SetLinkDownCallback (Callback 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, Mac48Address from) +{ + m_upCallback (packet, from); +} +void +NqapWifiMac::ForwardDown (Ptr 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 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="< packet = Create (); + 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="< packet = Create (); + 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="< packet = Create (); + 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="<RecordGotAssocTxOk (); + } +} +void +NqapWifiMac::TxFailed (WifiMacHeader const &hdr) +{ + WifiRemoteStation *station = m_stationManager->Lookup (hdr.GetAddr1 ()); + if (hdr.IsAssocResp () && + station->IsWaitAssocTxOk ()) + { + TRACE ("assoc failed with sta="<RecordGotAssocTxFailed (); + } +} +void +NqapWifiMac::Receive (Ptr 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="<GetAddr2 ()); + ForwardUp (packet, hdr->GetAddr2 ()); + } + else + { + TRACE ("forwarding frame from="<GetAddr2 ()<<", to="<GetAddr3 ()); + Ptr 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 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/nqap-wifi-mac.h --- /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 + */ +#ifndef MAC_HIGH_NQAP_H +#define MAC_HIGH_NQAP_H + +#include +#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 phy); + virtual void SetWifiRemoteStationManager (Ptr stationManager); + virtual void Enqueue (Ptr packet, Mac48Address to); + virtual void SetForwardUpCallback (Callback, const Mac48Address &> upCallback); + virtual void SetLinkUpCallback (Callback linkUp); + virtual void SetLinkDownCallback (Callback 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, WifiMacHeader const *hdr); + void ForwardUp (Ptr packet, Mac48Address from); + void ForwardDown (Ptr 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 m_dca; + Ptr m_beaconDca; + Ptr m_stationManager; + Ptr m_phy; + Callback,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 */ diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/nqsta-wifi-mac.cc --- /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 + */ + +#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 () + .AddConstructor () + .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 ()) + ; + 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 (); + 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 phy) +{ + m_phy = phy; +} +void +NqstaWifiMac::SetWifiRemoteStationManager (Ptr stationManager) +{ + m_stationManager = stationManager; +} +void +NqstaWifiMac::SetForwardUpCallback (Callback, const Mac48Address &> upCallback) +{ + m_forwardUp = upCallback; +} +void +NqstaWifiMac::SetLinkUpCallback (Callback linkUp) +{ + m_linkUp = linkUp; +} +void +NqstaWifiMac::SetLinkDownCallback (Callback 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, 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 = Create (); + 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 = Create (); + 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 packet, Mac48Address to) +{ + if (!IsAssociated ()) + { + TryToEnsureAssociated (); + return; + } + //TRACE ("enqueue size="<GetSize ()<<", to="<Queue (packet, hdr); +} + +void +NqstaWifiMac::Receive (Ptr 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 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/nqsta-wifi-mac.h --- /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 + */ +#ifndef NQSTA_WIFI_MAC_H +#define NQSTA_WIFI_MAC_H + +#include + +#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 phy); + virtual void SetWifiRemoteStationManager (Ptr stationManager); + virtual void Enqueue (Ptr packet, Mac48Address to); + virtual void SetForwardUpCallback (Callback, const Mac48Address &> upCallback); + virtual void SetLinkUpCallback (Callback linkUp); + virtual void SetLinkDownCallback (Callback 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, const Mac48Address &address); + void Receive (Ptr 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,const Mac48Address &> m_forwardUp; + Callback m_linkUp; + Callback m_linkDown; + Ptr m_dca; + EventId m_beaconWatchdog; + Time m_beaconWatchdogEnd; + Mac48Address m_bssid; + uint32_t m_maxMissedBeacons; + + Ptr m_phy; + Ptr m_stationManager; + DcfManager *m_dcfManager; + MacRxMiddle *m_rxMiddle; + MacLow *m_low; + Mac48Address m_address; + Ssid m_ssid; +}; + +} // namespace ns3 + + +#endif /* NQSTA_WIFI_MAC_H */ diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-channel.cc --- 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 device, ReceiveCallback callback) +WifiChannel::Add (Ptr device, Ptr phy) { - m_deviceList.push_back (std::make_pair (device, callback)); + m_deviceList.push_back (std::make_pair (device, phy)); } void -WifiChannel::Send (Ptr sender, Ptr packet, double txPowerDbm, +WifiChannel::Send (Ptr sender, Ptr packet, double txPowerDbm, WifiMode wifiMode, WifiPreamble preamble) const { - Ptr senderMobility = sender->GetNode ()->GetObject (); + Ptr senderMobility = 0; + for (DeviceList::const_iterator i = m_deviceList.begin (); i != m_deviceList.end (); i++) + { + if (sender == i->second) + { + senderMobility = i->first->GetNode ()->GetObject (); + 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 receiverMobility = i->first->GetNode ()->GetObject (); Time delay = m_delay->GetDelay (senderMobility, receiverMobility); @@ -83,7 +92,7 @@ WifiChannel::Receive (uint32_t i, Ptr 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 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-channel.h --- 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 device, ReceiveCallback callback); + void Add (Ptr device, Ptr 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 sender, Ptr packet, double txPowerDbm, + void Send (Ptr sender, Ptr packet, double txPowerDbm, WifiMode wifiMode, WifiPreamble preamble) const; private: - typedef std::vector, ReceiveCallback> > DeviceList; + typedef std::vector, Ptr > > DeviceList; void Receive (uint32_t i, Ptr packet, double rxPowerDbm, WifiMode txMode, WifiPreamble preamble) const; /** diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-helper.cc --- /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 channel = CreateObjectWith (); + return Build (c, channel); +} +NetDeviceContainer +WifiHelper::Build (NodeContainer c, Ptr channel) const +{ + NetDeviceContainer devices; + for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++) + { + Ptr node = *i; + Ptr device = CreateObject (); + Ptr manager = m_stationManager.Create (); + Ptr mac = m_mac.Create (); + Ptr phy = m_phy.Create (); + device->Setup (node, mac, phy, manager, channel); + node->AddDevice (device); + devices.Add (device); + NS_LOG_DEBUG ("node="< channel) const; + +private: + ObjectFactory m_stationManager; + ObjectFactory m_mac; + ObjectFactory m_phy; +}; + +} // namespace ns3 + +#endif /* WIFI_HELPER_H */ diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-mac-queue.cc --- 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 () + .AddConstructor () + .AddAttribute ("MaxPacketNumber", "XXX", + Uinteger (400), + MakeUintegerAccessor (&WifiMacQueue::m_maxSize), + MakeUintegerChecker ()) + .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 packet, WifiMacHeader const &hdr) { diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-mac-queue.h --- 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 #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 packet, WifiMacHeader const &hdr); Ptr Dequeue (WifiMacHeader *hdr); diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-mac.cc --- /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 () + .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 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-mac.h --- /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 packet, Mac48Address to) = 0; + virtual void SetWifiPhy (Ptr phy) = 0; + virtual void SetWifiRemoteStationManager (Ptr stationManager) = 0; + virtual void SetForwardUpCallback (Callback, const Mac48Address &> upCallback) = 0; + virtual void SetLinkUpCallback (Callback linkUp) = 0; + virtual void SetLinkDownCallback (Callback 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 */ diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-mode.cc --- 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; } diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-mode.h --- 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 #include #include +#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); diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-net-device.cc --- 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 */ -#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 ("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 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 () + .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, 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 (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 low = CreateObject (); - 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 -WifiNetDevice::CreateDca (uint32_t minCw, uint32_t maxCw, uint32_t aifsn) const + +void +WifiNetDevice::Setup (Ptr node, Ptr mac, Ptr phy, + Ptr manager, + Ptr channel) { - Ptr dca = CreateObject (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 -WifiNetDevice::GetTraceResolver (void) const -{ - Ptr resolver = - Create (); - 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 channel) -{ - m_channel = channel; - m_phy->SetChannel (channel); - NotifyAttached (); -} -void -WifiNetDevice::DoForwardUp (Ptr 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 +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 +WifiNetDevice::GetPhy (void) const { - m_linkUp = true; - if (!m_linkChangeCallback.IsNull ()) - { - m_linkChangeCallback (); - } + return m_phy; } -void -WifiNetDevice::NotifyLinkDown (void) +Ptr +WifiNetDevice::GetRemoteStationManager (void) const { - m_linkUp = false; - m_linkChangeCallback (); + return m_stationManager; } void @@ -381,43 +110,53 @@ Ptr 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 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, const Address& to, uint16_t protocolNumber) +WifiNetDevice::Send(Ptr 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 WifiNetDevice::GetNode (void) const @@ -467,276 +207,35 @@ void WifiNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) { - m_rxCallback = cb; -} - - -/***************************************************** - * Adhoc code - *****************************************************/ - -AdhocWifiNetDevice::AdhocWifiNetDevice (Ptr 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 (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 packet, Mac48Address const &to) +void +WifiNetDevice::ForwardUp (Ptr 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 -AdhocWifiNetDevice::GetTraceResolver (void) const -{ - Ptr resolver = - Create (); - 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, 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 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 -NqstaWifiNetDevice::GetTraceResolver (void) const +WifiNetDevice::LinkDown (void) { - Ptr resolver = - Create (); - resolver->AddComposite ("dca", m_dca); - resolver->SetParentResolver (WifiNetDevice::GetTraceResolver ()); - return resolver; -} - -/***************************************************** - * AP code - *****************************************************/ - - -NqapWifiNetDevice::NqapWifiNetDevice (Ptr 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 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 -NqapWifiNetDevice::GetTraceResolver (void) const -{ - Ptr resolver = - Create (); - resolver->AddComposite ("dca", m_dca); - resolver->AddComposite ("beaconDca", m_beaconDca); - resolver->SetParentResolver (WifiNetDevice::GetTraceResolver ()); - return resolver; + m_linkChange (); + } } } // namespace ns3 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-net-device.h --- 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 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 channel); + + void Setup (Ptr node, Ptr mac, Ptr phy, + Ptr manager, + Ptr channel); + Ptr GetMac (void) const; + Ptr GetPhy (void) const; + Ptr 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 packet, const Mac48Address &to) = 0; - // private helper - void Construct (void); - - CallbackTraceSource, Mac48Address> m_rxLogger; - CallbackTraceSource, Mac48Address> m_txLogger; -protected: - WifiNetDevice (Ptr node, Mac48Address self); - void DoForwardUp (Ptr packet, const Mac48Address &from); - Ptr 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 GetTraceResolver (void) const; - - Ptr m_channel; + void ForwardUp (Ptr packet, const Mac48Address &from); + void LinkUp (void); + void LinkDown (void); + Ptr m_node; Ptr m_phy; - MacStations *m_stations; - Ptr m_low; - MacRxMiddle *m_rxMiddle; - MacTxMiddle *m_txMiddle; - WifiMacParameters *m_parameters; - DcfManager *m_manager; - PhyListener *m_phyListener; - NavListener *m_navListener; - - Ptr m_node; - Mac48Address m_address; - NetDevice::ReceiveCallback m_rxCallback; + Ptr m_mac; + Ptr m_stationManager; + Callback ,Ptr,uint16_t,const Address &> m_forwardUp; + TracedCallback, Mac48Address> m_rxLogger; + TracedCallback, Mac48Address> m_txLogger; uint32_t m_ifIndex; std::string m_name; bool m_linkUp; - Callback 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, 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 packet, Mac48Address const & to); - virtual void NotifyAttached (void); - virtual Ptr GetTraceResolver (void) const; - - Ssid m_ssid; - Ptr 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, 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 packet, Mac48Address const & to); - virtual void NotifyAttached (void); - virtual Ptr GetTraceResolver (void) const; - - Ssid m_ssid; - Ptr 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); - NqapWifiNetDevice (Ptr 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 packet, Mac48Address const & to); - virtual void NotifyAttached (void); - virtual Ptr GetTraceResolver (void) const; - - Ssid m_ssid; - Ptr m_dca; - Ptr m_beaconDca; - MacHighNqap *m_high; + Callback m_linkChange; + mutable uint16_t m_mtu; }; } // namespace ns3 diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-phy.cc --- 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 NS_LOG_COMPONENT_DEFINE ("WifiPhy"); @@ -176,15 +177,71 @@ * The actual WifiPhy class ****************************************************************/ -WifiPhy::WifiPhy (Ptr 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 () + .AddConstructor () + .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 ()) + .AddAttribute ("TxGain", + "Transmission gain (dB).", + Double (1.0), + MakeDoubleAccessor (&WifiPhy::SetTxGain, + &WifiPhy::GetTxGain), + MakeDoubleChecker ()) + .AddAttribute ("RxGain", + "Reception gain (dB).", + Double (1.0), + MakeDoubleAccessor (&WifiPhy::SetRxGain, + &WifiPhy::GetRxGain), + MakeDoubleChecker ()) + .AddAttribute ("TxPowerLevels", + "Number of transmission power levels available between " + "TxPowerBase and TxPowerEnd included.", + Uinteger (1), + MakeUintegerAccessor (&WifiPhy::m_nTxPower), + MakeUintegerChecker ()) + .AddAttribute ("TxPowerEnd", + "Maximum available transmission level (dbm).", + Double (16.0206), + MakeDoubleAccessor (&WifiPhy::SetTxPowerEnd, + &WifiPhy::GetTxPowerEnd), + MakeDoubleChecker ()) + .AddAttribute ("TxPowerStart", + "Minimum available transmission level (dbm).", + Double (16.0206), + MakeDoubleAccessor (&WifiPhy::SetTxPowerStart, + &WifiPhy::GetTxPowerStart), + MakeDoubleChecker ()) + .AddAttribute ("RxNoise", + "Ratio of energy lost by receiver (dB).", + Double (7), + MakeDoubleAccessor (&WifiPhy::SetRxNoise, + &WifiPhy::GetRxNoise), + MakeDoubleChecker ()) + .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 -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 -WifiPhy::GetTraceResolver (void) const +double +WifiPhy::GetEdThreshold (void) const { - Ptr resolver = - Create (); - 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 +WifiPhy::GetChannel (void) const +{ + return m_channel; +} void WifiPhy::SetChannel (Ptr 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, - double rxPowerDbm, - WifiMode txMode, - enum WifiPreamble preamble) +WifiPhy::StartReceivePacket (Ptr 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 (); diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-phy.h --- 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, 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 device); - virtual ~WifiPhy (); + uint32_t GetNTxPower (void) const; + double GetTxGain (void) const; + double GetRxGain (void) const; + double GetEdThreshold (void) const; + Ptr 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, + double rxPowerDbm, + WifiMode mode, + WifiPreamble preamble); + + Ptr GetChannel (void) const; + private: class NiChange { public: @@ -249,8 +266,6 @@ typedef std::vector NiChanges; private: - // inherited from ns3::Object. - virtual Ptr 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, - double rxPowerDbm, - WifiMode mode, - WifiPreamble preamble); private: uint64_t m_txPrepareDelayUs; uint64_t m_plcpLongPreambleDelayUs; @@ -330,7 +342,6 @@ Time m_previousStateChangeTime; Ptr m_channel; - Ptr 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 m_stateLogger; + TracedCallback m_stateLogger; WifiPhyStandard m_standard; }; diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wifi-remote-station-manager.cc --- /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 + */ + +#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 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 GetManager (void) const; + virtual WifiMode DoGetDataMode (uint32_t size); + virtual WifiMode DoGetRtsMode (void); + Ptr m_stations; +}; + +NonUnicastWifiRemoteStation::NonUnicastWifiRemoteStation (Ptr 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="< () + .AddAttribute ("IsLowLatency", "XXX", + Boolean (true), + MakeBooleanAccessor (&WifiRemoteStationManager::m_isLowLatency), + MakeBooleanChecker ()) + .AddAttribute ("MaxSsrc", "XXX", + Uinteger (7), + MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSsrc), + MakeUintegerChecker ()) + .AddAttribute ("MaxSlrc", "XXX", + Uinteger (7), + MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSlrc), + MakeUintegerChecker ()) + .AddAttribute ("RtsCtsThreshold", "XXX", + Uinteger (1500), + MakeUintegerAccessor (&WifiRemoteStationManager::m_rtsCtsThreshold), + MakeUintegerChecker ()) + .AddAttribute ("FragmentationThreshold", "XXX", + Uinteger (1500), + MakeUintegerAccessor (&WifiRemoteStationManager::m_fragmentationThreshold), + MakeUintegerChecker ()) + ; + 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 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 ("ns3.wifi.TxModeTag"); + return uid; +} +void +TxModeTag::Print (std::ostream &os) const +{ + os << "rts="< + */ +#ifndef WIFI_REMOTE_STATION_MANAGER_H +#define WIFI_REMOTE_STATION_MANAGER_H + +#include +#include +#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 BasicModes; +public: + typedef BasicModes::const_iterator BasicModesIterator; + + static TypeId GetTypeId (void); + + WifiRemoteStationManager (); + virtual ~WifiRemoteStationManager (); + + virtual void SetupPhy (Ptr 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 > 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 packet, uint32_t fullPacketSize); + WifiMode GetDataMode (Ptr packet, uint32_t fullPacketSize); + WifiMode GetRtsMode (Ptr 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 packet); + virtual uint32_t GetMaxSsrc (Ptr packet); + virtual uint32_t GetMaxSlrc (Ptr packet); + virtual bool NeedFragmentation (Ptr packet); + virtual uint32_t GetNFragments (Ptr packet); + virtual uint32_t GetFragmentSize (Ptr packet, uint32_t fragmentNumber); + virtual bool IsLastFragment (Ptr packet, uint32_t fragmentNumber); + + WifiMode GetCtsMode (WifiMode rtsMode); + WifiMode GetAckMode (WifiMode dataMode); + +private: + typedef std::vector SupportedModes; + virtual Ptr 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 */ diff -r 58182a1561cc -r db72c0e7743e src/devices/wifi/wscript --- 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', ]