This commit is contained in:
Mathieu Lacage
2007-10-31 16:26:31 +01:00
parent 570126f8ff
commit d072cdd527
10 changed files with 451 additions and 58 deletions

View File

@@ -24,6 +24,14 @@
namespace ns3 {
/**
* \brief AARF Rate control algorithm
*
* This class implements the AARF rate control algorithm which
* was initially described in <i>IEEE 802.11 Rate Adaptation:
* A Practical Approach</i>, by M. Lacage, M.H. Manshaei, and
* T. Turletti.
*/
class AarfMacStations : public ArfMacStations {
public:
AarfMacStations (WifiMode defaultTxMode,

View File

@@ -24,6 +24,20 @@
namespace ns3 {
/**
* \brief ARF Rate control algorithm
*
* This class implements the so-called ARF algorithm which was
* initially described in <i>WaveLAN-II: A High-performance wireless
* LAN for the unlicensed band</i>, by A. Kamerman and L. Monteban. in
* Bell Lab Technical Journal, pages 118-133, Summer 1997.
*
* This implementation differs from the initial description in that it
* uses a packet-based timer rather than a time-based timer as described
* in XXX (I cannot find back the original paper which described how
* the time-based timer could be easily replaced with a packet-based
* timer.)
*/
class ArfMacStations : public MacStations {
public:
ArfMacStations (WifiMode defaultTxMode, uint32_t timerThreshold, uint32_t successThreshold);

View File

@@ -26,6 +26,12 @@
namespace ns3 {
/**
* \brief use constant rates for data and control transmissions
*
* This class uses always the same transmission rate for every
* packet sent.
*/
class CrMacStations : public MacStations
{
public:

View File

@@ -38,12 +38,39 @@ class WifiPhy;
class MacParameters;
class MacTxMiddle;
/**
* \brief handle packet fragmentation and retransmissions.
*
* This class implements the packet fragmentation and
* retransmission policy. It uses the ns3::MacLow and ns3::Dcf
* helper classes to respectively send packets and decide when
* to send them. Packets are stored in a ns3::WifiMacQueue until
* they can be sent.
*
* The policy currently implemented uses a simple fragmentation
* threshold: any packet bigger than this threshold is fragmented
* in fragments whose size is smaller than the threshold.
*
* The retransmission policy is also very simple: every packet is
* retransmitted until it is either successfully transmitted or
* it has been retransmitted up until the ssrc or slrc thresholds.
*
* The rts/cts policy is similar to the fragmentation policy: when
* a packet is bigger than a threshold, the rts/cts protocol is used.
*/
class DcaTxop
{
public:
typedef Callback <void, WifiMacHeader const&> TxOk;
typedef Callback <void, WifiMacHeader const&> TxFailed;
/**
* \param minCw forwarded to ns3::Dcf constructor
* \param maxCw forwarded to ns3::Dcf constructor
*
* Initialized from \valueref{WifiMaxSsrc}, \valueref{WifiMaxSlrc},
* \valueref{WifiRtsCtsThreshold}, and, \valueref{WifiFragmentationThreshold}.
*/
DcaTxop (uint32_t minCw, uint32_t maxCw);
~DcaTxop ();
@@ -51,7 +78,15 @@ public:
void SetPhy (Ptr<WifiPhy> phy);
void SetParameters (MacParameters *parameters);
void SetTxMiddle (MacTxMiddle *txMiddle);
/**
* \param callback the callback to invoke when a
* packet transmission was completed successfully.
*/
void SetTxOkCallback (TxOk callback);
/**
* \param callback the callback to invoke when a
* packet transmission was completed unsuccessfully.
*/
void SetTxFailedCallback (TxFailed callback);
void SetDifs (Time difs);
@@ -60,6 +95,13 @@ public:
void SetMaxQueueSize (uint32_t size);
void SetMaxQueueDelay (Time delay);
/**
* \param packet packet to send
* \param hdr header of packet to send.
*
* Store the packet in the internal queue until it
* can be sent safely.
*/
void Queue (Packet packet, WifiMacHeader const &hdr);
private:
class AccessListener;

View File

@@ -31,56 +31,177 @@ namespace ns3 {
class RandomStream;
class MacParameters;
/**
* \brief listen to DCF events
*
* If you want to call methods from the ns3::Dcf class,
* you need to provide an instance of this class
* to be notified of the DCF evens.
*/
class DcfAccessListener {
public:
DcfAccessListener ();
virtual ~DcfAccessListener ();
/* Tell the listener than it can start
/**
* Tell the listener than it can start
* accessing the medium right now.
*/
virtual void AccessGrantedNow (void) = 0;
/* ask the listener if there are candidates
/**
* ask the listener if there are candidates
* who need access to the medium.
*
* \return true if access to the medium is
* needed, false otherwise.
*/
virtual bool AccessNeeded (void) = 0;
/* ask the listener if it is currently
/**
* ask the listener if it is currently
* performing an access which was granted
* earlier to him and if it will notify
* the Dcf when the access is complete.
*
* \return true if the listener expects to call
* Dcf::RequestAccess later, false otherwise.
*/
virtual bool AccessingAndWillNotify (void) = 0;
};
/**
* \brief the Distributed Coordination Function
*
* This class implements the DCF as described in IEEE 802.11-1999
* section 9.2, p72.
*
* This implementation is based on the technique described in
* <i>Scalable simulation of large-scale wireless networks with
* bounded inaccuracies.</i>, by Z. Ji, J. Zhou, M. Takai, and R. Bagrodia.
*/
class Dcf
{
public:
/**
* \param minCw the minimum value for CW
* \param maxCW the maximum value for CW
*/
Dcf (uint32_t minCw, uint32_t maxCw);
~Dcf ();
/**
* \param parameters
*
* Must be invoked after construction to configure
* a set of parameters.
*/
void SetParameters (const MacParameters *parameters);
/**
* \param difs the difs
*
* Must be invoked after construction.
*/
void SetDifs (Time difs);
/**
* \param eifs the eifs
*
* Must be invoked after construction.
*/
void SetEifs (Time eifs);
/**
* \param minCw the minimum value for CW
* \param maxCw the maximum value for CW
*
* Reset the cw bounds and CW to minCW.
*/
void SetCwBounds (uint32_t minCw, uint32_t maxCw);
/**
* \param listener the listener
*
* This listener is notified of DCF-specific events
* when they happen. You _must_ register a listener
* before calling Dcf::RequestAccess.
*/
void RegisterAccessListener (DcfAccessListener *listener);
/**
* Request access to the medium. This method will grant
* access by calling the DcfAccessListener::AccessGrantedNow
* method
*/
void RequestAccess (void);
/**
* Reset the CW to CWmin
* This method is typically invoked after a successfully
* transmission or after the maximum number of retries has
* been reached.
*/
void ResetCw (void);
/**
* Update the CW to a new value. This method is typically
* invoked after a failed transmission before calling
* Dcf::StartBackoff.
*/
void UpdateFailedCw (void);
/**
* Start a backoff now by picking a backoff duration
* in the [0, cw] interval.
*/
void StartBackoff (void);
/* notification methods. */
/**
* \param duration expected duration of reception
*
* Notify the DCF that a packet reception started
* for the expected duration.
*/
void NotifyRxStartNow (Time duration);
/**
* Notify the DCF that a packet reception was just
* completed successfully.
*/
void NotifyRxEndOkNow (void);
/**
* Notify the DCF that a packet reception was just
* completed unsuccessfully.
*/
void NotifyRxEndErrorNow (void);
/**
* \param duration expected duration of transmission
*
* Notify the DCF that a packet transmission was
* just started and is expected to last for the specified
* duration.
*/
void NotifyTxStartNow (Time duration);
/**
* \param duration expected duration of cca busy period
*
* Notify the DCF that a CCA busy period has just started.
*/
void NotifyCcaBusyStartNow (Time duration);
/**
* \param now the time at which a NAV starts
* \param duration the value of the received NAV.
*/
void NotifyNavReset (Time now, Time duration);
/**
* \param now the time at which a NAV starts
* \param duration the value of the received NAV.
*/
void NotifyNavStart (Time now, Time duration);
/**
* \param now the time at which a NAV starts
* \param duration the value of the received NAV.
*/
void NotifyNavContinue (Time now, Time duration);
// for testing only.
/**
* \param stream a random stream
*
* This method is used for testing only to force a predictable
* set of random numbers to be used.
*/
void ResetRngForTest (RandomStream *stream);
private:
void AccessTimeout (void);

View File

@@ -27,6 +27,20 @@
namespace ns3 {
/**
* \brief Ideal rate control algorithm
*
* This class implements an 'ideal' rate control algorithm
* similar to RBAR in spirit (see <i>A rate-adaptive MAC
* protocol for multihop wireless networks</i> by G. Holland,
* N. Vaidya, and P. Bahl.): every station keeps track of the
* snr of every packet received and sends back this snr to the
* original transmitter by an out-of-band mechanism. Each
* transmitter keeps track of the last snr sent back by a receiver
* and uses it to pick a transmission mode based on a set
* of snr thresholds built from a target ber and transmission
* mode-specific snr/ber curves.
*/
class IdealMacStations : public MacStations {
public:
IdealMacStations (WifiMode defaultTxMode);

View File

@@ -42,93 +42,223 @@ class MacStations;
class MacStation;
class MacParameters;
/**
* \brief listen to events coming from ns3::MacLow.
*/
class MacLowTransmissionListener {
public:
MacLowTransmissionListener ();
virtual ~MacLowTransmissionListener ();
/**
* \param snr the snr of the cts
* \param txMode the txMode of the cts
*
* ns3::MacLow received an expected CTS within
* CtsTimeout.
*/
virtual void GotCts (double snr, WifiMode txMode) = 0;
/**
* ns3::MacLow did not receive an expected CTS
* within CtsTimeout.
*/
virtual void MissedCts (void) = 0;
/* Do not rely on the gotAck method to be
* given valid parameters when SuperFastAck is
* enabled.
/**
* \param snr the snr of the ack
* \param txMode the transmission mode of the ack
*
* ns3::MacLow received an expected ACL within
* AckTimeout. The <i>snr</i> and <i>txMode</i>
* arguments are not valid when SUPER_FAST_ACK is
* used.
*/
virtual void GotAck (double snr, WifiMode txMode) = 0;
/**
* ns3::MacLow did not receive an expected ACK within
* AckTimeout.
*/
virtual void MissedAck (void) = 0;
/**
* Invoked when ns3::MacLow wants to start a new transmission
* as configured by MacLowTransmissionParameters::EnableNextData.
* The listener is expected to call again MacLow::StartTransmission
* with the "next" data to send.
*/
virtual void StartNext (void) = 0;
/* Invoked if this transmission was canceled
/**
* Invoked if this transmission was canceled
* one way or another. When this method is invoked,
* you can assume that the packet has not been passed
* down the stack to the PHY. You are responsible
* for freeing the packet if you want to.
* down the stack to the PHY.
*/
virtual void Cancel (void) = 0;
};
/**
* \brief listen to NAV events
*
* This class is typically connected to an instance of ns3::Dcf
* and calls to its methods are forwards to the corresponding
* ns3::Dcf methods.
*/
class MacLowNavListener {
public:
MacLowNavListener ();
virtual ~MacLowNavListener ();
/**
* \param now start of NAV timer
* \param duration duration of NAV timer
*/
virtual void NavStart (Time now, Time duration) = 0;
/**
* \param now start of NAV timer
* \param duration duration of NAV timer
*/
virtual void NavContinue (Time now, Time duration) = 0;
/**
* \param now start of NAV timer
* \param duration duration of NAV timer
*/
virtual void NavReset (Time now, Time duration) = 0;
};
/**
* \brief control how a packet is transmitted.
*
* The ns3::MacLow::StartTransmission method expects
* an instance of this class to describe how the packet
* should be transmitted.
*/
class MacLowTransmissionParameters {
public:
MacLowTransmissionParameters ();
/* If ACK is enabled, we wait ACKTimeout for an ACK.
/**
* Wait ACKTimeout for an ACK. If we get an ACK
* on time, call MacLowTransmissionListener::GotAck.
* Call MacLowTransmissionListener::MissedAck otherwise.
*/
void EnableAck (void);
/* If FastAck is enabled, we:
* - wait PIFS after end-of-tx. If idle, report
* FastAckMissed.
/**
* - wait PIFS after end-of-tx. If idle, call
* MacLowTransmissionListener::MissedAck.
* - if busy at end-of-tx+PIFS, wait end-of-rx
* - if Ack ok at end-of-rx, report FastAck ok.
* - if Ack not ok at end-of-rx, report FastAckMissed
* - if Ack ok at end-of-rx, call
* MacLowTransmissionListener::GotAck.
* - if Ack not ok at end-of-rx, report call
* MacLowTransmissionListener::MissedAck
* at end-of-rx+SIFS.
*
* This is really complicated but it is needed for
* proper HCCA support.
*/
void EnableFastAck (void);
/* If SuperFastAck is enabled, we:
* - if busy at end-of-tx+PIFS, report gotAck
* - if idle at end-of-tx+PIFS, report missedAck
/**
* - if busy at end-of-tx+PIFS, call
* MacLowTransmissionListener::GotAck
* - if idle at end-of-tx+PIFS, call
* MacLowTransmissionListener::MissedAck
*/
void EnableSuperFastAck (void);
/* If RTS is enabled, we wait CTSTimeout for a CTS.
* Otherwise, no RTS is sent.
/**
* Send a RTS, and wait CTSTimeout for a CTS. If we get a
* CTS on time, call MacLowTransmissionListener::GotCts
* and send data. Otherwise, call MacLowTransmissionListener::MissedCts
* and do not send data.
*/
void EnableRts (void);
/* If NextData is enabled, we add the transmission duration
* of the nextData to the durationId and we notify the
* transmissionListener at the end of the current
* transmission + SIFS.
/**
* \param size size of next data to send after current packet is
* sent.
*
* Add the transmission duration of the next data to the
* durationId of the outgoing packet and call
* MacLowTransmissionListener::StartNext at the end of
* the current transmission + SIFS.
*/
void EnableNextData (uint32_t size);
/* If we enable this, we ignore all other durationId
* calculation and simply force the packet's durationId
* field to this value.
/**
* \param durationId the value to set in the duration/Id field of
* the outgoing packet.
*
* Ignore all other durationId calculation and simply force the
* packet's durationId field to this value.
*/
void EnableOverrideDurationId (Time durationId);
/**
* Do not wait for Ack after data transmission. Typically
* used for Broadcast and multicast frames.
*/
void DisableAck (void);
/**
* Do not send rts and wait for cts before sending data.
*/
void DisableRts (void);
/**
* Do not attempt to send data burst after current transmission
*/
void DisableNextData (void);
/**
* Do not force the duration/id field of the packet: its
* value is automatically calculated by the MacLow before
* calling WifiPhy::Send.
*/
void DisableOverrideDurationId (void);
/**
* \returns true if must wait for ACK after data transmission,
* false otherwise.
*
* This methods returns true when any of MustWaitNormalAck,
* MustWaitFastAck, or MustWaitSuperFastAck return true.
*/
bool MustWaitAck (void) const;
/**
* \returns true if normal ACK protocol should be used, false
* otherwise.
*
* \sa EnableAck
*/
bool MustWaitNormalAck (void) const;
/**
* \returns true if fast ack protocol should be used, false
* otherwise.
*
* \sa EnableFastAck
*/
bool MustWaitFastAck (void) const;
/**
* \returns true if super fast ack protocol should be used, false
* otherwise.
*
* \sa EnableSuperFastAck
*/
bool MustWaitSuperFastAck (void) const;
/**
* \returns true if RTS should be sent and CTS waited for before
* sending data, false otherwise.
*/
bool MustSendRts (void) const;
/**
* \returns true if a duration/id was forced with
* EnableOverrideDurationId, false otherwise.
*/
bool HasDurationId (void) const;
/**
* \returns the duration/id forced by EnableOverrideDurationId
*/
Time GetDurationId (void) const;
/**
* \returns true if EnableNextData was called, false otherwise.
*/
bool HasNextPacket (void) const;
/**
* \returns the size specified by EnableNextData.
*/
uint32_t GetNextPacketSize (void) const;
private:
@@ -144,6 +274,9 @@ private:
};
/**
* \brief handle RTS/CTS/DATA/ACK transactions.
*/
class MacLow {
public:
typedef Callback<void, Packet , WifiMacHeader const*> MacLowRxCallback;
@@ -155,23 +288,62 @@ public:
void SetPhy (Ptr<WifiPhy> phy);
void SetStations (MacStations *stations);
void SetParameters (MacParameters *parameters);
/**
* \param callback the callback which receives every incoming packet.
*
* This callback typically forwards incoming packets to
* an instance of ns3::MacRxMiddle.
*/
void SetRxCallback (MacLowRxCallback callback);
/**
* \param listener listen to NAV events for every incoming
* and outgoing packet.
*/
void RegisterNavListener (MacLowNavListener *listener);
/* This transmission time includes the time required for
/**
* \param payloadSize size of packet to send (does not include the 802.11 MAC header and checksum)
* \param to destination address of packet.
* \param parameters transmission parameters of packet.
*
* This transmission time includes the time required for
* the next packet transmission if one was selected.
*/
Time CalculateTransmissionTime (uint32_t payloadSize,
Mac48Address to,
MacLowTransmissionParameters const&parameters) const;
/* start the transmission of the currently-stored data. */
/**
* \param packet packet to send
* \param hdr 802.11 header for packet to send
* \param parameters the transmission parameters to use for this packet.
* \param listener listen to transmission events.
*
* Start the transmission of the input packet and notify the listener
* of transmission events.
*/
void StartTransmission (Packet packet,
WifiMacHeader const*hdr,
MacLowTransmissionParameters parameters,
MacLowTransmissionListener *listener);
/**
* \param packet packet received
* \param rxSnr snr of packet received
* \param txMode transmission mode of packet received
* \param preamble type of preamble used for the packet received
*
* This method is typically invoked by the lower PHY layer to notify
* the MAC layer that a packet was successfully received.
*/
void ReceiveOk (Packet packet, double rxSnr, WifiMode txMode, WifiPreamble preamble);
/**
* \param packet packet received.
* \param rxSnr snr of packet received.
*
* This method is typically invoked by the lower PHY layer to notify
* the MAC layer that a packet was unsuccessfully received.
*/
void ReceiveError (Packet packet, double rxSnr);
private:
void CancelAllEvents (void);

View File

@@ -20,26 +20,6 @@
#ifndef WIFI_MAC_QUEUE_H
#define WIFI_MAC_QUEUE_H
/* This queue implements what is needed for the 802.11e standard
* Specifically, it refers to 802.11e/D9, section 9.9.1.6, paragraph 6.
*
* When a packet is received by the MAC, to be sent to the PHY,
* it is queued in the internal queue after being tagged by the
* current time. If the queue is non-Empty (quite likely), we
* notify m_packetNotify. This information is forwarded to
* The associated MacLow80211 which might try to dequeue packets
* from this queue if it is not doing anything else more important.
*
* If it is doing something too important to handle new packets,
* the MacLow80211 is supposed to try to dequeue packets the next
* time it can.
*
* When a packet is dequeued, the queue checks its timestamp
* to verify whether or not it should be dropped. If
* dot11EDCATableMSDULifetime has elapsed, it is dropped.
* Otherwise, it is returned to the caller.
*/
#include <deque>
#include <utility>
#include "ns3/packet.h"
@@ -50,6 +30,21 @@ namespace ns3 {
class MacParameters;
/**
* \brief a 802.11e-specific queue.
*
* This queue implements what is needed for the 802.11e standard
* Specifically, it refers to 802.11e/D9, section 9.9.1.6, paragraph 6.
*
* When a packet is received by the MAC, to be sent to the PHY,
* it is queued in the internal queue after being tagged by the
* current time.
*
* When a packet is dequeued, the queue checks its timestamp
* to verify whether or not it should be dropped. If
* dot11EDCATableMSDULifetime has elapsed, it is dropped.
* Otherwise, it is returned to the caller.
*/
class WifiMacQueue {
public:
WifiMacQueue ();

View File

@@ -168,6 +168,9 @@ private:
class NqstaWifiNetDevice : public WifiNetDevice
{
public:
/**
* The ssid is initialized from \valueref{WifiSsid}.
*/
NqstaWifiNetDevice (Ptr<Node> node);
virtual ~NqstaWifiNetDevice ();
@@ -205,6 +208,9 @@ private:
class NqapWifiNetDevice : public WifiNetDevice
{
public:
/**
* The ssid is initialized from \valueref{WifiSsid}.
*/
NqapWifiNetDevice (Ptr<Node> node);
virtual ~NqapWifiNetDevice ();

View File

@@ -6,11 +6,13 @@
* and to provide a not-so-slow PHY-level model of the 802.11a
* specification.
*
* The current implementation provides roughly 3 levels of models:
* The current implementation provides roughly 4 levels of models:
* - the PHY layer models
* - the so-called MAC low models: they implement DCF
* - the so-called MAC high models: they implement the MAC-level
* beacon generation, probing, and association state machines.
* - a set of Rate control algorithms used by the MAC low models.
*
*
* We have today 3 MAC high models:
* - a simple adhoc state machine which does not perform any
@@ -24,13 +26,26 @@
* accepts every attempt to associate. This AP state machine
* is implemented by the ns3::NqapWifiNetDevice.
*
* The PHY layer implements the model described in
* "Yet Another Network Simulator", (http://cutebugs.net/files/wns2-yans.pdf)
* The implementation is located in the ns3::WifiPhy class.
* The MAC low layer is split in 3 components:
* - ns3::MacLow which takes care of RTS/CTS/DATA/ACK transactions.
* - ns3::Dcf which implements the DCF function.
* - ns3::DcaTxop which handles the packet queue, packet fragmentation,
* and packet retransmissions if they are needed.
*
* The PHY layer implements a single model in ns3::WifiPhy.
*
* It also provides a set of Rate control algorithms:
* - ns3::ArfMacStations (initialized from \valueref{WifiArfTimerThreshold}, and,
* \valueref{WifiArfSuccessThreshold})
* - ns3::AArfMacStations (initialized from \valueref{WifiAarfMinSuccessThreshold},
* \valueref{WifiAarfMinTimerThreshold}, \valueref{WifiAarfSuccessK},
* \valueref{WifiAarfMaxSuccessThreshold}, and, \valueref{WifiAarfTimerK}
* - ns3::IdealMacStations (initialized from \valueref{WifiIdealRateControlBerThreshold})
* - ns3::CrMacStations (initialized from \valueref{WifiConstantDataRate}, and,
* \valueref{WifiConstantCtlRate}).
*
* The type of rate control algorithm is controlled through \valueref{WifiRateControlAlgorithm}.
*
* The MAC low models attempt to implement the 802.11 DCF function
* in an optimized way through the technique described in XXX.
* This implementation is located in the ns3::Dcf class.
*
* \section Wifi Tutorial
*