Bug 978: Consolidate Wi-Fi MAC high functionality
This change reorganises the Wi-Fi MAC high classes in attempt to
reduce duplication of functionality that is required for more than one
of the MAC high models. A new class called RegularWifiMac has been
created. This derives from the abstract WifiMac, and is parent of
AdhocWifiMac, StaWifiMac, ApWifiMac, and MeshWifiInterfaceMac. The QoS
and non-QoS class variants are no longer, with a RegularWifiMac
attribute "QosSupported" allowing selection between these two modes of
operation. QosWifiMacHelper and NqosWifiMacHelper continue to work as
previously.
Updates to some regression traces are necessary because the
reorganisation has led to random number streams being initialised in
slightly different orders and thus over-the-air timing changing.
--- a/CHANGES.html Wed Dec 01 08:01:24 2010 -0800
+++ b/CHANGES.html Thu Dec 02 07:51:34 2010 +0000
@@ -60,6 +60,19 @@
<h2>New API:</h2>
<h2>Changes to existing API:</h2>
+<ul>
+<li><b>Consolidation of Wi-Fi MAC high functionality</b>
+<p>Wi-Fi MAC high classes have been reorganised in attempt to
+consolidate shared functionality into a single class. This new class
+is RegularWifiMac, and it derives from the abstract WifiMac, and is
+parent of AdhocWifiMac, StaWifiMac, ApWifiMac, and
+MeshWifiInterfaceMac. The QoS and non-QoS class variants are no
+longer, with a RegularWifiMac attribute "QosSupported" allowing
+selection between these two modes of operation. QosWifiMacHelper and
+NqosWifiMacHelper continue to work as previously, with a
+behind-the-scenes manipulation of the 'afore-mentioned attribute.
+</p>
+</ul>
<h2>Changed behavior:</h2>
<ul>
--- a/RELEASE_NOTES Wed Dec 01 08:01:24 2010 -0800
+++ b/RELEASE_NOTES Thu Dec 02 07:51:34 2010 +0000
@@ -23,6 +23,15 @@
New user-visible features
-------------------------
+ - Wi-Fi MAC high classes have been reorganised in attempt to
+ consolidate shared functionality into a single class. This new
+ class is RegularWifiMac, and it derives from the abstract
+ WifiMac, and is parent of AdhocWifiMac, StaWifiMac, ApWifiMac,
+ and MeshWifiInterfaceMac. The QoS and non-QoS class variants are
+ no longer, with a RegularWifiMac attribute "QosSupported"
+ allowing selection between these two modes of
+ operation.
+
- Support for IEEE 802.11g (specifically, rates with Modulation
Class ERP-OFDM) has been added to the wifi module. The new
WifiModes have names of the form ErpOfdmRatexxMbps, where xx is
@@ -52,6 +61,7 @@
The following lists many of the bugs fixed or small feature additions
since ns-3.9, in many cases referencing the Bugzilla bug number
+ - bug 978 - Consolidate Wi-Fi MAC high functionality
- bug 852 - Add support for 802.11g devices
- bug 892 - WaypointMobilityModel incompatible with MobilityHelper::Install
- bug 893 - Lazy CourseChange notification for WaypointMobilityModel
--- a/doc/manual/attributes.texi Wed Dec 01 08:01:24 2010 -0800
+++ b/doc/manual/attributes.texi Thu Dec 02 07:51:34 2010 +0000
@@ -777,10 +777,10 @@
<default name="ns3::EdcaTxopN::MinCw" value="31"/>
<default name="ns3::EdcaTxopN::MaxCw" value="1023"/>
<default name="ns3::EdcaTxopN::Aifsn" value="3"/>
- <default name="ns3::QstaWifiMac::ProbeRequestTimeout" value="50000000ns"/>
- <default name="ns3::QstaWifiMac::AssocRequestTimeout" value="500000000ns"/>
- <default name="ns3::QstaWifiMac::MaxMissedBeacons" value="10"/>
- <default name="ns3::QstaWifiMac::ActiveProbing" value="false"/>
+ <default name="ns3::StaWifiMac::ProbeRequestTimeout" value="50000000ns"/>
+ <default name="ns3::StaWifiMac::AssocRequestTimeout" value="500000000ns"/>
+ <default name="ns3::StaWifiMac::MaxMissedBeacons" value="10"/>
+ <default name="ns3::StaWifiMac::ActiveProbing" value="false"/>
...
@end example
@end smallformat
--- a/doc/manual/wifi.texi Wed Dec 01 08:01:24 2010 -0800
+++ b/doc/manual/wifi.texi Thu Dec 02 07:51:34 2010 +0000
@@ -46,49 +46,46 @@
@item a set of @strong{Rate control algorithms} used by the MAC low models
@end itemize
-There are presently six @strong{MAC high models}, three for non-QoS MACs and three
-for QoS MACs.
-@itemize @bullet
-@item @strong{non-QoS MACs:}
-@enumerate
-@item a simple adhoc state machine that does not perform any
-kind of beacon generation, probing, or association. This
-state machine is implemented by the @code{ns3::AdhocWifiMac} class.
-@item an active probing and association state machine that handles
-automatic re-association whenever too many beacons are missed
-is implemented by the @code{ns3::NqstaWifiMac} class.
-@item an access point that generates periodic beacons, and that
-accepts every attempt to associate. This AP state machine
-is implemented by the @code{ns3::NqapWifiMac} class.
-@end enumerate
-@item @strong{QoS MACs:}
-@enumerate
-@item a simple adhoc state machine like above but also able to manage QoS traffic.
-This state machine is implemented by @code{ns3::QadhocWifiMac} class.
-@item a station state machine like above but also able to manage QoS traffic.
-Implemented by @code{ns3::QstaWifiMac}.
-@item a QoS access point state machine like above implemented by @code{ns3::QapWifiMac}.
-@end enumerate
-@end itemize
+There are presently three @strong{MAC high models} that provide for
+the three (non-mesh; the mesh equivalent, which is a sibling of these
+with common parent @code{ns3::RegularWifiMac}, is not discussed here)
+Wi-Fi topological elements - Access Point (AP) (implemented in class
+@code{ns3::ApWifiMac}), non-AP Station (STA) (@code{ns3::StaWifiMac}),
+and STA in an Independent Basic Service Set (IBSS - also commonly
+referred to as an ad hoc network) (@code{ns3::AdhocWifiMac}).
-With QoS MAC models is possible to work with traffic belonging to
-four different access classes: @strong{AC_VO} for voice traffic, @strong{AC_VI}
-for video traffic, @strong{AC_BE} for best-effort traffic and @strong{AC_BK}
-for background traffic.
-In order to determine MSDU's access class, every packet forwarded down
-to these MAC layers should be marked using @code{ns3::QosTag} in order to set
-a TID (traffic id) for that packet otherwise it will be considered
-belonging to @strong{AC_BE} access class.
+The simplest of these is @code{ns3::AdhocWifiMac}, which implements a
+Wi-Fi MAC that does not perform any kind of beacon generation,
+probing, or association. The @code{ns3::StaWifiMac} class implements
+an active probing and association state machine that handles automatic
+re-association whenever too many beacons are missed. Finally,
+@code{ns3::ApWifiMac} implements an AP that generates periodic
+beacons, and that accepts every attempt to associate.
+
+These three MAC high models share a common parent in
+@code{ns3::RegularWifiMac}, which exposes, among other MAC
+configuration, an attribute (@code{QosSupported}) that allows
+configuration of 802.11e/WMM-style QoS support. With QoS-enabled MAC
+models it is possible to work with traffic belonging to four different
+Access Categories (ACs): @strong{AC_VO} for voice traffic,
+@strong{AC_VI} for video traffic, @strong{AC_BE} for best-effort
+traffic and @strong{AC_BK} for background traffic. In order for the
+MAC to determine the appropriate AC for an MSDU, packets forwarded
+down to these MAC layers should be marked using @code{ns3::QosTag} in
+order to set a TID (traffic id) for that packet otherwise it will be
+considered belonging to @strong{AC_BE}.
The @strong{MAC low layer} is split into three components:
@enumerate
@item @code{ns3::MacLow} which takes care of RTS/CTS/DATA/ACK transactions.
@item @code{ns3::DcfManager} and @code{ns3::DcfState} which implements the DCF and EDCAF functions.
-@item @code{ns3::DcaTxop} or @code{ns3::EdcaTxopN} which handle the packet queue,
+@item @code{ns3::DcaTxop} and @code{ns3::EdcaTxopN} which handle the packet queue,
packet fragmentation, and packet retransmissions if they are needed.
-@code{ns3::DcaTxop} object is used by non-QoS high MACs. @code{ns3::EdcaTxopN} is
-used by QoS high MACs and performs also QoS operations like 802.11n MSDU
-aggregation.
+The @code{ns3::DcaTxop} object is used by high MACs that are not
+QoS-enabled, and for transmission of frames (e.g., of type Management)
+that the standard says should access the medium using the
+DCF. @code{ns3::EdcaTxopN} is used by QoS-enabled high MACs and also
+performs QoS operations like 802.11n-style MSDU aggregation.
@end enumerate
There are also several @strong{rate control algorithms} that can be used by the Mac low layer:
@@ -198,37 +195,50 @@
@subsection NqosWifiMacHelper and QosWifiMacHelper
-The @code{ns3::NqosWifiMacHelper} and @code{ns3::QosWifiMacHelper} configure an
-object factory to create instances of a @code{ns3::WifiMac}. They are used to
-configure MAC parameters like type of MAC.
-Setting up a non-QoS MAC layers the object we use is @code{ns3::NqosWifiMacHelper}.
-For example the following user code configures a non-QoS MAC sta:
+The @code{ns3::NqosWifiMacHelper} and @code{ns3::QosWifiMacHelper}
+configure an object factory to create instances of a
+@code{ns3::WifiMac}. They are used to configure MAC parameters like
+type of MAC.
+
+The former, @code{ns3::NqosWifiMacHelper}, supports creation of MAC
+instances that do not have 802.11e/WMM-style QoS support enabled.
+
+For example, the following user code configures a non-QoS MAC that
+will be a non-AP STA in an infrastructure network where the AP has
+SSID ``ns-3-ssid''.
+
@smallformat
@example
NqosWifiMacHelper wifiMacHelper = NqosWifiMacHelper::Default ();
Ssid ssid = Ssid ("ns-3-ssid");
- wifiMacHelper.SetType ("ns3::NqstaWifiMac", "Ssid", SsidValue (ssid),
-"ActiveProbing", BooleanValue (false));
+ wifiMacHelper.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
@end example
@end smallformat
-Setting up a QoS MACs we use a @code{ns3::QosWifiMacHelper} instead.
-This object could be also used to set:
+To create MAC instances with QoS support enabled,
+@code{ns3::QosWifiMacHelper} is used in place of
+@code{ns3::NqosWifiMacHelper}. This object can be also used to set:
+
@itemize @bullet
-@item a MSDU aggregator for a particular access class in order to use 802.11n MSDU aggregation feature;
+@item a MSDU aggregator for a particular Access Category (AC) in order to use 802.11n MSDU aggregation feature;
@item block ack parameters like threshold (number of packets for which block ack mechanism should be used) and inactivity timeout.
@end itemize
-A possible user code:
+The following code shows an example use of
+@code{ns3::QosWifiMacHelper} to create an AP with QoS enabled,
+aggregation on AC_VO, and Block Ack on AC_BE:
+
@smallformat
@example
QosWifiMacHelper wifiMacHelper = QosWifiMacHelper::Default ();
- wifiMacHelper.SetType ("ns3::QapWifiMac",
- "Ssid", SsidValue (ssid),
- "BeaconGeneration", BooleanValue (true),
- "BeaconInterval", TimeValue (Seconds (2.5)));
- wifiMacHelper.SetMsduAggregatorForAc (AC_VO, "ns3::MsduStandardAggregator",
- "MaxAmsduSize", UintegerValue (3839));
+ wifiMacHelper.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid),
+ "BeaconGeneration", BooleanValue (true),
+ "BeaconInterval", TimeValue (Seconds (2.5)));
+ wifiMacHelper.SetMsduAggregatorForAc (AC_VO, "ns3::MsduStandardAggregator",
+ "MaxAmsduSize", UintegerValue (3839));
wifiMacHelper.SetBlockAckThresholdForAc (AC_BE, 10);
wifiMacHelper.SetBlockAckInactivityTimeoutForAc (AC_BE, 5);
@end example
--- a/doc/tutorial/building-topologies.texi Wed Dec 01 08:01:24 2010 -0800
+++ b/doc/tutorial/building-topologies.texi Thu Dec 02 07:51:34 2010 +0000
@@ -996,18 +996,23 @@
@verbatim
Ssid ssid = Ssid ("ns-3-ssid");
- mac.SetType ("ns3::NqstaWifiMac",
+ mac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));
@end verbatim
-This code first creates an 802.11 service set identifier (SSID) object that
-will be used to set the value of the ``Ssid'' @code{Attribute} of the MAC
-layer implementation. The particular kind of MAC layer is specified by
-@code{Attribute} as being of the "ns3::NqstaWifiMac" type. This means that
-the MAC will use a ``non-QoS station'' (nqsta) state machine. Finally, the
-``ActiveProbing'' @code{Attribute} is set to false. This means that probe
-requests will not be sent by MACs created by this helper.
+This code first creates an 802.11 service set identifier (SSID) object
+that will be used to set the value of the ``Ssid'' @code{Attribute} of
+the MAC layer implementation. The particular kind of MAC layer that
+will be created by the helper is specified by @code{Attribute} as
+being of the "ns3::StaWifiMac" type. The use of
+@code{NqosWifiMacHelper} will ensure that the ''QosSupported''
+@code{Attribute} for created MAC objects is set false. The combination
+of these two configurations means that the MAC instance next created
+will be a non-QoS non-AP station (STA) in an infrastructure BSS (i.e.,
+a BSS with an AP). Finally, the ``ActiveProbing'' @code{Attribute} is
+set to false. This means that probe requests will not be sent by MACs
+created by this helper.
Once all the station-specific parameters are fully configured, both at the
MAC and PHY layers, we can invoke our now-familiar @code{Install} method to
@@ -1024,16 +1029,19 @@
requirements of the AP.
@verbatim
- mac.SetType ("ns3::NqapWifiMac",
+ mac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid),
"BeaconGeneration", BooleanValue (true),
"BeaconInterval", TimeValue (Seconds (2.5)));
@end verbatim
-In this case, the @code{NqosWifiMacHelper} is going to create MAC layers of the
-``ns3::NqapWifiMac'' (Non-Qos Access Point) type. We set the
-``BeaconGeneration'' @code{Attribute} to true and also set an interval between
-beacons of 2.5 seconds.
+In this case, the @code{NqosWifiMacHelper} is going to create MAC
+layers of the ``ns3::ApWifiMac'', the latter specifying that a MAC
+instance configured as an AP should be created, with the helper type
+implying that the ''QosSupported'' @code{Attribute} should be set to
+false - disabling 802.11e/WMM-style QoS support at created APs. We
+set the ``BeaconGeneration'' @code{Attribute} to true and also set an
+interval between beacons of 2.5 seconds.
The next lines create the single AP which shares the same set of PHY-level
@code{Attributes} (and channel) as the stations:
--- a/examples/mpi/third-distributed.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/mpi/third-distributed.cc Thu Dec 02 07:51:34 2010 +0000
@@ -132,15 +132,15 @@
NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();
Ssid ssid = Ssid ("ns-3-ssid");
- mac.SetType ("ns3::NqstaWifiMac",
- "Ssid", SsidValue (ssid),
- "ActiveProbing", BooleanValue (false));
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
NetDeviceContainer staDevices;
staDevices = wifi.Install (phy, mac, wifiStaNodes);
- mac.SetType ("ns3::NqapWifiMac",
- "Ssid", SsidValue (ssid));
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
NetDeviceContainer apDevices;
apDevices = wifi.Install (phy, mac, wifiApNode);
--- a/examples/tap/tap-wifi-dumbbell.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/tap/tap-wifi-dumbbell.cc Thu Dec 02 07:51:34 2010 +0000
@@ -140,13 +140,13 @@
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
wifi.SetRemoteStationManager ("ns3::ArfWifiManager");
- wifiMac.SetType ("ns3::NqapWifiMac",
+ wifiMac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid));
NetDeviceContainer devicesLeft = wifi.Install (wifiPhy, wifiMac, nodesLeft.Get (0));
- wifiMac.SetType ("ns3::NqstaWifiMac",
- "Ssid", SsidValue (ssid),
+ wifiMac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));
devicesLeft.Add (wifi.Install (wifiPhy, wifiMac, NodeContainer (nodesLeft.Get (1), nodesLeft.Get (2), nodesLeft.Get (3))));
--- a/examples/tutorial/third.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/tutorial/third.cc Thu Dec 02 07:51:34 2010 +0000
@@ -92,15 +92,15 @@
NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();
Ssid ssid = Ssid ("ns-3-ssid");
- mac.SetType ("ns3::NqstaWifiMac",
- "Ssid", SsidValue (ssid),
- "ActiveProbing", BooleanValue (false));
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
NetDeviceContainer staDevices;
staDevices = wifi.Install (phy, mac, wifiStaNodes);
- mac.SetType ("ns3::NqapWifiMac",
- "Ssid", SsidValue (ssid));
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
NetDeviceContainer apDevices;
apDevices = wifi.Install (phy, mac, wifiApNode);
--- a/examples/wireless/mixed-wireless.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/wireless/mixed-wireless.cc Thu Dec 02 07:51:34 2010 +0000
@@ -280,12 +280,13 @@
Ssid ssid = Ssid (ssidString);
wifiInfra.SetRemoteStationManager ("ns3::ArfWifiManager");
// setup stas
- macInfra.SetType ("ns3::NqstaWifiMac",
- "Ssid", SsidValue (ssid),
- "ActiveProbing", BooleanValue (false));
+ macInfra.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
NetDeviceContainer staDevices = wifiInfra.Install (wifiPhy, macInfra, stas);
// setup ap.
- macInfra.SetType ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid));
+ macInfra.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
NetDeviceContainer apDevices = wifiInfra.Install (wifiPhy, macInfra, backbone.Get (i));
// Collect all of these new devices
NetDeviceContainer infraDevices (apDevices, staDevices);
--- a/examples/wireless/mixed-wireless.py Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/wireless/mixed-wireless.py Thu Dec 02 07:51:34 2010 +0000
@@ -230,16 +230,17 @@
wifiPhy.SetChannel(wifiChannel.Create())
wifiInfra.SetRemoteStationManager('ns3::ArfWifiManager')
macInfra = ns3.NqosWifiMacHelper.Default();
- macInfra.SetType("ns3::NqstaWifiMac",
- "Ssid", ns3.SsidValue(ssid),
- "ActiveProbing", ns3.BooleanValue(False))
+ macInfra.SetType("ns3::StaWifiMac",
+ "Ssid", ns3.SsidValue(ssid),
+ "ActiveProbing", ns3.BooleanValue(False))
# setup stas
staDevices = wifiInfra.Install(wifiPhy, macInfra, stas)
# setup ap.
- macInfra.SetType("ns3::NqapWifiMac", "Ssid", ns3.SsidValue(ssid),
- "BeaconGeneration", ns3.BooleanValue(True),
- "BeaconInterval", ns3.TimeValue(ns3.Seconds(2.5)))
+ macInfra.SetType("ns3::ApWifiMac",
+ "Ssid", ns3.SsidValue(ssid),
+ "BeaconGeneration", ns3.BooleanValue(True),
+ "BeaconInterval", ns3.TimeValue(ns3.Seconds(2.5)))
apDevices = wifiInfra.Install(wifiPhy, macInfra, backbone.Get(i))
# Collect all of these new devices
infraDevices = ns3.NetDeviceContainer(apDevices, staDevices)
--- a/examples/wireless/multirate.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/wireless/multirate.cc Thu Dec 02 07:51:34 2010 +0000
@@ -553,7 +553,8 @@
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
Ssid ssid = Ssid ("Testbed");
- wifiMac.SetType ("ns3::AdhocWifiMac", "Ssid", SsidValue(ssid));
+ wifiMac.SetType ("ns3::AdhocWifiMac",
+ "Ssid", SsidValue(ssid));
wifi.SetStandard (WIFI_PHY_STANDARD_holland);
wifi.SetRemoteStationManager (experiment.GetRateManager());
--- a/examples/wireless/simple-wifi-frame-aggregation.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/wireless/simple-wifi-frame-aggregation.cc Thu Dec 02 07:51:34 2010 +0000
@@ -69,17 +69,17 @@
wifi.SetRemoteStationManager ("ns3::AarfWifiManager", "FragmentationThreshold", UintegerValue (2500));
Ssid ssid = Ssid ("ns-3-802.11n");
- mac.SetType ("ns3::QstaWifiMac",
- "Ssid", SsidValue (ssid),
- "ActiveProbing", BooleanValue (false));
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
mac.SetMsduAggregatorForAc (AC_BE, "ns3::MsduStandardAggregator",
"MaxAmsduSize", UintegerValue (3839));
NetDeviceContainer staDevices;
staDevices = wifi.Install (phy, mac, wifiNodes);
- mac.SetType ("ns3::QapWifiMac",
- "Ssid", SsidValue (ssid));
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
mac.SetMsduAggregatorForAc (AC_BE, "ns3::MsduStandardAggregator",
"MaxAmsduSize", UintegerValue (7935));
--- a/examples/wireless/wifi-ap.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/wireless/wifi-ap.cc Thu Dec 02 07:51:34 2010 +0000
@@ -150,12 +150,13 @@
Ssid ssid = Ssid ("wifi-default");
wifi.SetRemoteStationManager ("ns3::ArfWifiManager");
// setup stas.
- wifiMac.SetType ("ns3::NqstaWifiMac",
- "Ssid", SsidValue (ssid),
- "ActiveProbing", BooleanValue (false));
+ wifiMac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
staDevs = wifi.Install (wifiPhy, wifiMac, stas);
// setup ap.
- wifiMac.SetType ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid));
+ wifiMac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
wifi.Install (wifiPhy, wifiMac, ap);
// mobility.
--- a/examples/wireless/wifi-ap.py Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/wireless/wifi-ap.py Thu Dec 02 07:51:34 2010 +0000
@@ -118,14 +118,15 @@
wifiMac = ns3.NqosWifiMacHelper.Default()
# setup stas.
- wifiMac.SetType("ns3::NqstaWifiMac",
- "Ssid", ns3.SsidValue(ssid),
- "ActiveProbing", ns3.BooleanValue(False))
+ wifiMac.SetType("ns3::StaWifiMac",
+ "Ssid", ns3.SsidValue(ssid),
+ "ActiveProbing", ns3.BooleanValue(False))
staDevs = wifi.Install(wifiPhy, wifiMac, stas)
# setup ap.
- wifiMac.SetType("ns3::NqapWifiMac", "Ssid", ns3.SsidValue(ssid),
- "BeaconGeneration", ns3.BooleanValue(True),
- "BeaconInterval", ns3.TimeValue(ns3.Seconds(2.5)))
+ wifiMac.SetType("ns3::ApWifiMac",
+ "Ssid", ns3.SsidValue(ssid),
+ "BeaconGeneration", ns3.BooleanValue(True),
+ "BeaconInterval", ns3.TimeValue(ns3.Seconds(2.5)))
wifi.Install(wifiPhy, wifiMac, ap)
# mobility.
--- a/examples/wireless/wifi-blockack.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/wireless/wifi-blockack.cc Thu Dec 02 07:51:34 2010 +0000
@@ -70,14 +70,17 @@
Ssid ssid ("My-network");
- mac.SetType ("ns3::QstaWifiMac", "Ssid" , SsidValue (ssid), "ActiveProbing", BooleanValue (false));
+ mac.SetType ("ns3::StaWifiMac",
+ "Ssid" , SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
/* setting blockack threshold for sta's BE queue */
mac.SetBlockAckThresholdForAc (AC_BE, 2);
/* setting block inactivity timeout to 3*1024 = 3072 microseconds */
//mac.SetBlockAckInactivityTimeoutForAc (AC_BE, 3);
NetDeviceContainer staDevice = wifi.Install (phy, mac, sta);
- mac.SetType ("ns3::QapWifiMac", "Ssid", SsidValue (ssid));
+ mac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
mac.SetBlockAckThresholdForAc (AC_BE, 0);
NetDeviceContainer apDevice = wifi.Install (phy, mac, ap);
--- a/examples/wireless/wifi-simple-infra.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/wireless/wifi-simple-infra.cc Thu Dec 02 07:51:34 2010 +0000
@@ -154,13 +154,14 @@
// Setup the rest of the upper mac
Ssid ssid = Ssid ("wifi-default");
// setup sta.
- wifiMac.SetType ("ns3::NqstaWifiMac",
+ wifiMac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));
NetDeviceContainer staDevice = wifi.Install (wifiPhy, wifiMac, c.Get(0));
NetDeviceContainer devices = staDevice;
// setup ap.
- wifiMac.SetType ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid));
+ wifiMac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
NetDeviceContainer apDevice = wifi.Install (wifiPhy, wifiMac, c.Get(1));
devices.Add (apDevice);
--- a/examples/wireless/wifi-wired-bridging.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/examples/wireless/wifi-wired-bridging.cc Thu Dec 02 07:51:34 2010 +0000
@@ -127,8 +127,8 @@
// setup the AP.
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (backboneNodes.Get (i));
- wifiMac.SetType ("ns3::NqapWifiMac",
- "Ssid", SsidValue (ssid));
+ wifiMac.SetType ("ns3::ApWifiMac",
+ "Ssid", SsidValue (ssid));
apDev = wifi.Install (wifiPhy, wifiMac, backboneNodes.Get (i));
NetDeviceContainer bridgeDev;
@@ -145,9 +145,9 @@
"Speed", StringValue ("Constant:1.0"),
"Bounds", RectangleValue (Rectangle (wifiX, wifiX+5.0,0.0, (nStas+1)*5.0)));
mobility.Install (sta);
- wifiMac.SetType ("ns3::NqstaWifiMac",
- "Ssid", SsidValue (ssid),
- "ActiveProbing", BooleanValue (false));
+ wifiMac.SetType ("ns3::StaWifiMac",
+ "Ssid", SsidValue (ssid),
+ "ActiveProbing", BooleanValue (false));
staDev = wifi.Install (wifiPhy, wifiMac, sta);
staInterface = ip.Assign (staDev);
--- a/src/contrib/flow-monitor/examples/wifi-olsr-flowmon.py Wed Dec 01 08:01:24 2010 -0800
+++ b/src/contrib/flow-monitor/examples/wifi-olsr-flowmon.py Thu Dec 02 07:51:34 2010 +0000
@@ -44,7 +44,8 @@
wifiPhy.SetChannel(wifiChannel.Create())
ssid = ns3.Ssid("wifi-default")
wifi.SetRemoteStationManager("ns3::ArfWifiManager")
- wifiMac.SetType ("ns3::AdhocWifiMac", "Ssid", ns3.SsidValue(ssid))
+ wifiMac.SetType ("ns3::AdhocWifiMac",
+ "Ssid", ns3.SsidValue(ssid))
internet = ns3.InternetStackHelper()
list_routing = ns3.Ipv4ListRoutingHelper()
--- a/src/devices/mesh/dot11s/airtime-metric.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/src/devices/mesh/dot11s/airtime-metric.cc Thu Dec 02 07:51:34 2010 +0000
@@ -86,9 +86,9 @@
*/
NS_ASSERT (!peerAddress.IsGroup ());
//obtain current rate:
- WifiMode mode = mac->GetStationManager ()->GetDataMode (peerAddress, &m_testHeader, m_testFrame, m_testFrame->GetSize ());
+ WifiMode mode = mac->GetWifiRemoteStationManager ()->GetDataMode (peerAddress, &m_testHeader, m_testFrame, m_testFrame->GetSize ());
//obtain frame error rate:
- double failAvg = mac->GetStationManager ()->GetInfo (peerAddress).GetFrameErrorRate ();
+ double failAvg = mac->GetWifiRemoteStationManager ()->GetInfo (peerAddress).GetFrameErrorRate ();
NS_ASSERT (failAvg < 1.0);
//calculate metric
uint32_t metric = (uint32_t)((double)(/*Overhead + payload*/
Binary file src/devices/mesh/dot11s/test/hwmp-proactive-regression-test-0-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-proactive-regression-test-1-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-proactive-regression-test-2-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-proactive-regression-test-3-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-proactive-regression-test-4-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-reactive-regression-test-0-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-reactive-regression-test-1-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-reactive-regression-test-2-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-reactive-regression-test-3-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-reactive-regression-test-4-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-reactive-regression-test-5-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-simplest-regression-test-0-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-simplest-regression-test-1-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-target-flags-regression-test-0-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-target-flags-regression-test-1-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-target-flags-regression-test-2-1.pcap has changed
Binary file src/devices/mesh/dot11s/test/hwmp-target-flags-regression-test-3-1.pcap has changed
--- a/src/devices/mesh/mesh-wifi-interface-mac.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/src/devices/mesh/mesh-wifi-interface-mac.cc Thu Dec 02 07:51:34 2010 +0000
@@ -45,7 +45,7 @@
MeshWifiInterfaceMac::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::MeshWifiInterfaceMac")
- .SetParent<WifiMac> ()
+ .SetParent<RegularWifiMac> ()
.AddConstructor<MeshWifiInterfaceMac> ()
.AddAttribute ( "BeaconInterval",
"Beacon Interval",
@@ -69,16 +69,6 @@
&MeshWifiInterfaceMac::SetBeaconGeneration, &MeshWifiInterfaceMac::GetBeaconGeneration),
MakeBooleanChecker ()
)
- .AddTraceSource ( "TxOkHeader",
- "The header of successfully transmitted packet",
- MakeTraceSourceAccessor (
- &MeshWifiInterfaceMac::m_txOkCallback)
- )
- .AddTraceSource ( "TxErrHeader",
- "The header of unsuccessfully transmitted packet",
- MakeTraceSourceAccessor (
- &MeshWifiInterfaceMac::m_txErrCallback)
- )
;
return tid;
}
@@ -87,136 +77,17 @@
{
NS_LOG_FUNCTION (this);
- m_rxMiddle = new MacRxMiddle ();
- m_rxMiddle->SetForwardCallback (MakeCallback (&MeshWifiInterfaceMac::Receive, this));
-
- m_low = CreateObject<MacLow> ();
- m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
-
- m_dcfManager = new DcfManager ();
- m_dcfManager->SetupLowListener (m_low);
-
- m_beaconDca = CreateObject<DcaTxop> ();
- m_beaconDca->SetLow (m_low);
- m_beaconDca->SetMinCw (0);
- m_beaconDca->SetMaxCw (0);
- m_beaconDca->SetAifsn (1);
- m_beaconDca->SetManager (m_dcfManager);
-
- // Construct the EDCAFs. The ordering is important - highest
- // priority (see Table 9-1 in IEEE 802.11-2007) must be created
- // first.
- SetQueue (AC_VO);
- SetQueue (AC_VI);
- SetQueue (AC_BE);
- SetQueue (AC_BK);
+ // Let the lower layers know that we are acting as a mesh node
+ SetTypeOfStation (MESH);
}
MeshWifiInterfaceMac::~MeshWifiInterfaceMac ()
{
NS_LOG_FUNCTION (this);
- m_beaconDca = 0;
- m_stationManager = 0;
- m_phy = 0;
- m_low = 0;
}
//-----------------------------------------------------------------------------
// WifiMac inherited
//-----------------------------------------------------------------------------
void
-MeshWifiInterfaceMac::SetSlot (Time slotTime)
-{
- NS_LOG_FUNCTION (this << slotTime);
- m_dcfManager->SetSlot (slotTime);
- m_low->SetSlotTime (slotTime);
- m_slot = slotTime;
-}
-void
-MeshWifiInterfaceMac::SetSifs (Time sifs)
-{
- NS_LOG_FUNCTION (this << sifs);
- m_dcfManager->SetSifs (sifs);
- m_low->SetSifs (sifs);
- m_sifs = sifs;
-}
-void
-MeshWifiInterfaceMac::SetAckTimeout (Time ackTimeout)
-{
- m_low->SetAckTimeout (ackTimeout);
-}
-void
-MeshWifiInterfaceMac::SetCtsTimeout (Time ctsTimeout)
-{
- m_low->SetCtsTimeout (ctsTimeout);
-}
-void
-MeshWifiInterfaceMac::SetPifs (Time pifs)
-{
- NS_LOG_FUNCTION (this << pifs);
- m_pifs = pifs;
-}
-void
-MeshWifiInterfaceMac::SetEifsNoDifs (Time eifsNoDifs)
-{
- NS_LOG_FUNCTION (this << eifsNoDifs);
- m_dcfManager->SetEifsNoDifs (eifsNoDifs);
- m_eifsNoDifs = eifsNoDifs;
-}
-Time
-MeshWifiInterfaceMac::GetSlot () const
-{
- return m_slot;
-}
-Time
-MeshWifiInterfaceMac::GetSifs () const
-{
- return m_sifs;
-}
-Time
-MeshWifiInterfaceMac::GetEifsNoDifs () const
-{
- return m_eifsNoDifs;
-}
-Time
-MeshWifiInterfaceMac::GetAckTimeout () const
-{
- return m_low->GetAckTimeout ();
-}
-Time
-MeshWifiInterfaceMac::GetCtsTimeout () const
-{
- return m_low->GetCtsTimeout ();
-}
-Time
-MeshWifiInterfaceMac::GetPifs () const
-{
- return m_low->GetPifs ();
-}
-void
-MeshWifiInterfaceMac::SetWifiPhy (Ptr<WifiPhy> phy)
-{
- NS_LOG_FUNCTION (this << phy);
- m_phy = phy;
- m_dcfManager->SetupPhyListener (phy);
- m_low->SetPhy (phy);
-}
-Ptr<WifiPhy>
-MeshWifiInterfaceMac::GetWifiPhy () const
-{
- return m_phy;
-}
-void
-MeshWifiInterfaceMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
-{
- NS_LOG_FUNCTION (this << stationManager);
- m_stationManager = stationManager;
- for (Queues::const_iterator i = m_queues.begin (); i != m_queues.end (); i++)
- {
- i->second->SetWifiRemoteStationManager (stationManager);
- }
- m_beaconDca->SetWifiRemoteStationManager (stationManager);
- m_low->SetWifiRemoteStationManager (stationManager);
-}
-void
MeshWifiInterfaceMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
{
NS_LOG_FUNCTION (this << packet << to << from);
@@ -234,72 +105,24 @@
return true;
}
void
-MeshWifiInterfaceMac::SetForwardUpCallback (
- Callback<void, Ptr<Packet> , Mac48Address, Mac48Address> upCallback)
-{
- NS_LOG_FUNCTION (this);
- m_upCallback = upCallback;
-}
-void
MeshWifiInterfaceMac::SetLinkUpCallback (Callback<void> linkUp)
{
NS_LOG_FUNCTION (this);
- if (!linkUp.IsNull ())
- {
- linkUp ();
- }
-}
-void
-MeshWifiInterfaceMac::SetLinkDownCallback (Callback<void> linkDown)
-{
- NS_LOG_FUNCTION (this);
-}
-Mac48Address
-MeshWifiInterfaceMac::GetAddress () const
-{
- return m_address;
-}
-Mac48Address
-MeshWifiInterfaceMac::GetBssid () const
-{
- return m_address;
-}
-Ssid
-MeshWifiInterfaceMac::GetSsid () const
-{
- return m_meshId;
-}
-void
-MeshWifiInterfaceMac::SetAddress (Mac48Address address)
-{
- NS_LOG_FUNCTION (address);
- m_low->SetAddress (address);
- m_address = address;
-}
-void
-MeshWifiInterfaceMac::SetSsid (Ssid ssid)
-{
- NS_LOG_FUNCTION (ssid);
- m_meshId = ssid;
+ RegularWifiMac::SetLinkUpCallback (linkUp);
+
+ // The approach taken here is that, from the point of view of a mesh
+ // node, the link is always up, so we immediately invoke the
+ // callback if one is set
+ linkUp ();
}
void
MeshWifiInterfaceMac::DoDispose ()
{
NS_LOG_FUNCTION (this);
- delete m_rxMiddle;
- delete m_dcfManager;
- //Delete smart pointers:
- m_rxMiddle = 0;
- m_low = 0;
- m_dcfManager = 0;
- m_stationManager = 0;
- m_phy = 0;
- m_queues.clear ();
m_plugins.clear ();
m_beaconSendEvent.Cancel ();
- m_beaconDca = 0;
- WifiMac::DoDispose ();
+ RegularWifiMac::DoDispose ();
}
//-----------------------------------------------------------------------------
// Plugins
@@ -353,16 +176,9 @@
m_dcfManager->NotifyNavResetNow (Seconds (0));
}
//-----------------------------------------------------------------------------
-// Forward frame up/down
+// Forward frame down
//-----------------------------------------------------------------------------
void
-MeshWifiInterfaceMac::ForwardUp (Ptr<Packet> packet, Mac48Address src, Mac48Address dst)
-{
- NS_LOG_FUNCTION (this << packet << src);
- m_upCallback (packet, src, dst);
-}
-
-void
MeshWifiInterfaceMac::ForwardDown (Ptr<const Packet> const_packet, Mac48Address from, Mac48Address to)
{
// copy packet to allow modifications
@@ -418,8 +234,8 @@
}
m_stats.sentFrames++;
m_stats.sentBytes += packet->GetSize ();
- NS_ASSERT (m_queues.find (ac) != m_queues.end ());
- m_queues[ac]->Queue (packet, hdr);
+ NS_ASSERT (m_edca.find (ac) != m_edca.end ());
+ m_edca[ac]->Queue (packet, hdr);
}
void
MeshWifiInterfaceMac::SendManagementFrame (Ptr<Packet> packet, const WifiMacHeader& hdr)
@@ -436,7 +252,7 @@
}
m_stats.sentFrames++;
m_stats.sentBytes += packet->GetSize ();
- if ((m_queues.find (AC_VO) == m_queues.end ()) || (m_queues.find (AC_BK) == m_queues.end ()))
+ if ((m_edca.find (AC_VO) == m_edca.end ()) || (m_edca.find (AC_BK) == m_edca.end ()))
{
NS_FATAL_ERROR ("Voice or Background queue is not set up!");
}
@@ -450,11 +266,11 @@
*/
if (hdr.GetAddr1 () != Mac48Address::GetBroadcast ())
{
- m_queues[AC_VO]->Queue (packet, header);
+ m_edca[AC_VO]->Queue (packet, header);
}
else
{
- m_queues[AC_BK]->Queue (packet, header);
+ m_edca[AC_BK]->Queue (packet, header);
}
}
SupportedRates
@@ -573,7 +389,7 @@
{
(*i)->UpdateBeacon (beacon);
}
- m_beaconDca->Queue (beacon.CreatePacket (), beacon.CreateHeader (GetAddress (), GetMeshPointAddress ()));
+ m_dca->Queue (beacon.CreatePacket (), beacon.CreateHeader (GetAddress (), GetMeshPointAddress ()));
ScheduleNextBeacon ();
}
@@ -639,6 +455,10 @@
{
ForwardUp (packet, hdr->GetAddr4 (), hdr->GetAddr3 ());
}
+
+ // We don't bother invoking RegularWifiMac::Receive() here, because
+ // we've explicitly handled all the frames we care about. This is in
+ // contrast to most classes which derive from RegularWifiMac.
}
uint32_t
MeshWifiInterfaceMac::GetLinkMetric (Mac48Address peerAddress)
@@ -655,11 +475,6 @@
{
m_linkMetricCallback = cb;
}
-Ptr<WifiRemoteStationManager>
-MeshWifiInterfaceMac::GetStationManager ()
-{
- return m_stationManager;
-}
void
MeshWifiInterfaceMac::SetMeshPointAddress (Mac48Address a)
{
@@ -701,71 +516,19 @@
{
m_stats = Statistics ();
}
+
void
-MeshWifiInterfaceMac::SetQueue (AcIndex ac)
-{
- if (m_queues.find (ac) != m_queues.end ())
- {
- NS_LOG_WARN ("Queue is already set!");
- return;
- }
- Ptr<DcaTxop> queue = Create<DcaTxop> ();
- queue->SetLow (m_low);
- queue->SetManager (m_dcfManager);
- queue->SetTxOkCallback (MakeCallback (&MeshWifiInterfaceMac::TxOk, this));
- queue->SetTxFailedCallback (MakeCallback (&MeshWifiInterfaceMac::TxFailed, this));
-
- m_queues.insert (std::make_pair (ac, queue));
-}
-void
-MeshWifiInterfaceMac::TxOk (WifiMacHeader const &hdr)
-{
- m_txOkCallback (hdr);
-}
-void
-MeshWifiInterfaceMac::TxFailed (WifiMacHeader const &hdr)
-{
- m_txErrCallback (hdr);
-}
-void
-MeshWifiInterfaceMac::DoStart ()
-{
- m_beaconDca->Start ();
- for (Queues::iterator i = m_queues.begin (); i != m_queues.end (); i ++)
- {
- i->second->Start ();
- }
- WifiMac::DoStart ();
-}
-
-void
MeshWifiInterfaceMac::FinishConfigureStandard (enum WifiPhyStandard standard)
{
- switch (standard)
- {
- case WIFI_PHY_STANDARD_holland:
- // fall through
- case WIFI_PHY_STANDARD_80211a:
- // fall through
- case WIFI_PHY_STANDARD_80211_10Mhz:
- // fall through
- case WIFI_PHY_STANDARD_80211_5Mhz:
- ConfigureDcf (m_queues[AC_BK], 15, 1023, AC_BK);
- ConfigureDcf (m_queues[AC_BE], 15, 1023, AC_BE);
- ConfigureDcf (m_queues[AC_VI], 15, 1023, AC_VI);
- ConfigureDcf (m_queues[AC_VO], 15, 1023, AC_VO);
- break;
- case WIFI_PHY_STANDARD_80211b:
- ConfigureDcf (m_queues[AC_BK], 31, 1023, AC_BK);
- ConfigureDcf (m_queues[AC_BE], 31, 1023, AC_BE);
- ConfigureDcf (m_queues[AC_VI], 31, 1023, AC_VI);
- ConfigureDcf (m_queues[AC_VO], 31, 1023, AC_VO);
- break;
- default:
- NS_ASSERT (false);
- break;
- }
+ RegularWifiMac::FinishConfigureStandard (standard);
m_standard = standard;
+
+ // We use the single DCF provided by WifiMac for the purpose of
+ // Beacon transmission. For this we need to reconfigure the channel
+ // access parameters slightly, and do so here.
+ m_dca->SetMinCw (0);
+ m_dca->SetMaxCw (0);
+ m_dca->SetAifsn (1);
}
WifiPhyStandard
MeshWifiInterfaceMac::GetPhyStandard () const
--- a/src/devices/mesh/mesh-wifi-interface-mac.h Wed Dec 01 08:01:24 2010 -0800
+++ b/src/devices/mesh/mesh-wifi-interface-mac.h Thu Dec 02 07:51:34 2010 +0000
@@ -30,7 +30,7 @@
#include "ns3/packet.h"
#include "ns3/nstime.h"
#include "ns3/wifi-remote-station-manager.h"
-#include "ns3/wifi-mac.h"
+#include "ns3/regular-wifi-mac.h"
#include "ns3/mesh-wifi-interface-mac-plugin.h"
#include "ns3/event-id.h"
#include "qos-utils.h"
@@ -38,10 +38,6 @@
class WifiMacHeader;
class DcaTxop;
-class WifiPhy;
-class DcfManager;
-class MacRxMiddle;
-class MacLow;
/**
* \ingroup mesh
*
@@ -53,7 +49,7 @@
* - management and priority traffic.
*
*/
-class MeshWifiInterfaceMac : public WifiMac
+class MeshWifiInterfaceMac : public RegularWifiMac
{
public:
/// Never forget to support typeid
@@ -65,34 +61,11 @@
///\name Inherited from WifiMac
//\{
- virtual void SetSlot (Time slotTime);
- virtual void SetSifs (Time sifs);
- virtual void SetPifs (Time pifs);
- virtual void SetCtsTimeout (Time ctsTimeout);
- virtual void SetAckTimeout (Time ackTimeout);
- virtual void SetEifsNoDifs (Time eifsNoDifs);
- virtual Time GetSlot () const;
- virtual Time GetSifs () const;
- virtual Time GetPifs () const;
- virtual Time GetCtsTimeout () const;
- virtual Time GetAckTimeout () const;
- virtual Time GetEifsNoDifs () const;
- virtual void SetWifiPhy (Ptr<WifiPhy> phy);
- virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
virtual bool SupportsSendFrom () const;
- virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
virtual void SetLinkUpCallback (Callback<void> linkUp);
- virtual void SetLinkDownCallback (Callback<void> linkDown);
- virtual Mac48Address GetAddress () const;
- virtual Mac48Address GetBssid () const;
- virtual Ssid GetSsid () const;
- virtual void SetAddress (Mac48Address address);
- virtual void SetSsid (Ssid ssid);
//\}
- ///Needed to obtain phy to calculate TX-duration
- Ptr<WifiPhy> GetWifiPhy () const;
///\name Each mesh point interfaces must know the mesh point address
//\{
void SetMeshPointAddress (Mac48Address);
@@ -152,26 +125,19 @@
///\{
void SetLinkMetricCallback (Callback<uint32_t, Mac48Address, Ptr<MeshWifiInterfaceMac> > cb);
uint32_t GetLinkMetric (Mac48Address peerAddress);
- Ptr<WifiRemoteStationManager> GetStationManager ();
///\}
///\brief Statistics:
void Report (std::ostream &) const;
void ResetStats ();
/// Enable/disable beacons
void SetBeaconGeneration (bool enable);
- void SetQueue (AcIndex ac);
WifiPhyStandard GetPhyStandard () const;
virtual void FinishConfigureStandard (enum WifiPhyStandard standard);
private:
/// Frame receive handler
void Receive (Ptr<Packet> packet, WifiMacHeader const *hdr);
- /// Forward frame to mesh point
- virtual void ForwardUp (Ptr<Packet> packet, Mac48Address src, Mac48Address dst);
/// Send frame. Frame is supposed to be tagged by routing information. TODO: clarify this point
void ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to);
- // Notify about tx OK/Error frames:
- void TxOk (WifiMacHeader const &hdr);
- void TxFailed (WifiMacHeader const &hdr);
/// Send beacon
void SendBeacon ();
/// Schedule next beacon
@@ -180,30 +146,9 @@
bool GetBeaconGeneration () const;
/// Real d-tor
virtual void DoDispose ();
- ///Initiator at t=0
- void DoStart ();
private:
- typedef std::map<AcIndex, Ptr<DcaTxop> > Queues;
typedef std::vector<Ptr<MeshWifiInterfaceMacPlugin> > PluginList;
- ///\name Wifi MAC internals
- //\{
- Queues m_queues;
- Ptr<DcaTxop> m_beaconDca;
- Ptr<WifiRemoteStationManager> m_stationManager;
- Ptr<WifiPhy> m_phy;
- Callback<void, Ptr<Packet> , Mac48Address, Mac48Address> m_upCallback;
- //\}
-
- ///\name Wifi timing intervals
- //\{
- Time m_slot;
- Time m_sifs;
- Time m_pifs;
- Time m_ackTimeout;
- Time m_ctsTimeout;
- Time m_eifsNoDifs;
- //\}
///\name Mesh timing intervals
//\{
@@ -215,18 +160,8 @@
Time m_tbtt;
//\}
- /// DCF implementation
- DcfManager* m_dcfManager;
- /// Middle MAC sublayer
- MacRxMiddle* m_rxMiddle;
- /// Low MAC sublayer
- Ptr<MacLow> m_low;
- /// My address
- Mac48Address m_address;
/// Mesh point address
Mac48Address m_mpAddress;
- /// SSID
- Ssid m_meshId;
/// "Timer" for the next beacon
EventId m_beaconSendEvent;
@@ -248,8 +183,6 @@
};
Statistics m_stats;
///\}
- TracedCallback<WifiMacHeader const &> m_txOkCallback;
- TracedCallback<WifiMacHeader const &> m_txErrCallback;
/// Current PHY standard: needed to configure metric
WifiPhyStandard m_standard;
};
--- a/src/devices/wifi/adhoc-wifi-mac.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/src/devices/wifi/adhoc-wifi-mac.cc Thu Dec 02 07:51:34 2010 +0000
@@ -1,9 +1,10 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2005 INRIA
+ * Copyright (c) 2006, 2009 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
*
* 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
+ * 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,
@@ -16,19 +17,24 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
*/
-
#include "adhoc-wifi-mac.h"
-#include "dca-txop.h"
+
+#include "ns3/pointer.h"
+#include "ns3/log.h"
+#include "ns3/string.h"
+#include "ns3/boolean.h"
+#include "ns3/trace-source-accessor.h"
+
+#include "qos-tag.h"
#include "mac-low.h"
+#include "dcf-manager.h"
#include "mac-rx-middle.h"
-#include "wifi-phy.h"
-#include "dcf-manager.h"
-#include "wifi-mac-trailer.h"
-#include "ns3/pointer.h"
-#include "ns3/packet.h"
-#include "ns3/log.h"
-#include "ns3/trace-source-accessor.h"
+#include "mac-tx-middle.h"
+#include "msdu-aggregator.h"
+#include "amsdu-subframe-header.h"
+#include "mgt-headers.h"
NS_LOG_COMPONENT_DEFINE ("AdhocWifiMac");
@@ -36,204 +42,50 @@
NS_OBJECT_ENSURE_REGISTERED (AdhocWifiMac);
-#undef NS_LOG_APPEND_CONTEXT
-#define NS_LOG_APPEND_CONTEXT if (m_low != 0) {std::clog << "[mac=" << m_low->GetAddress () << "] ";}
-
-TypeId
+TypeId
AdhocWifiMac::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::AdhocWifiMac")
- .SetParent<WifiMac> ()
+ .SetParent<RegularWifiMac> ()
.AddConstructor<AdhocWifiMac> ()
- .AddAttribute ("DcaTxop", "The DcaTxop object",
- PointerValue (),
- MakePointerAccessor (&AdhocWifiMac::GetDcaTxop),
- MakePointerChecker<DcaTxop> ())
- .AddTraceSource ( "TxOkHeader",
- "The header of successfully transmitted packet",
- MakeTraceSourceAccessor (&AdhocWifiMac::m_txOkCallback))
- .AddTraceSource ("TxErrHeader",
- "The header of unsuccessfully transmitted packet",
- MakeTraceSourceAccessor (&AdhocWifiMac::m_txErrCallback))
;
return tid;
}
AdhocWifiMac::AdhocWifiMac ()
{
- m_rxMiddle = new MacRxMiddle ();
- m_rxMiddle->SetForwardCallback (MakeCallback (&AdhocWifiMac::ForwardUp, this));
-
- m_low = CreateObject<MacLow> ();
- m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
- m_low->SetBssid (GetBssid ());
+ NS_LOG_FUNCTION (this);
- m_dcfManager = new DcfManager ();
- m_dcfManager->SetupLowListener (m_low);
-
- m_dca = CreateObject<DcaTxop> ();
- m_dca->SetLow (m_low);
- m_dca->SetManager (m_dcfManager);
- m_dca->SetTxFailedCallback (MakeCallback (&AdhocWifiMac::TxFailed, this));
+ // Let the lower layers know that we are acting in an IBSS
+ SetTypeOfStation (ADHOC_STA);
}
+
AdhocWifiMac::~AdhocWifiMac ()
-{}
-
-void
-AdhocWifiMac::DoDispose (void)
{
- delete m_rxMiddle;
- delete m_dcfManager;
- m_rxMiddle = 0;
- m_dcfManager = 0;
- m_low = 0;
- m_phy = 0;
- m_dca = 0;
- m_stationManager = 0;
- WifiMac::DoDispose ();
+ NS_LOG_FUNCTION (this);
}
-void
-AdhocWifiMac::SetSlot (Time slotTime)
-{
- m_dcfManager->SetSlot (slotTime);
- m_low->SetSlotTime (slotTime);
-}
-void
-AdhocWifiMac::SetSifs (Time sifs)
-{
- m_dcfManager->SetSifs (sifs);
- m_low->SetSifs (sifs);
-}
-void
-AdhocWifiMac::SetEifsNoDifs (Time eifsNoDifs)
-{
- m_dcfManager->SetEifsNoDifs (eifsNoDifs);
-}
-void
-AdhocWifiMac::SetAckTimeout (Time ackTimeout)
-{
- m_low->SetAckTimeout (ackTimeout);
-}
-void
-AdhocWifiMac::SetCtsTimeout (Time ctsTimeout)
-{
- m_low->SetCtsTimeout (ctsTimeout);
-}
-void
-AdhocWifiMac::SetPifs (Time pifs)
-{
- m_low->SetPifs (pifs);
-}
-Time
-AdhocWifiMac::GetSlot (void) const
-{
- return m_low->GetSlotTime ();
-}
-Time
-AdhocWifiMac::GetSifs (void) const
-{
- return m_low->GetSifs ();
-}
-Time
-AdhocWifiMac::GetEifsNoDifs (void) const
-{
- return m_dcfManager->GetEifsNoDifs ();
-}
-Time
-AdhocWifiMac::GetAckTimeout (void) const
-{
- return m_low->GetAckTimeout ();
-}
-Time
-AdhocWifiMac::GetCtsTimeout (void) const
-{
- return m_low->GetCtsTimeout ();
-}
-Time
-AdhocWifiMac::GetPifs (void) const
-{
- return m_low->GetPifs ();
-}
-void
-AdhocWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
-{
- m_phy = phy;
- m_dcfManager->SetupPhyListener (phy);
- m_low->SetPhy (phy);
-}
-void
-AdhocWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
-{
- m_stationManager = stationManager;
- m_dca->SetWifiRemoteStationManager (stationManager);
- m_low->SetWifiRemoteStationManager (stationManager);
-}
-void
-AdhocWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
-{
- m_upCallback = upCallback;
-}
-void
-AdhocWifiMac::SetLinkUpCallback (Callback<void> linkUp)
-{
- // an Adhoc network is always UP.
- linkUp ();
-}
-void
-AdhocWifiMac::SetLinkDownCallback (Callback<void> linkDown)
-{}
-Mac48Address
-AdhocWifiMac::GetAddress (void) const
-{
- return m_low->GetAddress ();
-}
-Ssid
-AdhocWifiMac::GetSsid (void) const
-{
- return m_ssid;
-}
-Mac48Address
-AdhocWifiMac::GetBssid (void) const
-{
- return m_low->GetBssid ();
-}
-void
+void
AdhocWifiMac::SetAddress (Mac48Address address)
{
- m_low->SetAddress (address);
- m_low->SetBssid (address);
- // XXX the bssid should be generated by the procedure
- // described in ieee802.11 section 11.1.3
-}
-void
-AdhocWifiMac::SetSsid (Ssid ssid)
-{
- // XXX: here, we should start a special adhoc network
- m_ssid = ssid;
+ // In an IBSS, the BSSID is supposed to be generated per Section
+ // 11.1.3 of IEEE 802.11. We don't currently do this - instead we
+ // make an IBSS STA a bit like an AP, with the BSSID for frames
+ // transmitted by each STA set to that STA's address.
+ //
+ // This is why we're overriding this method.
+ RegularWifiMac::SetAddress (address);
+ RegularWifiMac::SetBssid (address);
}
-void
-AdhocWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
-{
- NS_FATAL_ERROR ("Adhoc does not support a from != m_low->GetAddress ()");
-}
-void
+void
AdhocWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
{
- NS_LOG_FUNCTION (packet->GetSize () << to);
- WifiMacHeader hdr;
- hdr.SetType (WIFI_MAC_DATA);
- hdr.SetAddr1 (to);
- hdr.SetAddr2 (m_low->GetAddress ());
- hdr.SetAddr3 (GetBssid ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
-
+ NS_LOG_FUNCTION (this << packet << to);
if (m_stationManager->IsBrandNew (to))
{
- // in adhoc mode, we assume that every destination
- // supports all the rates we support.
+ // In ad hoc mode, we assume that every destination supports all
+ // the rates we support.
for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
{
m_stationManager->AddSupportedMode (to, m_phy->GetMode (i));
@@ -241,65 +93,99 @@
m_stationManager->RecordDisassociated (to);
}
- m_dca->Queue (packet, hdr);
-}
-bool
-AdhocWifiMac::SupportsSendFrom (void) const
-{
- return false;
-}
+ WifiMacHeader hdr;
+
+ // If we are not a QoS STA then we definitely want to use AC_BE to
+ // transmit the packet. A TID of zero will map to AC_BE (through \c
+ // QosUtilsMapTidToAc()), so we use that as our default here.
+ uint8_t tid = 0;
+
+ // For now, a STA that supports QoS does not support non-QoS
+ // associations, and vice versa. In future the STA model should fall
+ // back to non-QoS if talking to a peer that is also non-QoS. At
+ // that point there will need to be per-station QoS state maintained
+ // by the association state machine, and consulted here.
+ if (m_qosSupported)
+ {
+ hdr.SetType (WIFI_MAC_QOSDATA);
+ hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+ hdr.SetQosNoEosp ();
+ hdr.SetQosNoAmsdu ();
+ // Transmission of multiple frames in the same TXOP is not
+ // supported for now
+ hdr.SetQosTxopLimit (0);
-void
-AdhocWifiMac::ForwardUp (Ptr<Packet> packet, const WifiMacHeader *hdr)
-{
- NS_LOG_DEBUG ("received size="<<packet->GetSize ()<<", from="<<hdr->GetAddr2 ());
- m_upCallback (packet, hdr->GetAddr2 (), hdr->GetAddr1 ());
-}
-Ptr<DcaTxop>
-AdhocWifiMac::GetDcaTxop(void) const
-{
- return m_dca;
+ // Fill in the QoS control field in the MAC header
+ tid = QosUtilsGetTidForPacket (packet);
+ // Any value greater than 7 is invalid and likely indicates that
+ // the packet had no QoS tag, so we revert to zero, which'll
+ // mean that AC_BE is used.
+ if (tid >= 7)
+ {
+ tid = 0;
+ }
+ hdr.SetQosTid (tid);
+ }
+ else
+ {
+ hdr.SetTypeData ();
+ }
+
+ hdr.SetAddr1 (to);
+ hdr.SetAddr2 (m_low->GetAddress ());
+ hdr.SetAddr3 (GetBssid ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+
+ if (m_qosSupported)
+ {
+ // Sanity check that the TID is valid
+ NS_ASSERT (tid < 8);
+ m_edca[QosUtilsMapTidToAc (tid)]->Queue (packet, hdr);
+ }
+ else
+ {
+ m_dca->Queue (packet, hdr);
+ }
}
-void
-AdhocWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard)
+void
+AdhocWifiMac::SetLinkUpCallback (Callback<void> linkUp)
{
- switch (standard)
+ NS_LOG_FUNCTION (this);
+ RegularWifiMac::SetLinkUpCallback (linkUp);
+
+ // The approach taken here is that, from the point of view of a STA
+ // in IBSS mode, the link is always up, so we immediately invoke the
+ // callback if one is set
+ linkUp ();
+}
+
+void
+AdhocWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
+{
+ NS_LOG_FUNCTION (this << packet << hdr);
+ NS_ASSERT (!hdr->IsCtl ());
+ Mac48Address from = hdr->GetAddr2 ();
+ Mac48Address to = hdr->GetAddr1 ();
+ if (hdr->IsData ())
{
- case WIFI_PHY_STANDARD_holland:
- // fall through
- case WIFI_PHY_STANDARD_80211_10Mhz:
- // fall through
- case WIFI_PHY_STANDARD_80211_5Mhz:
- // fall through
- case WIFI_PHY_STANDARD_80211a:
- // fall through
- case WIFI_PHY_STANDARD_80211g:
- ConfigureDcf (m_dca, 15, 1023, AC_BE_NQOS);
- break;
- case WIFI_PHY_STANDARD_80211b:
- ConfigureDcf (m_dca, 31, 1023, AC_BE_NQOS);
- break;
- default:
- NS_ASSERT (false);
- break;
+ if (hdr->IsQosData () && hdr->IsQosAmsdu ())
+ {
+ NS_LOG_DEBUG ("Received A-MSDU from"<<from);
+ DeaggregateAmsduAndForward (packet, hdr);
+ }
+ else
+ {
+ ForwardUp (packet, from, to);
+ }
+ return;
}
-}
-void
-AdhocWifiMac::TxOk (const WifiMacHeader &hdr)
-{
- m_txOkCallback (hdr);
-}
-void
-AdhocWifiMac::TxFailed (const WifiMacHeader &hdr)
-{
- m_txErrCallback (hdr);
-}
-void
-AdhocWifiMac::DoStart ()
-{
- m_dca->Start ();
- WifiMac::DoStart ();
+
+ // Invoke the receive handler of our parent class to deal with any
+ // other frames. Specifically, this will handle Block Ack-related
+ // Management Action frames.
+ RegularWifiMac::Receive (packet, hdr);
}
} // namespace ns3
--- a/src/devices/wifi/adhoc-wifi-mac.h Wed Dec 01 08:01:24 2010 -0800
+++ b/src/devices/wifi/adhoc-wifi-mac.h Thu Dec 02 07:51:34 2010 +0000
@@ -1,9 +1,10 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2005 INRIA
+ * Copyright (c) 2006, 2009 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
*
* 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
+ * 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,
@@ -16,91 +17,47 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
*/
#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"
+#include "regular-wifi-mac.h"
+
+#include "amsdu-subframe-header.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
+class AdhocWifiMac : public RegularWifiMac
{
public:
- typedef Callback<void, Ptr<Packet>, const Mac48Address &> ForwardCallback;
-
static TypeId GetTypeId (void);
AdhocWifiMac ();
- ~AdhocWifiMac ();
+ virtual ~AdhocWifiMac ();
+
+ /**
+ * \param address the current address of this MAC layer.
+ */
+ virtual void SetAddress (Mac48Address address);
- // all inherited from WifiMac base class.
- virtual void SetSlot (Time slotTime);
- virtual void SetSifs (Time sifs);
- virtual void SetEifsNoDifs (Time eifsNoDifs);
- virtual void SetAckTimeout (Time ackTimeout);
- virtual void SetCtsTimeout (Time ctsTimeout);
- virtual void SetPifs (Time pifs);
- virtual Time GetSlot (void) const;
- virtual Time GetSifs (void) const;
- virtual Time GetEifsNoDifs (void) const;
- virtual Time GetAckTimeout (void) const;
- virtual Time GetCtsTimeout (void) const;
- virtual Time GetPifs (void) const;
- virtual void SetWifiPhy (Ptr<WifiPhy> phy);
- virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
- virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
+ /**
+ * \param linkUp the callback to invoke when the link becomes up.
+ */
+ virtual void SetLinkUpCallback (Callback<void> linkUp);
+
+ /**
+ * \param packet the packet to send.
+ * \param to the address to which the packet should be sent.
+ *
+ * The packet should be enqueued in a tx queue, and should be
+ * dequeued as soon as the channel access function determines that
+ * access is granted to this MAC.
+ */
virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
- virtual bool SupportsSendFrom (void) const;
- virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
- virtual void SetLinkUpCallback (Callback<void> linkUp);
- virtual void SetLinkDownCallback (Callback<void> linkDown);
- virtual Mac48Address GetAddress (void) const;
- virtual Ssid GetSsid (void) const;
- virtual void SetAddress (Mac48Address address);
- virtual void SetSsid (Ssid ssid);
- virtual Mac48Address GetBssid (void) const;
private:
- // inherited from Object base class.
- virtual void DoDispose (void);
- void DoStart ();
- /* invoked by the MacLows. */
- void ForwardUp (Ptr<Packet> packet, const WifiMacHeader *hdr);
- AdhocWifiMac (const AdhocWifiMac & ctor_arg);
- AdhocWifiMac &operator = (const AdhocWifiMac &o);
- Ptr<DcaTxop> GetDcaTxop(void) const;
- void TxOk (const WifiMacHeader &hdr);
- void TxFailed (const WifiMacHeader &hdr);
- virtual void FinishConfigureStandard (enum WifiPhyStandard standard);
- Ptr<DcaTxop> m_dca;
- Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> m_upCallback;
- Ptr<WifiRemoteStationManager> m_stationManager;
- Ptr<WifiPhy> m_phy;
- DcfManager *m_dcfManager;
- MacRxMiddle *m_rxMiddle;
- Ptr<MacLow> m_low;
- Ssid m_ssid;
- TracedCallback<const WifiMacHeader &> m_txOkCallback;
- TracedCallback<const WifiMacHeader &> m_txErrCallback;
+ virtual void Receive (Ptr<Packet> packet, const WifiMacHeader *hdr);
};
} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/ap-wifi-mac.cc Thu Dec 02 07:51:34 2010 +0000
@@ -0,0 +1,578 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "ap-wifi-mac.h"
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/string.h"
+#include "ns3/pointer.h"
+#include "ns3/boolean.h"
+
+#include "qos-tag.h"
+#include "wifi-phy.h"
+#include "dcf-manager.h"
+#include "mac-rx-middle.h"
+#include "mac-tx-middle.h"
+#include "mgt-headers.h"
+#include "mac-low.h"
+#include "amsdu-subframe-header.h"
+#include "msdu-aggregator.h"
+
+NS_LOG_COMPONENT_DEFINE ("ApWifiMac");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (ApWifiMac);
+
+TypeId
+ApWifiMac::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::ApWifiMac")
+ .SetParent<RegularWifiMac> ()
+ .AddConstructor<ApWifiMac> ()
+ .AddAttribute ("BeaconInterval", "Delay between two beacons",
+ TimeValue (MicroSeconds (102400)),
+ MakeTimeAccessor (&ApWifiMac::GetBeaconInterval,
+ &ApWifiMac::SetBeaconInterval),
+ MakeTimeChecker ())
+ .AddAttribute ("BeaconGeneration", "Whether or not beacons are generated.",
+ BooleanValue (true),
+ MakeBooleanAccessor (&ApWifiMac::SetBeaconGeneration,
+ &ApWifiMac::GetBeaconGeneration),
+ MakeBooleanChecker ())
+ ;
+ return tid;
+}
+
+ApWifiMac::ApWifiMac ()
+{
+ NS_LOG_FUNCTION (this);
+ m_beaconDca = CreateObject<DcaTxop> ();
+ m_beaconDca->SetAifsn(1);
+ m_beaconDca->SetMinCw(0);
+ m_beaconDca->SetMaxCw(0);
+ m_beaconDca->SetLow (m_low);
+ m_beaconDca->SetManager (m_dcfManager);
+
+ // Let the lower layers know that we are acting as an AP.
+ SetTypeOfStation (AP);
+
+ m_enableBeaconGeneration = false;
+}
+
+ApWifiMac::~ApWifiMac ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+ApWifiMac::DoDispose ()
+{
+ NS_LOG_FUNCTION (this);
+ m_beaconDca = 0;
+ m_enableBeaconGeneration = false;
+ m_beaconEvent.Cancel ();
+ RegularWifiMac::DoDispose ();
+}
+
+void
+ApWifiMac::SetAddress (Mac48Address address)
+{
+ // As an AP, our MAC address is also the BSSID. Hence we are
+ // overriding this function and setting both in our parent class.
+ RegularWifiMac::SetAddress (address);
+ RegularWifiMac::SetBssid (address);
+}
+
+void
+ApWifiMac::SetBeaconGeneration (bool enable)
+{
+ NS_LOG_FUNCTION (this << enable);
+ if (!enable)
+ {
+ m_beaconEvent.Cancel ();
+ }
+ else if (enable && !m_enableBeaconGeneration)
+ {
+ m_beaconEvent = Simulator::ScheduleNow (&ApWifiMac::SendOneBeacon, this);
+ }
+ m_enableBeaconGeneration = enable;
+}
+
+bool
+ApWifiMac::GetBeaconGeneration (void) const
+{
+ return m_enableBeaconGeneration;
+}
+
+Time
+ApWifiMac::GetBeaconInterval (void) const
+{
+ return m_beaconInterval;
+}
+
+void
+ApWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
+{
+ NS_LOG_FUNCTION (this << stationManager);
+ m_beaconDca->SetWifiRemoteStationManager (stationManager);
+ RegularWifiMac::SetWifiRemoteStationManager (stationManager);
+}
+
+void
+ApWifiMac::SetLinkUpCallback (Callback<void> linkUp)
+{
+ NS_LOG_FUNCTION (this);
+ RegularWifiMac::SetLinkUpCallback (linkUp);
+
+ // The approach taken here is that, from the point of view of an AP,
+ // the link is always up, so we immediately invoke the callback if
+ // one is set
+ linkUp ();
+}
+
+void
+ApWifiMac::SetBeaconInterval (Time interval)
+{
+ NS_LOG_FUNCTION (this << interval);
+ if ((interval.GetMicroSeconds () % 1024) != 0)
+ {
+ NS_LOG_WARN ("beacon interval should be multiple of 1024us, see IEEE Std. 802.11-2007, section 11.1.1.1");
+ }
+ m_beaconInterval = interval;
+}
+
+void
+ApWifiMac::StartBeaconing (void)
+{
+ NS_LOG_FUNCTION (this);
+ SendOneBeacon ();
+}
+
+void
+ApWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from,
+ Mac48Address to)
+{
+ // If we are not a QoS AP then we definitely want to use AC_BE to
+ // transmit the packet. A TID of zero will map to AC_BE (through \c
+ // QosUtilsMapTidToAc()), so we use that as our default here.
+ uint8_t tid = 0;
+
+ // If we are a QoS AP then we attempt to get a TID for this packet
+ if (m_qosSupported)
+ {
+ tid = QosUtilsGetTidForPacket (packet);
+ // Any value greater than 7 is invalid and likely indicates that
+ // the packet had no QoS tag, so we revert to zero, which'll
+ // mean that AC_BE is used.
+ if (tid >= 7)
+ {
+ tid = 0;
+ }
+ }
+
+ ForwardDown (packet, from, to, tid);
+}
+
+void
+ApWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from,
+ Mac48Address to, uint8_t tid)
+{
+ NS_LOG_FUNCTION (this << packet << from << to);
+ WifiMacHeader hdr;
+
+ // For now, an AP that supports QoS does not support non-QoS
+ // associations, and vice versa. In future the AP model should
+ // support simultaneously associated QoS and non-QoS STAs, at which
+ // point there will need to be per-association QoS state maintained
+ // by the association state machine, and consulted here.
+ if (m_qosSupported)
+ {
+ hdr.SetType (WIFI_MAC_QOSDATA);
+ hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+ hdr.SetQosNoEosp ();
+ hdr.SetQosNoAmsdu ();
+ // Transmission of multiple frames in the same TXOP is not
+ // supported for now
+ hdr.SetQosTxopLimit (0);
+ // Fill in the QoS control field in the MAC header
+ hdr.SetQosTid (tid);
+ }
+ else
+ {
+ hdr.SetTypeData ();
+ }
+
+ hdr.SetAddr1 (to);
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (from);
+ hdr.SetDsFrom ();
+ hdr.SetDsNotTo ();
+
+ if (m_qosSupported)
+ {
+ // Sanity check that the TID is valid
+ NS_ASSERT (tid < 8);
+ m_edca[QosUtilsMapTidToAc (tid)]->Queue (packet, hdr);
+ }
+ else
+ {
+ m_dca->Queue (packet, hdr);
+ }
+}
+
+void
+ApWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
+{
+ NS_LOG_FUNCTION (this << packet << to << from);
+ if (to.IsBroadcast () || m_stationManager->IsAssociated (to))
+ {
+ ForwardDown (packet, from, to);
+ }
+}
+
+void
+ApWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
+{
+ // We're sending this packet with a from address that is our own. We
+ // get that address from the lower MAC and make use of the
+ // from-spoofing Enqueue() method to avoid duplicated code.
+ Enqueue (packet, to, m_low->GetAddress ());
+}
+
+bool
+ApWifiMac::SupportsSendFrom (void) const
+{
+ return true;
+}
+
+SupportedRates
+ApWifiMac::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
+ApWifiMac::SendProbeResp (Mac48Address to)
+{
+ NS_LOG_FUNCTION (this << to);
+ WifiMacHeader hdr;
+ hdr.SetProbeResp ();
+ hdr.SetAddr1 (to);
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetAddress ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Ptr<Packet> packet = Create<Packet> ();
+ MgtProbeResponseHeader probe;
+ probe.SetSsid (GetSsid ());
+ probe.SetSupportedRates (GetSupportedRates ());
+ probe.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
+ packet->AddHeader (probe);
+
+ // The standard is not clear on the correct queue for management
+ // frames if we are a QoS AP. The approach taken here is to always
+ // use the DCF for these regardless of whether we have a QoS
+ // association or not.
+ m_dca->Queue (packet, hdr);
+}
+
+void
+ApWifiMac::SendAssocResp (Mac48Address to, bool success)
+{
+ NS_LOG_FUNCTION (this << to << success);
+ WifiMacHeader hdr;
+ hdr.SetAssocResp ();
+ hdr.SetAddr1 (to);
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetAddress ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Ptr<Packet> packet = Create<Packet> ();
+ MgtAssocResponseHeader assoc;
+ StatusCode code;
+ if (success)
+ {
+ code.SetSuccess ();
+ }
+ else
+ {
+ code.SetFailure ();
+ }
+ assoc.SetSupportedRates (GetSupportedRates ());
+ assoc.SetStatusCode (code);
+ packet->AddHeader (assoc);
+
+ // The standard is not clear on the correct queue for management
+ // frames if we are a QoS AP. The approach taken here is to always
+ // use the DCF for these regardless of whether we have a QoS
+ // association or not.
+ m_dca->Queue (packet, hdr);
+}
+
+void
+ApWifiMac::SendOneBeacon (void)
+{
+ NS_LOG_FUNCTION (this);
+ WifiMacHeader hdr;
+ hdr.SetBeacon ();
+ hdr.SetAddr1 (Mac48Address::GetBroadcast ());
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetAddress ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Ptr<Packet> packet = Create<Packet> ();
+ MgtBeaconHeader beacon;
+ beacon.SetSsid (GetSsid ());
+ beacon.SetSupportedRates (GetSupportedRates ());
+ beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
+
+ packet->AddHeader (beacon);
+
+ // The beacon has it's own special queue, so we load it in there
+ m_beaconDca->Queue (packet, hdr);
+ m_beaconEvent = Simulator::Schedule (m_beaconInterval, &ApWifiMac::SendOneBeacon, this);
+}
+
+void
+ApWifiMac::TxOk (const WifiMacHeader &hdr)
+{
+ NS_LOG_FUNCTION (this);
+ RegularWifiMac::TxOk (hdr);
+
+ if (hdr.IsAssocResp () &&
+ m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
+ {
+ NS_LOG_DEBUG ("associated with sta="<<hdr.GetAddr1 ());
+ m_stationManager->RecordGotAssocTxOk (hdr.GetAddr1 ());
+ }
+}
+
+void
+ApWifiMac::TxFailed (const WifiMacHeader &hdr)
+{
+ NS_LOG_FUNCTION (this);
+ RegularWifiMac::TxFailed (hdr);
+
+ if (hdr.IsAssocResp () &&
+ m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
+ {
+ NS_LOG_DEBUG ("assoc failed with sta="<<hdr.GetAddr1 ());
+ m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ());
+ }
+}
+
+void
+ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
+{
+ NS_LOG_FUNCTION (this << packet << hdr);
+
+ Mac48Address from = hdr->GetAddr2 ();
+
+ if (hdr->IsData ())
+ {
+ Mac48Address bssid = hdr->GetAddr1 ();
+ if (!hdr->IsFromDs () &&
+ hdr->IsToDs () &&
+ bssid == GetAddress () &&
+ m_stationManager->IsAssociated (from))
+ {
+ Mac48Address to = hdr->GetAddr3 ();
+ if (to == GetAddress ())
+ {
+ NS_LOG_DEBUG ("frame for me from="<<from);
+ if (hdr->IsQosData ())
+ {
+ if (hdr->IsQosAmsdu ())
+ {
+ NS_LOG_DEBUG ("Received A-MSDU from="<<from<<", size="<<packet->GetSize ());
+ DeaggregateAmsduAndForward (packet, hdr);
+ packet = 0;
+ }
+ else
+ {
+ ForwardUp (packet, from, bssid);
+ }
+ }
+ else
+ {
+ ForwardUp (packet, from, bssid);
+ }
+ }
+ else if (to.IsGroup () ||
+ m_stationManager->IsAssociated (to))
+ {
+ NS_LOG_DEBUG ("forwarding frame from="<<from<<", to="<<to);
+ Ptr<Packet> copy = packet->Copy ();
+
+ // If the frame we are forwarding is of type QoS Data,
+ // then we need to preserve the UP in the QoS control
+ // header...
+ if (hdr->IsQosData ())
+ {
+ ForwardDown (packet, from, to, hdr->GetQosTid ());
+ }
+ else
+ {
+ ForwardDown (packet, from, to);
+ }
+ ForwardUp (copy, from, to);
+ }
+ else
+ {
+ ForwardUp (packet, from, to);
+ }
+ }
+ else if (hdr->IsFromDs () &&
+ hdr->IsToDs ())
+ {
+ // this is an AP-to-AP frame
+ // we ignore for now.
+ NotifyRxDrop (packet);
+ }
+ else
+ {
+ // we can ignore these frames since
+ // they are not targeted at the AP
+ NotifyRxDrop (packet);
+ }
+ return;
+ }
+ else if (hdr->IsMgt ())
+ {
+ if (hdr->IsProbeReq ())
+ {
+ NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ());
+ SendProbeResp (from);
+ return;
+ }
+ 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 ()))
+ {
+ m_stationManager->AddSupportedMode (from, mode);
+ }
+ }
+ m_stationManager->RecordWaitAssocTxOk (from);
+ // send assoc response with success status.
+ SendAssocResp (hdr->GetAddr2 (), true);
+ }
+ return;
+ }
+ else if (hdr->IsDisassociation ())
+ {
+ m_stationManager->RecordDisassociated (from);
+ return;
+ }
+ }
+ }
+
+ // Invoke the receive handler of our parent class to deal with any
+ // other frames. Specifically, this will handle Block Ack-related
+ // Management Action frames.
+ RegularWifiMac::Receive (packet, hdr);
+}
+
+void
+ApWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket,
+ const WifiMacHeader *hdr)
+{
+ MsduAggregator::DeaggregatedMsdus packets =
+ MsduAggregator::Deaggregate (aggregatedPacket);
+
+ for (MsduAggregator::DeaggregatedMsdusCI i = packets.begin ();
+ i != packets.end (); ++i)
+ {
+ if ((*i).second.GetDestinationAddr () == GetAddress ())
+ {
+ ForwardUp ((*i).first, (*i).second.GetSourceAddr (),
+ (*i).second.GetDestinationAddr ());
+ }
+ else
+ {
+ Mac48Address from = (*i).second.GetSourceAddr ();
+ Mac48Address to = (*i).second.GetDestinationAddr ();
+ NS_LOG_DEBUG ("forwarding QoS frame from="<<from<<", to="<<to);
+ ForwardDown ((*i).first, from, to, hdr->GetQosTid ());
+ }
+ }
+}
+
+void
+ApWifiMac::DoStart (void)
+{
+ m_beaconDca->Start ();
+ m_beaconEvent.Cancel ();
+ if (m_enableBeaconGeneration)
+ {
+ m_beaconEvent = Simulator::ScheduleNow (&ApWifiMac::SendOneBeacon, this);
+ }
+ RegularWifiMac::DoStart ();
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/ap-wifi-mac.h Thu Dec 02 07:51:34 2010 +0000
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef AP_WIFI_MAC_H
+#define AP_WIFI_MAC_H
+
+#include "regular-wifi-mac.h"
+
+#include "amsdu-subframe-header.h"
+#include "supported-rates.h"
+
+namespace ns3 {
+
+/**
+ * \brief Wi-Fi AP state machine
+ *
+ * Handle association, dis-association and authentication,
+ * of STAs within an infrastructure BSS.
+ */
+class ApWifiMac : public RegularWifiMac
+{
+public:
+ static TypeId GetTypeId (void);
+
+ ApWifiMac ();
+ virtual ~ApWifiMac ();
+
+ /**
+ * \param stationManager the station manager attached to this MAC.
+ */
+ virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
+
+ /**
+ * \param linkUp the callback to invoke when the link becomes up.
+ */
+ virtual void SetLinkUpCallback (Callback<void> linkUp);
+
+ /**
+ * \param packet the packet to send.
+ * \param to the address to which the packet should be sent.
+ *
+ * The packet should be enqueued in a tx queue, and should be
+ * dequeued as soon as the channel access function determines that
+ * access is granted to this MAC.
+ */
+ virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
+
+ /**
+ * \param packet the packet to send.
+ * \param to the address to which the packet should be sent.
+ * \param from the address from which the packet should be sent.
+ *
+ * The packet should be enqueued in a tx queue, and should be
+ * dequeued as soon as the channel access function determines that
+ * access is granted to this MAC. The extra parameter "from" allows
+ * this device to operate in a bridged mode, forwarding received
+ * frames without altering the source address.
+ */
+ virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
+ virtual bool SupportsSendFrom (void) const;
+
+ /**
+ * \param address the current address of this MAC layer.
+ */
+ virtual void SetAddress (Mac48Address address);
+ /**
+ * \param interval the interval between two beacon transmissions.
+ */
+ void SetBeaconInterval (Time interval);
+ /**
+ * \returns the interval between two beacon transmissions.
+ */
+ Time GetBeaconInterval (void) const;
+ /**
+ * Start beacon transmission immediately.
+ */
+ void StartBeaconing (void);
+
+private:
+ virtual void Receive (Ptr<Packet> packet, const WifiMacHeader *hdr);
+ virtual void TxOk (const WifiMacHeader &hdr);
+ virtual void TxFailed (const WifiMacHeader &hdr);
+
+ /**
+ * This method is called to de-aggregate an A-MSDU and forward the
+ * constituent packets up the stack. We override the WifiMac version
+ * here because, as an AP, we also need to think about redistributing
+ * to other associated STAs.
+ *
+ * \param aggregatedPacket the Packet containing the A-MSDU.
+ * \param hdr a pointer to the MAC header for \c aggregatedPacket.
+ */
+ virtual void DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket,
+ const WifiMacHeader *hdr);
+
+ void ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to);
+ void ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to, uint8_t tid);
+ void SendProbeResp (Mac48Address to);
+ void SendAssocResp (Mac48Address to, bool success);
+ void SendOneBeacon (void);
+ SupportedRates GetSupportedRates (void) const;
+ void SetBeaconGeneration (bool enable);
+ bool GetBeaconGeneration (void) const;
+ virtual void DoDispose (void);
+ virtual void DoStart (void);
+
+ Ptr<DcaTxop> m_beaconDca;
+ Time m_beaconInterval;
+ bool m_enableBeaconGeneration;
+ EventId m_beaconEvent;
+};
+
+} // namespace ns3
+
+#endif /* AP_WIFI_MAC_H */
--- a/src/devices/wifi/edca-txop-n.h Wed Dec 01 08:01:24 2010 -0800
+++ b/src/devices/wifi/edca-txop-n.h Thu Dec 02 07:51:34 2010 +0000
@@ -27,8 +27,8 @@
#include "ns3/packet.h"
#include "wifi-mode.h"
-#include "wifi-mac.h"
#include "wifi-mac-header.h"
+#include "wifi-remote-station-manager.h"
#include "qos-utils.h"
#include "dcf.h"
#include "ctrl-headers.h"
@@ -43,6 +43,7 @@
class DcfManager;
class MacLow;
class MacTxMiddle;
+class WifiMac;
class WifiMacParameters;
class WifiMacQueue;
class RandomStream;
@@ -67,7 +68,8 @@
{
STA,
AP,
- ADHOC_STA
+ ADHOC_STA,
+ MESH
};
class EdcaTxopN : public Dcf
--- a/src/devices/wifi/mac-low.h Wed Dec 01 08:01:24 2010 -0800
+++ b/src/devices/wifi/mac-low.h Thu Dec 02 07:51:34 2010 +0000
@@ -453,16 +453,22 @@
*/
void NotifySwitchingStartNow (Time duration);
/**
- * \param respHdr Add block ack response from originator (action frame).
- * \param originator Address of peer station involved in block ack mechanism.
- * \param startingSeq Sequence number of the first MPDU of all packets for which block ack was negotiated.
- *
- * This function is typically invoked only by ns3::QapWifiMac and ns3::QstaWifiMac.
- * If we are transmitting an Add block ack response, MacLow must allocate buffers to collect
- * all correctly received packets belonging to category for which block ack was negotiated.
- * It's needed in order to send a Block ack after corresponding originator's Block ack request.
+ * \param respHdr Add block ack response from originator (action
+ * frame).
+ * \param originator Address of peer station involved in block ack
+ * mechanism.
+ * \param startingSeq Sequence number of the first MPDU of all
+ * packets for which block ack was negotiated.
+ *
+ * This function is typically invoked only by ns3::RegularWifiMac
+ * when the STA (which may be non-AP in ESS, or in an IBSS) has
+ * received an ADDBA Request frame and is transmitting an ADDBA
+ * Response frame. At this point MacLow must allocate buffers to
+ * collect all correctly received packets belonging to the category
+ * for which Block Ack was negotiated.
*/
- void CreateBlockAckAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Address originator,
+ void CreateBlockAckAgreement (const MgtAddBaResponseHeader *respHdr,
+ Mac48Address originator,
uint16_t startingSeq);
/**
* \param originator Address of peer participating in Block Ack mechanism.
--- a/src/devices/wifi/msdu-aggregator.h Wed Dec 01 08:01:24 2010 -0800
+++ b/src/devices/wifi/msdu-aggregator.h Thu Dec 02 07:51:34 2010 +0000
@@ -38,6 +38,7 @@
{
public:
typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> > DeaggregatedMsdus;
+ typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> >::const_iterator DeaggregatedMsdusCI;
static TypeId GetTypeId (void);
/* Adds <i>packet</i> to <i>aggregatedPacket</i>. In concrete aggregator's implementation is
--- a/src/devices/wifi/nqap-wifi-mac.cc Wed Dec 01 08:01:24 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,623 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "ns3/assert.h"
-#include "ns3/log.h"
-#include "ns3/simulator.h"
-#include "ns3/node.h"
-#include "ns3/boolean.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"
-#include "wifi-mac-trailer.h"
-#include "ns3/pointer.h"
-
-NS_LOG_COMPONENT_DEFINE ("NqapWifiMac");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (NqapWifiMac);
-
-#undef NS_LOG_APPEND_CONTEXT
-#define NS_LOG_APPEND_CONTEXT if (m_low != 0) {std::clog << "[mac=" << m_low->GetAddress () << "] ";}
-
-TypeId
-NqapWifiMac::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::NqapWifiMac")
- .SetParent<WifiMac> ()
- .AddConstructor<NqapWifiMac> ()
- .AddAttribute ("BeaconInterval", "Delay between two beacons",
- TimeValue (MicroSeconds (102400)),
- MakeTimeAccessor (&NqapWifiMac::GetBeaconInterval,
- &NqapWifiMac::SetBeaconInterval),
- MakeTimeChecker ())
- .AddAttribute ("BeaconGeneration", "Whether or not beacons are generated.",
- BooleanValue (true),
- MakeBooleanAccessor (&NqapWifiMac::SetBeaconGeneration,
- &NqapWifiMac::GetBeaconGeneration),
- MakeBooleanChecker ())
- .AddAttribute ("DcaTxop", "The DcaTxop object",
- PointerValue (),
- MakePointerAccessor (&NqapWifiMac::GetDcaTxop),
- MakePointerChecker<DcaTxop> ())
- ;
- return tid;
-}
-
-NqapWifiMac::NqapWifiMac ()
-{
- NS_LOG_FUNCTION (this);
- m_rxMiddle = new MacRxMiddle ();
- m_rxMiddle->SetForwardCallback (MakeCallback (&NqapWifiMac::Receive, this));
-
- m_low = CreateObject<MacLow> ();
- m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
-
- m_dcfManager = new DcfManager ();
- m_dcfManager->SetupLowListener (m_low);
-
- m_beaconDca = CreateObject<DcaTxop> ();
- m_beaconDca->SetAifsn(1);
- m_beaconDca->SetMinCw(0);
- m_beaconDca->SetMaxCw(0);
- m_beaconDca->SetLow (m_low);
- m_beaconDca->SetManager (m_dcfManager);
-
- m_dca = CreateObject<DcaTxop> ();
- m_dca->SetLow (m_low);
- m_dca->SetManager (m_dcfManager);
- m_dca->SetTxOkCallback (MakeCallback (&NqapWifiMac::TxOk, this));
- m_dca->SetTxFailedCallback (MakeCallback (&NqapWifiMac::TxFailed, this));
-
- m_enableBeaconGeneration = false;
-}
-NqapWifiMac::~NqapWifiMac ()
-{
- NS_LOG_FUNCTION (this);
-}
-
-void
-NqapWifiMac::DoDispose (void)
-{
- NS_LOG_FUNCTION (this);
- delete m_rxMiddle;
- delete m_dcfManager;
- m_low->Dispose ();
- m_rxMiddle = 0;
- m_low = 0;
- m_dcfManager = 0;
- m_phy = 0;
- m_dca = 0;
- m_beaconDca = 0;
- m_stationManager = 0;
- m_enableBeaconGeneration = false;
- m_beaconEvent.Cancel ();
- WifiMac::DoDispose ();
-}
-
-void
-NqapWifiMac::SetBeaconGeneration (bool enable)
-{
- NS_LOG_FUNCTION (this << enable);
- if (!enable)
- {
- m_beaconEvent.Cancel ();
- }
- else if (enable && !m_enableBeaconGeneration)
- {
- m_beaconEvent = Simulator::ScheduleNow (&NqapWifiMac::SendOneBeacon, this);
- }
- m_enableBeaconGeneration = enable;
-}
-
-bool
-NqapWifiMac::GetBeaconGeneration (void) const
-{
- return m_enableBeaconGeneration;
-}
-Time
-NqapWifiMac::GetBeaconInterval (void) const
-{
- return m_beaconInterval;
-}
-
-void
-NqapWifiMac::SetSlot (Time slotTime)
-{
- NS_LOG_FUNCTION (this << slotTime);
- m_dcfManager->SetSlot (slotTime);
- m_low->SetSlotTime (slotTime);
-}
-void
-NqapWifiMac::SetSifs (Time sifs)
-{
- NS_LOG_FUNCTION (this << sifs);
- m_dcfManager->SetSifs (sifs);
- m_low->SetSifs (sifs);
-}
-void
-NqapWifiMac::SetEifsNoDifs (Time eifsNoDifs)
-{
- NS_LOG_FUNCTION (this << eifsNoDifs);
- m_dcfManager->SetEifsNoDifs (eifsNoDifs);
-}
-void
-NqapWifiMac::SetAckTimeout (Time ackTimeout)
-{
- m_low->SetAckTimeout (ackTimeout);
-}
-void
-NqapWifiMac::SetCtsTimeout (Time ctsTimeout)
-{
- m_low->SetCtsTimeout (ctsTimeout);
-}
-void
-NqapWifiMac::SetPifs (Time pifs)
-{
- m_low->SetPifs (pifs);
-}
-Time
-NqapWifiMac::GetSlot (void) const
-{
- return m_low->GetSlotTime ();
-}
-Time
-NqapWifiMac::GetSifs (void) const
-{
- return m_low->GetSifs ();
-}
-Time
-NqapWifiMac::GetEifsNoDifs (void) const
-{
- return m_dcfManager->GetEifsNoDifs ();
-}
-Time
-NqapWifiMac::GetAckTimeout (void) const
-{
- return m_low->GetAckTimeout ();
-}
-Time
-NqapWifiMac::GetCtsTimeout (void) const
-{
- return m_low->GetCtsTimeout ();
-}
-Time
-NqapWifiMac::GetPifs (void) const
-{
- return m_low->GetPifs ();
-}
-void
-NqapWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
-{
- NS_LOG_FUNCTION (this << phy);
- m_phy = phy;
- m_dcfManager->SetupPhyListener (phy);
- m_low->SetPhy (phy);
-}
-void
-NqapWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
-{
- NS_LOG_FUNCTION (this << stationManager);
- m_stationManager = stationManager;
- m_dca->SetWifiRemoteStationManager (stationManager);
- m_beaconDca->SetWifiRemoteStationManager (stationManager);
- m_low->SetWifiRemoteStationManager (stationManager);
-}
-void
-NqapWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
-{
- NS_LOG_FUNCTION (this);
- m_upCallback = upCallback;
-}
-void
-NqapWifiMac::SetLinkUpCallback (Callback<void> linkUp)
-{
- NS_LOG_FUNCTION (this);
- if (!linkUp.IsNull ())
- {
- linkUp ();
- }
-}
-void
-NqapWifiMac::SetLinkDownCallback (Callback<void> linkDown)
-{
- NS_LOG_FUNCTION (this);
-}
-Mac48Address
-NqapWifiMac::GetAddress (void) const
-{
- return m_low->GetAddress ();
-}
-Ssid
-NqapWifiMac::GetSsid (void) const
-{
- return m_ssid;
-}
-void
-NqapWifiMac::SetAddress (Mac48Address address)
-{
- NS_LOG_FUNCTION (address);
- m_low->SetAddress (address);
- m_low->SetBssid (address);
-}
-void
-NqapWifiMac::SetSsid (Ssid ssid)
-{
- NS_LOG_FUNCTION (ssid);
- m_ssid = ssid;
-}
-Mac48Address
-NqapWifiMac::GetBssid (void) const
-{
- return m_low->GetBssid ();
-}
-
-
-void
-NqapWifiMac::SetBeaconInterval (Time interval)
-{
- NS_LOG_FUNCTION (this << interval);
- if ((interval.GetMicroSeconds () % 1024) != 0)
- {
- NS_LOG_WARN ("beacon interval should be multiple of 1024us, see IEEE Std. 802.11-2007, section 11.1.1.1");
- }
- m_beaconInterval = interval;
-}
-void
-NqapWifiMac::StartBeaconing (void)
-{
- NS_LOG_FUNCTION (this);
- SendOneBeacon ();
-}
-void
-NqapWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
-{
- NS_LOG_FUNCTION (this << packet << from);
- m_upCallback (packet, from, to);
-}
-
-void
-NqapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
-{
- NS_LOG_FUNCTION (this << packet << from << to);
- WifiMacHeader hdr;
- hdr.SetTypeData ();
- hdr.SetAddr1 (to);
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (from);
- hdr.SetDsFrom ();
- hdr.SetDsNotTo ();
- m_dca->Queue (packet, hdr);
-}
-void
-NqapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
-{
- NS_LOG_FUNCTION (this << packet << to << from);
- if (to.IsBroadcast () || m_stationManager->IsAssociated (to))
- {
- ForwardDown (packet, from, to);
- }
-}
-void
-NqapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
-{
- NS_LOG_FUNCTION (this << packet << to);
- if (to.IsBroadcast () || m_stationManager->IsAssociated (to))
- {
- ForwardDown (packet, m_low->GetAddress (), to);
- }
-}
-bool
-NqapWifiMac::SupportsSendFrom (void) const
-{
- return true;
-}
-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)
-{
- NS_LOG_FUNCTION (this << to);
- WifiMacHeader hdr;
- hdr.SetProbeResp ();
- hdr.SetAddr1 (to);
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Ptr<Packet> packet = Create<Packet> ();
- MgtProbeResponseHeader probe;
- probe.SetSsid (GetSsid ());
- probe.SetSupportedRates (GetSupportedRates ());
- probe.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
- packet->AddHeader (probe);
-
- m_dca->Queue (packet, hdr);
-}
-void
-NqapWifiMac::SendAssocResp (Mac48Address to, bool success)
-{
- NS_LOG_FUNCTION (this << to << success);
- WifiMacHeader hdr;
- hdr.SetAssocResp ();
- hdr.SetAddr1 (to);
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Ptr<Packet> packet = Create<Packet> ();
- MgtAssocResponseHeader assoc;
- StatusCode code;
- if (success)
- {
- code.SetSuccess ();
- }
- else
- {
- code.SetFailure ();
- }
- assoc.SetSupportedRates (GetSupportedRates ());
- assoc.SetStatusCode (code);
- packet->AddHeader (assoc);
-
- m_dca->Queue (packet, hdr);
-}
-void
-NqapWifiMac::SendOneBeacon (void)
-{
- NS_LOG_FUNCTION (this);
- WifiMacHeader hdr;
- hdr.SetBeacon ();
- hdr.SetAddr1 (Mac48Address::GetBroadcast ());
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Ptr<Packet> packet = Create<Packet> ();
- MgtBeaconHeader beacon;
- beacon.SetSsid (GetSsid ());
- beacon.SetSupportedRates (GetSupportedRates ());
- beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
- packet->AddHeader (beacon);
-
- m_beaconDca->Queue (packet, hdr);
- m_beaconEvent = Simulator::Schedule (m_beaconInterval, &NqapWifiMac::SendOneBeacon, this);
-}
-void
-NqapWifiMac::TxOk (const WifiMacHeader &hdr)
-{
- NS_LOG_FUNCTION (this);
- if (hdr.IsAssocResp () &&
- m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
- {
- NS_LOG_DEBUG ("associated with sta="<<hdr.GetAddr1 ());
- m_stationManager->RecordGotAssocTxOk (hdr.GetAddr1 ());
- }
-}
-void
-NqapWifiMac::TxFailed (const WifiMacHeader &hdr)
-{
- NS_LOG_FUNCTION (this);
- if (hdr.IsAssocResp () &&
- m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
- {
- NS_LOG_DEBUG ("assoc failed with sta="<<hdr.GetAddr1 ());
- m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ());
- }
-}
-void
-NqapWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
-{
- NS_LOG_FUNCTION (this << packet << hdr);
-
- Mac48Address from = hdr->GetAddr2 ();
-
- if (hdr->IsData ())
- {
- Mac48Address bssid = hdr->GetAddr1 ();
- if (!hdr->IsFromDs () &&
- hdr->IsToDs () &&
- bssid == GetAddress () &&
- m_stationManager->IsAssociated (from))
- {
- Mac48Address to = hdr->GetAddr3 ();
- if (to == GetAddress ())
- {
- NS_LOG_DEBUG ("frame for me from="<<from);
- ForwardUp (packet, from, bssid);
- }
- else if (to.IsGroup () ||
- m_stationManager->IsAssociated (to))
- {
- NS_LOG_DEBUG ("forwarding frame from="<<from<<", to="<<to);
- Ptr<Packet> copy = packet->Copy ();
- ForwardDown (packet,
- from,
- to);
- ForwardUp (copy, from, to);
- }
- else
- {
- ForwardUp (packet, from, to);
- }
- }
- else if (hdr->IsFromDs () &&
- hdr->IsToDs ())
- {
- // this is an AP-to-AP frame
- // we ignore for now.
- NotifyRxDrop (packet);
- }
- else
- {
- // we can ignore these frames since
- // they are not targeted at the AP
- NotifyRxDrop (packet);
- }
- }
- 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 ()))
- {
- m_stationManager->AddSupportedMode (from, mode);
- }
- }
- m_stationManager->RecordWaitAssocTxOk (from);
- // send assoc response with success status.
- SendAssocResp (hdr->GetAddr2 (), true);
- }
- }
- else if (hdr->IsDisassociation ())
- {
- m_stationManager->RecordDisassociated (from);
- }
- 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);
- }
-}
-Ptr<DcaTxop>
-NqapWifiMac::GetDcaTxop(void) const
-{
- return m_dca;
-}
-
-void
-NqapWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard)
-{
- switch (standard)
- {
- case WIFI_PHY_STANDARD_holland:
- // fall through
- case WIFI_PHY_STANDARD_80211_10Mhz:
- // fall through
- case WIFI_PHY_STANDARD_80211_5Mhz:
- // fall through
- case WIFI_PHY_STANDARD_80211a:
- // fall through
- case WIFI_PHY_STANDARD_80211g:
- ConfigureDcf (m_dca, 15, 1023, AC_BE_NQOS);
- break;
- case WIFI_PHY_STANDARD_80211b:
- ConfigureDcf (m_dca, 31, 1023, AC_BE_NQOS);
- break;
- default:
- NS_ASSERT (false);
- break;
- }
-}
-
-
-void
-NqapWifiMac::DoStart (void)
-{
- m_beaconEvent.Cancel ();
- if (m_enableBeaconGeneration)
- {
- m_beaconEvent = Simulator::ScheduleNow (&NqapWifiMac::SendOneBeacon, this);
- }
- m_dca->Start ();
- m_beaconDca->Start ();
- WifiMac::DoStart ();
-}
-
-} // namespace ns3
--- a/src/devices/wifi/nqap-wifi-mac.h Wed Dec 01 08:01:24 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef MAC_HIGH_NQAP_H
-#define MAC_HIGH_NQAP_H
-
-#include <stdint.h>
-
-#include "ns3/mac48-address.h"
-#include "ns3/callback.h"
-#include "ns3/packet.h"
-#include "ns3/nstime.h"
-#include "supported-rates.h"
-#include "wifi-remote-station-manager.h"
-#include "wifi-mac.h"
-
-namespace ns3 {
-
-class WifiMacHeader;
-class DcaTxop;
-class WifiPhy;
-class DcfManager;
-class MacRxMiddle;
-class MacLow;
-
-/**
- * \brief non-QoS AP state machine
- *
- * Handle association, dis-association and authentication,
- * of STAs within an IBSS.
- * This class uses two output queues, each of which is server by
- * a single DCF
- * - the highest priority DCF serves the queue which contains
- * only beacons.
- * - the lowest priority DCF serves the queue which contains all
- * other frames, including user data frames.
- */
-class NqapWifiMac : public WifiMac
-{
-public:
- static TypeId GetTypeId (void);
-
- NqapWifiMac ();
- ~NqapWifiMac ();
-
- // inherited from WifiMac.
- virtual void SetSlot (Time slotTime);
- virtual void SetSifs (Time sifs);
- virtual void SetEifsNoDifs (Time eifsNoDifs);
- virtual void SetAckTimeout (Time ackTimeout);
- virtual void SetCtsTimeout (Time ctsTimeout);
- virtual void SetPifs (Time pifs);
- virtual Time GetSlot (void) const;
- virtual Time GetSifs (void) const;
- virtual Time GetEifsNoDifs (void) const;
- virtual Time GetAckTimeout (void) const;
- virtual Time GetCtsTimeout (void) const;
- virtual Time GetPifs (void) const;
- virtual void SetWifiPhy (Ptr<WifiPhy> phy);
- virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
- virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
- virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
- virtual bool SupportsSendFrom (void) const;
- virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
- virtual void SetLinkUpCallback (Callback<void> linkUp);
- virtual void SetLinkDownCallback (Callback<void> linkDown);
- virtual Mac48Address GetAddress (void) const;
- virtual Ssid GetSsid (void) const;
- virtual void SetAddress (Mac48Address address);
- virtual void SetSsid (Ssid ssid);
- virtual Mac48Address GetBssid (void) const;
-
- /**
- * \param interval the interval between two beacon transmissions.
- */
- void SetBeaconInterval (Time interval);
- /**
- * \returns the interval between two beacon transmissions.
- */
- Time GetBeaconInterval (void) const;
- /**
- * Start beacon transmission immediately.
- */
- void StartBeaconing (void);
-
-private:
- void Receive (Ptr<Packet> packet, const WifiMacHeader *hdr);
- void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
- void ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to);
- void TxOk (const WifiMacHeader &hdr);
- void TxFailed (const WifiMacHeader &hdr);
- void SendProbeResp (Mac48Address to);
- void SendAssocResp (Mac48Address to, bool success);
- void SendOneBeacon (void);
- SupportedRates GetSupportedRates (void) const;
- void SetBeaconGeneration (bool enable);
- bool GetBeaconGeneration (void) const;
- virtual void DoDispose (void);
- virtual void DoStart (void);
- NqapWifiMac (const NqapWifiMac & ctor_arg);
- NqapWifiMac &operator = (const NqapWifiMac &o);
- Ptr<DcaTxop> GetDcaTxop (void) const;
- virtual void FinishConfigureStandard (enum WifiPhyStandard standard);
-
- Ptr<DcaTxop> m_dca;
- Ptr<DcaTxop> m_beaconDca;
- Ptr<WifiRemoteStationManager> m_stationManager;
- Ptr<WifiPhy> m_phy;
- Callback<void, Ptr<Packet>,Mac48Address, Mac48Address> m_upCallback;
- Time m_beaconInterval;
- bool m_enableBeaconGeneration;
-
- DcfManager *m_dcfManager;
- MacRxMiddle *m_rxMiddle;
- Ptr<MacLow> m_low;
- Ssid m_ssid;
- EventId m_beaconEvent;
-};
-
-} // namespace ns3
-
-
-#endif /* MAC_HIGH_NQAP_H */
--- a/src/devices/wifi/nqsta-wifi-mac.cc Wed Dec 01 08:01:24 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,697 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ns3/packet.h"
-#include "ns3/simulator.h"
-#include "ns3/assert.h"
-#include "ns3/log.h"
-#include "ns3/node.h"
-#include "ns3/uinteger.h"
-#include "ns3/boolean.h"
-#include "ns3/trace-source-accessor.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"
-#include "wifi-mac-trailer.h"
-#include "ns3/trace-source-accessor.h"
-#include "ns3/pointer.h"
-
-NS_LOG_COMPONENT_DEFINE ("NqstaWifiMac");
-
-#undef NS_LOG_APPEND_CONTEXT
-#define NS_LOG_APPEND_CONTEXT if (m_low != 0) {std::clog << "[mac=" << m_low->GetAddress () << "] ";}
-
-/*
- * 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 ("ns3::NqstaWifiMac")
- .SetParent<WifiMac> ()
- .AddConstructor<NqstaWifiMac> ()
- .AddAttribute ("ProbeRequestTimeout", "The interval between two consecutive probe request attempts.",
- TimeValue (Seconds (0.05)),
- MakeTimeAccessor (&NqstaWifiMac::m_probeRequestTimeout),
- MakeTimeChecker ())
- .AddAttribute ("AssocRequestTimeout", "The interval between two consecutive assoc request attempts.",
- TimeValue (Seconds (0.5)),
- MakeTimeAccessor (&NqstaWifiMac::m_assocRequestTimeout),
- MakeTimeChecker ())
- .AddAttribute ("MaxMissedBeacons",
- "Number of beacons which much be consecutively missed before "
- "we attempt to restart association.",
- UintegerValue (10),
- MakeUintegerAccessor (&NqstaWifiMac::m_maxMissedBeacons),
- MakeUintegerChecker<uint32_t> ())
- .AddAttribute ("ActiveProbing", "If true, we send probe requests. If false, we don't.",
- BooleanValue (false),
- MakeBooleanAccessor (&NqstaWifiMac::SetActiveProbing),
- MakeBooleanChecker ())
- .AddAttribute ("DcaTxop", "The DcaTxop object",
- PointerValue (),
- MakePointerAccessor (&NqstaWifiMac::GetDcaTxop),
- MakePointerChecker<DcaTxop> ())
- .AddTraceSource ("Assoc", "Associated with an access point.",
- MakeTraceSourceAccessor (&NqstaWifiMac::m_assocLogger))
- .AddTraceSource ("DeAssoc", "Association with an access point lost.",
- MakeTraceSourceAccessor (&NqstaWifiMac::m_deAssocLogger))
- ;
- return tid;
-}
-
-NqstaWifiMac::NqstaWifiMac ()
- : m_state (BEACON_MISSED),
- m_probeRequestEvent (),
- m_assocRequestEvent (),
- m_beaconWatchdogEnd (Seconds (0.0))
-{
- NS_LOG_FUNCTION (this);
- m_rxMiddle = new MacRxMiddle ();
- m_rxMiddle->SetForwardCallback (MakeCallback (&NqstaWifiMac::Receive, this));
-
- m_low = CreateObject<MacLow> ();
- m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
-
- m_dcfManager = new DcfManager ();
- m_dcfManager->SetupLowListener (m_low);
-
- m_dca = CreateObject<DcaTxop> ();
- m_dca->SetLow (m_low);
- m_dca->SetManager (m_dcfManager);
-}
-
-NqstaWifiMac::~NqstaWifiMac ()
-{
- NS_LOG_FUNCTION (this);
-}
-
-void
-NqstaWifiMac::DoDispose (void)
-{
- NS_LOG_FUNCTION (this);
- delete m_rxMiddle;
- delete m_dcfManager;
- m_low->Dispose ();
- m_rxMiddle = 0;
- m_low = 0;
- m_dcfManager = 0;
- m_phy = 0;
- m_dca = 0;
- m_stationManager = 0;
- WifiMac::DoDispose ();
-}
-
-void
-NqstaWifiMac::SetSlot (Time slotTime)
-{
- NS_LOG_FUNCTION (this << slotTime);
- m_dcfManager->SetSlot (slotTime);
- m_low->SetSlotTime (slotTime);
-}
-void
-NqstaWifiMac::SetSifs (Time sifs)
-{
- NS_LOG_FUNCTION (this << sifs);
- m_dcfManager->SetSifs (sifs);
- m_low->SetSifs (sifs);
-}
-void
-NqstaWifiMac::SetEifsNoDifs (Time eifsNoDifs)
-{
- NS_LOG_FUNCTION (this << eifsNoDifs);
- m_dcfManager->SetEifsNoDifs (eifsNoDifs);
-}
-void
-NqstaWifiMac::SetAckTimeout (Time ackTimeout)
-{
- m_low->SetAckTimeout (ackTimeout);
-}
-void
-NqstaWifiMac::SetCtsTimeout (Time ctsTimeout)
-{
- m_low->SetCtsTimeout (ctsTimeout);
-}
-void
-NqstaWifiMac::SetPifs (Time pifs)
-{
- m_low->SetPifs (pifs);
-}
-Time
-NqstaWifiMac::GetSlot (void) const
-{
- return m_low->GetSlotTime ();
-}
-Time
-NqstaWifiMac::GetSifs (void) const
-{
- return m_low->GetSifs ();
-}
-Time
-NqstaWifiMac::GetEifsNoDifs (void) const
-{
- return m_dcfManager->GetEifsNoDifs ();
-}
-Time
-NqstaWifiMac::GetAckTimeout (void) const
-{
- return m_low->GetAckTimeout ();
-}
-Time
-NqstaWifiMac::GetCtsTimeout (void) const
-{
- return m_low->GetCtsTimeout ();
-}
-Time
-NqstaWifiMac::GetPifs (void) const
-{
- return m_low->GetPifs ();
-}
-Ptr<DcaTxop>
-NqstaWifiMac::GetDcaTxop(void) const
-{
- return m_dca;
-}
-void
-NqstaWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
-{
- m_phy = phy;
- m_dcfManager->SetupPhyListener (phy);
- m_low->SetPhy (phy);
-}
-void
-NqstaWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
-{
- m_stationManager = stationManager;
- m_dca->SetWifiRemoteStationManager (stationManager);
- m_low->SetWifiRemoteStationManager (stationManager);
-}
-void
-NqstaWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
-{
- m_forwardUp = upCallback;
-}
-void
-NqstaWifiMac::SetLinkUpCallback (Callback<void> linkUp)
-{
- m_linkUp = linkUp;
-}
-void
-NqstaWifiMac::SetLinkDownCallback (Callback<void> linkDown)
-{
- m_linkDown = linkDown;
-}
-Mac48Address
-NqstaWifiMac::GetAddress (void) const
-{
- return m_low->GetAddress ();
-}
-Ssid
-NqstaWifiMac::GetSsid (void) const
-{
- return m_ssid;
-}
-Mac48Address
-NqstaWifiMac::GetBssid (void) const
-{
- return m_low->GetBssid ();
-}
-void
-NqstaWifiMac::SetAddress (Mac48Address address)
-{
- NS_LOG_FUNCTION (this << address);
- m_low->SetAddress (address);
-}
-void
-NqstaWifiMac::SetSsid (Ssid ssid)
-{
- NS_LOG_FUNCTION (this << ssid);
- m_ssid = ssid;
-}
-void
-NqstaWifiMac::SetMaxMissedBeacons (uint32_t missed)
-{
- NS_LOG_FUNCTION (this << missed);
- m_maxMissedBeacons = missed;
-}
-void
-NqstaWifiMac::SetProbeRequestTimeout (Time timeout)
-{
- NS_LOG_FUNCTION (this << timeout);
- m_probeRequestTimeout = timeout;
-}
-void
-NqstaWifiMac::SetAssocRequestTimeout (Time timeout)
-{
- NS_LOG_FUNCTION (this << timeout);
- m_assocRequestTimeout = timeout;
-}
-
-void
-NqstaWifiMac::StartActiveAssociation (void)
-{
- NS_LOG_FUNCTION (this);
- TryToEnsureAssociated ();
-}
-
-Mac48Address
-NqstaWifiMac::GetBroadcastBssid (void)
-{
- return Mac48Address::GetBroadcast ();
-}
-
-void
-NqstaWifiMac::SetBssid (Mac48Address bssid)
-{
- NS_LOG_FUNCTION (this << bssid);
- m_low->SetBssid (bssid);
-}
-void
-NqstaWifiMac::SetActiveProbing (bool enable)
-{
- NS_LOG_FUNCTION (this << enable);
- if (enable)
- {
- TryToEnsureAssociated ();
- }
- else
- {
- m_probeRequestEvent.Cancel ();
- }
-}
-void
-NqstaWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
-{
- NS_LOG_FUNCTION (this << packet << from << to);
- m_forwardUp (packet, from, to);
-}
-void
-NqstaWifiMac::SendProbeRequest (void)
-{
- NS_LOG_FUNCTION (this);
- WifiMacHeader hdr;
- hdr.SetProbeReq ();
- hdr.SetAddr1 (GetBroadcastBssid ());
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetBroadcastBssid ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Ptr<Packet> packet = Create<Packet> ();
- MgtProbeRequestHeader probe;
- probe.SetSsid (GetSsid ());
- probe.SetSupportedRates (GetSupportedRates ());
- packet->AddHeader (probe);
-
- m_dca->Queue (packet, hdr);
-
- m_probeRequestEvent = Simulator::Schedule (m_probeRequestTimeout,
- &NqstaWifiMac::ProbeRequestTimeout, this);
-}
-
-void
-NqstaWifiMac::SendAssociationRequest (void)
-{
- NS_LOG_FUNCTION (this << GetBssid ());
- WifiMacHeader hdr;
- hdr.SetAssocReq ();
- hdr.SetAddr1 (GetBssid ());
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetBssid ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Ptr<Packet> packet = Create<Packet> ();
- MgtAssocRequestHeader assoc;
- assoc.SetSsid (GetSsid ());
- assoc.SetSupportedRates (GetSupportedRates ());
- packet->AddHeader (assoc);
-
- m_dca->Queue (packet, hdr);
-
- m_assocRequestEvent = Simulator::Schedule (m_assocRequestTimeout,
- &NqstaWifiMac::AssocRequestTimeout, this);
-}
-void
-NqstaWifiMac::TryToEnsureAssociated (void)
-{
- NS_LOG_FUNCTION (this);
- 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 ();
- SetState (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)
-{
- NS_LOG_FUNCTION (this);
- SetState (WAIT_ASSOC_RESP);
- SendAssociationRequest ();
-}
-void
-NqstaWifiMac::ProbeRequestTimeout (void)
-{
- NS_LOG_FUNCTION (this);
- SetState (WAIT_PROBE_RESP);
- SendProbeRequest ();
-}
-void
-NqstaWifiMac::MissedBeacons (void)
-{
- NS_LOG_FUNCTION (this);
- if (m_beaconWatchdogEnd > Simulator::Now ())
- {
- m_beaconWatchdog = Simulator::Schedule (m_beaconWatchdogEnd - Simulator::Now (),
- &NqstaWifiMac::MissedBeacons, this);
- return;
- }
- NS_LOG_DEBUG ("beacon missed");
- SetState (BEACON_MISSED);
- TryToEnsureAssociated ();
-}
-void
-NqstaWifiMac::RestartBeaconWatchdog (Time delay)
-{
- NS_LOG_FUNCTION (this << delay);
- m_beaconWatchdogEnd = std::max (Simulator::Now () + delay, m_beaconWatchdogEnd);
- if (Simulator::GetDelayLeft (m_beaconWatchdog) < delay &&
- m_beaconWatchdog.IsExpired ())
- {
- NS_LOG_DEBUG ("really restart watchdog.");
- m_beaconWatchdog = Simulator::Schedule (delay, &NqstaWifiMac::MissedBeacons, this);
- }
-}
-bool
-NqstaWifiMac::IsAssociated (void) const
-{
- return m_state == ASSOCIATED;
-}
-
-bool
-NqstaWifiMac::IsWaitAssocResp (void) const
-{
- return m_state == WAIT_ASSOC_RESP;
-}
-
-void
-NqstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
-{
- NS_FATAL_ERROR ("Qsta does not support SendTo");
-}
-
-void
-NqstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
-{
- NS_LOG_FUNCTION (this << packet << to);
- if (!IsAssociated ())
- {
- NotifyTxDrop (packet);
- TryToEnsureAssociated ();
- return;
- }
- //NS_LOG_DEBUG ("enqueue size="<<packet->GetSize ()<<", to="<<to);
- WifiMacHeader hdr;
- hdr.SetTypeData ();
- hdr.SetAddr1 (GetBssid ());
- hdr.SetAddr2 (m_low->GetAddress ());
- hdr.SetAddr3 (to);
- hdr.SetDsNotFrom ();
- hdr.SetDsTo ();
-
- m_dca->Queue (packet, hdr);
-}
-
-bool
-NqstaWifiMac::SupportsSendFrom (void) const
-{
- //
- // The 802.11 MAC protocol has no way to support bridging outside of
- // infrastructure mode
- //
- return false;
-}
-
-
-void
-NqstaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
-{
- NS_LOG_FUNCTION (this << packet << hdr);
- NS_ASSERT (!hdr->IsCtl ());
- if (hdr->GetAddr3 () == GetAddress ())
- {
- NS_LOG_LOGIC ("packet sent by us.");
- }
- else if (hdr->GetAddr1 () != GetAddress () &&
- !hdr->GetAddr1 ().IsGroup ())
- {
- NS_LOG_LOGIC ("packet is not for us");
- NotifyRxDrop (packet);
- }
- else if (hdr->IsData ())
- {
- if (!IsAssociated ())
- {
- NS_LOG_LOGIC ("Received data frame while not associated: ignore");
- NotifyRxDrop (packet);
- return;
- }
- if (!(hdr->IsFromDs () && !hdr->IsToDs ()))
- {
- NS_LOG_LOGIC ("Received data frame not from the DS: ignore");
- NotifyRxDrop (packet);
- return;
- }
- if (hdr->GetAddr2 () != GetBssid ())
- {
- NS_LOG_LOGIC ("Received data frame not from the the BSS we are associated with: ignore");
- NotifyRxDrop (packet);
- return;
- }
-
- ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
- }
- else if (hdr->IsProbeReq () ||
- hdr->IsAssocReq ())
- {
- /* this is a frame aimed at an AP.
- * so we can safely ignore it.
- */
- NotifyRxDrop (packet);
- }
- else if (hdr->IsBeacon ())
- {
- MgtBeaconHeader beacon;
- packet->RemoveHeader (beacon);
- bool goodBeacon = false;
- if (GetSsid ().IsBroadcast () ||
- beacon.GetSsid ().IsEqual (GetSsid ()))
- {
- goodBeacon = true;
- }
- if ((IsWaitAssocResp () || IsAssociated ()) && hdr->GetAddr3 () != GetBssid ())
- {
- goodBeacon = false;
- }
- if (goodBeacon)
- {
- Time delay = MicroSeconds (beacon.GetBeaconIntervalUs () * m_maxMissedBeacons);
- RestartBeaconWatchdog (delay);
- SetBssid (hdr->GetAddr3 ());
- }
- if (goodBeacon && m_state == BEACON_MISSED)
- {
- SetState (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 ();
- }
- SetState (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 ())
- {
- SetState (ASSOCIATED);
- NS_LOG_DEBUG ("assoc completed");
- SupportedRates rates = assocResp.GetSupportedRates ();
- for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
- {
- WifiMode mode = m_phy->GetMode (i);
- if (rates.IsSupportedRate (mode.GetDataRate ()))
- {
- m_stationManager->AddSupportedMode (hdr->GetAddr2 (), mode);
- if (rates.IsBasicRate (mode.GetDataRate ()))
- {
- m_stationManager->AddBasicMode (mode);
- }
- }
- }
- if (!m_linkUp.IsNull ())
- {
- m_linkUp ();
- }
- }
- else
- {
- NS_LOG_DEBUG ("assoc refused");
- SetState (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;
-}
-
-void
-NqstaWifiMac::SetState (MacState value)
-{
- if (value == ASSOCIATED &&
- m_state != ASSOCIATED)
- {
- m_assocLogger (GetBssid ());
- }
- else if (value != ASSOCIATED &&
- m_state == ASSOCIATED)
- {
- m_deAssocLogger (GetBssid ());
- }
- m_state = value;
-}
-
-void
-NqstaWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard)
-{
- switch (standard)
- {
- case WIFI_PHY_STANDARD_holland:
- // fall through
- case WIFI_PHY_STANDARD_80211_10Mhz:
- // fall through
- case WIFI_PHY_STANDARD_80211_5Mhz:
- // fall through
- case WIFI_PHY_STANDARD_80211a:
- // fall through
- case WIFI_PHY_STANDARD_80211g:
- ConfigureDcf (m_dca, 15, 1023, AC_BE_NQOS);
- break;
- case WIFI_PHY_STANDARD_80211b:
- ConfigureDcf (m_dca, 31, 1023, AC_BE_NQOS);
- break;
- default:
- NS_ASSERT (false);
- break;
- }
-}
-void
-NqstaWifiMac::DoStart ()
-{
- m_dca->Start ();
- WifiMac::DoStart ();
-}
-} // namespace ns3
--- a/src/devices/wifi/nqsta-wifi-mac.h Wed Dec 01 08:01:24 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef NQSTA_WIFI_MAC_H
-#define NQSTA_WIFI_MAC_H
-
-#include <stdint.h>
-
-#include "ns3/mac48-address.h"
-#include "ns3/callback.h"
-#include "ns3/event-id.h"
-#include "ns3/packet.h"
-#include "ns3/nstime.h"
-#include "ns3/traced-callback.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 ();
-
- // inherited from WifiMac.
- virtual void SetSlot (Time slotTime);
- virtual void SetSifs (Time sifs);
- virtual void SetEifsNoDifs (Time eifsNoDifs);
- virtual void SetAckTimeout (Time ackTimeout);
- virtual void SetCtsTimeout (Time ctsTimeout);
- virtual void SetPifs (Time pifs);
- virtual Time GetSlot (void) const;
- virtual Time GetSifs (void) const;
- virtual Time GetEifsNoDifs (void) const;
- virtual Time GetAckTimeout (void) const;
- virtual Time GetCtsTimeout (void) const;
- virtual Time GetPifs (void) const;
- virtual void SetWifiPhy (Ptr<WifiPhy> phy);
- virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
- virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
- virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
- virtual bool SupportsSendFrom (void) const;
- virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
- virtual void SetLinkUpCallback (Callback<void> linkUp);
- virtual void SetLinkDownCallback (Callback<void> linkDown);
- virtual Mac48Address GetAddress (void) const;
- virtual Ssid GetSsid (void) const;
- virtual void SetAddress (Mac48Address address);
- virtual void SetSsid (Ssid ssid);
- virtual Mac48Address GetBssid (void) const;
-
- /**
- * \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:
- enum MacState{
- ASSOCIATED,
- WAIT_PROBE_RESP,
- WAIT_ASSOC_RESP,
- BEACON_MISSED,
- REFUSED
- };
- void DoStart ();
- void SetBssid (Mac48Address bssid);
- void SetActiveProbing (bool enable);
- bool GetActiveProbing (void) const;
- void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
- void Receive (Ptr<Packet> packet, const WifiMacHeader *hdr);
- Mac48Address GetBroadcastBssid (void);
- void SendProbeRequest (void);
- void SendAssociationRequest (void);
- void TryToEnsureAssociated (void);
- void AssocRequestTimeout (void);
- void ProbeRequestTimeout (void);
- bool IsAssociated (void) const;
- bool IsWaitAssocResp (void) const;
- void MissedBeacons (void);
- void RestartBeaconWatchdog (Time delay);
- SupportedRates GetSupportedRates (void) const;
- virtual void DoDispose (void);
- NqstaWifiMac (const NqstaWifiMac & ctor_arg);
- NqstaWifiMac &operator = (const NqstaWifiMac & ctor_arg);
- Ptr<DcaTxop> GetDcaTxop(void) const;
- void SetState (enum MacState value);
- virtual void FinishConfigureStandard (enum WifiPhyStandard standard);
-
- enum MacState m_state;
- Time m_probeRequestTimeout;
- Time m_assocRequestTimeout;
- EventId m_probeRequestEvent;
- EventId m_assocRequestEvent;
- Callback<void, Ptr<Packet>, Mac48Address, Mac48Address> m_forwardUp;
- Callback<void> m_linkUp;
- Callback<void> m_linkDown;
- Ptr<DcaTxop> m_dca;
- EventId m_beaconWatchdog;
- Time m_beaconWatchdogEnd;
- uint32_t m_maxMissedBeacons;
-
- Ptr<WifiPhy> m_phy;
- Ptr<WifiRemoteStationManager> m_stationManager;
- DcfManager *m_dcfManager;
- MacRxMiddle *m_rxMiddle;
- Ptr<MacLow> m_low;
- Ssid m_ssid;
-
- TracedCallback<Mac48Address> m_assocLogger;
- TracedCallback<Mac48Address> m_deAssocLogger;
-};
-
-} // namespace ns3
-
-
-#endif /* NQSTA_WIFI_MAC_H */
--- a/src/devices/wifi/qadhoc-wifi-mac.cc Wed Dec 01 08:01:24 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,574 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006, 2009 INRIA
- * Copyright (c) 2009 MIRKO BANCHI
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Author: Mirko Banchi <mk.banchi@gmail.com>
- */
-#include "ns3/pointer.h"
-#include "ns3/log.h"
-#include "ns3/string.h"
-
-#include "qos-tag.h"
-#include "edca-txop-n.h"
-#include "qadhoc-wifi-mac.h"
-#include "mac-low.h"
-#include "dcf-manager.h"
-#include "mac-rx-middle.h"
-#include "mac-tx-middle.h"
-#include "wifi-mac-header.h"
-#include "msdu-aggregator.h"
-#include "amsdu-subframe-header.h"
-#include "mgt-headers.h"
-
-NS_LOG_COMPONENT_DEFINE ("QadhocWifiMac");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (QadhocWifiMac);
-
-TypeId
-QadhocWifiMac::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::QadhocWifiMac")
- .SetParent<WifiMac> ()
- .AddConstructor<QadhocWifiMac> ()
- .AddAttribute ("VO_EdcaTxopN",
- "Queue that manages packets belonging to AC_VO access class",
- PointerValue (),
- MakePointerAccessor(&QadhocWifiMac::GetVOQueue),
- MakePointerChecker<EdcaTxopN> ())
- .AddAttribute ("VI_EdcaTxopN",
- "Queue that manages packets belonging to AC_VI access class",
- PointerValue (),
- MakePointerAccessor(&QadhocWifiMac::GetVIQueue),
- MakePointerChecker<EdcaTxopN> ())
- .AddAttribute ("BE_EdcaTxopN",
- "Queue that manages packets belonging to AC_BE access class",
- PointerValue (),
- MakePointerAccessor(&QadhocWifiMac::GetBEQueue),
- MakePointerChecker<EdcaTxopN> ())
- .AddAttribute ("BK_EdcaTxopN",
- "Queue that manages packets belonging to AC_BK access class",
- PointerValue (),
- MakePointerAccessor(&QadhocWifiMac::GetBKQueue),
- MakePointerChecker<EdcaTxopN> ())
- ;
- return tid;
-}
-
-QadhocWifiMac::QadhocWifiMac ()
-{
- NS_LOG_FUNCTION (this);
- m_rxMiddle = new MacRxMiddle ();
- m_rxMiddle->SetForwardCallback (MakeCallback (&QadhocWifiMac::Receive, this));
-
- m_txMiddle = new MacTxMiddle ();
-
- m_low = CreateObject<MacLow> ();
- m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
-
- m_dcfManager = new DcfManager ();
- m_dcfManager->SetupLowListener (m_low);
-
- // Construct the EDCAFs. The ordering is important - highest
- // priority (see Table 9-1 in IEEE 802.11-2007) must be created
- // first.
- SetQueue (AC_VO);
- SetQueue (AC_VI);
- SetQueue (AC_BE);
- SetQueue (AC_BK);
-}
-
-QadhocWifiMac::~QadhocWifiMac ()
-{
- NS_LOG_FUNCTION (this);
-}
-
-void
-QadhocWifiMac::DoDispose (void)
-{
- NS_LOG_FUNCTION (this);
- delete m_rxMiddle;
- m_rxMiddle = 0;
- delete m_txMiddle;
- m_txMiddle = 0;
- delete m_dcfManager;
- m_dcfManager = 0;
- m_low = 0;
- m_phy = 0;
- m_stationManager = 0;
- for (Queues::iterator i = m_queues.begin (); i != m_queues.end (); ++i)
- {
- (*i).second = 0;
- }
- WifiMac::DoDispose ();
-}
-
-void
-QadhocWifiMac::SetSlot (Time slotTime)
-{
- m_dcfManager->SetSlot (slotTime);
- m_low->SetSlotTime (slotTime);
-}
-
-void
-QadhocWifiMac::SetSifs (Time sifs)
-{
- m_dcfManager->SetSifs (sifs);
- m_low->SetSifs (sifs);
-}
-
-void
-QadhocWifiMac::SetEifsNoDifs (Time eifsNoDifs)
-{
- m_dcfManager->SetEifsNoDifs (eifsNoDifs);
- m_eifsNoDifs = eifsNoDifs;
-}
-
-void
-QadhocWifiMac::SetAckTimeout (Time ackTimeout)
-{
- m_low->SetAckTimeout (ackTimeout);
-}
-
-void
-QadhocWifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
-{
- m_low->SetBasicBlockAckTimeout (blockAckTimeout);
-}
-
-void
-QadhocWifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
-{
- m_low->SetCompressedBlockAckTimeout (blockAckTimeout);
-}
-
-void
-QadhocWifiMac::SetCtsTimeout (Time ctsTimeout)
-{
- m_low->SetCtsTimeout (ctsTimeout);
-}
-
-void
-QadhocWifiMac::SetPifs (Time pifs)
-{
- m_low->SetPifs (pifs);
-}
-
-Time
-QadhocWifiMac::GetSlot (void) const
-{
- return m_low->GetSlotTime ();
-}
-
-Time
-QadhocWifiMac::GetSifs (void) const
-{
- return m_low->GetSifs ();
-}
-
-Time
-QadhocWifiMac::GetEifsNoDifs (void) const
-{
- return m_eifsNoDifs;
-}
-
-Time
-QadhocWifiMac::GetAckTimeout (void) const
-{
- return m_low->GetAckTimeout ();
-}
-
-Time
-QadhocWifiMac::GetBasicBlockAckTimeout (void) const
-{
- return m_low->GetBasicBlockAckTimeout ();
-}
-
-Time
-QadhocWifiMac::GetCompressedBlockAckTimeout (void) const
-{
- return m_low->GetCompressedBlockAckTimeout ();
-}
-
-Time
-QadhocWifiMac::GetCtsTimeout (void) const
-{
- return m_low->GetCtsTimeout ();
-}
-
-Time
-QadhocWifiMac::GetPifs (void) const
-{
- return m_low->GetPifs ();
-}
-
-void
-QadhocWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
-{
- m_phy = phy;
- m_dcfManager->SetupPhyListener (phy);
- m_low->SetPhy (phy);
-}
-
-void
-QadhocWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
-{
- NS_LOG_FUNCTION (this << stationManager);
- m_stationManager = stationManager;
- for (Queues::iterator i = m_queues.begin (); i != m_queues.end (); ++i)
- {
- (*i).second->SetWifiRemoteStationManager (stationManager);
- }
- m_low->SetWifiRemoteStationManager (stationManager);
-}
-
-void
-QadhocWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
-{
- NS_FATAL_ERROR ("Adhoc does not support a from != m_low->GetAddress ()");
-}
-
-void
-QadhocWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
-{
- /* For now Qos adhoc stations sends only Qos frame. In the future they
- * should be able to send frames also to Non-Qos Stas.
- */
- NS_LOG_FUNCTION (packet->GetSize () << to);
- WifiMacHeader hdr;
- hdr.SetType (WIFI_MAC_QOSDATA);
- hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
- hdr.SetQosNoEosp ();
- hdr.SetQosNoAmsdu ();
- /* Transmission of multiple frames in the same
- Txop is not supported for now */
- hdr.SetQosTxopLimit (0);
-
- hdr.SetAddr1 (to);
- hdr.SetAddr2 (m_low->GetAddress ());
- hdr.SetAddr3 (GetBssid ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
-
- if (m_stationManager->IsBrandNew (to))
- {
- // in adhoc mode, we assume that every destination
- // supports all the rates we support.
- for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
- {
- m_stationManager->AddSupportedMode (to, m_phy->GetMode (i));
- }
- m_stationManager->RecordDisassociated (to);
- }
-
- uint8_t tid = QosUtilsGetTidForPacket (packet);
- if (tid < 8)
- {
- hdr.SetQosTid (tid);
- AcIndex ac = QosUtilsMapTidToAc (tid);
- m_queues[ac]->Queue (packet, hdr);
- }
- else
- {
- //packet is considerated belonging to BestEffort AC
- hdr.SetQosTid (0);
- m_queues[AC_BE]->Queue (packet, hdr);
- }
-}
-
-bool
-QadhocWifiMac::SupportsSendFrom (void) const
-{
- return false;
-}
-
-void
-QadhocWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
-{
- m_forwardUp = upCallback;
-}
-
-void
-QadhocWifiMac::SetLinkUpCallback (Callback<void> linkUp)
-{
- // an Adhoc network is always UP.
- linkUp ();
-}
-
-void
-QadhocWifiMac::SetLinkDownCallback (Callback<void> linkDown)
-{}
-
-Mac48Address
-QadhocWifiMac::GetAddress (void) const
-{
- return m_low->GetAddress ();
-}
-
-Ssid
-QadhocWifiMac::GetSsid (void) const
-{
- return m_ssid;
-}
-
-void
-QadhocWifiMac::SetAddress (Mac48Address address)
-{
- m_low->SetAddress (address);
- m_low->SetBssid (address);
-}
-
-void
-QadhocWifiMac::SetSsid (Ssid ssid)
-{
- NS_LOG_FUNCTION (this << ssid);
- // XXX: here, we should start a special adhoc network
- m_ssid = ssid;
-}
-
-Mac48Address
-QadhocWifiMac::GetBssid (void) const
-{
- return m_low->GetBssid ();
-}
-
-void
-QadhocWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
-{
- NS_LOG_FUNCTION (this << packet << from);
- m_forwardUp (packet, from, to);
-}
-
-void
-QadhocWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
-{
- NS_LOG_FUNCTION (this << packet << hdr);
- NS_ASSERT (!hdr->IsCtl ());
- Mac48Address from = hdr->GetAddr2 ();
- Mac48Address to = hdr->GetAddr1 ();
- if (hdr->IsData ())
- {
- if (hdr->IsQosData () && hdr->IsQosAmsdu ())
- {
- NS_LOG_DEBUG ("Received A-MSDU from"<<from);
- DeaggregateAmsduAndForward (packet, hdr);
- }
- else
- {
- ForwardUp (packet, from, to);
- }
- }
- else if (hdr->IsMgt ())
- {
- if (hdr->IsAction ())
- {
- WifiActionHeader actionHdr;
- packet->RemoveHeader (actionHdr);
- if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
- actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST)
- {
- MgtAddBaRequestHeader reqHdr;
- packet->RemoveHeader (reqHdr);
- SendAddBaResponse (&reqHdr, hdr->GetAddr2 ());
- }
- else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
- actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE)
- {
- MgtAddBaResponseHeader respHdr;
- packet->RemoveHeader (respHdr);
- m_queues[QosUtilsMapTidToAc (respHdr.GetTid ())]->GotAddBaResponse (&respHdr, hdr->GetAddr2 ());
- }
- else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
- actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_DELBA)
- {
- MgtDelBaHeader delBaHdr;
- packet->RemoveHeader (delBaHdr);
- if (delBaHdr.IsByOriginator ())
- {
- /* Delba frame was sent by originator, this means that an ingoing established
- agreement exists in MacLow */
- m_low->DestroyBlockAckAgreement (hdr->GetAddr2 (), delBaHdr.GetTid ()); }
- else
- {
- /* We must notify correct queue tear down of agreement */
- AcIndex ac = QosUtilsMapTidToAc (delBaHdr.GetTid ());
- m_queues[ac]->GotDelBaFrame (&delBaHdr, hdr->GetAddr2 ());
- }
- }
- }
- }
-}
-
-void
-QadhocWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket,
- const WifiMacHeader *hdr)
-{
- DeaggregatedMsdus packets = MsduAggregator::Deaggregate (aggregatedPacket);
- for (DeaggregatedMsdusCI i = packets.begin (); i != packets.end (); ++i)
- {
- ForwardUp ((*i).first, (*i).second.GetSourceAddr (),
- (*i).second.GetDestinationAddr ());
- }
-}
-
-Ptr<EdcaTxopN>
-QadhocWifiMac::GetVOQueue (void) const
-{
- return m_queues.find (AC_VO)->second;
-}
-
-Ptr<EdcaTxopN>
-QadhocWifiMac::GetVIQueue (void) const
-{
- return m_queues.find (AC_VI)->second;
-}
-
-Ptr<EdcaTxopN>
-QadhocWifiMac::GetBEQueue (void) const
-{
- return m_queues.find (AC_BE)->second;
-}
-void
-QadhocWifiMac::DoStart ()
-{
- for (Queues::iterator i = m_queues.begin (); i != m_queues.end (); ++i)
- {
- i->second->Start ();
- }
- WifiMac::DoStart ();
-}
-
-Ptr<EdcaTxopN>
-QadhocWifiMac::GetBKQueue (void) const
-{
- return m_queues.find (AC_BK)->second;
-}
-
-void
-QadhocWifiMac::SetQueue (enum AcIndex ac)
-{
- Ptr<EdcaTxopN> edca = CreateObject<EdcaTxopN> ();
- edca->SetLow (m_low);
- edca->SetManager (m_dcfManager);
- edca->SetTypeOfStation (ADHOC_STA);
- edca->SetTxMiddle (m_txMiddle);
- edca->SetAccessCategory (ac);
- edca->CompleteConfig ();
- m_queues.insert (std::make_pair(ac, edca));
-}
-
-void
-QadhocWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard)
-{
- switch (standard)
- {
- case WIFI_PHY_STANDARD_80211p_CCH:
- ConfigureCCHDcf (m_queues[AC_BK], 15, 511, AC_BK);
- ConfigureCCHDcf (m_queues[AC_BE], 15, 511, AC_BE);
- ConfigureCCHDcf (m_queues[AC_VI], 15, 511, AC_VI);
- ConfigureCCHDcf (m_queues[AC_VO], 15, 511, AC_VO);
- break;
- case WIFI_PHY_STANDARD_80211p_SCH:
- ConfigureDcf (m_queues[AC_BK], 15, 511, AC_BK);
- ConfigureDcf (m_queues[AC_BE], 15, 511, AC_BE);
- ConfigureDcf (m_queues[AC_VI], 15, 511, AC_VI);
- ConfigureDcf (m_queues[AC_VO], 15, 511, AC_VO);
- break;
- case WIFI_PHY_STANDARD_holland:
- // fall through
- case WIFI_PHY_STANDARD_80211a:
- // fall through
- case WIFI_PHY_STANDARD_80211g:
- // fall through
- case WIFI_PHY_STANDARD_80211_10Mhz:
- // fall through
- case WIFI_PHY_STANDARD_80211_5Mhz:
- ConfigureDcf (m_queues[AC_BK], 15, 1023, AC_BK);
- ConfigureDcf (m_queues[AC_BE], 15, 1023, AC_BE);
- ConfigureDcf (m_queues[AC_VI], 15, 1023, AC_VI);
- ConfigureDcf (m_queues[AC_VO], 15, 1023, AC_VO);
- break;
- case WIFI_PHY_STANDARD_80211b:
- ConfigureDcf (m_queues[AC_BK], 31, 1023, AC_BK);
- ConfigureDcf (m_queues[AC_BE], 31, 1023, AC_BE);
- ConfigureDcf (m_queues[AC_VI], 31, 1023, AC_VI);
- ConfigureDcf (m_queues[AC_VO], 31, 1023, AC_VO);
- break;
- default:
- NS_ASSERT (false);
- break;
- }
-}
-
-
-void
-QadhocWifiMac::SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator)
-{
- NS_LOG_FUNCTION (this);
- WifiMacHeader hdr;
- hdr.SetAction ();
- hdr.SetAddr1 (originator);
- hdr.SetAddr2 (m_low->GetAddress ());
- hdr.SetAddr3 (m_low->GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
-
- MgtAddBaResponseHeader respHdr;
- StatusCode code;
- code.SetSuccess ();
- respHdr.SetStatusCode (code);
- //Here a control about queues type?
- respHdr.SetAmsduSupport (reqHdr->IsAmsduSupported ());
-
- if (reqHdr->IsImmediateBlockAck ())
- {
- respHdr.SetImmediateBlockAck ();
- }
- else
- {
- respHdr.SetDelayedBlockAck ();
- }
- respHdr.SetTid (reqHdr->GetTid ());
- /* For now there's not no control about limit of reception.
- We assume that receiver has no limit on reception.
- However we assume that a receiver sets a bufferSize in order to satisfy
- next equation:
- (bufferSize + 1) % 16 = 0
- So if a recipient is able to buffer a packet, it should be also able to buffer
- all possible packet's fragments.
- See section 7.3.1.14 in IEEE802.11e for more details. */
- respHdr.SetBufferSize (1023);
- respHdr.SetTimeout (reqHdr->GetTimeout ());
-
- WifiActionHeader actionHdr;
- WifiActionHeader::ActionValue action;
- action.blockAck = WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE;
- actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
-
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (respHdr);
- packet->AddHeader (actionHdr);
-
- /* ns3::MacLow have to buffer all correctly received packet for this block ack session */
- m_low->CreateBlockAckAgreement (&respHdr, originator, reqHdr->GetStartingSequence ());
-
- //Better a management queue?
- m_queues[QosUtilsMapTidToAc (reqHdr->GetTid ())]->PushFront (packet, hdr);
-}
-} //namespace ns3
--- a/src/devices/wifi/qadhoc-wifi-mac.h Wed Dec 01 08:01:24 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006, 2009 INRIA
- * Copyright (c) 2009 MIRKO BANCHI
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Author: Mirko Banchi <mk.banchi@gmail.com>
- */
-#ifndef QADHOC_WIFI_MAC_H
-#define QADHOC_WIFI_MAC_H
-
-#include "ns3/mac48-address.h"
-#include "ns3/callback.h"
-#include "ns3/packet.h"
-
-#include "wifi-mac.h"
-#include "qos-utils.h"
-#include "amsdu-subframe-header.h"
-
-namespace ns3 {
-
-class EdcaTxopN;
-class WifiMacHeader;
-class WifiPhy;
-class DcfManager;
-class MacLow;
-class MacRxMiddle;
-class MgtAddBaRequestHeader;
-
-class QadhocWifiMac : public WifiMac
-{
-public:
- static TypeId GetTypeId (void);
-
- QadhocWifiMac ();
- ~QadhocWifiMac ();
-
- // all inherited from WifiMac base class.
- virtual void SetSlot (Time slotTime);
- virtual void SetSifs (Time sifs);
- virtual void SetEifsNoDifs (Time eifsNoDifs);
- virtual void SetAckTimeout (Time ackTimeout);
- virtual void SetCtsTimeout (Time ctsTimeout);
- virtual void SetPifs (Time pifs);
- virtual Time GetSlot (void) const;
- virtual Time GetSifs (void) const;
- virtual Time GetEifsNoDifs (void) const;
- virtual Time GetAckTimeout (void) const;
- virtual Time GetCtsTimeout (void) const;
- virtual Time GetPifs (void) const;
- virtual void SetWifiPhy (Ptr<WifiPhy> phy);
- virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
- virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
- virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
- virtual bool SupportsSendFrom (void) const;
- virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
- virtual void SetLinkUpCallback (Callback<void> linkUp);
- virtual void SetLinkDownCallback (Callback<void> linkDown);
- virtual Mac48Address GetAddress (void) const;
- virtual Ssid GetSsid (void) const;
- virtual void SetAddress (Mac48Address address);
- virtual void SetSsid (Ssid ssid);
- virtual Mac48Address GetBssid (void) const;
- virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
- virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
- virtual Time GetBasicBlockAckTimeout (void) const;
- virtual Time GetCompressedBlockAckTimeout (void) const;
-
-
-private:
- Callback<void, Ptr<Packet>, Mac48Address, Mac48Address> m_forwardUp;
- virtual void DoDispose (void);
- void DoStart ();
- void Receive (Ptr<Packet> packet, const WifiMacHeader *hdr);
- void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
- QadhocWifiMac &operator = (const QadhocWifiMac &);
- QadhocWifiMac (const QadhocWifiMac &);
- void SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator);
-
- /**
- * When an A-MSDU is received, is deaggregated by this method and all extracted packets are
- * forwarded up.
- */
- void DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, const WifiMacHeader *hdr);
-
- typedef std::map<AcIndex, Ptr<EdcaTxopN> > Queues;
- typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> > DeaggregatedMsdus;
- typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> >::const_iterator DeaggregatedMsdusCI;
-
- virtual void FinishConfigureStandard (enum WifiPhyStandard standard);
- void SetQueue (enum AcIndex ac);
- Ptr<EdcaTxopN> GetVOQueue (void) const;
- Ptr<EdcaTxopN> GetVIQueue (void) const;
- Ptr<EdcaTxopN> GetBEQueue (void) const;
- Ptr<EdcaTxopN> GetBKQueue (void) const;
-
- Queues m_queues;
- Ptr<MacLow> m_low;
- Ptr<WifiPhy> m_phy;
- Ptr<WifiRemoteStationManager> m_stationManager;
- MacRxMiddle *m_rxMiddle;
- MacTxMiddle *m_txMiddle;
- DcfManager *m_dcfManager;
- Ssid m_ssid;
- Time m_eifsNoDifs;
-};
-
-} //namespace ns3
-
-#endif /* QADHOC_WIFI_MAC_H */
--- a/src/devices/wifi/qap-wifi-mac.cc Wed Dec 01 08:01:24 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,937 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006, 2009 INRIA
- * Copyright (c) 2009 MIRKO BANCHI
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Author: Mirko Banchi <mk.banchi@gmail.com>
- */
-#include "ns3/assert.h"
-#include "ns3/log.h"
-#include "ns3/simulator.h"
-#include "ns3/string.h"
-#include "ns3/pointer.h"
-#include "ns3/boolean.h"
-
-#include "qos-tag.h"
-#include "qap-wifi-mac.h"
-#include "dca-txop.h"
-#include "edca-txop-n.h"
-#include "wifi-phy.h"
-#include "dcf-manager.h"
-#include "mac-rx-middle.h"
-#include "mac-tx-middle.h"
-#include "mgt-headers.h"
-#include "mac-low.h"
-#include "amsdu-subframe-header.h"
-#include "msdu-aggregator.h"
-
-NS_LOG_COMPONENT_DEFINE ("QapWifiMac");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (QapWifiMac);
-
-TypeId
-QapWifiMac::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::QapWifiMac")
- .SetParent<WifiMac> ()
- .AddConstructor<QapWifiMac> ()
- .AddAttribute ("BeaconInterval", "Delay between two beacons",
- TimeValue (MicroSeconds (102400)),
- MakeTimeAccessor (&QapWifiMac::GetBeaconInterval,
- &QapWifiMac::SetBeaconInterval),
- MakeTimeChecker ())
- .AddAttribute ("BeaconGeneration", "Whether or not beacons are generated.",
- BooleanValue (true),
- MakeBooleanAccessor (&QapWifiMac::SetBeaconGeneration,
- &QapWifiMac::GetBeaconGeneration),
- MakeBooleanChecker ())
- .AddAttribute ("VO_EdcaTxopN",
- "Queue that manages packets belonging to AC_VO access class",
- PointerValue (),
- MakePointerAccessor(&QapWifiMac::GetVOQueue),
- MakePointerChecker<EdcaTxopN> ())
- .AddAttribute ("VI_EdcaTxopN",
- "Queue that manages packets belonging to AC_VI access class",
- PointerValue (),
- MakePointerAccessor(&QapWifiMac::GetVIQueue),
- MakePointerChecker<EdcaTxopN> ())
- .AddAttribute ("BE_EdcaTxopN",
- "Queue that manages packets belonging to AC_BE access class",
- PointerValue (),
- MakePointerAccessor(&QapWifiMac::GetBEQueue),
- MakePointerChecker<EdcaTxopN> ())
- .AddAttribute ("BK_EdcaTxopN",
- "Queue that manages packets belonging to AC_BK access class",
- PointerValue (),
- MakePointerAccessor(&QapWifiMac::GetBKQueue),
- MakePointerChecker<EdcaTxopN> ())
- ;
- return tid;
-}
-
-QapWifiMac::QapWifiMac ()
-{
- NS_LOG_FUNCTION (this);
- m_rxMiddle = new MacRxMiddle ();
- m_rxMiddle->SetForwardCallback (MakeCallback (&QapWifiMac::Receive, this));
-
- m_txMiddle = new MacTxMiddle ();
-
- m_low = CreateObject<MacLow> ();
- m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
-
- m_dcfManager = new DcfManager ();
- m_dcfManager->SetupLowListener (m_low);
-
- m_beaconDca = CreateObject<DcaTxop> ();
- m_beaconDca->SetAifsn(1);
- m_beaconDca->SetMinCw(0);
- m_beaconDca->SetMaxCw(0);
- m_beaconDca->SetLow (m_low);
- m_beaconDca->SetManager (m_dcfManager);
-
- // Construct the EDCAFs. The ordering is important - highest
- // priority (see Table 9-1 in IEEE 802.11-2007) must be created
- // first.
- SetQueue (AC_VO);
- SetQueue (AC_VI);
- SetQueue (AC_BE);
- SetQueue (AC_BK);
-
- m_enableBeaconGeneration = false;
-}
-
-QapWifiMac::~QapWifiMac ()
-{
- NS_LOG_FUNCTION (this);
-}
-
-void
-QapWifiMac::DoDispose ()
-{
- delete m_rxMiddle;
- delete m_txMiddle;
- delete m_dcfManager;
- m_low->Dispose ();
- m_rxMiddle = 0;
- m_txMiddle = 0;
- m_dcfManager = 0;
- m_low = 0;
- m_phy = 0;
- m_beaconDca = 0;
- m_enableBeaconGeneration = false;
- m_beaconEvent.Cancel ();
- m_stationManager = 0;
- for (Queues::iterator i = m_queues.begin (); i != m_queues.end (); ++i)
- {
- (*i).second = 0;
- }
- WifiMac::DoDispose ();
-}
-
-void
-QapWifiMac::SetBeaconGeneration (bool enable)
-{
- NS_LOG_FUNCTION (this << enable);
- if (!enable)
- {
- m_beaconEvent.Cancel ();
- }
- else if (enable && !m_enableBeaconGeneration)
- {
- m_beaconEvent = Simulator::ScheduleNow (&QapWifiMac::SendOneBeacon, this);
- }
- m_enableBeaconGeneration = enable;
-}
-
-bool
-QapWifiMac::GetBeaconGeneration (void) const
-{
- return m_enableBeaconGeneration;
-}
-
-Time
-QapWifiMac::GetBeaconInterval (void) const
-{
- return m_beaconInterval;
-}
-
-void
-QapWifiMac::SetSlot (Time slotTime)
-{
- NS_LOG_FUNCTION (this << slotTime);
- m_dcfManager->SetSlot (slotTime);
- m_low->SetSlotTime (slotTime);
-}
-
-void
-QapWifiMac::SetSifs (Time sifs)
-{
- NS_LOG_FUNCTION (this << sifs);
- m_dcfManager->SetSifs (sifs);
- m_low->SetSifs (sifs);
-}
-
-void
-QapWifiMac::SetEifsNoDifs (Time eifsNoDifs)
-{
- NS_LOG_FUNCTION (this << eifsNoDifs);
- m_dcfManager->SetEifsNoDifs (eifsNoDifs);
-}
-
-void
-QapWifiMac::SetAckTimeout (Time ackTimeout)
-{
- m_low->SetAckTimeout (ackTimeout);
-}
-
-void
-QapWifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
-{
- m_low->SetBasicBlockAckTimeout (blockAckTimeout);
-}
-
-void
-QapWifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
-{
- m_low->SetCompressedBlockAckTimeout (blockAckTimeout);
-}
-
-void
-QapWifiMac::SetCtsTimeout (Time ctsTimeout)
-{
- m_low->SetCtsTimeout (ctsTimeout);
-}
-
-void
-QapWifiMac::SetPifs (Time pifs)
-{
- m_low->SetPifs (pifs);
-}
-
-Time
-QapWifiMac::GetSlot (void) const
-{
- return m_low->GetSlotTime ();
-}
-
-Time
-QapWifiMac::GetSifs (void) const
-{
- return m_low->GetSifs ();
-}
-
-Time
-QapWifiMac::GetEifsNoDifs (void) const
-{
- return m_dcfManager->GetEifsNoDifs ();
-}
-
-Time
-QapWifiMac::GetAckTimeout (void) const
-{
- return m_low->GetAckTimeout ();
-}
-
-Time
-QapWifiMac::GetBasicBlockAckTimeout () const
-{
- return m_low->GetBasicBlockAckTimeout ();
-}
-
-Time
-QapWifiMac::GetCompressedBlockAckTimeout () const
-{
- return m_low->GetCompressedBlockAckTimeout ();
-}
-
-Time
-QapWifiMac::GetCtsTimeout (void) const
-{
- return m_low->GetCtsTimeout ();
-}
-
-Time
-QapWifiMac::GetPifs (void) const
-{
- return m_low->GetPifs ();
-}
-
-void
-QapWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
-{
- NS_LOG_FUNCTION (this << phy);
- m_phy = phy;
- m_dcfManager->SetupPhyListener (phy);
- m_low->SetPhy (phy);
-}
-
-void
-QapWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
-{
- NS_LOG_FUNCTION (this << stationManager);
- m_stationManager = stationManager;
- for (Queues::iterator i = m_queues.begin (); i != m_queues.end (); ++i)
- {
- (*i).second->SetWifiRemoteStationManager (stationManager);
- }
- m_beaconDca->SetWifiRemoteStationManager (stationManager);
- m_low->SetWifiRemoteStationManager (stationManager);
-}
-
-void
-QapWifiMac::SetForwardUpCallback (Callback<void, Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
-{
- NS_LOG_FUNCTION (this);
- m_forwardUp = upCallback;
-}
-
-void
-QapWifiMac::SetLinkUpCallback (Callback<void> linkUp)
-{
- NS_LOG_FUNCTION (this);
- if (!linkUp.IsNull ())
- {
- linkUp ();
- }
-}
-
-void
-QapWifiMac::SetLinkDownCallback (Callback<void> linkDown)
-{
- NS_LOG_FUNCTION (this);
-}
-
-Mac48Address
-QapWifiMac::GetAddress () const
-{
- return m_low->GetAddress ();
-}
-
-Ssid
-QapWifiMac::GetSsid (void) const
-{
- return m_ssid;
-}
-
-void
-QapWifiMac::SetAddress (Mac48Address address)
-{
- NS_LOG_FUNCTION (address);
- m_low->SetAddress (address);
- m_low->SetBssid (address);
-}
-
-void
-QapWifiMac::SetSsid (Ssid ssid)
-{
- NS_LOG_FUNCTION (this << ssid);
- m_ssid = ssid;
-}
-
-Mac48Address
-QapWifiMac::GetBssid (void) const
-{
- return m_low->GetBssid ();
-}
-
-void
-QapWifiMac::SetBeaconInterval (Time interval)
-{
- NS_LOG_FUNCTION (this << interval);
- if ((interval.GetMicroSeconds () % 1024) != 0)
- {
- NS_LOG_WARN ("beacon interval should be multiple of 1024us, see IEEE Std. 802.11-2007, section 11.1.1.1");
- }
- m_beaconInterval = interval;
-}
-
-void
-QapWifiMac::StartBeaconing (void)
-{
- NS_LOG_FUNCTION (this);
- SendOneBeacon ();
-}
-
-void
-QapWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
-{
- NS_LOG_FUNCTION (this << packet << from);
- m_forwardUp (packet, from, to);
-}
-
-void
-QapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
-{
- /* For now Qos AP sends only Qos frame. In the future it should be able to
- send frames also to Non-Qos Stas.
- */
- NS_LOG_FUNCTION (this << packet << from << to);
- WifiMacHeader hdr;
- hdr.SetType (WIFI_MAC_QOSDATA);
- hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
- hdr.SetQosNoEosp ();
- hdr.SetQosNoAmsdu ();
- /* Transmission of multiple frames in the same
- Txop is not supported for now */
- hdr.SetQosTxopLimit (0);
-
- hdr.SetAddr1 (to);
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (from);
- hdr.SetDsFrom ();
- hdr.SetDsNotTo ();
-
- uint8_t tid = QosUtilsGetTidForPacket (packet);
- if (tid < 8)
- {
- hdr.SetQosTid (tid);
- AcIndex ac = QosUtilsMapTidToAc (tid);
- m_queues[ac]->Queue (packet, hdr);
- }
- else
- {
- //packet is considerated belonging to BestEffort AC
- hdr.SetQosTid (0);
- m_queues[AC_BE]->Queue (packet, hdr);
- }
-}
-
-void
-QapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to,
- const WifiMacHeader *oldHdr)
-{
- /* For now Qos AP sends only Qos frame. In the future it should be able to
- send frames also to Non-Qos Stas.
- */
- NS_LOG_FUNCTION (this << packet << from << to);
- NS_ASSERT (oldHdr->IsQosData ());
- WifiMacHeader hdr;
- hdr.SetType (WIFI_MAC_QOSDATA);
- hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
- hdr.SetQosNoEosp ();
- hdr.SetQosNoAmsdu ();
- /* Transmission of multiple frames in the same
- Txop is not supported for now */
- hdr.SetQosTxopLimit (0);
- hdr.SetQosTid (oldHdr->GetQosTid ());
-
- hdr.SetAddr1 (to);
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (from);
- hdr.SetDsFrom ();
- hdr.SetDsNotTo ();
-
- AcIndex ac = QosUtilsMapTidToAc (oldHdr->GetQosTid ());
- m_queues[ac]->Queue (packet, hdr);
-}
-
-void
-QapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
-{
- NS_LOG_FUNCTION (this << packet << from << to);
- if (to.IsBroadcast () || m_stationManager->IsAssociated (to))
- {
- ForwardDown (packet, from, to);
- }
-}
-
-void
-QapWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
-{
- NS_LOG_FUNCTION (this << packet << to);
- if (to.IsBroadcast () || m_stationManager->IsAssociated (to))
- {
- ForwardDown (packet, m_low->GetAddress (), to);
- }
-}
-
-bool
-QapWifiMac::SupportsSendFrom (void) const
-{
- return true;
-}
-
-SupportedRates
-QapWifiMac::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
-QapWifiMac::SendProbeResp (Mac48Address to)
-{
- NS_LOG_FUNCTION (this << to);
- WifiMacHeader hdr;
- hdr.SetProbeResp ();
- hdr.SetAddr1 (to);
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Ptr<Packet> packet = Create<Packet> ();
- MgtProbeResponseHeader probe;
- probe.SetSsid (GetSsid ());
- probe.SetSupportedRates (GetSupportedRates ());
- probe.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
- packet->AddHeader (probe);
-
- /* Which is correct queue for management frames ? */
- m_queues[AC_VO]->Queue (packet, hdr);
-}
-
-void
-QapWifiMac::SendAssocResp (Mac48Address to, bool success)
-{
- NS_LOG_FUNCTION (this << to << success);
- WifiMacHeader hdr;
- hdr.SetAssocResp ();
- hdr.SetAddr1 (to);
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Ptr<Packet> packet = Create<Packet> ();
- MgtAssocResponseHeader assoc;
- StatusCode code;
- if (success)
- {
- code.SetSuccess ();
- }
- else
- {
- code.SetFailure ();
- }
- assoc.SetSupportedRates (GetSupportedRates ());
- assoc.SetStatusCode (code);
- packet->AddHeader (assoc);
-
- /* Which is correct queue for management frames ? */
- m_queues[AC_VO]->Queue (packet, hdr);
-}
-
-void
-QapWifiMac::SendOneBeacon (void)
-{
- NS_LOG_FUNCTION (this);
- WifiMacHeader hdr;
- hdr.SetBeacon ();
- hdr.SetAddr1 (Mac48Address::GetBroadcast ());
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Ptr<Packet> packet = Create<Packet> ();
- MgtBeaconHeader beacon;
- beacon.SetSsid (GetSsid ());
- beacon.SetSupportedRates (GetSupportedRates ());
- beacon.SetBeaconIntervalUs (m_beaconInterval.GetMicroSeconds ());
-
- packet->AddHeader (beacon);
-
- m_beaconDca->Queue (packet, hdr);
- m_beaconEvent = Simulator::Schedule (m_beaconInterval, &QapWifiMac::SendOneBeacon, this);
-}
-
-void
-QapWifiMac::TxOk (const WifiMacHeader &hdr)
-{
- NS_LOG_FUNCTION (this);
- if (hdr.IsAssocResp () &&
- m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
- {
- NS_LOG_DEBUG ("associated with sta="<<hdr.GetAddr1 ());
- m_stationManager->RecordGotAssocTxOk (hdr.GetAddr1 ());
- }
-}
-
-void
-QapWifiMac::TxFailed (const WifiMacHeader &hdr)
-{
- NS_LOG_FUNCTION (this);
- if (hdr.IsAssocResp () &&
- m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
- {
- NS_LOG_DEBUG ("assoc failed with sta="<<hdr.GetAddr1 ());
- m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ());
- }
-}
-
-void
-QapWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
-{
- NS_LOG_FUNCTION (this << packet << hdr);
-
- Mac48Address from = hdr->GetAddr2 ();
-
- if (hdr->IsData ())
- {
- Mac48Address bssid = hdr->GetAddr1 ();
- if (!hdr->IsFromDs () &&
- hdr->IsToDs () &&
- bssid == GetAddress () &&
- m_stationManager->IsAssociated (from))
- {
- Mac48Address to = hdr->GetAddr3 ();
-
- if (to == GetAddress ())
- {
- NS_LOG_DEBUG ("frame for me (Qap) from="<<from);
- if (hdr->IsQosData ())
- {
- if (hdr->IsQosAmsdu ())
- {
- NS_LOG_DEBUG ("Received A-MSDU from="<<from<<", size="<<packet->GetSize ());
- DeaggregateAmsduAndForward (packet, hdr);
- packet = 0;
- }
- else
- {
- ForwardUp (packet, from, bssid);
- }
- }
- else
- {
- ForwardUp (packet, from, bssid);
- }
- }
- else if (to.IsGroup () ||
- m_stationManager->IsAssociated (to))
- {
- NS_LOG_DEBUG ("forwarding frame from="<<from<<", to="<<to);
- Ptr<Packet> copy = packet->Copy ();
- ForwardDown (packet, from, to, hdr);
- ForwardUp (copy, from, to);
- }
- else
- {
- ForwardUp (packet, from, to);
- }
- }
- 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 ()))
- {
- m_stationManager->AddSupportedMode (from, mode);
- }
- }
- m_stationManager->RecordWaitAssocTxOk (from);
- // send assoc response with success status.
- SendAssocResp (hdr->GetAddr2 (), true);
- }
- }
- else if (hdr->IsDisassociation ())
- {
- m_stationManager->RecordDisassociated (from);
- }
- else if (hdr->IsReassocReq ())
- {
- /* we don't support reassoc frames for now */
- }
- else if (hdr->IsAction ())
- {
- WifiActionHeader actionHdr;
- packet->RemoveHeader (actionHdr);
- if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
- actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST)
- {
- MgtAddBaRequestHeader reqHdr;
- packet->RemoveHeader (reqHdr);
- SendAddBaResponse (&reqHdr, hdr->GetAddr2 ());
- }
- else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
- actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE)
- {
- MgtAddBaResponseHeader respHdr;
- packet->RemoveHeader (respHdr);
- m_queues[QosUtilsMapTidToAc (respHdr.GetTid ())]->GotAddBaResponse (&respHdr, hdr->GetAddr2 ());
- }
- else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
- actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_DELBA)
- {
- MgtDelBaHeader delBaHdr;
- packet->RemoveHeader (delBaHdr);
- if (delBaHdr.IsByOriginator ())
- {
- /* Delba frame was sent by originator, this means that an ingoing established
- agreement exists in MacLow */
- m_low->DestroyBlockAckAgreement (hdr->GetAddr2 (), delBaHdr.GetTid ());
- }
- else
- {
- /* We must notify correct queue tear down of agreement */
- AcIndex ac = QosUtilsMapTidToAc (delBaHdr.GetTid ());
- m_queues[ac]->GotDelBaFrame (&delBaHdr, hdr->GetAddr2 ());
- }
- }
- }
- else if (hdr->IsAuthentication () ||
- hdr->IsDeauthentication ())
- {
- /*
- */
- }
- else
- {
- /* unknown mgt frame
- */
- }
- }
- }
-}
-
-void
-QapWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, const WifiMacHeader *hdr)
-{
- DeaggregatedMsdus packets = MsduAggregator::Deaggregate (aggregatedPacket);
- for (DeaggregatedMsdusCI i = packets.begin (); i != packets.end (); ++i)
- {
- if ((*i).second.GetDestinationAddr () == GetAddress ())
- {
- ForwardUp ((*i).first, (*i).second.GetSourceAddr (),
- (*i).second.GetDestinationAddr ());
- }
- else
- {
- Mac48Address from = (*i).second.GetSourceAddr ();
- Mac48Address to = (*i).second.GetDestinationAddr ();
- NS_LOG_DEBUG ("forwarding QoS frame from="<<from<<", to="<<to);
- ForwardDown ((*i).first, from, to, hdr);
- }
- }
-}
-
-Ptr<EdcaTxopN>
-QapWifiMac::GetVOQueue (void) const
-{
- return m_queues.find (AC_VO)->second;
-}
-
-Ptr<EdcaTxopN>
-QapWifiMac::GetVIQueue (void) const
-{
- return m_queues.find (AC_VI)->second;
-}
-
-Ptr<EdcaTxopN>
-QapWifiMac::GetBEQueue (void) const
-{
- return m_queues.find (AC_BE)->second;
-}
-
-Ptr<EdcaTxopN>
-QapWifiMac::GetBKQueue (void) const
-{
- return m_queues.find (AC_BK)->second;
-}
-
-void
-QapWifiMac::SetQueue (enum AcIndex ac)
-{
- Ptr<EdcaTxopN> edca = CreateObject<EdcaTxopN> ();
- edca->SetLow (m_low);
- edca->SetManager (m_dcfManager);
- edca->SetTypeOfStation (AP);
- edca->SetTxMiddle (m_txMiddle);
- edca->SetTxOkCallback (MakeCallback (&QapWifiMac::TxOk, this));
- edca->SetTxFailedCallback (MakeCallback (&QapWifiMac::TxFailed, this));
- edca->SetAccessCategory (ac);
- edca->CompleteConfig ();
- m_queues.insert (std::make_pair(ac, edca));
-}
-
-void
-QapWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard)
-{
- switch (standard)
- {
- case WIFI_PHY_STANDARD_80211p_CCH:
- ConfigureCCHDcf (m_queues[AC_BK], 15, 511, AC_BK);
- ConfigureCCHDcf (m_queues[AC_BE], 15, 511, AC_BE);
- ConfigureCCHDcf (m_queues[AC_VI], 15, 511, AC_VI);
- ConfigureCCHDcf (m_queues[AC_VO], 15, 511, AC_VO);
- break;
- case WIFI_PHY_STANDARD_80211p_SCH:
- ConfigureDcf (m_queues[AC_BK], 15, 511, AC_BK);
- ConfigureDcf (m_queues[AC_BE], 15, 511, AC_BE);
- ConfigureDcf (m_queues[AC_VI], 15, 511, AC_VI);
- ConfigureDcf (m_queues[AC_VO], 15, 511, AC_VO);
- break;
- case WIFI_PHY_STANDARD_holland:
- // fall through
- case WIFI_PHY_STANDARD_80211a:
- // fall through
- case WIFI_PHY_STANDARD_80211g:
- // fall through
- case WIFI_PHY_STANDARD_80211_10Mhz:
- // fall through
- case WIFI_PHY_STANDARD_80211_5Mhz:
- ConfigureDcf (m_queues[AC_BK], 15, 1023, AC_BK);
- ConfigureDcf (m_queues[AC_BE], 15, 1023, AC_BE);
- ConfigureDcf (m_queues[AC_VI], 15, 1023, AC_VI);
- ConfigureDcf (m_queues[AC_VO], 15, 1023, AC_VO);
- break;
- case WIFI_PHY_STANDARD_80211b:
- ConfigureDcf (m_queues[AC_BK], 31, 1023, AC_BK);
- ConfigureDcf (m_queues[AC_BE], 31, 1023, AC_BE);
- ConfigureDcf (m_queues[AC_VI], 31, 1023, AC_VI);
- ConfigureDcf (m_queues[AC_VO], 31, 1023, AC_VO);
- break;
- default:
- NS_ASSERT (false);
- break;
- }
-}
-
-void
-QapWifiMac::DoStart (void)
-{
- m_beaconDca->Start ();
- for (Queues::iterator i = m_queues.begin (); i != m_queues.end (); ++i)
- {
- i->second->Start ();
- }
- m_beaconEvent.Cancel ();
- if (m_enableBeaconGeneration)
- {
- m_beaconEvent = Simulator::ScheduleNow (&QapWifiMac::SendOneBeacon, this);
- }
- WifiMac::DoStart ();
-}
-
-void
-QapWifiMac::SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator)
-{
- NS_LOG_FUNCTION (this);
- WifiMacHeader hdr;
- hdr.SetAction ();
- hdr.SetAddr1 (originator);
- hdr.SetAddr2 (m_low->GetAddress ());
- hdr.SetAddr3 (m_low->GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
-
- MgtAddBaResponseHeader respHdr;
- StatusCode code;
- code.SetSuccess ();
- respHdr.SetStatusCode (code);
- //Here a control about queues type?
- respHdr.SetAmsduSupport (reqHdr->IsAmsduSupported ());
-
- if (reqHdr->IsImmediateBlockAck ())
- {
- respHdr.SetImmediateBlockAck ();
- }
- else
- {
- respHdr.SetDelayedBlockAck ();
- }
- respHdr.SetTid (reqHdr->GetTid ());
- /* For now there's not no control about limit of reception.
- We assume that receiver has no limit on reception.
- However we assume that a receiver sets a bufferSize in order to satisfy
- next equation:
- (bufferSize + 1) % 16 = 0
- So if a recipient is able to buffer a packet, it should be also able to buffer
- all possible packet's fragments.
- See section 7.3.1.14 in IEEE802.11e for more details. */
- respHdr.SetBufferSize (1023);
- respHdr.SetTimeout (reqHdr->GetTimeout ());
-
- WifiActionHeader actionHdr;
- WifiActionHeader::ActionValue action;
- action.blockAck = WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE;
- actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
-
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (respHdr);
- packet->AddHeader (actionHdr);
-
- /* ns3::MacLow have to buffer all correctly received packet for this block ack session */
- m_low->CreateBlockAckAgreement (&respHdr, originator, reqHdr->GetStartingSequence ());
-
- //Better a management queue?
- m_queues[QosUtilsMapTidToAc (reqHdr->GetTid ())]->PushFront (packet, hdr);
-}
-
-} //namespace ns3
--- a/src/devices/wifi/qap-wifi-mac.h Wed Dec 01 08:01:24 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006, 2009 INRIA
- * Copyright (c) 2009 MIRKO BANCHI
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Author: Mirko Banchi <mk.banchi@gmail.com>
- */
-#ifndef QAP_WIFI_MAC_H
-#define QAP_WIFI_MAC_H
-
-#include "ns3/mac48-address.h"
-#include "ns3/callback.h"
-#include "ns3/packet.h"
-#include "ns3/nstime.h"
-#include "ns3/event-id.h"
-
-#include "supported-rates.h"
-#include "wifi-remote-station-manager.h"
-#include "wifi-mac.h"
-#include "qos-utils.h"
-
-#include <map>
-
-namespace ns3 {
-
-class DcaTxop;
-class EdcaTxopN;
-class WifiMacHeader;
-class WifiPhy;
-class MacLow;
-class MacRxMiddle;
-class MacTxMiddle;
-class DcfManager;
-class AmsduSubframeHeader;
-class MsduAggregator;
-class MgtAddBaRequestHeader;
-
-class QapWifiMac : public WifiMac
-{
-public:
- static TypeId GetTypeId (void);
- QapWifiMac ();
- virtual ~QapWifiMac ();
-
- // inherited from WifiMac.
- virtual void SetSlot (Time slotTime);
- virtual void SetSifs (Time sifs);
- virtual void SetEifsNoDifs (Time eifsNoDifs);
- virtual void SetAckTimeout (Time ackTimeout);
- virtual void SetCtsTimeout (Time ctsTimeout);
- virtual void SetPifs (Time pifs);
- virtual Time GetSlot (void) const;
- virtual Time GetSifs (void) const;
- virtual Time GetEifsNoDifs (void) const;
- virtual Time GetAckTimeout (void) const;
- virtual Time GetCtsTimeout (void) const;
- virtual Time GetPifs (void) const;
- virtual void SetWifiPhy (Ptr<WifiPhy> phy);
- virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
- virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
- virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
- virtual bool SupportsSendFrom (void) const;
- virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
- virtual void SetLinkUpCallback (Callback<void> linkUp);
- virtual void SetLinkDownCallback (Callback<void> linkDown);
- virtual Mac48Address GetAddress (void) const;
- virtual Ssid GetSsid (void) const;
- virtual void SetAddress (Mac48Address address);
- virtual void SetSsid (Ssid ssid);
- virtual Mac48Address GetBssid (void) const;
- virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
- virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
- virtual Time GetBasicBlockAckTimeout (void) const;
- virtual Time GetCompressedBlockAckTimeout (void) const;
-
- void SetBeaconInterval (Time interval);
- Time GetBeaconInterval (void) const;
- void StartBeaconing (void);
-
-private:
- typedef std::map<AcIndex, Ptr<EdcaTxopN> > Queues;
- typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> > DeaggregatedMsdus;
- typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> >::const_iterator DeaggregatedMsdusCI;
-
- virtual void DoDispose (void);
- virtual void DoStart (void);
- void Receive (Ptr<Packet> packet, const WifiMacHeader* hdr);
- void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
- void ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to);
- /* Next function is invoked only when ap relies a frame. */
- void ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to,
- const WifiMacHeader* oldHdr);
- void TxOk (const WifiMacHeader& hdr);
- void TxFailed (const WifiMacHeader& hdr);
- void SendProbeResp (Mac48Address to);
- void SendAssocResp (Mac48Address to, bool success);
- void SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator);
- void SendOneBeacon (void);
- SupportedRates GetSupportedRates (void) const;
- void SetBeaconGeneration (bool enable);
- bool GetBeaconGeneration (void) const;
-
- void DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, const WifiMacHeader* hdr);
- QapWifiMac &operator = (const QapWifiMac &);
- QapWifiMac (const QapWifiMac &);
-
- Ptr<EdcaTxopN> GetVOQueue (void) const;
- Ptr<EdcaTxopN> GetVIQueue (void) const;
- Ptr<EdcaTxopN> GetBEQueue (void) const;
- Ptr<EdcaTxopN> GetBKQueue (void) const;
- void SetQueue (enum AcIndex ac);
-
- virtual void FinishConfigureStandard (enum WifiPhyStandard standard);
-
- Queues m_queues;
- Ptr<DcaTxop> m_beaconDca;
- Ptr<MacLow> m_low;
- Ptr<WifiPhy> m_phy;
- Ptr<WifiRemoteStationManager> m_stationManager;
- MacRxMiddle *m_rxMiddle;
- MacTxMiddle *m_txMiddle;
- DcfManager *m_dcfManager;
- Ssid m_ssid;
- EventId m_beaconEvent;
- Time m_beaconInterval;
- bool m_enableBeaconGeneration;
- Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> m_forwardUp;
-};
-
-} //namespace ns3
-
-#endif /* QAP_WIFI_MAC_H */
--- a/src/devices/wifi/qsta-wifi-mac.cc Wed Dec 01 08:01:24 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,910 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006, 2009 INRIA
- * Copyright (c) 2009 MIRKO BANCHI
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Author: Mirko Banchi <mk.banchi@gmail.com>
- */
-#include "ns3/log.h"
-#include "ns3/simulator.h"
-#include "ns3/string.h"
-#include "ns3/pointer.h"
-#include "ns3/boolean.h"
-
-#include "qos-tag.h"
-#include "edca-txop-n.h"
-#include "qsta-wifi-mac.h"
-#include "mac-low.h"
-#include "dcf-manager.h"
-#include "mac-rx-middle.h"
-#include "mac-tx-middle.h"
-#include "wifi-mac-header.h"
-#include "msdu-aggregator.h"
-#include "amsdu-subframe-header.h"
-#include "mgt-headers.h"
-
-NS_LOG_COMPONENT_DEFINE ("QstaWifiMac");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (QstaWifiMac);
-
-TypeId
-QstaWifiMac::GetTypeId (void)
-{
- static TypeId tid = TypeId ("ns3::QstaWifiMac")
- .SetParent<WifiMac> ()
- .AddConstructor<QstaWifiMac> ()
- .AddAttribute ("ProbeRequestTimeout", "The interval between two consecutive probe request attempts.",
- TimeValue (Seconds (0.05)),
- MakeTimeAccessor (&QstaWifiMac::m_probeRequestTimeout),
- MakeTimeChecker ())
- .AddAttribute ("AssocRequestTimeout", "The interval between two consecutive assoc request attempts.",
- TimeValue (Seconds (0.5)),
- MakeTimeAccessor (&QstaWifiMac::m_assocRequestTimeout),
- MakeTimeChecker ())
- .AddAttribute ("MaxMissedBeacons",
- "Number of beacons which much be consecutively missed before "
- "we attempt to restart association.",
- UintegerValue (10),
- MakeUintegerAccessor (&QstaWifiMac::m_maxMissedBeacons),
- MakeUintegerChecker<uint32_t> ())
- .AddAttribute ("ActiveProbing", "If true, we send probe requests. If false, we don't.",
- BooleanValue (false),
- MakeBooleanAccessor (&QstaWifiMac::SetActiveProbing),
- MakeBooleanChecker ())
- .AddAttribute ("VO_EdcaTxopN",
- "Queue that manages packets belonging to AC_VO access class",
- PointerValue (),
- MakePointerAccessor(&QstaWifiMac::GetVOQueue),
- MakePointerChecker<EdcaTxopN> ())
- .AddAttribute ("VI_EdcaTxopN",
- "Queue that manages packets belonging to AC_VI access class",
- PointerValue (),
- MakePointerAccessor(&QstaWifiMac::GetVIQueue),
- MakePointerChecker<EdcaTxopN> ())
- .AddAttribute ("BE_EdcaTxopN",
- "Queue that manages packets belonging to AC_BE access class",
- PointerValue (),
- MakePointerAccessor(&QstaWifiMac::GetBEQueue),
- MakePointerChecker<EdcaTxopN> ())
- .AddAttribute ("BK_EdcaTxopN",
- "Queue that manages packets belonging to AC_BK access class",
- PointerValue (),
- MakePointerAccessor(&QstaWifiMac::GetBKQueue),
- MakePointerChecker<EdcaTxopN> ())
- ;
- return tid;
-}
-
-QstaWifiMac::QstaWifiMac ()
- : m_state (BEACON_MISSED),
- m_probeRequestEvent (),
- m_assocRequestEvent (),
- m_beaconWatchdogEnd (Seconds (0.0))
-{
- NS_LOG_FUNCTION (this);
- m_rxMiddle = new MacRxMiddle ();
- m_rxMiddle->SetForwardCallback (MakeCallback (&QstaWifiMac::Receive, this));
- /*TxMiddle can be shared between all queues */
- m_txMiddle= new MacTxMiddle ();
-
- m_low = CreateObject<MacLow> ();
- m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
-
- m_dcfManager = new DcfManager ();
- m_dcfManager->SetupLowListener (m_low);
-
- // Construct the EDCAFs. The ordering is important - highest
- // priority (see Table 9-1 in IEEE 802.11-2007) must be created
- // first.
- SetQueue (AC_VO);
- SetQueue (AC_VI);
- SetQueue (AC_BE);
- SetQueue (AC_BK);
-}
-
-QstaWifiMac::~QstaWifiMac ()
-{
- NS_LOG_FUNCTION (this);
-}
-
-void
-QstaWifiMac::DoDispose ()
-{
- NS_LOG_FUNCTION (this);
- delete m_rxMiddle;
- delete m_txMiddle;
- delete m_dcfManager;
- m_low->Dispose ();
- m_rxMiddle = 0;
- m_txMiddle = 0;
- m_low = 0;
- m_phy = 0;
- m_dcfManager = 0;
- m_stationManager = 0;
- for (Queues::iterator i = m_queues.begin (); i != m_queues.end (); ++i)
- {
- (*i).second = 0;
- }
- WifiMac::DoDispose ();
-}
-
-void
-QstaWifiMac::SetSlot (Time slotTime)
-{
- NS_LOG_FUNCTION (this << slotTime);
- m_dcfManager->SetSlot (slotTime);
- m_low->SetSlotTime (slotTime);
-}
-
-void
-QstaWifiMac::SetSifs (Time sifs)
-{
- NS_LOG_FUNCTION (this << sifs);
- m_dcfManager->SetSifs (sifs);
- m_low->SetSifs (sifs);
-}
-
-void
-QstaWifiMac::SetEifsNoDifs (Time eifsNoDifs)
-{
- NS_LOG_FUNCTION (this << eifsNoDifs);
- m_dcfManager->SetEifsNoDifs (eifsNoDifs);
-}
-
-void
-QstaWifiMac::SetAckTimeout (Time ackTimeout)
-{
- m_low->SetAckTimeout (ackTimeout);
-}
-
-void
-QstaWifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
-{
- m_low->SetBasicBlockAckTimeout (blockAckTimeout);
-}
-
-void
-QstaWifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
-{
- m_low->SetCompressedBlockAckTimeout (blockAckTimeout);
-}
-
-void
-QstaWifiMac::SetCtsTimeout (Time ctsTimeout)
-{
- m_low->SetCtsTimeout (ctsTimeout);
-}
-
-void
-QstaWifiMac::SetPifs (Time pifs)
-{
- m_low->SetPifs (pifs);
-}
-
-Time
-QstaWifiMac::GetSlot (void) const
-{
- return m_low->GetSlotTime ();
-}
-
-Time
-QstaWifiMac::GetSifs (void) const
-{
- return m_low->GetSifs ();
-}
-
-Time
-QstaWifiMac::GetEifsNoDifs (void) const
-{
- return m_dcfManager->GetEifsNoDifs ();
-}
-
-Time
-QstaWifiMac::GetAckTimeout (void) const
-{
- return m_low->GetAckTimeout ();
-}
-
-Time
-QstaWifiMac::GetBasicBlockAckTimeout (void) const
-{
- return m_low->GetBasicBlockAckTimeout ();
-}
-
-Time
-QstaWifiMac::GetCompressedBlockAckTimeout (void) const
-{
- return m_low->GetCompressedBlockAckTimeout ();
-}
-
-Time
-QstaWifiMac::GetCtsTimeout (void) const
-{
- return m_low->GetCtsTimeout ();
-}
-
-Time
-QstaWifiMac::GetPifs (void) const
-{
- return m_low->GetPifs ();
-}
-
-void
-QstaWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
-{
- m_phy = phy;
- m_dcfManager->SetupPhyListener (phy);
- m_low->SetPhy (phy);
-}
-
-void
-QstaWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
-{
- m_stationManager = stationManager;
- m_queues[AC_VO]->SetWifiRemoteStationManager (stationManager);
- m_queues[AC_VI]->SetWifiRemoteStationManager (stationManager);
- m_queues[AC_BE]->SetWifiRemoteStationManager (stationManager);
- m_queues[AC_BK]->SetWifiRemoteStationManager (stationManager);
- m_low->SetWifiRemoteStationManager (stationManager);
-}
-
-void
-QstaWifiMac::SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback)
-{
- m_forwardUp = upCallback;
-}
-
-void
-QstaWifiMac::SetLinkUpCallback (Callback<void> linkUp)
-{
- m_linkUp = linkUp;
-}
-
-void
-QstaWifiMac::SetLinkDownCallback (Callback<void> linkDown)
-{
- m_linkDown = linkDown;
-}
-
-Mac48Address
-QstaWifiMac::GetAddress (void) const
-{
- return m_low->GetAddress ();
-}
-
-Ssid
-QstaWifiMac::GetSsid (void) const
-{
- return m_ssid;
-}
-
-Mac48Address
-QstaWifiMac::GetBssid () const
-{
- return m_low->GetBssid ();
-}
-
-void
-QstaWifiMac::SetAddress (Mac48Address address)
-{
- NS_LOG_FUNCTION (this << address);
- m_low->SetAddress (address);
-}
-
-void
-QstaWifiMac::SetSsid (Ssid ssid)
-{
- NS_LOG_FUNCTION (this << ssid);
- m_ssid = ssid;
-}
-
-void
-QstaWifiMac::SetMaxMissedBeacons (uint32_t missed)
-{
- NS_LOG_FUNCTION (this << missed);
- m_maxMissedBeacons = missed;
-}
-
-void
-QstaWifiMac::SetProbeRequestTimeout (Time timeout)
-{
- NS_LOG_FUNCTION (this << timeout);
- m_probeRequestTimeout = timeout;
-}
-
-void
-QstaWifiMac::SetAssocRequestTimeout (Time timeout)
-{
- NS_LOG_FUNCTION (this << timeout);
- m_assocRequestTimeout = timeout;
-}
-
-void
-QstaWifiMac::StartActiveAssociation (void)
-{
- NS_LOG_FUNCTION (this);
- TryToEnsureAssociated ();
-}
-
-Mac48Address
-QstaWifiMac::GetBroadcastBssid (void)
-{
- return Mac48Address::GetBroadcast ();
-}
-
-void
-QstaWifiMac::SetBssid (Mac48Address bssid)
-{
- NS_LOG_FUNCTION (this << bssid);
- m_low->SetBssid (bssid);
-}
-
-void
-QstaWifiMac::SetActiveProbing (bool enable)
-{
- NS_LOG_FUNCTION (this << enable);
- if (enable)
- {
- TryToEnsureAssociated ();
- }
- else
- {
- m_probeRequestEvent.Cancel ();
- }
-}
-
-void
-QstaWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
-{
- NS_LOG_FUNCTION (this << packet << from << to);
- m_forwardUp (packet, from, to);
-}
-
-void
-QstaWifiMac::SendProbeRequest (void)
-{
- NS_LOG_FUNCTION (this);
- WifiMacHeader hdr;
- hdr.SetProbeReq ();
- hdr.SetAddr1 (GetBroadcastBssid ());
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetBroadcastBssid ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Ptr<Packet> packet = Create<Packet> ();
- MgtProbeRequestHeader probe;
- probe.SetSsid (GetSsid ());
- probe.SetSupportedRates (GetSupportedRates ());
- packet->AddHeader (probe);
-
- /* Which is correct queue for management frames ? */
- m_queues[AC_VO]->Queue (packet, hdr);
-
- m_probeRequestEvent = Simulator::Schedule (m_probeRequestTimeout,
- &QstaWifiMac::ProbeRequestTimeout, this);
-}
-
-void
-QstaWifiMac::SendAssociationRequest (void)
-{
- NS_LOG_FUNCTION (this << GetBssid ());
- WifiMacHeader hdr;
- hdr.SetAssocReq ();
- hdr.SetAddr1 (GetBssid ());
- hdr.SetAddr2 (GetAddress ());
- hdr.SetAddr3 (GetBssid ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
- Ptr<Packet> packet = Create<Packet> ();
- MgtAssocRequestHeader assoc;
- assoc.SetSsid (GetSsid ());
- assoc.SetSupportedRates (GetSupportedRates ());
- packet->AddHeader (assoc);
-
- /* Which is correct queue for management frames ? */
- m_queues[AC_VO]->Queue (packet, hdr);
-
- m_assocRequestEvent = Simulator::Schedule (m_assocRequestTimeout,
- &QstaWifiMac::AssocRequestTimeout, this);
-}
-
-void
-QstaWifiMac::TryToEnsureAssociated (void)
-{
- NS_LOG_FUNCTION (this);
- 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
-QstaWifiMac::AssocRequestTimeout (void)
-{
- NS_LOG_FUNCTION (this);
- m_state = WAIT_ASSOC_RESP;
- SendAssociationRequest ();
-}
-
-void
-QstaWifiMac::ProbeRequestTimeout (void)
-{
- NS_LOG_FUNCTION (this);
- m_state = WAIT_PROBE_RESP;
- SendProbeRequest ();
-}
-
-void
-QstaWifiMac::MissedBeacons (void)
-{
- NS_LOG_FUNCTION (this);
- if (m_beaconWatchdogEnd > Simulator::Now ())
- {
- m_beaconWatchdog = Simulator::Schedule (m_beaconWatchdogEnd - Simulator::Now (),
- &QstaWifiMac::MissedBeacons, this);
- return;
- }
- NS_LOG_DEBUG ("beacon missed");
- m_state = BEACON_MISSED;
- TryToEnsureAssociated ();
-}
-
-void
-QstaWifiMac::RestartBeaconWatchdog (Time delay)
-{
- NS_LOG_FUNCTION (this << delay);
- m_beaconWatchdogEnd = std::max (Simulator::Now () + delay, m_beaconWatchdogEnd);
- if (Simulator::GetDelayLeft (m_beaconWatchdog) < delay &&
- m_beaconWatchdog.IsExpired ())
- {
- NS_LOG_DEBUG ("really restart watchdog.");
- m_beaconWatchdog = Simulator::Schedule (delay, &QstaWifiMac::MissedBeacons, this);
- }
-}
-
-bool
-QstaWifiMac::IsAssociated (void) const
-{
- return m_state == ASSOCIATED;
-}
-
-bool
-QstaWifiMac::IsWaitAssocResp (void) const
-{
- return m_state == WAIT_ASSOC_RESP;
-}
-
-void
-QstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
-{
- NS_LOG_FUNCTION (this << packet << to);
- if (!IsAssociated ())
- {
- TryToEnsureAssociated ();
- return;
- }
- WifiMacHeader hdr;
-
- hdr.SetType (WIFI_MAC_QOSDATA);
- hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
- hdr.SetQosNoAmsdu ();
- hdr.SetQosNoEosp ();
- /* Transmission of multiple frames in the same
- Txop is not supported for now */
- hdr.SetQosTxopLimit (0);
-
- hdr.SetAddr1 (GetBssid ());
- hdr.SetAddr2 (m_low->GetAddress ());
- hdr.SetAddr3 (to);
- hdr.SetDsNotFrom ();
- hdr.SetDsTo ();
-
- uint8_t tid = QosUtilsGetTidForPacket (packet);
- if (tid < 8)
- {
- hdr.SetQosTid (tid);
- AcIndex ac = QosUtilsMapTidToAc (tid);
- m_queues[ac]->Queue (packet, hdr);
- }
- else
- {
- //packet is considerated belonging to BestEffort Access Class (AC_BE)
- hdr.SetQosTid (0);
- m_queues[AC_BE]->Queue (packet, hdr);
- }
-}
-
-bool
-QstaWifiMac::SupportsSendFrom (void) const
-{
- return true;
-}
-
-void
-QstaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
-{
- NS_LOG_FUNCTION (this);
- NS_ASSERT (!hdr->IsCtl ());
- if (hdr->GetAddr1 () != GetAddress () &&
- !hdr->GetAddr1 ().IsGroup ())
- {
- NS_LOG_LOGIC ("packet is not for us");
- }
- else if (hdr->IsData ())
- {
- if (!IsAssociated ())
- {
- NS_LOG_LOGIC ("Received data frame while not associated: ignore");
- return;
- }
- if (!(hdr->IsFromDs () && !hdr->IsToDs ()))
- {
- NS_LOG_LOGIC ("Received data frame not from the DS: ignore");
- return;
- }
- if (hdr->GetAddr2 () != GetBssid ())
- {
- NS_LOG_LOGIC ("Received data frame not from the BSS we are associated with: ignore");
- return;
- }
- if (hdr->GetAddr3 () != GetAddress ())
- {
- if (hdr->IsQosData ())
- {
- if (hdr->IsQosAmsdu ())
- {
- NS_ASSERT (hdr->GetAddr3 () == GetBssid ());
- DeaggregateAmsduAndForward (packet, hdr);
- packet = 0;
- }
- else
- {
- ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
- }
- }
- else
- {
- ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
- }
- }
- }
- else if (hdr->IsBeacon ())
- {
- MgtBeaconHeader beacon;
- packet->RemoveHeader (beacon);
- bool goodBeacon = false;
- if (GetSsid ().IsBroadcast () ||
- beacon.GetSsid ().IsEqual (GetSsid ()))
- {
- goodBeacon = true;
- }
- if ((IsWaitAssocResp () || IsAssociated ()) && hdr->GetAddr3 () != GetBssid ())
- {
- goodBeacon = false;
- }
- if (goodBeacon)
- {
- Time delay = MicroSeconds (beacon.GetBeaconIntervalUs () * m_maxMissedBeacons);
- RestartBeaconWatchdog (delay);
- 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;
- NS_LOG_DEBUG ("assoc completed");
- SupportedRates rates = assocResp.GetSupportedRates ();
- for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
- {
- WifiMode mode = m_phy->GetMode (i);
- if (rates.IsSupportedRate (mode.GetDataRate ()))
- {
- m_stationManager->AddSupportedMode (hdr->GetAddr2 (), mode);
- if (rates.IsBasicRate (mode.GetDataRate ()))
- {
- m_stationManager->AddBasicMode (mode);
- }
- }
- }
- if (!m_linkUp.IsNull ())
- {
- m_linkUp ();
- }
- }
- else
- {
- NS_LOG_DEBUG ("assoc refused");
- m_state = REFUSED;
- }
- }
- }
- else if (hdr->IsAction ())
- {
- WifiActionHeader actionHdr;
- packet->RemoveHeader (actionHdr);
- if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
- actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST)
- {
- MgtAddBaRequestHeader reqHdr;
- packet->RemoveHeader (reqHdr);
- SendAddBaResponse (&reqHdr, hdr->GetAddr2 ());
- }
- else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
- actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE)
- {
- MgtAddBaResponseHeader respHdr;
- packet->RemoveHeader (respHdr);
- m_queues[QosUtilsMapTidToAc (respHdr.GetTid ())]->GotAddBaResponse (&respHdr, hdr->GetAddr2 ());
- }
- else if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK &&
- actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_DELBA)
- {
- MgtDelBaHeader delBaHdr;
- packet->RemoveHeader (delBaHdr);
- if (delBaHdr.IsByOriginator ())
- {
- /* Delba frame was sent by originator, this means that an ingoing established
- agreement exists in MacLow */
- m_low->DestroyBlockAckAgreement (hdr->GetAddr2 (), delBaHdr.GetTid ());
- }
- else
- {
- /* We must notify correct queue tear down of agreement */
- AcIndex ac = QosUtilsMapTidToAc (delBaHdr.GetTid ());
- m_queues[ac]->GotDelBaFrame (&delBaHdr, hdr->GetAddr2 ());
- }
- }
- }
-}
-
-SupportedRates
-QstaWifiMac::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;
-}
-
-void
-QstaWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, const WifiMacHeader *hdr)
-{
- DeaggregatedMsdus packets = MsduAggregator::Deaggregate (aggregatedPacket);
- for (DeaggregatedMsdusCI i = packets.begin (); i != packets.end (); ++i)
- {
- ForwardUp ((*i).first, (*i).second.GetSourceAddr (),
- (*i).second.GetDestinationAddr ());
- }
-}
-
-Ptr<EdcaTxopN>
-QstaWifiMac::GetVOQueue (void) const
-{
- return m_queues.find (AC_VO)->second;
-}
-
-Ptr<EdcaTxopN>
-QstaWifiMac::GetVIQueue (void) const
-{
- return m_queues.find (AC_VI)->second;
-}
-
-Ptr<EdcaTxopN>
-QstaWifiMac::GetBEQueue (void) const
-{
- return m_queues.find (AC_BE)->second;
-}
-
-Ptr<EdcaTxopN>
-QstaWifiMac::GetBKQueue (void) const
-{
- return m_queues.find (AC_BK)->second;
-}
-
-void
-QstaWifiMac::SetQueue (enum AcIndex ac)
-{
- Ptr<EdcaTxopN> edca = CreateObject<EdcaTxopN> ();
- edca->SetLow (m_low);
- edca->SetManager (m_dcfManager);
- edca->SetTypeOfStation (STA);
- edca->SetTxMiddle (m_txMiddle);
- edca->SetAccessCategory (ac);
- edca->CompleteConfig ();
- m_queues.insert (std::make_pair(ac, edca));
-}
-void
-QstaWifiMac::DoStart ()
-{
- for (Queues::iterator i = m_queues.begin (); i != m_queues.end (); ++i)
- {
- i->second->Start ();
- }
- WifiMac::DoStart ();
-}
-
-void
-QstaWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard)
-{
- switch (standard)
- {
- case WIFI_PHY_STANDARD_80211p_CCH:
- ConfigureCCHDcf (m_queues[AC_BK], 15, 511, AC_BK);
- ConfigureCCHDcf (m_queues[AC_BE], 15, 511, AC_BE);
- ConfigureCCHDcf (m_queues[AC_VI], 15, 511, AC_VI);
- ConfigureCCHDcf (m_queues[AC_VO], 15, 511, AC_VO);
- break;
- case WIFI_PHY_STANDARD_80211p_SCH:
- ConfigureDcf (m_queues[AC_BK], 15, 511, AC_BK);
- ConfigureDcf (m_queues[AC_BE], 15, 511, AC_BE);
- ConfigureDcf (m_queues[AC_VI], 15, 511, AC_VI);
- ConfigureDcf (m_queues[AC_VO], 15, 511, AC_VO);
- break;
- case WIFI_PHY_STANDARD_holland:
- // fall through
- case WIFI_PHY_STANDARD_80211a:
- // fall through
- case WIFI_PHY_STANDARD_80211g:
- // fall through
- case WIFI_PHY_STANDARD_80211_10Mhz:
- // fall through
- case WIFI_PHY_STANDARD_80211_5Mhz:
- ConfigureDcf (m_queues[AC_BK], 15, 1023, AC_BK);
- ConfigureDcf (m_queues[AC_BE], 15, 1023, AC_BE);
- ConfigureDcf (m_queues[AC_VI], 15, 1023, AC_VI);
- ConfigureDcf (m_queues[AC_VO], 15, 1023, AC_VO);
- break;
- case WIFI_PHY_STANDARD_80211b:
- ConfigureDcf (m_queues[AC_BK], 31, 1023, AC_BK);
- ConfigureDcf (m_queues[AC_BE], 31, 1023, AC_BE);
- ConfigureDcf (m_queues[AC_VI], 31, 1023, AC_VI);
- ConfigureDcf (m_queues[AC_VO], 31, 1023, AC_VO);
- break;
- default:
- NS_ASSERT (false);
- break;
- }
-}
-
-void
-QstaWifiMac::SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator)
-{
- NS_LOG_FUNCTION (this);
- WifiMacHeader hdr;
- hdr.SetAction ();
- hdr.SetAddr1 (originator);
- hdr.SetAddr2 (m_low->GetAddress ());
- hdr.SetAddr3 (m_low->GetAddress ());
- hdr.SetDsNotFrom ();
- hdr.SetDsNotTo ();
-
- MgtAddBaResponseHeader respHdr;
- StatusCode code;
- code.SetSuccess ();
- respHdr.SetStatusCode (code);
- //Here a control about queues type?
- respHdr.SetAmsduSupport (reqHdr->IsAmsduSupported ());
-
- if (reqHdr->IsImmediateBlockAck ())
- {
- respHdr.SetImmediateBlockAck ();
- }
- else
- {
- respHdr.SetDelayedBlockAck ();
- }
- respHdr.SetTid (reqHdr->GetTid ());
- /* For now there's not no control about limit of reception.
- We assume that receiver has no limit on reception.
- However we assume that a receiver sets a bufferSize in order to satisfy
- next equation:
- (bufferSize + 1) % 16 = 0
- So if a recipient is able to buffer a packet, it should be also able to buffer
- all possible packet's fragments.
- See section 7.3.1.14 in IEEE802.11e for more details. */
- respHdr.SetBufferSize (1023);
- respHdr.SetTimeout (reqHdr->GetTimeout ());
-
- WifiActionHeader actionHdr;
- WifiActionHeader::ActionValue action;
- action.blockAck = WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE;
- actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
-
- Ptr<Packet> packet = Create<Packet> ();
- packet->AddHeader (respHdr);
- packet->AddHeader (actionHdr);
-
- /* ns3::MacLow have to buffer all correctly received packet for this block ack session */
- m_low->CreateBlockAckAgreement (&respHdr, originator, reqHdr->GetStartingSequence ());
-
- //Better a management queue?
- m_queues[QosUtilsMapTidToAc (reqHdr->GetTid ())]->PushFront (packet, hdr);
-}
-
-} //namespace ns3
--- a/src/devices/wifi/qsta-wifi-mac.h Wed Dec 01 08:01:24 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006, 2009 INRIA
- * Copyright (c) 2009 MIRKO BANCHI
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Author: Mirko Banchi <mk.banchi@gmail.com>
- */
-#ifndef QSTA_WIFI_MAC_H
-#define QSTA_WIFI_MAC_H
-
-#include "ns3/callback.h"
-#include "ns3/packet.h"
-#include "ns3/event-id.h"
-
-#include "wifi-mac.h"
-#include "supported-rates.h"
-#include "qos-utils.h"
-
-#include <string>
-#include <vector>
-#include <list>
-#include <map>
-
-namespace ns3 {
-
-class DcfManager;
-class EdcaTxopN;
-class MacRxMiddle;
-class MacTxMiddle;
-class MacLow;
-class WifiMacHeader;
-class AmsduSubframeHeader;
-class MsduAggregator;
-class MgtAddBaRequestHeader;
-
-class QstaWifiMac : public WifiMac
-{
-public:
- static TypeId GetTypeId (void);
-
- QstaWifiMac ();
- virtual ~QstaWifiMac ();
-
- // inherited from WifiMac.
- virtual void SetSlot (Time slotTime);
- virtual void SetSifs (Time sifs);
- virtual void SetEifsNoDifs (Time eifsNoDifs);
- virtual void SetAckTimeout (Time ackTimeout);
- virtual void SetCtsTimeout (Time ctsTimeout);
- virtual void SetPifs (Time pifs);
- virtual Time GetSlot (void) const;
- virtual Time GetSifs (void) const;
- virtual Time GetEifsNoDifs (void) const;
- virtual Time GetAckTimeout (void) const;
- virtual Time GetCtsTimeout (void) const;
- virtual Time GetPifs (void) const;
- virtual void SetWifiPhy (Ptr<WifiPhy> phy);
- virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
- virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from){};
- virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
- virtual bool SupportsSendFrom (void) const;
- virtual void SetForwardUpCallback (Callback<void,Ptr<Packet>, Mac48Address, Mac48Address> upCallback);
- virtual void SetLinkUpCallback (Callback<void> linkUp);
- virtual void SetLinkDownCallback (Callback<void> linkDown);
- virtual Mac48Address GetAddress (void) const;
- virtual Ssid GetSsid (void) const;
- virtual void SetAddress (Mac48Address address);
- virtual void SetSsid (Ssid ssid);
- virtual Mac48Address GetBssid (void) const;
- virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
- virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
- virtual Time GetBasicBlockAckTimeout (void) const;
- virtual Time GetCompressedBlockAckTimeout (void) const;
-
- void SetMaxMissedBeacons (uint32_t missed);
- void SetProbeRequestTimeout (Time timeout);
- void SetAssocRequestTimeout (Time timeout);
- void StartActiveAssociation (void);
-
-private:
- void DoStart ();
- void SetBssid (Mac48Address bssid);
- Mac48Address GetBroadcastBssid (void);
- void Receive (Ptr<Packet> p, const WifiMacHeader *hdr);
- void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
- void SetActiveProbing (bool enable);
- bool GetActiveProbing (void) const;
- void MissedBeacons (void);
- SupportedRates GetSupportedRates (void) const;
- void RestartBeaconWatchdog (Time delay);
- void AssocRequestTimeout (void);
- void ProbeRequestTimeout (void);
- void SendAssociationRequest (void);
- void SendProbeRequest (void);
- void SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Mac48Address originator);
- void TryToEnsureAssociated (void);
- bool IsAssociated (void) const;
- bool IsWaitAssocResp (void) const;
- virtual void DoDispose (void);
-
- /**
- * When an A-MSDU is received, is deaggregated by this method and all extracted packets are
- * forwarded up.
- */
- void DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, const WifiMacHeader *hdr);
-
- QstaWifiMac &operator = (const QstaWifiMac &);
- QstaWifiMac (const QstaWifiMac &);
- virtual void FinishConfigureStandard (enum WifiPhyStandard standard);
- void SetQueue (enum AcIndex ac);
- Ptr<EdcaTxopN> GetVOQueue (void) const;
- Ptr<EdcaTxopN> GetVIQueue (void) const;
- Ptr<EdcaTxopN> GetBEQueue (void) const;
- Ptr<EdcaTxopN> GetBKQueue (void) const;
-
- typedef std::map<AcIndex, Ptr<EdcaTxopN> > Queues;
- typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> > DeaggregatedMsdus;
- typedef std::list<std::pair<Ptr<Packet>, AmsduSubframeHeader> >::const_iterator DeaggregatedMsdusCI;
-
- enum {
- ASSOCIATED,
- WAIT_PROBE_RESP,
- WAIT_ASSOC_RESP,
- BEACON_MISSED,
- REFUSED
- } m_state;
-
- Queues m_queues;
- Ptr<MacLow> m_low;
- Ptr<WifiPhy> m_phy;
- Ptr<WifiRemoteStationManager> m_stationManager;
- DcfManager *m_dcfManager;
- MacRxMiddle *m_rxMiddle;
- MacTxMiddle *m_txMiddle;
- Ssid m_ssid;
-
- Callback<void, Ptr<Packet>, Mac48Address, Mac48Address> m_forwardUp;
- Callback<void> m_linkUp;
- Callback<void> m_linkDown;
-
- Time m_probeRequestTimeout;
- Time m_assocRequestTimeout;
- EventId m_probeRequestEvent;
- EventId m_assocRequestEvent;
-
- Time m_beaconWatchdogEnd;
- EventId m_beaconWatchdog;
-
- uint32_t m_maxMissedBeacons;
-};
-
-} //namespace ns3
-
-#endif /* QSTA_WIFI_MAC_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/regular-wifi-mac.cc Thu Dec 02 07:51:34 2010 +0000
@@ -0,0 +1,692 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "regular-wifi-mac.h"
+
+#include "ns3/log.h"
+#include "ns3/boolean.h"
+#include "ns3/pointer.h"
+#include "ns3/uinteger.h"
+#include "ns3/trace-source-accessor.h"
+
+#include "mac-rx-middle.h"
+#include "mac-tx-middle.h"
+#include "mac-low.h"
+#include "dcf.h"
+#include "dcf-manager.h"
+#include "wifi-phy.h"
+
+#include "msdu-aggregator.h"
+
+NS_LOG_COMPONENT_DEFINE ("RegularWifiMac");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (RegularWifiMac);
+
+RegularWifiMac::RegularWifiMac ()
+{
+ NS_LOG_FUNCTION (this);
+ m_rxMiddle = new MacRxMiddle ();
+ m_rxMiddle->SetForwardCallback (MakeCallback (&RegularWifiMac::Receive, this));
+
+ m_txMiddle = new MacTxMiddle ();
+
+ m_low = CreateObject<MacLow> ();
+ m_low->SetRxCallback (MakeCallback (&MacRxMiddle::Receive, m_rxMiddle));
+
+ m_dcfManager = new DcfManager ();
+ m_dcfManager->SetupLowListener (m_low);
+
+ m_dca = CreateObject<DcaTxop> ();
+ m_dca->SetLow (m_low);
+ m_dca->SetManager (m_dcfManager);
+ m_dca->SetTxOkCallback (MakeCallback (&RegularWifiMac::TxOk, this));
+ m_dca->SetTxFailedCallback (MakeCallback (&RegularWifiMac::TxFailed, this));
+
+ // Construct the EDCAFs. The ordering is important - highest
+ // priority (see Table 9-1 in IEEE 802.11-2007) must be created
+ // first.
+ SetupEdcaQueue (AC_VO);
+ SetupEdcaQueue (AC_VI);
+ SetupEdcaQueue (AC_BE);
+ SetupEdcaQueue (AC_BK);
+}
+
+RegularWifiMac::~RegularWifiMac ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+RegularWifiMac::DoStart ()
+{
+ NS_LOG_FUNCTION (this);
+
+ m_dca->Start ();
+
+ for (EdcaQueues::iterator i = m_edca.begin (); i != m_edca.end (); ++i)
+ {
+ i->second->Start ();
+ }
+}
+
+void
+RegularWifiMac::DoDispose ()
+{
+ NS_LOG_FUNCTION (this);
+ delete m_rxMiddle;
+ m_rxMiddle = NULL;
+
+ delete m_txMiddle;
+ m_txMiddle = NULL;
+
+ delete m_dcfManager;
+ m_dcfManager = NULL;
+
+ m_low->Dispose ();
+ m_low = NULL;
+
+ m_phy = NULL;
+ m_stationManager = NULL;
+
+ m_dca->Dispose ();
+ m_dca = NULL;
+
+ for (EdcaQueues::iterator i = m_edca.begin (); i != m_edca.end (); ++i)
+ {
+ i->second = NULL;
+ }
+}
+
+void
+RegularWifiMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
+{
+ NS_LOG_FUNCTION (this << stationManager);
+ m_stationManager = stationManager;
+ m_low->SetWifiRemoteStationManager (stationManager);
+
+ m_dca->SetWifiRemoteStationManager (stationManager);
+
+ for (EdcaQueues::iterator i = m_edca.begin (); i != m_edca.end (); ++i)
+ {
+ i->second->SetWifiRemoteStationManager (stationManager);
+ }
+}
+
+Ptr<WifiRemoteStationManager>
+RegularWifiMac::GetWifiRemoteStationManager () const
+{
+ return m_stationManager;
+}
+
+void
+RegularWifiMac::SetupEdcaQueue (enum AcIndex ac)
+{
+ NS_LOG_FUNCTION (this << ac);
+
+ // Our caller shouldn't be attempting to setup a queue that is
+ // already configured.
+ NS_ASSERT (m_edca.find (ac) == m_edca.end ());
+
+ Ptr<EdcaTxopN> edca = CreateObject<EdcaTxopN> ();
+ edca->SetLow (m_low);
+ edca->SetManager (m_dcfManager);
+ edca->SetTxMiddle (m_txMiddle);
+ edca->SetTxOkCallback (MakeCallback (&RegularWifiMac::TxOk, this));
+ edca->SetTxFailedCallback (MakeCallback (&RegularWifiMac::TxFailed, this));
+ edca->SetAccessCategory (ac);
+ edca->CompleteConfig ();
+ m_edca.insert (std::make_pair(ac, edca));
+}
+
+void
+RegularWifiMac::SetTypeOfStation (TypeOfStation type)
+{
+ NS_LOG_FUNCTION (this << type);
+ for (EdcaQueues::iterator i = m_edca.begin (); i != m_edca.end (); ++i)
+ {
+ i->second->SetTypeOfStation (type);
+ }
+}
+
+Ptr<DcaTxop>
+RegularWifiMac::GetDcaTxop () const
+{
+ return m_dca;
+}
+
+Ptr<EdcaTxopN>
+RegularWifiMac::GetVOQueue () const
+{
+ return m_edca.find (AC_VO)->second;
+}
+
+Ptr<EdcaTxopN>
+RegularWifiMac::GetVIQueue () const
+{
+ return m_edca.find (AC_VI)->second;
+}
+
+Ptr<EdcaTxopN>
+RegularWifiMac::GetBEQueue () const
+{
+ return m_edca.find (AC_BE)->second;
+}
+
+Ptr<EdcaTxopN>
+RegularWifiMac::GetBKQueue () const
+{
+ return m_edca.find (AC_BK)->second;
+}
+
+void
+RegularWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
+{
+ NS_LOG_FUNCTION (this << phy);
+ m_phy = phy;
+ m_dcfManager->SetupPhyListener (phy);
+ m_low->SetPhy (phy);
+}
+
+Ptr<WifiPhy>
+RegularWifiMac::GetWifiPhy () const
+{
+ return m_phy;
+}
+
+void
+RegularWifiMac::SetForwardUpCallback (ForwardUpCallback upCallback)
+{
+ NS_LOG_FUNCTION (this);
+ m_forwardUp = upCallback;
+}
+
+void
+RegularWifiMac::SetLinkUpCallback (Callback<void> linkUp)
+{
+ NS_LOG_FUNCTION (this);
+ m_linkUp = linkUp;
+}
+
+void
+RegularWifiMac::SetLinkDownCallback (Callback<void> linkDown)
+{
+ NS_LOG_FUNCTION (this);
+ m_linkDown = linkDown;
+}
+
+void
+RegularWifiMac::SetQosSupported (bool enable)
+{
+ NS_LOG_FUNCTION (this);
+ m_qosSupported = enable;
+}
+
+bool
+RegularWifiMac::GetQosSupported () const
+{
+ return m_qosSupported;
+}
+
+void
+RegularWifiMac::SetSlot (Time slotTime)
+{
+ NS_LOG_FUNCTION (this << slotTime);
+ m_dcfManager->SetSlot (slotTime);
+ m_low->SetSlotTime (slotTime);
+}
+
+Time
+RegularWifiMac::GetSlot (void) const
+{
+ return m_low->GetSlotTime ();
+}
+
+void
+RegularWifiMac::SetSifs (Time sifs)
+{
+ NS_LOG_FUNCTION (this << sifs);
+ m_dcfManager->SetSifs (sifs);
+ m_low->SetSifs (sifs);
+}
+
+Time
+RegularWifiMac::GetSifs (void) const
+{
+ return m_low->GetSifs ();
+}
+
+void
+RegularWifiMac::SetEifsNoDifs (Time eifsNoDifs)
+{
+ NS_LOG_FUNCTION (this << eifsNoDifs);
+ m_dcfManager->SetEifsNoDifs (eifsNoDifs);
+}
+
+Time
+RegularWifiMac::GetEifsNoDifs (void) const
+{
+ return m_dcfManager->GetEifsNoDifs ();
+}
+
+void
+RegularWifiMac::SetPifs (Time pifs)
+{
+ NS_LOG_FUNCTION (this << pifs);
+ m_low->SetPifs (pifs);
+}
+
+Time
+RegularWifiMac::GetPifs (void) const
+{
+ return m_low->GetPifs ();
+}
+
+void
+RegularWifiMac::SetAckTimeout (Time ackTimeout)
+{
+ NS_LOG_FUNCTION (this << ackTimeout);
+ m_low->SetAckTimeout (ackTimeout);
+}
+
+Time
+RegularWifiMac::GetAckTimeout (void) const
+{
+ return m_low->GetAckTimeout ();
+}
+
+void
+RegularWifiMac::SetCtsTimeout (Time ctsTimeout)
+{
+ NS_LOG_FUNCTION (this << ctsTimeout);
+ m_low->SetCtsTimeout (ctsTimeout);
+}
+
+Time
+RegularWifiMac::GetCtsTimeout (void) const
+{
+ return m_low->GetCtsTimeout ();
+}
+
+void
+RegularWifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout)
+{
+ NS_LOG_FUNCTION (this << blockAckTimeout);
+ m_low->SetBasicBlockAckTimeout (blockAckTimeout);
+}
+
+Time
+RegularWifiMac::GetBasicBlockAckTimeout (void) const
+{
+ return m_low->GetBasicBlockAckTimeout ();
+}
+
+void
+RegularWifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout)
+{
+ NS_LOG_FUNCTION (this << blockAckTimeout);
+ m_low->SetCompressedBlockAckTimeout (blockAckTimeout);
+}
+
+Time
+RegularWifiMac::GetCompressedBlockAckTimeout (void) const
+{
+ return m_low->GetCompressedBlockAckTimeout ();
+}
+
+void
+RegularWifiMac::SetAddress (Mac48Address address)
+{
+ NS_LOG_FUNCTION (this << address);
+ m_low->SetAddress (address);
+}
+
+Mac48Address
+RegularWifiMac::GetAddress (void) const
+{
+ return m_low->GetAddress ();
+}
+
+void
+RegularWifiMac::SetSsid (Ssid ssid)
+{
+ NS_LOG_FUNCTION (this << ssid);
+ m_ssid = ssid;
+}
+
+Ssid
+RegularWifiMac::GetSsid (void) const
+{
+ return m_ssid;
+}
+
+void
+RegularWifiMac::SetBssid (Mac48Address bssid)
+{
+ NS_LOG_FUNCTION (this << bssid);
+ m_low->SetBssid (bssid);
+}
+
+Mac48Address
+RegularWifiMac::GetBssid (void) const
+{
+ return m_low->GetBssid ();
+}
+
+void
+RegularWifiMac::Enqueue (Ptr<const Packet> packet,
+ Mac48Address to, Mac48Address from)
+{
+ // We expect RegularWifiMac subclasses which do support forwarding (e.g.,
+ // AP) to override this method. Therefore, we throw a fatal error if
+ // someone tries to invoke this method on a class which has not done
+ // this.
+ NS_FATAL_ERROR ("This MAC entity (" << this << ", " << GetAddress ()
+ << ") does not support Enqueue() with from address");
+}
+
+bool
+RegularWifiMac::SupportsSendFrom (void) const
+{
+ return false;
+}
+
+void
+RegularWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
+{
+ NS_LOG_FUNCTION (this << packet << from);
+ m_forwardUp (packet, from, to);
+}
+
+void
+RegularWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
+{
+ NS_LOG_FUNCTION (this << packet << hdr);
+
+ Mac48Address to = hdr->GetAddr1 ();
+ Mac48Address from = hdr->GetAddr2 ();
+
+ if (hdr->IsMgt () && hdr->IsAction () && to == GetAddress ())
+ {
+ // There is currently only any reason for Management Action
+ // frames to be flying about if we are a QoS STA.
+ NS_ASSERT (m_qosSupported);
+
+ WifiActionHeader actionHdr;
+ packet->RemoveHeader (actionHdr);
+
+ switch (actionHdr.GetCategory ())
+ {
+ case WifiActionHeader::BLOCK_ACK:
+
+ switch (actionHdr.GetAction().blockAck)
+ {
+ case WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST:
+ {
+ MgtAddBaRequestHeader reqHdr;
+ packet->RemoveHeader (reqHdr);
+
+ // We've received an ADDBA Request. Our policy here is
+ // to automatically accept it, so we get the ADDBA
+ // Response on it's way immediately.
+ SendAddBaResponse (&reqHdr, from);
+ // This frame is now completely dealt with, so we're done.
+ return;
+ }
+
+ case WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE:
+ {
+ MgtAddBaResponseHeader respHdr;
+ packet->RemoveHeader (respHdr);
+
+ // We've received an ADDBA Response. We assume that it
+ // indicates success after an ADDBA Request we have
+ // sent (we could, in principle, check this, but it
+ // seems a waste given the level of the current model)
+ // and act by locally establishing the agreement on
+ // the appropriate queue.
+ AcIndex ac = QosUtilsMapTidToAc (respHdr.GetTid ());
+ m_edca[ac]->GotAddBaResponse (&respHdr, from);
+ // This frame is now completely dealt with, so we're done.
+ return;
+ }
+
+ case WifiActionHeader::BLOCK_ACK_DELBA:
+ {
+ MgtDelBaHeader delBaHdr;
+ packet->RemoveHeader (delBaHdr);
+
+ if (delBaHdr.IsByOriginator ())
+ {
+ // This DELBA frame was sent by the originator, so
+ // this means that an ingoing established
+ // agreement exists in MacLow and we need to
+ // destroy it.
+ m_low->DestroyBlockAckAgreement (from, delBaHdr.GetTid ());
+ }
+ else
+ {
+ // We must have been the originator. We need to
+ // tell the correct queue that the agreement has
+ // been torn down
+ AcIndex ac = QosUtilsMapTidToAc (delBaHdr.GetTid ());
+ m_edca[ac]->GotDelBaFrame (&delBaHdr, from);
+ }
+ // This frame is now completely dealt with, so we're done.
+ return;
+ }
+
+ default:
+ NS_FATAL_ERROR ("Unsupported Action field in Block Ack Action frame");
+ }
+
+ default:
+ NS_FATAL_ERROR ("Unsupported Action frame received");
+ }
+ }
+ NS_FATAL_ERROR ("Don't know how to handle frame (type=" << hdr->GetType ());
+}
+
+void
+RegularWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket,
+ const WifiMacHeader *hdr)
+{
+ MsduAggregator::DeaggregatedMsdus packets =
+ MsduAggregator::Deaggregate (aggregatedPacket);
+
+ for (MsduAggregator::DeaggregatedMsdusCI i = packets.begin ();
+ i != packets.end (); ++i)
+ {
+ ForwardUp ((*i).first, (*i).second.GetSourceAddr (),
+ (*i).second.GetDestinationAddr ());
+ }
+}
+
+void
+RegularWifiMac::SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr,
+ Mac48Address originator)
+{
+ NS_LOG_FUNCTION (this);
+ WifiMacHeader hdr;
+ hdr.SetAction ();
+ hdr.SetAddr1 (originator);
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetAddress ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+
+ MgtAddBaResponseHeader respHdr;
+ StatusCode code;
+ code.SetSuccess ();
+ respHdr.SetStatusCode (code);
+ //Here a control about queues type?
+ respHdr.SetAmsduSupport (reqHdr->IsAmsduSupported ());
+
+ if (reqHdr->IsImmediateBlockAck ())
+ {
+ respHdr.SetImmediateBlockAck ();
+ }
+ else
+ {
+ respHdr.SetDelayedBlockAck ();
+ }
+ respHdr.SetTid (reqHdr->GetTid ());
+ // For now there's not no control about limit of reception. We
+ // assume that receiver has no limit on reception. However we assume
+ // that a receiver sets a bufferSize in order to satisfy next
+ // equation: (bufferSize + 1) % 16 = 0 So if a recipient is able to
+ // buffer a packet, it should be also able to buffer all possible
+ // packet's fragments. See section 7.3.1.14 in IEEE802.11e for more
+ // details.
+ respHdr.SetBufferSize (1023);
+ respHdr.SetTimeout (reqHdr->GetTimeout ());
+
+ WifiActionHeader actionHdr;
+ WifiActionHeader::ActionValue action;
+ action.blockAck = WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE;
+ actionHdr.SetAction (WifiActionHeader::BLOCK_ACK, action);
+
+ Ptr<Packet> packet = Create<Packet> ();
+ packet->AddHeader (respHdr);
+ packet->AddHeader (actionHdr);
+
+ // We need to notify our MacLow object as it will have to buffer all
+ // correctly received packets for this Block Ack session
+ m_low->CreateBlockAckAgreement (&respHdr, originator,
+ reqHdr->GetStartingSequence ());
+
+ // It is unclear which queue this frame should go into. For now we
+ // bung it into the queue corresponding to the TID for which we are
+ // establishing an agreement, and push it to the head.
+ m_edca[QosUtilsMapTidToAc (reqHdr->GetTid ())]->PushFront (packet, hdr);
+}
+
+TypeId
+RegularWifiMac::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::RegularWifiMac")
+ .SetParent<WifiMac> ()
+ .AddAttribute ("QosSupported",
+ "This Boolean attribute is set to enable 802.11e/WMM-style QoS support at this STA",
+ BooleanValue (false),
+ MakeBooleanAccessor (&RegularWifiMac::SetQosSupported,
+ &RegularWifiMac::GetQosSupported),
+ MakeBooleanChecker ())
+ .AddAttribute ("DcaTxop", "The DcaTxop object",
+ PointerValue (),
+ MakePointerAccessor (&RegularWifiMac::GetDcaTxop),
+ MakePointerChecker<DcaTxop> ())
+ .AddAttribute ("VO_EdcaTxopN",
+ "Queue that manages packets belonging to AC_VO access class",
+ PointerValue (),
+ MakePointerAccessor(&RegularWifiMac::GetVOQueue),
+ MakePointerChecker<EdcaTxopN> ())
+ .AddAttribute ("VI_EdcaTxopN",
+ "Queue that manages packets belonging to AC_VI access class",
+ PointerValue (),
+ MakePointerAccessor(&RegularWifiMac::GetVIQueue),
+ MakePointerChecker<EdcaTxopN> ())
+ .AddAttribute ("BE_EdcaTxopN",
+ "Queue that manages packets belonging to AC_BE access class",
+ PointerValue (),
+ MakePointerAccessor(&RegularWifiMac::GetBEQueue),
+ MakePointerChecker<EdcaTxopN> ())
+ .AddAttribute ("BK_EdcaTxopN",
+ "Queue that manages packets belonging to AC_BK access class",
+ PointerValue (),
+ MakePointerAccessor(&RegularWifiMac::GetBKQueue),
+ MakePointerChecker<EdcaTxopN> ())
+ .AddTraceSource ( "TxOkHeader",
+ "The header of successfully transmitted packet",
+ MakeTraceSourceAccessor (&RegularWifiMac::m_txOkCallback))
+ .AddTraceSource ("TxErrHeader",
+ "The header of unsuccessfully transmitted packet",
+ MakeTraceSourceAccessor (&RegularWifiMac::m_txErrCallback))
+ ;
+
+ return tid;
+}
+
+void
+RegularWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard)
+{
+ uint32_t cwmin;
+ uint32_t cwmax;
+
+ switch (standard)
+ {
+ case WIFI_PHY_STANDARD_80211p_CCH:
+ case WIFI_PHY_STANDARD_80211p_SCH:
+ cwmin = 15;
+ cwmax = 511;
+ break;
+
+ case WIFI_PHY_STANDARD_holland:
+ case WIFI_PHY_STANDARD_80211a:
+ case WIFI_PHY_STANDARD_80211g:
+ case WIFI_PHY_STANDARD_80211_10Mhz:
+ case WIFI_PHY_STANDARD_80211_5Mhz:
+ cwmin = 15;
+ cwmax = 1023;
+ break;
+
+ case WIFI_PHY_STANDARD_80211b:
+ cwmin = 31;
+ cwmax = 1023;
+ break;
+
+ default:
+ NS_FATAL_ERROR ("Unsupported WifiPhyStandard in RegularWifiMac::FinishConfigureStandard ()");
+ }
+
+ // The special value of AC_BE_NQOS which exists in the Access
+ // Category enumeration allows us to configure plain old DCF.
+ ConfigureDcf (m_dca, cwmin, cwmax, AC_BE_NQOS);
+
+ // Now we configure the EDCA functions
+ for (EdcaQueues::iterator i = m_edca.begin (); i != m_edca.end (); ++i)
+ {
+ // Special configuration for 802.11p CCH
+ if (standard == WIFI_PHY_STANDARD_80211p_CCH)
+ {
+ ConfigureCCHDcf (i->second, cwmin, cwmax, i->first);
+ }
+ else
+ {
+ ConfigureDcf (i->second, cwmin, cwmax, i->first);
+ }
+ }
+}
+
+void
+RegularWifiMac::TxOk (const WifiMacHeader &hdr)
+{
+ NS_LOG_FUNCTION (this << hdr);
+ m_txOkCallback (hdr);
+}
+
+void
+RegularWifiMac::TxFailed (const WifiMacHeader &hdr)
+{
+ NS_LOG_FUNCTION (this << hdr);
+ m_txErrCallback (hdr);
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/regular-wifi-mac.h Thu Dec 02 07:51:34 2010 +0000
@@ -0,0 +1,342 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef REGULAR_WIFI_MAC_H
+#define REGULAR_WIFI_MAC_H
+
+#include "ns3/wifi-mac.h"
+
+#include "dca-txop.h"
+#include "edca-txop-n.h"
+#include "wifi-remote-station-manager.h"
+#include "ssid.h"
+#include "qos-utils.h"
+
+#include <map>
+
+namespace ns3 {
+
+class Dcf;
+class MacLow;
+class MacRxMiddle;
+class MacTxMiddle;
+class DcfManager;
+
+/**
+ * \brief base class for all MAC-level wifi objects.
+ *
+ * This class encapsulates all the low-level MAC functionality
+ * DCA, EDCA, etc) and all the high-level MAC functionality
+ * (association/disassociation state machines).
+ *
+ */
+class RegularWifiMac : public WifiMac
+{
+public:
+ static TypeId GetTypeId (void);
+
+ RegularWifiMac ();
+ virtual ~RegularWifiMac ();
+
+ /**
+ * \param slotTime the slot duration
+ */
+ void SetSlot (Time slotTime);
+ /**
+ * \param sifs the sifs duration
+ */
+ void SetSifs (Time sifs);
+ /**
+ * \param eifsNoDifs the duration of an EIFS minus DIFS.
+ *
+ * This value is used to calculate the EIFS depending
+ * on AIFSN.
+ */
+ void SetEifsNoDifs (Time eifsNoDifs);
+ /**
+ * \param pifs the pifs duration.
+ */
+ void SetPifs (Time pifs);
+ /**
+ * \param ctsTimeout the duration of a CTS timeout.
+ */
+ void SetCtsTimeout (Time ctsTimeout);
+ /**
+ * \param ackTimeout the duration of an ACK timeout.
+ */
+ void SetAckTimeout (Time ackTimeout);
+ /**
+ * \returns the current PIFS duration.
+ */
+ Time GetPifs (void) const;
+ /**
+ * \returns the current SIFS duration.
+ */
+ Time GetSifs (void) const;
+ /**
+ * \returns the current slot duration.
+ */
+ Time GetSlot (void) const;
+ /**
+ * \returns the current EIFS minus DIFS duration
+ */
+ Time GetEifsNoDifs (void) const;
+ /**
+ * \returns the current CTS timeout duration.
+ */
+ Time GetCtsTimeout (void) const;
+ /**
+ * \returns the current ACK timeout duration.
+ */
+ Time GetAckTimeout (void) const;
+ /**
+ * \returns the MAC address associated to this MAC layer.
+ */
+ virtual Mac48Address GetAddress (void) const;
+ /**
+ * \returns the ssid which this MAC layer is going to try to stay in.
+ */
+ virtual Ssid GetSsid (void) const;
+ /**
+ * \param address the current address of this MAC layer.
+ */
+ virtual void SetAddress (Mac48Address address);
+ /**
+ * \param ssid the current ssid of this MAC layer.
+ */
+ virtual void SetSsid (Ssid ssid);
+ /**
+ * \param bssid the BSSID of the network that this device belongs to.
+ */
+ virtual void SetBssid (Mac48Address bssid);
+ /**
+ * \returns the bssid of the network this device belongs to.
+ */
+ virtual Mac48Address GetBssid (void) const;
+
+ /**
+ * \param packet the packet to send.
+ * \param to the address to which the packet should be sent.
+ * \param from the address from which the packet should be sent.
+ *
+ * The packet should be enqueued in a tx queue, and should be
+ * dequeued as soon as the channel access function determines that
+ * access is granted to this MAC. The extra parameter "from" allows
+ * this device to operate in a bridged mode, forwarding received
+ * frames without altering the source address.
+ */
+ virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from);
+ virtual bool SupportsSendFrom (void) const;
+
+ /**
+ * \param packet the packet to send.
+ * \param to the address to which the packet should be sent.
+ *
+ * The packet should be enqueued in a tx queue, and should be
+ * dequeued as soon as the channel access function determines that
+ * access is granted to this MAC.
+ */
+ virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to) = 0;
+ /**
+ * \param phy the physical layer attached to this MAC.
+ */
+ virtual void SetWifiPhy (Ptr<WifiPhy> phy);
+ /**
+ * \returns the physical layer attached to this MAC.
+ */
+ virtual Ptr<WifiPhy> GetWifiPhy () const;
+ /**
+ * \param stationManager the station manager attached to this MAC.
+ */
+ virtual void SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager);
+ /**
+ * \returns the station manager attached to this MAC.
+ */
+ virtual Ptr<WifiRemoteStationManager> GetWifiRemoteStationManager () const;
+
+ /**
+ * This type defines the callback of a higher layer that a
+ * WifiMac(-derived) object invokes to pass a packet up the stack.
+ *
+ * \param packet the packet that has been received.
+ * \param from the MAC address of the device that sent the packet.
+ * \param to the MAC address ot the device that the packet is
+ * destined for.
+ */
+ typedef Callback<void, Ptr<Packet>, Mac48Address, Mac48Address> ForwardUpCallback;
+ /**
+ * \param upCallback the callback to invoke when a packet must be
+ * forwarded up the stack.
+ */
+ virtual void SetForwardUpCallback (ForwardUpCallback upCallback);
+ /**
+ * \param linkUp the callback to invoke when the link becomes up.
+ */
+ virtual void SetLinkUpCallback (Callback<void> linkUp);
+ /**
+ * \param linkDown the callback to invoke when the link becomes down.
+ */
+ virtual void SetLinkDownCallback (Callback<void> linkDown);
+ /* Next functions are not pure virtual so non Qos WifiMacs are not
+ * forced to implement them.
+ */
+ virtual void SetBasicBlockAckTimeout (Time blockAckTimeout);
+ virtual Time GetBasicBlockAckTimeout (void) const;
+ virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
+ virtual Time GetCompressedBlockAckTimeout (void) const;
+
+protected:
+ virtual void DoStart ();
+ virtual void DoDispose ();
+
+ MacRxMiddle *m_rxMiddle;
+ MacTxMiddle *m_txMiddle;
+ Ptr<MacLow> m_low;
+ DcfManager *m_dcfManager;
+ Ptr<WifiPhy> m_phy;
+
+ Ptr<WifiRemoteStationManager> m_stationManager;
+
+ ForwardUpCallback m_forwardUp;
+ Callback<void> m_linkUp;
+ Callback<void> m_linkDown;
+
+ Ssid m_ssid;
+
+ /** This holds a pointer to the DCF instance for this WifiMac - used
+ for transmission of frames to non-QoS peers. */
+ Ptr<DcaTxop> m_dca;
+
+ /** This type defines a mapping between an Access Category index,
+ and a pointer to the corresponding channel access function */
+ typedef std::map<AcIndex, Ptr<EdcaTxopN> > EdcaQueues;
+ /** This is a map from Access Category index to the corresponding
+ channel access function */
+ EdcaQueues m_edca;
+
+ /**
+ * \param standard the phy standard to be used
+ *
+ * This method is called by ns3::WifiMac::ConfigureStandard to
+ * complete the configuration process for a requested phy standard.
+ *
+ * This method may be overriden by a derived class (e.g., in order
+ * to apply DCF or EDCA parameters specific to the usage model it is
+ * dealing with), in which case the reimplementation may choose to
+ * deal with certain values in the WifiPhyStandard enumeration, and
+ * chain up to this implementation to deal with the remainder.
+ */
+ virtual void FinishConfigureStandard (enum WifiPhyStandard standard);
+
+ /**
+ * This method is invoked by a subclass to specify what type of
+ * station it is implementing. This is something that the channel
+ * access functions (instantiated within this class as EdcaTxopN's)
+ * need to know.
+ *
+ * \param type the type of station.
+ */
+ void SetTypeOfStation (TypeOfStation type);
+
+ /**
+ * This method acts as the MacRxMiddle receive callback and is
+ * invoked to notify us that a frame has been received. The
+ * implementation is intended to capture logic that is going to be
+ * common to all (or most) derived classes. Specifically, handling
+ * of Block Ack managment frames is dealt with here.
+ *
+ * This method will need, however, to be overriden by derived
+ * classes so that they can perform their data handling before
+ * invoking the base version.
+ *
+ * \param packet the packet that has been received.
+ * \param hdr a pointer to the MAC header of the received frame.
+ */
+ virtual void Receive (Ptr<Packet> packet, const WifiMacHeader *hdr);
+ virtual void TxOk (const WifiMacHeader &hdr);
+ virtual void TxFailed (const WifiMacHeader &hdr);
+
+ void ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to);
+
+ /**
+ * This method can be called to de-aggregate an A-MSDU and forward
+ * the constituent packets up the stack.
+ *
+ * \param aggregatedPacket the Packet containing the A-MSDU.
+ * \param hdr a pointer to the MAC header for \c aggregatedPacket.
+ */
+ virtual void DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket,
+ const WifiMacHeader *hdr);
+
+ /**
+ * This method can be called to accept a received ADDBA Request. An
+ * ADDBA Response will be constructed and queued for transmission.
+ *
+ * \param reqHdr a pointer to the received ADDBA Request header.
+ * \param originator the MAC address of the originator.
+ */
+ virtual void SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr,
+ Mac48Address originator);
+
+ /**
+ * This Boolean is set \c true iff this WifiMac is to model
+ * 802.11e/WMM style Quality of Service. It is exposed through the
+ * attribute system.
+ *
+ * At the moment, this flag is the sole selection between QoS and
+ * non-QoS operation for the STA (whether IBSS, AP, or
+ * non-AP). Ultimately, we will want a QoS-enabled STA to be able to
+ * fall back to non-QoS operation with a non-QoS peer. This'll
+ * require further intelligence - i.e., per-association QoS
+ * state. Having a big switch seems like a good intermediate stage,
+ * however.
+ */
+ bool m_qosSupported;
+ /** Set accessor for the \c m_qosSupported member */
+ void SetQosSupported (bool enable);
+ /** Get accessor for the \c m_qosSupported member */
+ bool GetQosSupported () const;
+private:
+ /**
+ * This method is a private utility invoked to configure the channel
+ * access function for the specified Access Category.
+ *
+ * \param ac the Access Category index of the queue to initialise.
+ */
+ void SetupEdcaQueue (enum AcIndex ac);
+
+ /** Accessor for the DCF object */
+ Ptr<DcaTxop> GetDcaTxop (void) const;
+
+ /** Accessor for the AC_VO channel access function */
+ Ptr<EdcaTxopN> GetVOQueue (void) const;
+ /** Accessor for the AC_VI channel access function */
+ Ptr<EdcaTxopN> GetVIQueue (void) const;
+ /** Accessor for the AC_BE channel access function */
+ Ptr<EdcaTxopN> GetBEQueue (void) const;
+ /** Accessor for the AC_BK channel access function */
+ Ptr<EdcaTxopN> GetBKQueue (void) const;
+
+ TracedCallback<const WifiMacHeader &> m_txOkCallback;
+ TracedCallback<const WifiMacHeader &> m_txErrCallback;
+};
+
+} // namespace ns3
+
+#endif /* REGULAR_WIFI_MAC_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/sta-wifi-mac.cc Thu Dec 02 07:51:34 2010 +0000
@@ -0,0 +1,561 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "sta-wifi-mac.h"
+
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/string.h"
+#include "ns3/pointer.h"
+#include "ns3/boolean.h"
+#include "ns3/trace-source-accessor.h"
+
+#include "qos-tag.h"
+#include "mac-low.h"
+#include "dcf-manager.h"
+#include "mac-rx-middle.h"
+#include "mac-tx-middle.h"
+#include "wifi-mac-header.h"
+#include "msdu-aggregator.h"
+#include "amsdu-subframe-header.h"
+#include "mgt-headers.h"
+
+NS_LOG_COMPONENT_DEFINE ("StaWifiMac");
+
+
+/*
+ * The state machine for this STA is:
+ -------------- -----------
+ | Associated | <-------------------- -------> | Refused |
+ -------------- \ / -----------
+ \ \ /
+ \ ----------------- -----------------------------
+ \-> | Beacon Missed | --> | Wait Association Response |
+ ----------------- -----------------------------
+ \ ^
+ \ |
+ \ -----------------------
+ \-> | Wait Probe Response |
+ -----------------------
+ */
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (StaWifiMac);
+
+TypeId
+StaWifiMac::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::StaWifiMac")
+ .SetParent<RegularWifiMac> ()
+ .AddConstructor<StaWifiMac> ()
+ .AddAttribute ("ProbeRequestTimeout", "The interval between two consecutive probe request attempts.",
+ TimeValue (Seconds (0.05)),
+ MakeTimeAccessor (&StaWifiMac::m_probeRequestTimeout),
+ MakeTimeChecker ())
+ .AddAttribute ("AssocRequestTimeout", "The interval between two consecutive assoc request attempts.",
+ TimeValue (Seconds (0.5)),
+ MakeTimeAccessor (&StaWifiMac::m_assocRequestTimeout),
+ MakeTimeChecker ())
+ .AddAttribute ("MaxMissedBeacons",
+ "Number of beacons which much be consecutively missed before "
+ "we attempt to restart association.",
+ UintegerValue (10),
+ MakeUintegerAccessor (&StaWifiMac::m_maxMissedBeacons),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("ActiveProbing", "If true, we send probe requests. If false, we don't.",
+ BooleanValue (false),
+ MakeBooleanAccessor (&StaWifiMac::SetActiveProbing),
+ MakeBooleanChecker ())
+ .AddTraceSource ("Assoc", "Associated with an access point.",
+ MakeTraceSourceAccessor (&StaWifiMac::m_assocLogger))
+ .AddTraceSource ("DeAssoc", "Association with an access point lost.",
+ MakeTraceSourceAccessor (&StaWifiMac::m_deAssocLogger))
+ ;
+ return tid;
+}
+
+StaWifiMac::StaWifiMac ()
+ : m_state (BEACON_MISSED),
+ m_probeRequestEvent (),
+ m_assocRequestEvent (),
+ m_beaconWatchdogEnd (Seconds (0.0))
+{
+ NS_LOG_FUNCTION (this);
+
+ // Let the lower layers know that we are acting as a non-AP STA in
+ // an infrastructure BSS.
+ SetTypeOfStation (STA);
+}
+
+StaWifiMac::~StaWifiMac ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+StaWifiMac::SetMaxMissedBeacons (uint32_t missed)
+{
+ NS_LOG_FUNCTION (this << missed);
+ m_maxMissedBeacons = missed;
+}
+
+void
+StaWifiMac::SetProbeRequestTimeout (Time timeout)
+{
+ NS_LOG_FUNCTION (this << timeout);
+ m_probeRequestTimeout = timeout;
+}
+
+void
+StaWifiMac::SetAssocRequestTimeout (Time timeout)
+{
+ NS_LOG_FUNCTION (this << timeout);
+ m_assocRequestTimeout = timeout;
+}
+
+void
+StaWifiMac::StartActiveAssociation (void)
+{
+ NS_LOG_FUNCTION (this);
+ TryToEnsureAssociated ();
+}
+
+void
+StaWifiMac::SetActiveProbing (bool enable)
+{
+ NS_LOG_FUNCTION (this << enable);
+ if (enable)
+ {
+ TryToEnsureAssociated ();
+ }
+ else
+ {
+ m_probeRequestEvent.Cancel ();
+ }
+}
+
+void
+StaWifiMac::SendProbeRequest (void)
+{
+ NS_LOG_FUNCTION (this);
+ WifiMacHeader hdr;
+ hdr.SetProbeReq ();
+ hdr.SetAddr1 (Mac48Address::GetBroadcast ());
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (Mac48Address::GetBroadcast ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Ptr<Packet> packet = Create<Packet> ();
+ MgtProbeRequestHeader probe;
+ probe.SetSsid (GetSsid ());
+ probe.SetSupportedRates (GetSupportedRates ());
+ packet->AddHeader (probe);
+
+ // The standard is not clear on the correct queue for management
+ // frames if we are a QoS AP. The approach taken here is to always
+ // use the DCF for these regardless of whether we have a QoS
+ // association or not.
+ m_dca->Queue (packet, hdr);
+
+ m_probeRequestEvent = Simulator::Schedule (m_probeRequestTimeout,
+ &StaWifiMac::ProbeRequestTimeout, this);
+}
+
+void
+StaWifiMac::SendAssociationRequest (void)
+{
+ NS_LOG_FUNCTION (this << GetBssid ());
+ WifiMacHeader hdr;
+ hdr.SetAssocReq ();
+ hdr.SetAddr1 (GetBssid ());
+ hdr.SetAddr2 (GetAddress ());
+ hdr.SetAddr3 (GetBssid ());
+ hdr.SetDsNotFrom ();
+ hdr.SetDsNotTo ();
+ Ptr<Packet> packet = Create<Packet> ();
+ MgtAssocRequestHeader assoc;
+ assoc.SetSsid (GetSsid ());
+ assoc.SetSupportedRates (GetSupportedRates ());
+ packet->AddHeader (assoc);
+
+ // The standard is not clear on the correct queue for management
+ // frames if we are a QoS AP. The approach taken here is to always
+ // use the DCF for these regardless of whether we have a QoS
+ // association or not.
+ m_dca->Queue (packet, hdr);
+
+ m_assocRequestEvent = Simulator::Schedule (m_assocRequestTimeout,
+ &StaWifiMac::AssocRequestTimeout, this);
+}
+
+void
+StaWifiMac::TryToEnsureAssociated (void)
+{
+ NS_LOG_FUNCTION (this);
+ 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 ();
+ SetState (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
+StaWifiMac::AssocRequestTimeout (void)
+{
+ NS_LOG_FUNCTION (this);
+ SetState (WAIT_ASSOC_RESP);
+ SendAssociationRequest ();
+}
+
+void
+StaWifiMac::ProbeRequestTimeout (void)
+{
+ NS_LOG_FUNCTION (this);
+ SetState (WAIT_PROBE_RESP);
+ SendProbeRequest ();
+}
+
+void
+StaWifiMac::MissedBeacons (void)
+{
+ NS_LOG_FUNCTION (this);
+ if (m_beaconWatchdogEnd > Simulator::Now ())
+ {
+ m_beaconWatchdog = Simulator::Schedule (m_beaconWatchdogEnd - Simulator::Now (),
+ &StaWifiMac::MissedBeacons, this);
+ return;
+ }
+ NS_LOG_DEBUG ("beacon missed");
+ SetState (BEACON_MISSED);
+ TryToEnsureAssociated ();
+}
+
+void
+StaWifiMac::RestartBeaconWatchdog (Time delay)
+{
+ NS_LOG_FUNCTION (this << delay);
+ m_beaconWatchdogEnd = std::max (Simulator::Now () + delay, m_beaconWatchdogEnd);
+ if (Simulator::GetDelayLeft (m_beaconWatchdog) < delay &&
+ m_beaconWatchdog.IsExpired ())
+ {
+ NS_LOG_DEBUG ("really restart watchdog.");
+ m_beaconWatchdog = Simulator::Schedule (delay, &StaWifiMac::MissedBeacons, this);
+ }
+}
+
+bool
+StaWifiMac::IsAssociated (void) const
+{
+ return m_state == ASSOCIATED;
+}
+
+bool
+StaWifiMac::IsWaitAssocResp (void) const
+{
+ return m_state == WAIT_ASSOC_RESP;
+}
+
+void
+StaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
+{
+ NS_LOG_FUNCTION (this << packet << to);
+ if (!IsAssociated ())
+ {
+ NotifyTxDrop (packet);
+ TryToEnsureAssociated ();
+ return;
+ }
+ WifiMacHeader hdr;
+
+ // If we are not a QoS AP then we definitely want to use AC_BE to
+ // transmit the packet. A TID of zero will map to AC_BE (through \c
+ // QosUtilsMapTidToAc()), so we use that as our default here.
+ uint8_t tid = 0;
+
+ // For now, an AP that supports QoS does not support non-QoS
+ // associations, and vice versa. In future the AP model should
+ // support simultaneously associated QoS and non-QoS STAs, at which
+ // point there will need to be per-association QoS state maintained
+ // by the association state machine, and consulted here.
+ if (m_qosSupported)
+ {
+ hdr.SetType (WIFI_MAC_QOSDATA);
+ hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK);
+ hdr.SetQosNoEosp ();
+ hdr.SetQosNoAmsdu ();
+ // Transmission of multiple frames in the same TXOP is not
+ // supported for now
+ hdr.SetQosTxopLimit (0);
+
+ // Fill in the QoS control field in the MAC header
+ tid = QosUtilsGetTidForPacket (packet);
+ // Any value greater than 7 is invalid and likely indicates that
+ // the packet had no QoS tag, so we revert to zero, which'll
+ // mean that AC_BE is used.
+ if (tid >= 7)
+ {
+ tid = 0;
+ }
+ hdr.SetQosTid (tid);
+ }
+ else
+ {
+ hdr.SetTypeData ();
+ }
+
+ hdr.SetAddr1 (GetBssid ());
+ hdr.SetAddr2 (m_low->GetAddress ());
+ hdr.SetAddr3 (to);
+ hdr.SetDsNotFrom ();
+ hdr.SetDsTo ();
+
+ if (m_qosSupported)
+ {
+ // Sanity check that the TID is valid
+ NS_ASSERT (tid < 8);
+ m_edca[QosUtilsMapTidToAc (tid)]->Queue (packet, hdr);
+ }
+ else
+ {
+ m_dca->Queue (packet, hdr);
+ }
+}
+
+void
+StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
+{
+ NS_LOG_FUNCTION (this << packet << hdr);
+ NS_ASSERT (!hdr->IsCtl ());
+ if (hdr->GetAddr3 () == GetAddress ())
+ {
+ NS_LOG_LOGIC ("packet sent by us.");
+ return;
+ }
+ else if (hdr->GetAddr1 () != GetAddress () &&
+ !hdr->GetAddr1 ().IsGroup ())
+ {
+ NS_LOG_LOGIC ("packet is not for us");
+ NotifyRxDrop (packet);
+ return;
+ }
+ else if (hdr->IsData ())
+ {
+ if (!IsAssociated ())
+ {
+ NS_LOG_LOGIC ("Received data frame while not associated: ignore");
+ NotifyRxDrop (packet);
+ return;
+ }
+ if (!(hdr->IsFromDs () && !hdr->IsToDs ()))
+ {
+ NS_LOG_LOGIC ("Received data frame not from the DS: ignore");
+ NotifyRxDrop (packet);
+ return;
+ }
+ if (hdr->GetAddr2 () != GetBssid ())
+ {
+ NS_LOG_LOGIC ("Received data frame not from the BSS we are associated with: ignore");
+ NotifyRxDrop (packet);
+ return;
+ }
+
+ if (hdr->IsQosData ())
+ {
+ if (hdr->IsQosAmsdu ())
+ {
+ NS_ASSERT (hdr->GetAddr3 () == GetBssid ());
+ DeaggregateAmsduAndForward (packet, hdr);
+ packet = 0;
+ }
+ else
+ {
+ ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
+ }
+ }
+ else
+ {
+ ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
+ }
+ return;
+ }
+ else if (hdr->IsProbeReq () ||
+ hdr->IsAssocReq ())
+ {
+ // This is a frame aimed at an AP, so we can safely ignore it.
+ NotifyRxDrop (packet);
+ return;
+ }
+ else if (hdr->IsBeacon ())
+ {
+ MgtBeaconHeader beacon;
+ packet->RemoveHeader (beacon);
+ bool goodBeacon = false;
+ if (GetSsid ().IsBroadcast () ||
+ beacon.GetSsid ().IsEqual (GetSsid ()))
+ {
+ goodBeacon = true;
+ }
+ if ((IsWaitAssocResp () || IsAssociated ()) && hdr->GetAddr3 () != GetBssid ())
+ {
+ goodBeacon = false;
+ }
+ if (goodBeacon)
+ {
+ Time delay = MicroSeconds (beacon.GetBeaconIntervalUs () * m_maxMissedBeacons);
+ RestartBeaconWatchdog (delay);
+ SetBssid (hdr->GetAddr3 ());
+ }
+ if (goodBeacon && m_state == BEACON_MISSED)
+ {
+ SetState (WAIT_ASSOC_RESP);
+ SendAssociationRequest ();
+ }
+ return;
+ }
+ 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 ();
+ }
+ SetState (WAIT_ASSOC_RESP);
+ SendAssociationRequest ();
+ }
+ return;
+ }
+ 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 ())
+ {
+ SetState (ASSOCIATED);
+ NS_LOG_DEBUG ("assoc completed");
+ SupportedRates rates = assocResp.GetSupportedRates ();
+ for (uint32_t i = 0; i < m_phy->GetNModes (); i++)
+ {
+ WifiMode mode = m_phy->GetMode (i);
+ if (rates.IsSupportedRate (mode.GetDataRate ()))
+ {
+ m_stationManager->AddSupportedMode (hdr->GetAddr2 (), mode);
+ if (rates.IsBasicRate (mode.GetDataRate ()))
+ {
+ m_stationManager->AddBasicMode (mode);
+ }
+ }
+ }
+ if (!m_linkUp.IsNull ())
+ {
+ m_linkUp ();
+ }
+ }
+ else
+ {
+ NS_LOG_DEBUG ("assoc refused");
+ SetState (REFUSED);
+ }
+ }
+ return;
+ }
+
+ // Invoke the receive handler of our parent class to deal with any
+ // other frames. Specifically, this will handle Block Ack-related
+ // Management Action frames.
+ RegularWifiMac::Receive (packet, hdr);
+}
+
+SupportedRates
+StaWifiMac::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;
+}
+
+void
+StaWifiMac::SetState (MacState value)
+{
+ if (value == ASSOCIATED &&
+ m_state != ASSOCIATED)
+ {
+ m_assocLogger (GetBssid ());
+ }
+ else if (value != ASSOCIATED &&
+ m_state == ASSOCIATED)
+ {
+ m_deAssocLogger (GetBssid ());
+ }
+ m_state = value;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/sta-wifi-mac.h Thu Dec 02 07:51:34 2010 +0000
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006, 2009 INRIA
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#ifndef STA_WIFI_MAC_H
+#define STA_WIFI_MAC_H
+
+#include "regular-wifi-mac.h"
+
+#include "ns3/event-id.h"
+#include "ns3/packet.h"
+#include "ns3/traced-callback.h"
+
+#include "supported-rates.h"
+#include "amsdu-subframe-header.h"
+
+namespace ns3 {
+
+class MgtAddBaRequestHeader;
+
+class StaWifiMac : public RegularWifiMac
+{
+public:
+ static TypeId GetTypeId (void);
+
+ StaWifiMac ();
+ virtual ~StaWifiMac ();
+
+ /**
+ * \param packet the packet to send.
+ * \param to the address to which the packet should be sent.
+ *
+ * The packet should be enqueued in a tx queue, and should be
+ * dequeued as soon as the channel access function determines that
+ * access is granted to this MAC.
+ */
+ virtual void Enqueue (Ptr<const Packet> packet, Mac48Address to);
+
+ /**
+ * \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:
+ enum MacState {
+ ASSOCIATED,
+ WAIT_PROBE_RESP,
+ WAIT_ASSOC_RESP,
+ BEACON_MISSED,
+ REFUSED
+ };
+
+ void SetActiveProbing (bool enable);
+ bool GetActiveProbing (void) const;
+ virtual void Receive (Ptr<Packet> packet, const WifiMacHeader *hdr);
+ void SendProbeRequest (void);
+ void SendAssociationRequest (void);
+ void TryToEnsureAssociated (void);
+ void AssocRequestTimeout (void);
+ void ProbeRequestTimeout (void);
+ bool IsAssociated (void) const;
+ bool IsWaitAssocResp (void) const;
+ void MissedBeacons (void);
+ void RestartBeaconWatchdog (Time delay);
+ SupportedRates GetSupportedRates (void) const;
+ void SetState (enum MacState value);
+
+ enum MacState m_state;
+ Time m_probeRequestTimeout;
+ Time m_assocRequestTimeout;
+ EventId m_probeRequestEvent;
+ EventId m_assocRequestEvent;
+ EventId m_beaconWatchdog;
+ Time m_beaconWatchdogEnd;
+ uint32_t m_maxMissedBeacons;
+
+ TracedCallback<Mac48Address> m_assocLogger;
+ TracedCallback<Mac48Address> m_deAssocLogger;
+};
+
+} // namespace ns3
+
+#endif /* STA_WIFI_MAC_H */
--- a/src/devices/wifi/wifi-test.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/src/devices/wifi/wifi-test.cc Thu Dec 02 07:51:34 2010 +0000
@@ -136,9 +136,9 @@
m_mac.SetTypeId ("ns3::AdhocWifiMac");
RunOne ();
- m_mac.SetTypeId ("ns3::NqapWifiMac");
+ m_mac.SetTypeId ("ns3::ApWifiMac");
RunOne ();
- m_mac.SetTypeId ("ns3::NqstaWifiMac");
+ m_mac.SetTypeId ("ns3::StaWifiMac");
RunOne ();
--- a/src/devices/wifi/wifi.h Wed Dec 01 08:01:24 2010 -0800
+++ b/src/devices/wifi/wifi.h Thu Dec 02 07:51:34 2010 +0000
@@ -16,82 +16,86 @@
* beacon generation, probing, and association state machines.
* - a set of Rate control algorithms used by the MAC low models.
*
- * We have today 6 MAC high models, 3 for non QoS MACs and 3 for QoS MACs.
- *
- * a)non QoS MACs:
+ * There are presently three MAC high models, corresponding to the
+ * three primary Wi-Fi topological elements - Access Point (AP)
+ * (implemented in ns3::ApWifiMac), non-AP Station (STA) (implemented
+ * in ns3::StaWifiMac), and STA in an Independent Basic Service Set
+ * (IBSS - also commonly referred to as an ad hoc network. Implemented
+ * in ns3::AdhocWifiMac).
+ *
*
- * - a simple adhoc state machine which does not perform any
- * kind of beacon generation, probing, or association. This
- * state machine is implemented by the ns3::AdhocWifiMac class.
- * - an active probing and association state machine which handles
- * automatic re-association whenever too many beacons are missed
- * is implemented by the ns3::NqstaWifiMac class.
- * - an access point which generates periodic beacons, and which
- * accepts every attempt to associate. This AP state machine
- * is implemented by the ns3::NqapWifiMac class.
+ * The simplest of these is ns3::AdhocWifiMac, which implements a
+ * Wi-Fi MAC that does not perform any kind of beacon generation,
+ * probing, or association. The ns3::StaWifiMac class implements an
+ * active probing and association state machine that handles automatic
+ * re-association whenever too many beacons are missed. Finally,
+ * ns3::ApWifiMac implements an AP that generates periodic beacons,
+ * and that accepts every attempt to associate.
*
- * b)QoS MACs:
+ * These three MAC high models share a common parent in
+ * ns3::RegularWifiMac, which exposes, among other MAC configuration,
+ * an attribute (QosSupported) that allows configuration of
+ * 802.11e/WMM-style QoS support. With QoS-enabled MAC models it is
+ * possible to work with traffic belonging to four different Access
+ * Categories (ACs): AC_VO for voice traffic, AC_VI for video traffic,
+ * AC_BE for best-effort traffic and AC_BK for background traffic. In
+ * order for the MAC to determine the appropriate AC for an MSDU,
+ * packets forwarded down to these MAC layers should be marked using
+ * ns3::QosTag in order to set a TID (traffic id) for that packet
+ * otherwise it will be considered belonging to AC_BE.
+ *
+ * How TIDs are mapped to access classes are shown in the table below.
*
- * - like above but these MAC models are also able to manage QoS traffic.
- * These MAC layers are implemented respectively by ns3::QadhocWifiMac,
- * ns3::QstaWifiMac and ns3::QapWifiMac classes.
- * With these MAC models is possible to work with traffic belonging to
- * four different access classes: AC_VO for voice traffic, AC_VI for video
- * traffic, AC_BE for best-effort traffic and AC_BK for background traffic.
- * In order to determine MSDU's access class, every packet forwarded down
- * to these MAC layers should be marked using ns3::QosTag in order to set
- * a TID (traffic id) for that packet otherwise it will be considered
- * belonging to AC_BE access class.
- * How TIDs are mapped to access classes are shown in the table below.
- *
- * TID-AcIndex mapping:
- *
- * <table border=1>
- * <tr>
- * <td><b> TID </b></td>
- * <td><b> Access class </b></td>
- * </tr>
- * <tr>
- * <td> 7 </td>
- * <td> AC_VO </td>
- * </tr>
- * <tr>
- * <td> 6 </td>
- * <td> AC_VO </td>
- * </tr>
- * <tr>
- * <td> 5 </td>
- * <td> AC_VI </td>
- * </tr>
- * <tr>
- * <td> 4 </td>
- * <td> AC_VI </td>
- * </tr>
- * <tr>
- * <td> 3 </td>
- * <td> AC_BE </td>
- * </tr>
- * <tr>
- * <td> 0 </td>
- * <td> AC_BE </td>
- * </tr>
- * <tr>
- * <td> 2 </td>
- * <td> AC_BK </td>
- * </tr>
- * <tr>
- * <td> 1 </td>
- * <td> AC_BK </td>
- * </tr>
- * </table>
- *
+ * <table border=1>
+ * <tr>
+ * <td><b> TID </b></td>
+ * <td><b> Access Category </b></td>
+ * </tr>
+ * <tr>
+ * <td> 7 </td>
+ * <td> AC_VO </td>
+ * </tr>
+ * <tr>
+ * <td> 6 </td>
+ * <td> AC_VO </td>
+ * </tr>
+ * <tr>
+ * <td> 5 </td>
+ * <td> AC_VI </td>
+ * </tr>
+ * <tr>
+ * <td> 4 </td>
+ * <td> AC_VI </td>
+ * </tr>
+ * <tr>
+ * <td> 3 </td>
+ * <td> AC_BE </td>
+ * </tr>
+ * <tr>
+ * <td> 0 </td>
+ * <td> AC_BE </td>
+ * </tr>
+ * <tr>
+ * <td> 2 </td>
+ * <td> AC_BK </td>
+ * </tr>
+ * <tr>
+ * <td> 1 </td>
+ * <td> AC_BK </td>
+ * </tr>
+ * </table>
+ *
* The MAC low layer is split in 3 components:
* - ns3::MacLow which takes care of RTS/CTS/DATA/ACK transactions.
* - ns3::DcfManager and ns3::DcfState which implements the DCF function.
- * - ns3::DcaTxop or ns3::EdcaTxopN which handle the packet queue, packet
- * fragmentation, and packet retransmissions if they are needed.
- * ns3::DcaTxop object is used by non QoS high MACs. ns3::EdcaTxopN is
- * used by Qos high MACs and performs also QoS operations like 802.11n MSDU
+ *
+ * - ns3::DcaTxop and ns3::EdcaTxopN which handle the packet queue,
+ * packet fragmentation, and packet retransmissions if they are
+ * needed. The ns3::DcaTxop object is used by high MACs that are
+ * not QoS-enabled, and for transmission of frames (e.g., of type
+ * Management) that the standard says should access the medium
+ * using the DCF. ns3::EdcaTxopN is used by QoS-enabled high MACs
+ * and also performs QoS operations like 802.11n-style MSDU
* aggregation.
*
* The PHY layer implements a single 802.11a model in the ns3::WifiPhy class: the
--- a/src/devices/wifi/wscript Wed Dec 01 08:01:24 2010 -0800
+++ b/src/devices/wifi/wscript Thu Dec 02 07:51:34 2010 +0000
@@ -33,10 +33,11 @@
'dcf-manager.cc',
'dcf-manager-test.cc',
'wifi-mac.cc',
+ 'regular-wifi-mac.cc',
'wifi-remote-station-manager.cc',
+ 'ap-wifi-mac.cc',
+ 'sta-wifi-mac.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',
@@ -51,9 +52,6 @@
'wifi-test.cc',
'qos-tag.cc',
'qos-utils.cc',
- 'qadhoc-wifi-mac.cc',
- 'qap-wifi-mac.cc',
- 'qsta-wifi-mac.cc',
'edca-txop-n.cc',
'msdu-aggregator.cc',
'amsdu-subframe-header.cc',
@@ -83,6 +81,9 @@
'wifi-phy.h',
'interference-helper.h',
'wifi-remote-station-manager.h',
+ 'ap-wifi-mac.h',
+ 'sta-wifi-mac.h',
+ 'adhoc-wifi-mac.h',
'arf-wifi-manager.h',
'aarf-wifi-manager.h',
'ideal-wifi-manager.h',
@@ -94,9 +95,7 @@
'cara-wifi-manager.h',
'minstrel-wifi-manager.h',
'wifi-mac.h',
- 'adhoc-wifi-mac.h',
- 'nqsta-wifi-mac.h',
- 'nqap-wifi-mac.h',
+ 'regular-wifi-mac.h',
'wifi-phy.h',
'supported-rates.h',
'error-rate-model.h',
@@ -105,9 +104,6 @@
'dsss-error-rate-model.h',
'dca-txop.h',
'wifi-mac-header.h',
- 'qadhoc-wifi-mac.h',
- 'qap-wifi-mac.h',
- 'qsta-wifi-mac.h',
'qos-utils.h',
'edca-txop-n.h',
'msdu-aggregator.h',
--- a/src/helper/nqos-wifi-mac-helper.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/src/helper/nqos-wifi-mac-helper.cc Thu Dec 02 07:51:34 2010 +0000
@@ -20,6 +20,7 @@
#include "nqos-wifi-mac-helper.h"
#include "ns3/wifi-mac.h"
#include "ns3/pointer.h"
+#include "ns3/boolean.h"
#include "ns3/dca-txop.h"
namespace ns3 {
@@ -34,7 +35,12 @@
NqosWifiMacHelper::Default (void)
{
NqosWifiMacHelper helper;
- helper.SetType ("ns3::AdhocWifiMac");
+ // We're making non QoS-enabled Wi-Fi MACs here, so we set the
+ // necessary attribute. I've carefully positioned this here so that
+ // someone who knows what they're doing can override with explicit
+ // attributes.
+ helper.SetType ("ns3::AdhocWifiMac",
+ "QosSupported", BooleanValue (false));
return helper;
}
--- a/src/helper/nqos-wifi-mac-helper.h Wed Dec 01 08:01:24 2010 -0800
+++ b/src/helper/nqos-wifi-mac-helper.h Thu Dec 02 07:51:34 2010 +0000
@@ -25,8 +25,10 @@
namespace ns3 {
/**
- * \brief create non-qos MAC layers for a ns3::WifiNetDevice.
- * This class can create MACs of type ns3::NqapWifiMac, ns3::NqstaWifiMac, and, ns3::AdhocWifiMac
+ * \brief create non QoS-enabled MAC layers for a ns3::WifiNetDevice.
+ *
+ * This class can create MACs of type ns3::ApWifiMac, ns3::StaWifiMac,
+ * and, ns3::AdhocWifiMac, with QosSupported attribute set to False.
*/
class NqosWifiMacHelper : public WifiMacHelper
{
--- a/src/helper/qos-wifi-mac-helper.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/src/helper/qos-wifi-mac-helper.cc Thu Dec 02 07:51:34 2010 +0000
@@ -22,6 +22,7 @@
#include "ns3/wifi-mac.h"
#include "ns3/edca-txop-n.h"
#include "ns3/pointer.h"
+#include "ns3/boolean.h"
#include "ns3/uinteger.h"
namespace ns3 {
@@ -36,8 +37,14 @@
QosWifiMacHelper::Default (void)
{
QosWifiMacHelper helper;
- helper.SetType ("ns3::QstaWifiMac");
-
+
+ // We're making QoS-enabled Wi-Fi MACs here, so we set the necessary
+ // attribute. I've carefully positioned this here so that someone
+ // who knows what they're doing can override with explicit
+ // attributes.
+ helper.SetType ("ns3::StaWifiMac",
+ "QosSupported", BooleanValue (true));
+
return helper;
}
--- a/src/helper/qos-wifi-mac-helper.h Wed Dec 01 08:01:24 2010 -0800
+++ b/src/helper/qos-wifi-mac-helper.h Thu Dec 02 07:51:34 2010 +0000
@@ -28,8 +28,10 @@
namespace ns3 {
/**
- * \brief create qos MAC layers for a ns3::WifiNetDevice.
- * This class can create MACs of type ns3::QapWifiMac, ns3::QstaWifiMac, and, ns3::QadhocWifiMac
+ * \brief create QoS-enabled MAC layers for a ns3::WifiNetDevice.
+ *
+ * This class can create MACs of type ns3::ApWifiMac, ns3::StaWifiMac,
+ * and, ns3::AdhocWifiMac, with QosSupported attribute set to True.
*/
class QosWifiMacHelper : public WifiMacHelper
{
--- a/src/helper/wifi-helper.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/src/helper/wifi-helper.cc Thu Dec 02 07:51:34 2010 +0000
@@ -131,6 +131,7 @@
LogComponentEnable ("Aarfcd", LOG_LEVEL_ALL);
LogComponentEnable ("AdhocWifiMac", LOG_LEVEL_ALL);
LogComponentEnable ("AmrrWifiRemoteStation", LOG_LEVEL_ALL);
+ LogComponentEnable ("ApWifiMac", LOG_LEVEL_ALL);
LogComponentEnable ("ns3::ArfWifiManager", LOG_LEVEL_ALL);
LogComponentEnable ("Cara", LOG_LEVEL_ALL);
LogComponentEnable ("DcaTxop", LOG_LEVEL_ALL);
@@ -144,14 +145,11 @@
LogComponentEnable ("MsduAggregator", LOG_LEVEL_ALL);
LogComponentEnable ("MsduStandardAggregator", LOG_LEVEL_ALL);
LogComponentEnable ("NistErrorRateModel", LOG_LEVEL_ALL);
- LogComponentEnable ("NqapWifiMac", LOG_LEVEL_ALL);
- LogComponentEnable ("NqstaWifiMac", LOG_LEVEL_ALL);
LogComponentEnable ("OnoeWifiRemoteStation", LOG_LEVEL_ALL);
LogComponentEnable ("PropagationLossModel", LOG_LEVEL_ALL);
- LogComponentEnable ("QadhocWifiMac", LOG_LEVEL_ALL);
- LogComponentEnable ("QapWifiMac", LOG_LEVEL_ALL);
- LogComponentEnable ("QstaWifiMac", LOG_LEVEL_ALL);
+ LogComponentEnable ("RegularWifiMac", LOG_LEVEL_ALL);
LogComponentEnable ("RraaWifiManager", LOG_LEVEL_ALL);
+ LogComponentEnable ("StaWifiMac", LOG_LEVEL_ALL);
LogComponentEnable ("SupportedRates", LOG_LEVEL_ALL);
LogComponentEnable ("WifiChannel", LOG_LEVEL_ALL);
LogComponentEnable ("WifiPhyStateHelper", LOG_LEVEL_ALL);
Binary file src/routing/aodv/test/aodv-chain-regression-test-0-0.pcap has changed
Binary file src/routing/aodv/test/aodv-chain-regression-test-1-0.pcap has changed
Binary file src/routing/aodv/test/aodv-chain-regression-test-2-0.pcap has changed
Binary file src/routing/aodv/test/aodv-chain-regression-test-3-0.pcap has changed
Binary file src/routing/aodv/test/aodv-chain-regression-test-4-0.pcap has changed
Binary file src/routing/aodv/test/bug-606-test-0-0.pcap has changed
Binary file src/routing/aodv/test/bug-606-test-1-0.pcap has changed
Binary file src/routing/aodv/test/bug-606-test-2-0.pcap has changed
Binary file src/routing/aodv/test/tcp-chain-test-0-0.pcap has changed
Binary file src/routing/aodv/test/tcp-chain-test-9-0.pcap has changed
Binary file src/routing/aodv/test/udp-chain-test-0-0.pcap has changed
Binary file src/routing/aodv/test/udp-chain-test-9-0.pcap has changed
Binary file src/routing/olsr/test/bug780-0-0.pcap has changed
Binary file src/routing/olsr/test/bug780-1-0.pcap has changed
Binary file src/routing/olsr/test/olsr-tc-regression-test-0-1.pcap has changed
Binary file src/routing/olsr/test/olsr-tc-regression-test-1-1.pcap has changed
Binary file src/routing/olsr/test/olsr-tc-regression-test-2-1.pcap has changed
--- a/src/routing/olsr/test/tc-regression-test.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/src/routing/olsr/test/tc-regression-test.cc Thu Dec 02 07:51:34 2010 +0000
@@ -21,6 +21,7 @@
#include "tc-regression-test.h"
#include "ns3/simulator.h"
#include "ns3/random-variable.h"
+#include "ns3/boolean.h"
#include "ns3/double.h"
#include "ns3/uinteger.h"
#include "ns3/string.h"
--- a/src/test/ns3wifi/wifi-msdu-aggregator-test-suite.cc Wed Dec 01 08:01:24 2010 -0800
+++ b/src/test/ns3wifi/wifi-msdu-aggregator-test-suite.cc Thu Dec 02 07:51:34 2010 +0000
@@ -84,7 +84,7 @@
// and thus has an aggregator on AC_BE.
NodeContainer ap;
ap.Create (1);
- wifiMac.SetType ("ns3::QapWifiMac",
+ wifiMac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid),
"BeaconGeneration", BooleanValue (true),
"BeaconInterval", TimeValue (MicroSeconds (102400)));
@@ -95,7 +95,7 @@
// Setup one STA, which will be the sink for traffic in this test.
NodeContainer sta;
sta.Create (1);
- wifiMac.SetType ("ns3::QstaWifiMac",
+ wifiMac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));
NetDeviceContainer staDev = wifi.Install (wifiPhy, wifiMac, sta);