From cf232568a6d892ff8f2ba41e05d7ca1bf9d280af Mon Sep 17 00:00:00 2001 From: Mirko Banchi Date: Wed, 3 Feb 2010 20:34:50 +0100 Subject: [PATCH] handle wifi action frames in high MACs --- src/devices/wifi/edca-txop-n.cc | 10 ++++ src/devices/wifi/edca-txop-n.h | 3 + src/devices/wifi/qadhoc-wifi-mac.cc | 89 +++++++++++++++++++++++++++- src/devices/wifi/qadhoc-wifi-mac.h | 4 +- src/devices/wifi/qap-wifi-mac.cc | 90 ++++++++++++++++++++++++++++- src/devices/wifi/qap-wifi-mac.h | 2 + src/devices/wifi/qsta-wifi-mac.cc | 87 ++++++++++++++++++++++++++++ src/devices/wifi/qsta-wifi-mac.h | 2 + 8 files changed, 284 insertions(+), 3 deletions(-) diff --git a/src/devices/wifi/edca-txop-n.cc b/src/devices/wifi/edca-txop-n.cc index 0a773dd10..7401bfae0 100644 --- a/src/devices/wifi/edca-txop-n.cc +++ b/src/devices/wifi/edca-txop-n.cc @@ -31,6 +31,7 @@ #include "random-stream.h" #include "wifi-mac-queue.h" #include "msdu-aggregator.h" +#include "mgt-headers.h" NS_LOG_COMPONENT_DEFINE ("EdcaTxopN"); @@ -699,4 +700,13 @@ EdcaTxopN::PushFront (Ptr packet, const WifiMacHeader &hdr) StartAccessIfNeeded (); } +void +EdcaTxopN::GotAddBaResponse (const MgtAddBaResponseHeader *respHdr, Mac48Address recipient) +{ + NS_LOG_FUNCTION (this); + MY_DEBUG ("received AddBa response from "< packet, const WifiMacHeader *hdr) } else if (hdr->IsMgt ()) { - //Handling action frames + 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_REQUEST) + { + 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 ()) + { + /* Block ack agreement tear down */ + } + else + { + /* We must notify correct queue tear down of agreement */ + } + } + } } } @@ -446,4 +478,59 @@ QadhocWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard) } } + +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 = Create (); + packet->AddHeader (respHdr); + packet->AddHeader (actionHdr); + + /* ns3::MacLow have to buffer all correctly received packet for this block ack session */ + //m_low->CreateIngoingAgreement (&respHdr, originator, reqHdr->GetStartingSequence ()); + + //Better a management queue? + m_queues[QosUtilsMapTidToAc (reqHdr->GetTid ())]->PushFront (packet, hdr); +} } //namespace ns3 diff --git a/src/devices/wifi/qadhoc-wifi-mac.h b/src/devices/wifi/qadhoc-wifi-mac.h index bf65b0299..c579de269 100644 --- a/src/devices/wifi/qadhoc-wifi-mac.h +++ b/src/devices/wifi/qadhoc-wifi-mac.h @@ -38,6 +38,7 @@ class WifiPhy; class DcfManager; class MacLow; class MacRxMiddle; +class MgtAddBaRequestHeader; class QadhocWifiMac : public WifiMac { @@ -82,7 +83,8 @@ private: void ForwardUp (Ptr 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. diff --git a/src/devices/wifi/qap-wifi-mac.cc b/src/devices/wifi/qap-wifi-mac.cc index ec9a8d6f1..9c01acfa9 100644 --- a/src/devices/wifi/qap-wifi-mac.cc +++ b/src/devices/wifi/qap-wifi-mac.cc @@ -673,7 +673,40 @@ QapWifiMac::Receive (Ptr packet, const WifiMacHeader *hdr) 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 ()) + { + /* Block ack agreement tear down */ + } + else + { + /* We must notify correct queue tear down of agreement */ + } + } + } else if (hdr->IsAuthentication () || hdr->IsDeauthentication ()) { @@ -799,4 +832,59 @@ QapWifiMac::DoStart (void) 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 = Create (); + packet->AddHeader (respHdr); + packet->AddHeader (actionHdr); + + /* ns3::MacLow have to buffer all correctly received packet for this block ack session */ + //m_low->CreateIngoingAgreement (&respHdr, originator, reqHdr->GetStartingSequence ()); + + //Better a management queue? + m_queues[QosUtilsMapTidToAc (reqHdr->GetTid ())]->PushFront (packet, hdr); +} + } //namespace ns3 diff --git a/src/devices/wifi/qap-wifi-mac.h b/src/devices/wifi/qap-wifi-mac.h index ec1de5e49..41709944e 100644 --- a/src/devices/wifi/qap-wifi-mac.h +++ b/src/devices/wifi/qap-wifi-mac.h @@ -47,6 +47,7 @@ class MacTxMiddle; class DcfManager; class AmsduSubframeHeader; class MsduAggregator; +class MgtAddBaRequestHeader; class QapWifiMac : public WifiMac { @@ -103,6 +104,7 @@ private: 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); diff --git a/src/devices/wifi/qsta-wifi-mac.cc b/src/devices/wifi/qsta-wifi-mac.cc index 1df061ed5..6b01e8243 100644 --- a/src/devices/wifi/qsta-wifi-mac.cc +++ b/src/devices/wifi/qsta-wifi-mac.cc @@ -674,6 +674,39 @@ QstaWifiMac::Receive (Ptr packet, const WifiMacHeader *hdr) } } } + 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 ()) + { + /* Block ack agreement tear down */ + } + else + { + /* We must notify correct queue tear down of agreement */ + } + } + } } SupportedRates @@ -775,5 +808,59 @@ QstaWifiMac::FinishConfigureStandard (enum WifiPhyStandard standard) } } +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 = Create (); + packet->AddHeader (respHdr); + packet->AddHeader (actionHdr); + + /* ns3::MacLow have to buffer all correctly received packet for this block ack session */ + //m_low->CreateIngoingAgreement (&respHdr, originator, reqHdr->GetStartingSequence ()); + + //Better a management queue? + m_queues[QosUtilsMapTidToAc (reqHdr->GetTid ())]->PushFront (packet, hdr); +} } //namespace ns3 diff --git a/src/devices/wifi/qsta-wifi-mac.h b/src/devices/wifi/qsta-wifi-mac.h index cc151f35b..8aea94cad 100644 --- a/src/devices/wifi/qsta-wifi-mac.h +++ b/src/devices/wifi/qsta-wifi-mac.h @@ -45,6 +45,7 @@ class MacLow; class WifiMacHeader; class AmsduSubframeHeader; class MsduAggregator; +class MgtAddBaRequestHeader; class QstaWifiMac : public WifiMac { @@ -100,6 +101,7 @@ private: 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;