--- a/src/devices/wifi/qap-wifi-mac.cc Thu Feb 25 13:51:59 2010 +0100
+++ b/src/devices/wifi/qap-wifi-mac.cc Thu Feb 25 14:17:21 2010 +0100
@@ -199,6 +199,18 @@
}
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);
@@ -235,6 +247,18 @@
}
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 ();
@@ -670,7 +694,44 @@
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 */
+ AccessClass ac = QosUtilsMapTidToAc (delBaHdr.GetTid ());
+ m_queues[ac]->GotDelBaFrame (&delBaHdr, hdr->GetAddr2 ());
+ }
+ }
+ }
else if (hdr->IsAuthentication () ||
hdr->IsDeauthentication ())
{
@@ -741,6 +802,8 @@
edca->SetTxMiddle (m_txMiddle);
edca->SetTxOkCallback (MakeCallback (&QapWifiMac::TxOk, this));
edca->SetTxFailedCallback (MakeCallback (&QapWifiMac::TxFailed, this));
+ edca->SetAccessClass (ac);
+ edca->CompleteConfig ();
m_queues.insert (std::make_pair(ac, edca));
}
@@ -796,4 +859,59 @@
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