wifi: Txop holds a channel access state
This is needed because (Qos)Txop will no longer hold a current MPDU that can be used to determine whether a frame exchange is ongoing.
This commit is contained in:
@@ -264,7 +264,8 @@ ChannelAccessManager::NeedBackoffUponAccess (Ptr<Txop> txop)
|
||||
* with that AC has now become non-empty and any other transmit queues
|
||||
* associated with that AC are empty; the medium is busy on the primary channel
|
||||
*/
|
||||
if (!txop->HasFramesToTransmit () && !txop->GetLow ()->IsCfPeriod () && txop->GetBackoffSlots () == 0)
|
||||
if (!txop->HasFramesToTransmit () && txop->GetAccessStatus () != Txop::GRANTED
|
||||
&& !txop->GetLow ()->IsCfPeriod () && txop->GetBackoffSlots () == 0)
|
||||
{
|
||||
if (!IsBusy ())
|
||||
{
|
||||
@@ -322,7 +323,7 @@ ChannelAccessManager::RequestAccess (Ptr<Txop> txop, bool isCfPeriod)
|
||||
}
|
||||
|
||||
UpdateBackoff ();
|
||||
NS_ASSERT (!txop->IsAccessRequested ());
|
||||
NS_ASSERT (txop->GetAccessStatus () != Txop::REQUESTED);
|
||||
txop->NotifyAccessRequested ();
|
||||
DoGrantDcfAccess ();
|
||||
DoRestartAccessTimeoutIfNeeded ();
|
||||
@@ -342,7 +343,7 @@ ChannelAccessManager::DoGrantDcfAccess (void)
|
||||
for (Txops::iterator i = m_txops.begin (); i != m_txops.end (); k++)
|
||||
{
|
||||
Ptr<Txop> txop = *i;
|
||||
if (txop->IsAccessRequested ()
|
||||
if (txop->GetAccessStatus () == Txop::REQUESTED
|
||||
&& GetBackoffEndFor (txop) <= Simulator::Now () )
|
||||
{
|
||||
/**
|
||||
@@ -356,7 +357,7 @@ ChannelAccessManager::DoGrantDcfAccess (void)
|
||||
for (Txops::iterator j = i; j != m_txops.end (); j++, k++)
|
||||
{
|
||||
Ptr<Txop> otherTxop = *j;
|
||||
if (otherTxop->IsAccessRequested ()
|
||||
if (otherTxop->GetAccessStatus () == Txop::REQUESTED
|
||||
&& GetBackoffEndFor (otherTxop) <= Simulator::Now ())
|
||||
{
|
||||
NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" <<
|
||||
@@ -511,7 +512,7 @@ ChannelAccessManager::DoRestartAccessTimeoutIfNeeded (void)
|
||||
Time expectedBackoffEnd = Simulator::GetMaximumSimulationTime ();
|
||||
for (auto txop : m_txops)
|
||||
{
|
||||
if (txop->IsAccessRequested ())
|
||||
if (txop->GetAccessStatus () == Txop::REQUESTED)
|
||||
{
|
||||
Time tmp = GetBackoffEndFor (txop);
|
||||
if (tmp > Simulator::Now ())
|
||||
@@ -653,7 +654,7 @@ ChannelAccessManager::NotifySwitchingStartNow (Time duration)
|
||||
NS_ASSERT (txop->GetBackoffSlots () == 0);
|
||||
}
|
||||
txop->ResetCw ();
|
||||
txop->m_accessRequested = false;
|
||||
txop->m_access = Txop::NOT_REQUESTED;
|
||||
txop->NotifyChannelSwitching ();
|
||||
}
|
||||
|
||||
@@ -712,7 +713,7 @@ ChannelAccessManager::NotifyWakeupNow (void)
|
||||
NS_ASSERT (txop->GetBackoffSlots () == 0);
|
||||
}
|
||||
txop->ResetCw ();
|
||||
txop->m_accessRequested = false;
|
||||
txop->m_access = Txop::NOT_REQUESTED;
|
||||
txop->NotifyWakeUp ();
|
||||
}
|
||||
}
|
||||
@@ -731,7 +732,7 @@ ChannelAccessManager::NotifyOnNow (void)
|
||||
NS_ASSERT (txop->GetBackoffSlots () == 0);
|
||||
}
|
||||
txop->ResetCw ();
|
||||
txop->m_accessRequested = false;
|
||||
txop->m_access = Txop::NOT_REQUESTED;
|
||||
txop->NotifyOn ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,8 +502,10 @@ void
|
||||
QosTxop::NotifyAccessGranted (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_ASSERT (m_accessRequested);
|
||||
m_accessRequested = false;
|
||||
// TODO FEM may have changed m_access to GRANTED, so the assert below holds not
|
||||
// always true. Anyway, this function will soon be removed altogether.
|
||||
// NS_ASSERT (m_access == REQUESTED);
|
||||
m_access = NOT_REQUESTED;
|
||||
m_isAccessRequestedForRts = false;
|
||||
m_startTxop = Simulator::Now ();
|
||||
// discard the current packet if it is a QoS Data frame with expired lifetime
|
||||
@@ -994,7 +996,7 @@ QosTxop::RestartAccessIfNeeded (void)
|
||||
bool queueIsNotEmpty = !m_queue->IsEmpty ();
|
||||
|
||||
if ((m_currentPacket != 0 || baManagerHasPackets || queueIsNotEmpty)
|
||||
&& !IsAccessRequested ())
|
||||
&& m_access == NOT_REQUESTED)
|
||||
{
|
||||
Ptr<const WifiMacQueueItem> item;
|
||||
if (m_currentPacket != 0)
|
||||
@@ -1031,7 +1033,7 @@ QosTxop::StartAccessIfNeeded (void)
|
||||
|
||||
if (m_currentPacket == 0
|
||||
&& (baManagerHasPackets || queueIsNotEmpty)
|
||||
&& !IsAccessRequested ())
|
||||
&& m_access == NOT_REQUESTED)
|
||||
{
|
||||
Ptr<const WifiMacQueueItem> item = PeekNextFrame ();
|
||||
if (item != 0)
|
||||
|
||||
@@ -89,7 +89,7 @@ Txop::Txop ()
|
||||
m_cwMax (0),
|
||||
m_cw (0),
|
||||
m_backoff (0),
|
||||
m_accessRequested (false),
|
||||
m_access (NOT_REQUESTED),
|
||||
m_backoffSlots (0),
|
||||
m_backoffStart (Seconds (0.0)),
|
||||
m_currentPacket (0)
|
||||
@@ -342,7 +342,7 @@ Txop::RestartAccessIfNeeded (void)
|
||||
NS_LOG_FUNCTION (this);
|
||||
if ((m_currentPacket != 0
|
||||
|| !m_queue->IsEmpty ())
|
||||
&& !IsAccessRequested ()
|
||||
&& m_access == NOT_REQUESTED
|
||||
&& !m_low->IsCfPeriod ())
|
||||
{
|
||||
m_channelAccessManager->RequestAccess (this);
|
||||
@@ -355,7 +355,7 @@ Txop::StartAccessIfNeeded (void)
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (m_currentPacket == 0
|
||||
&& !m_queue->IsEmpty ()
|
||||
&& !IsAccessRequested ()
|
||||
&& m_access == NOT_REQUESTED
|
||||
&& !m_low->IsCfPeriod ())
|
||||
{
|
||||
m_channelAccessManager->RequestAccess (this);
|
||||
@@ -457,25 +457,53 @@ Txop::GetFragmentPacket (WifiMacHeader *hdr)
|
||||
return fragment;
|
||||
}
|
||||
|
||||
bool
|
||||
Txop::IsAccessRequested (void) const
|
||||
Txop::ChannelAccessStatus
|
||||
Txop::GetAccessStatus (void) const
|
||||
{
|
||||
return m_accessRequested;
|
||||
return m_access;
|
||||
}
|
||||
|
||||
void
|
||||
Txop::NotifyAccessRequested (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_accessRequested = true;
|
||||
m_access = REQUESTED;
|
||||
}
|
||||
|
||||
void
|
||||
Txop::NotifyChannelAccessed (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_access = GRANTED;
|
||||
}
|
||||
|
||||
void
|
||||
Txop::NotifyChannelReleased (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_access = NOT_REQUESTED;
|
||||
GenerateBackoff ();
|
||||
if (HasFramesToTransmit ())
|
||||
{
|
||||
Simulator::ScheduleNow (&Txop::RequestAccess, this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Txop::RequestAccess (void)
|
||||
{
|
||||
if (m_access == NOT_REQUESTED)
|
||||
{
|
||||
m_channelAccessManager->RequestAccess (this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Txop::NotifyAccessGranted (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_ASSERT (m_accessRequested);
|
||||
m_accessRequested = false;
|
||||
// NS_ASSERT (m_access == REQUESTED); FEM may have changed m_access to GRANTED
|
||||
m_access = NOT_REQUESTED;
|
||||
if (m_currentPacket == 0)
|
||||
{
|
||||
if (m_queue->IsEmpty ())
|
||||
|
||||
@@ -94,6 +94,16 @@ public:
|
||||
*/
|
||||
typedef Callback <void, Ptr<const Packet> > TxDropped;
|
||||
|
||||
/**
|
||||
* Enumeration for channel access status
|
||||
*/
|
||||
enum ChannelAccessStatus
|
||||
{
|
||||
NOT_REQUESTED = 0,
|
||||
REQUESTED,
|
||||
GRANTED
|
||||
};
|
||||
|
||||
/**
|
||||
* Check for QoS TXOP.
|
||||
*
|
||||
@@ -329,6 +339,17 @@ public:
|
||||
*/
|
||||
virtual void TerminateTxop (void);
|
||||
|
||||
/**
|
||||
* Called by the FrameExchangeManager to notify that channel access has
|
||||
* been granted.
|
||||
*/
|
||||
virtual void NotifyChannelAccessed (void);
|
||||
/**
|
||||
* Called by the FrameExchangeManager to notify the completion of the transmissions.
|
||||
* This method generates a new backoff and restarts access if needed.
|
||||
*/
|
||||
virtual void NotifyChannelReleased (void);
|
||||
|
||||
/**
|
||||
* Check if the next PCF transmission can fit in the remaining CFP duration.
|
||||
*
|
||||
@@ -350,10 +371,9 @@ public:
|
||||
int64_t AssignStreams (int64_t stream);
|
||||
|
||||
/**
|
||||
* \returns true if access has been requested for this function and
|
||||
* has not been granted already, false otherwise.
|
||||
* \return the current channel access status.
|
||||
*/
|
||||
virtual bool IsAccessRequested (void) const;
|
||||
virtual ChannelAccessStatus GetAccessStatus (void) const;
|
||||
|
||||
/**
|
||||
* \param nSlots the number of slots of the backoff.
|
||||
@@ -401,6 +421,10 @@ protected:
|
||||
* Request access from Txop if needed.
|
||||
*/
|
||||
virtual void StartAccessIfNeeded (void);
|
||||
/**
|
||||
* Request access to the ChannelAccessManager
|
||||
*/
|
||||
void RequestAccess (void);
|
||||
|
||||
/**
|
||||
* \returns the current value of the CW variable. The initial value is
|
||||
@@ -512,12 +536,12 @@ protected:
|
||||
Ptr<WifiRemoteStationManager> m_stationManager; //!< the wifi remote station manager
|
||||
Ptr<UniformRandomVariable> m_rng; //!< the random stream
|
||||
|
||||
uint32_t m_cwMin; //!< the minimum contention window
|
||||
uint32_t m_cwMax; //!< the maximum contention window
|
||||
uint32_t m_cw; //!< the current contention window
|
||||
uint32_t m_backoff; //!< the current backoff
|
||||
bool m_accessRequested; //!< flag whether channel access is already requested
|
||||
uint32_t m_backoffSlots; //!< the number of backoff slots
|
||||
uint32_t m_cwMin; //!< the minimum contention window
|
||||
uint32_t m_cwMax; //!< the maximum contention window
|
||||
uint32_t m_cw; //!< the current contention window
|
||||
uint32_t m_backoff; //!< the current backoff
|
||||
ChannelAccessStatus m_access; //!< channel access status
|
||||
uint32_t m_backoffSlots; //!< the number of backoff slots
|
||||
/**
|
||||
* the backoffStart variable is used to keep track of the
|
||||
* time at which a backoff was started or the time at which
|
||||
|
||||
Reference in New Issue
Block a user