wifi: Add support for exchanging MU EDCA Parameter Set elements
This commit is contained in:
@@ -505,6 +505,60 @@ ApWifiMac::GetEdcaParameterSet (void) const
|
||||
return edcaParameters;
|
||||
}
|
||||
|
||||
MuEdcaParameterSet
|
||||
ApWifiMac::GetMuEdcaParameterSet (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
MuEdcaParameterSet muEdcaParameters;
|
||||
if (GetHeSupported ())
|
||||
{
|
||||
Ptr<HeConfiguration> heConfiguration = GetHeConfiguration ();
|
||||
NS_ASSERT (heConfiguration != 0);
|
||||
|
||||
muEdcaParameters.SetQosInfo (0);
|
||||
|
||||
UintegerValue uintegerValue;
|
||||
TimeValue timeValue;
|
||||
|
||||
heConfiguration->GetAttribute ("MuBeAifsn", uintegerValue);
|
||||
muEdcaParameters.SetMuAifsn (AC_BE, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("MuBeCwMin", uintegerValue);
|
||||
muEdcaParameters.SetMuCwMin (AC_BE, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("MuBeCwMax", uintegerValue);
|
||||
muEdcaParameters.SetMuCwMax (AC_BE, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("BeMuEdcaTimer", timeValue);
|
||||
muEdcaParameters.SetMuEdcaTimer (AC_BE, timeValue.Get ());
|
||||
|
||||
heConfiguration->GetAttribute ("MuBkAifsn", uintegerValue);
|
||||
muEdcaParameters.SetMuAifsn (AC_BK, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("MuBkCwMin", uintegerValue);
|
||||
muEdcaParameters.SetMuCwMin (AC_BK, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("MuBkCwMax", uintegerValue);
|
||||
muEdcaParameters.SetMuCwMax (AC_BK, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("BkMuEdcaTimer", timeValue);
|
||||
muEdcaParameters.SetMuEdcaTimer (AC_BK, timeValue.Get ());
|
||||
|
||||
heConfiguration->GetAttribute ("MuViAifsn", uintegerValue);
|
||||
muEdcaParameters.SetMuAifsn (AC_VI, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("MuViCwMin", uintegerValue);
|
||||
muEdcaParameters.SetMuCwMin (AC_VI, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("MuViCwMax", uintegerValue);
|
||||
muEdcaParameters.SetMuCwMax (AC_VI, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("ViMuEdcaTimer", timeValue);
|
||||
muEdcaParameters.SetMuEdcaTimer (AC_VI, timeValue.Get ());
|
||||
|
||||
heConfiguration->GetAttribute ("MuVoAifsn", uintegerValue);
|
||||
muEdcaParameters.SetMuAifsn (AC_VO, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("MuVoCwMin", uintegerValue);
|
||||
muEdcaParameters.SetMuCwMin (AC_VO, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("MuVoCwMax", uintegerValue);
|
||||
muEdcaParameters.SetMuCwMax (AC_VO, uintegerValue.Get ());
|
||||
heConfiguration->GetAttribute ("VoMuEdcaTimer", timeValue);
|
||||
muEdcaParameters.SetMuEdcaTimer (AC_VO, timeValue.Get ());
|
||||
}
|
||||
return muEdcaParameters;
|
||||
}
|
||||
|
||||
HtOperation
|
||||
ApWifiMac::GetHtOperation (void) const
|
||||
{
|
||||
@@ -709,6 +763,7 @@ ApWifiMac::SendProbeResp (Mac48Address to)
|
||||
{
|
||||
probe.SetHeCapabilities (GetHeCapabilities ());
|
||||
probe.SetHeOperation (GetHeOperation ());
|
||||
probe.SetMuEdcaParameterSet (GetMuEdcaParameterSet ());
|
||||
}
|
||||
packet->AddHeader (probe);
|
||||
|
||||
@@ -799,6 +854,7 @@ ApWifiMac::SendAssocResp (Mac48Address to, bool success, bool isReassoc)
|
||||
{
|
||||
assoc.SetHeCapabilities (GetHeCapabilities ());
|
||||
assoc.SetHeOperation (GetHeOperation ());
|
||||
assoc.SetMuEdcaParameterSet (GetMuEdcaParameterSet ());
|
||||
}
|
||||
packet->AddHeader (assoc);
|
||||
|
||||
@@ -855,6 +911,7 @@ ApWifiMac::SendOneBeacon (void)
|
||||
{
|
||||
beacon.SetHeCapabilities (GetHeCapabilities ());
|
||||
beacon.SetHeOperation (GetHeOperation ());
|
||||
beacon.SetMuEdcaParameterSet (GetMuEdcaParameterSet ());
|
||||
}
|
||||
packet->AddHeader (beacon);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ class CapabilityInformation;
|
||||
class DsssParameterSet;
|
||||
class ErpInformation;
|
||||
class EdcaParameterSet;
|
||||
class MuEdcaParameterSet;
|
||||
class HtOperation;
|
||||
class VhtOperation;
|
||||
class HeOperation;
|
||||
@@ -231,6 +232,12 @@ private:
|
||||
* \return the EDCA Parameter Set that we support
|
||||
*/
|
||||
EdcaParameterSet GetEdcaParameterSet (void) const;
|
||||
/**
|
||||
* Return the MU EDCA Parameter Set of the current AP.
|
||||
*
|
||||
* \return the MU EDCA Parameter Set that we support
|
||||
*/
|
||||
MuEdcaParameterSet GetMuEdcaParameterSet (void) const;
|
||||
/**
|
||||
* Return the HT operation of the current AP.
|
||||
*
|
||||
|
||||
@@ -360,12 +360,24 @@ MgtProbeResponseHeader::SetEdcaParameterSet (EdcaParameterSet edcaParameters)
|
||||
m_edcaParameterSet = edcaParameters;
|
||||
}
|
||||
|
||||
void
|
||||
MgtProbeResponseHeader::SetMuEdcaParameterSet (MuEdcaParameterSet muEdcaParameters)
|
||||
{
|
||||
m_muEdcaParameterSet = muEdcaParameters;
|
||||
}
|
||||
|
||||
EdcaParameterSet
|
||||
MgtProbeResponseHeader::GetEdcaParameterSet (void) const
|
||||
{
|
||||
return m_edcaParameterSet;
|
||||
}
|
||||
|
||||
MuEdcaParameterSet
|
||||
MgtProbeResponseHeader::GetMuEdcaParameterSet (void) const
|
||||
{
|
||||
return m_muEdcaParameterSet;
|
||||
}
|
||||
|
||||
TypeId
|
||||
MgtProbeResponseHeader::GetTypeId (void)
|
||||
{
|
||||
@@ -403,6 +415,7 @@ MgtProbeResponseHeader::GetSerializedSize (void) const
|
||||
size += m_vhtOperation.GetSerializedSize ();
|
||||
size += m_heCapability.GetSerializedSize ();
|
||||
size += m_heOperation.GetSerializedSize ();
|
||||
size += m_muEdcaParameterSet.GetSerializedSize ();
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -450,6 +463,7 @@ MgtProbeResponseHeader::Serialize (Buffer::Iterator start) const
|
||||
i = m_vhtOperation.Serialize (i);
|
||||
i = m_heCapability.Serialize (i);
|
||||
i = m_heOperation.Serialize (i);
|
||||
i = m_muEdcaParameterSet.Serialize (i);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -473,6 +487,7 @@ MgtProbeResponseHeader::Deserialize (Buffer::Iterator start)
|
||||
i = m_vhtOperation.DeserializeIfPresent (i);
|
||||
i = m_heCapability.DeserializeIfPresent (i);
|
||||
i = m_heOperation.DeserializeIfPresent (i);
|
||||
i = m_muEdcaParameterSet.DeserializeIfPresent (i);
|
||||
return i.GetDistanceFrom (start);
|
||||
}
|
||||
|
||||
@@ -1045,12 +1060,24 @@ MgtAssocResponseHeader::SetEdcaParameterSet (EdcaParameterSet edcaparameters)
|
||||
m_edcaParameterSet = edcaparameters;
|
||||
}
|
||||
|
||||
void
|
||||
MgtAssocResponseHeader::SetMuEdcaParameterSet (MuEdcaParameterSet muEdcaParameters)
|
||||
{
|
||||
m_muEdcaParameterSet = muEdcaParameters;
|
||||
}
|
||||
|
||||
EdcaParameterSet
|
||||
MgtAssocResponseHeader::GetEdcaParameterSet (void) const
|
||||
{
|
||||
return m_edcaParameterSet;
|
||||
}
|
||||
|
||||
MuEdcaParameterSet
|
||||
MgtAssocResponseHeader::GetMuEdcaParameterSet (void) const
|
||||
{
|
||||
return m_muEdcaParameterSet;
|
||||
}
|
||||
|
||||
TypeId
|
||||
MgtAssocResponseHeader::GetTypeId (void)
|
||||
{
|
||||
@@ -1086,6 +1113,7 @@ MgtAssocResponseHeader::GetSerializedSize (void) const
|
||||
size += m_vhtOperation.GetSerializedSize ();
|
||||
size += m_heCapability.GetSerializedSize ();
|
||||
size += m_heOperation.GetSerializedSize ();
|
||||
size += m_muEdcaParameterSet.GetSerializedSize ();
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -1123,6 +1151,7 @@ MgtAssocResponseHeader::Serialize (Buffer::Iterator start) const
|
||||
i = m_vhtOperation.Serialize (i);
|
||||
i = m_heCapability.Serialize (i);
|
||||
i = m_heOperation.Serialize (i);
|
||||
i = m_muEdcaParameterSet.Serialize (i);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -1143,6 +1172,7 @@ MgtAssocResponseHeader::Deserialize (Buffer::Iterator start)
|
||||
i = m_vhtOperation.DeserializeIfPresent (i);
|
||||
i = m_heCapability.DeserializeIfPresent (i);
|
||||
i = m_heOperation.DeserializeIfPresent (i);
|
||||
i = m_muEdcaParameterSet.DeserializeIfPresent (i);
|
||||
return i.GetDistanceFrom (start);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "edca-parameter-set.h"
|
||||
#include "ns3/he-capabilities.h"
|
||||
#include "ns3/he-operation.h"
|
||||
#include "ns3/mu-edca-parameter-set.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -399,6 +400,12 @@ public:
|
||||
* \return the EDCA Parameter Set
|
||||
*/
|
||||
EdcaParameterSet GetEdcaParameterSet (void) const;
|
||||
/**
|
||||
* Return the MU EDCA Parameter Set.
|
||||
*
|
||||
* \return the MU EDCA Parameter Set
|
||||
*/
|
||||
MuEdcaParameterSet GetMuEdcaParameterSet (void) const;
|
||||
/**
|
||||
* Set the Capability information.
|
||||
*
|
||||
@@ -465,6 +472,12 @@ public:
|
||||
* \param edcaParameterSet the EDCA Parameter Set
|
||||
*/
|
||||
void SetEdcaParameterSet (EdcaParameterSet edcaParameterSet);
|
||||
/**
|
||||
* Set the MU EDCA Parameter Set.
|
||||
*
|
||||
* \param muEdcaParameterSet the MU EDCA Parameter Set
|
||||
*/
|
||||
void SetMuEdcaParameterSet (MuEdcaParameterSet muEdcaParameterSet);
|
||||
/**
|
||||
* Set the HE capabilities.
|
||||
*
|
||||
@@ -504,6 +517,7 @@ private:
|
||||
EdcaParameterSet m_edcaParameterSet; //!< EDCA Parameter Set
|
||||
HeCapabilities m_heCapability; //!< HE capabilities
|
||||
HeOperation m_heOperation; //!< HE operation
|
||||
MuEdcaParameterSet m_muEdcaParameterSet; //!< MU EDCA Parameter Set
|
||||
};
|
||||
|
||||
|
||||
@@ -705,6 +719,12 @@ public:
|
||||
* \return the EDCA Parameter Set
|
||||
*/
|
||||
EdcaParameterSet GetEdcaParameterSet (void) const;
|
||||
/**
|
||||
* Return the MU EDCA Parameter Set.
|
||||
*
|
||||
* \return the MU EDCA Parameter Set
|
||||
*/
|
||||
MuEdcaParameterSet GetMuEdcaParameterSet (void) const;
|
||||
/**
|
||||
* Set the Capability information.
|
||||
*
|
||||
@@ -789,6 +809,12 @@ public:
|
||||
* \param edcaParameterSet the EDCA Parameter Set
|
||||
*/
|
||||
void SetEdcaParameterSet (EdcaParameterSet edcaParameterSet);
|
||||
/**
|
||||
* Set the MU EDCA Parameter Set.
|
||||
*
|
||||
* \param muEdcaParameterSet the MU EDCA Parameter Set
|
||||
*/
|
||||
void SetMuEdcaParameterSet (MuEdcaParameterSet muEdcaParameterSet);
|
||||
/**
|
||||
* Return the time stamp.
|
||||
*
|
||||
@@ -824,6 +850,7 @@ private:
|
||||
HeOperation m_heOperation; //!< HE operation
|
||||
ErpInformation m_erpInformation; //!< ERP information
|
||||
EdcaParameterSet m_edcaParameterSet; //!< EDCA Parameter Set
|
||||
MuEdcaParameterSet m_muEdcaParameterSet; //!< MU EDCA Parameter Set
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -92,7 +92,11 @@ QosTxop::GetTypeId (void)
|
||||
|
||||
QosTxop::QosTxop ()
|
||||
: m_startTxop (Seconds (0)),
|
||||
m_txopDuration (Seconds (0))
|
||||
m_txopDuration (Seconds (0)),
|
||||
m_muCwMin (0),
|
||||
m_muCwMax (0),
|
||||
m_muAifsn (0),
|
||||
m_muEdcaTimer (Seconds (0))
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_qosBlockedDestinations = Create<QosBlockedDestinations> ();
|
||||
@@ -145,6 +149,34 @@ QosTxop::SetDroppedMpduCallback (DroppedMpdu callback)
|
||||
.Bind (WIFI_MAC_DROP_EXPIRED_LIFETIME));
|
||||
}
|
||||
|
||||
void
|
||||
QosTxop::SetMuCwMin (uint16_t cwMin)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << cwMin);
|
||||
m_muCwMin = cwMin;
|
||||
}
|
||||
|
||||
void
|
||||
QosTxop::SetMuCwMax (uint16_t cwMax)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << cwMax);
|
||||
m_muCwMax = cwMax;
|
||||
}
|
||||
|
||||
void
|
||||
QosTxop::SetMuAifsn (uint8_t aifsn)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << +aifsn);
|
||||
m_muAifsn = aifsn;
|
||||
}
|
||||
|
||||
void
|
||||
QosTxop::SetMuEdcaTimer (Time timer)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << timer);
|
||||
m_muEdcaTimer = timer;
|
||||
}
|
||||
|
||||
Ptr<BlockAckManager>
|
||||
QosTxop::GetBaManager (void)
|
||||
{
|
||||
|
||||
@@ -389,6 +389,34 @@ public:
|
||||
*/
|
||||
virtual Time GetRemainingTxop (void) const;
|
||||
|
||||
/**
|
||||
* Set the minimum contention window size to use while the MU EDCA Timer
|
||||
* is running.
|
||||
*
|
||||
* \param cwMin the minimum contention window size.
|
||||
*/
|
||||
void SetMuCwMin (uint16_t cwMin);
|
||||
/**
|
||||
* Set the maximum contention window size to use while the MU EDCA Timer
|
||||
* is running.
|
||||
*
|
||||
* \param cwMax the maximum contention window size.
|
||||
*/
|
||||
void SetMuCwMax (uint16_t cwMax);
|
||||
/**
|
||||
* Set the number of slots that make up an AIFS while the MU EDCA Timer
|
||||
* is running.
|
||||
*
|
||||
* \param aifsn the number of slots that make up an AIFS.
|
||||
*/
|
||||
void SetMuAifsn (uint8_t aifsn);
|
||||
/**
|
||||
* Set the MU EDCA Timer.
|
||||
*
|
||||
* \param timer the timer duration.
|
||||
*/
|
||||
void SetMuEdcaTimer (Time timer);
|
||||
|
||||
protected:
|
||||
void DoDispose (void) override;
|
||||
|
||||
@@ -423,6 +451,11 @@ private:
|
||||
Time m_failedAddBaTimeout; //!< timeout after failed BA agreement
|
||||
bool m_useExplicitBarAfterMissedBlockAck; //!< flag whether explicit BlockAckRequest should be sent upon missed BlockAck Response
|
||||
|
||||
uint32_t m_muCwMin; //!< the MU CW minimum
|
||||
uint32_t m_muCwMax; //!< the MU CW maximum
|
||||
uint8_t m_muAifsn; //!< the MU AIFSN
|
||||
Time m_muEdcaTimer; //!< the MU EDCA Timer
|
||||
|
||||
TracedCallback<Time, Time> m_txopTrace; //!< TXOP trace callback
|
||||
};
|
||||
|
||||
|
||||
@@ -821,6 +821,19 @@ StaWifiMac::UpdateApInfoFromBeacon (MgtBeaconHeader beacon, Mac48Address apAddr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MuEdcaParameterSet muEdcaParameters = beacon.GetMuEdcaParameterSet ();
|
||||
if (muEdcaParameters.IsPresent ())
|
||||
{
|
||||
SetMuEdcaParameters (AC_BE, muEdcaParameters.GetMuCwMin (AC_BE), muEdcaParameters.GetMuCwMax (AC_BE),
|
||||
muEdcaParameters.GetMuAifsn (AC_BE), muEdcaParameters.GetMuEdcaTimer (AC_BE));
|
||||
SetMuEdcaParameters (AC_BK, muEdcaParameters.GetMuCwMin (AC_BK), muEdcaParameters.GetMuCwMax (AC_BK),
|
||||
muEdcaParameters.GetMuAifsn (AC_BK), muEdcaParameters.GetMuEdcaTimer (AC_BK));
|
||||
SetMuEdcaParameters (AC_VI, muEdcaParameters.GetMuCwMin (AC_VI), muEdcaParameters.GetMuCwMax (AC_VI),
|
||||
muEdcaParameters.GetMuAifsn (AC_VI), muEdcaParameters.GetMuEdcaTimer (AC_VI));
|
||||
SetMuEdcaParameters (AC_VO, muEdcaParameters.GetMuCwMin (AC_VO), muEdcaParameters.GetMuCwMax (AC_VO),
|
||||
muEdcaParameters.GetMuAifsn (AC_VO), muEdcaParameters.GetMuEdcaTimer (AC_VO));
|
||||
}
|
||||
}
|
||||
m_stationManager->SetShortPreambleEnabled (isShortPreambleEnabled);
|
||||
m_stationManager->SetShortSlotTimeEnabled (capabilities.IsShortSlotTime ());
|
||||
@@ -981,6 +994,19 @@ StaWifiMac::UpdateApInfoFromAssocResp (MgtAssocResponseHeader assocResp, Mac48Ad
|
||||
HeOperation heOperation = assocResp.GetHeOperation ();
|
||||
GetHeConfiguration ()->SetAttribute ("BssColor", UintegerValue (heOperation.GetBssColor ()));
|
||||
}
|
||||
|
||||
MuEdcaParameterSet muEdcaParameters = assocResp.GetMuEdcaParameterSet ();
|
||||
if (muEdcaParameters.IsPresent ())
|
||||
{
|
||||
SetMuEdcaParameters (AC_BE, muEdcaParameters.GetMuCwMin (AC_BE), muEdcaParameters.GetMuCwMax (AC_BE),
|
||||
muEdcaParameters.GetMuAifsn (AC_BE), muEdcaParameters.GetMuEdcaTimer (AC_BE));
|
||||
SetMuEdcaParameters (AC_BK, muEdcaParameters.GetMuCwMin (AC_BK), muEdcaParameters.GetMuCwMax (AC_BK),
|
||||
muEdcaParameters.GetMuAifsn (AC_BK), muEdcaParameters.GetMuEdcaTimer (AC_BK));
|
||||
SetMuEdcaParameters (AC_VI, muEdcaParameters.GetMuCwMin (AC_VI), muEdcaParameters.GetMuCwMax (AC_VI),
|
||||
muEdcaParameters.GetMuAifsn (AC_VI), muEdcaParameters.GetMuEdcaTimer (AC_VI));
|
||||
SetMuEdcaParameters (AC_VO, muEdcaParameters.GetMuCwMin (AC_VO), muEdcaParameters.GetMuCwMax (AC_VO),
|
||||
muEdcaParameters.GetMuAifsn (AC_VO), muEdcaParameters.GetMuEdcaTimer (AC_VO));
|
||||
}
|
||||
}
|
||||
for (const auto & mode : m_phy->GetModeList ())
|
||||
{
|
||||
@@ -1084,13 +1110,23 @@ StaWifiMac::SetState (MacState value)
|
||||
void
|
||||
StaWifiMac::SetEdcaParameters (AcIndex ac, uint32_t cwMin, uint32_t cwMax, uint8_t aifsn, Time txopLimit)
|
||||
{
|
||||
Ptr<QosTxop> edca = m_edca.find (ac)->second;
|
||||
Ptr<QosTxop> edca = GetQosTxop (ac);
|
||||
edca->SetMinCw (cwMin);
|
||||
edca->SetMaxCw (cwMax);
|
||||
edca->SetAifsn (aifsn);
|
||||
edca->SetTxopLimit (txopLimit);
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::SetMuEdcaParameters (AcIndex ac, uint16_t cwMin, uint16_t cwMax, uint8_t aifsn, Time muEdcaTimer)
|
||||
{
|
||||
Ptr<QosTxop> edca = GetQosTxop (ac);
|
||||
edca->SetMuCwMin (cwMin);
|
||||
edca->SetMuCwMax (cwMax);
|
||||
edca->SetMuAifsn (aifsn);
|
||||
edca->SetMuEdcaTimer (muEdcaTimer);
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::PhyCapabilitiesChanged (void)
|
||||
{
|
||||
|
||||
@@ -290,6 +290,16 @@ private:
|
||||
* \param txopLimit the TXOP limit
|
||||
*/
|
||||
void SetEdcaParameters (AcIndex ac, uint32_t cwMin, uint32_t cwMax, uint8_t aifsn, Time txopLimit);
|
||||
/**
|
||||
* Set the MU EDCA parameters.
|
||||
*
|
||||
* \param ac the Access Category
|
||||
* \param cwMin the minimum contention window size
|
||||
* \param cwMax the maximum contention window size
|
||||
* \param aifsn the number of slots that make up an AIFS
|
||||
* \param muEdcaTimer the MU EDCA timer
|
||||
*/
|
||||
void SetMuEdcaParameters (AcIndex ac, uint16_t cwMin, uint16_t cwMax, uint8_t aifsn, Time muEdcaTimer);
|
||||
/**
|
||||
* Return the Capability information of the current STA.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user