diff -r ccbdc2b19ea5 -r a2127017ecb4 src/devices/wifi/qadhoc-wifi-mac.cc --- a/src/devices/wifi/qadhoc-wifi-mac.cc Thu Feb 25 13:51:59 2010 +0100 +++ b/src/devices/wifi/qadhoc-wifi-mac.cc Thu Feb 25 14:17:21 2010 +0100 @@ -147,6 +147,18 @@ m_low->SetAckTimeout (ackTimeout); } +void +QadhocWifiMac::SetBasicBlockAckTimeout (Time blockAckTimeout) +{ + m_low->SetBasicBlockAckTimeout (blockAckTimeout); +} + +void +QadhocWifiMac::SetCompressedBlockAckTimeout (Time blockAckTimeout) +{ + m_low->SetCompressedBlockAckTimeout (blockAckTimeout); +} + void QadhocWifiMac::SetCtsTimeout (Time ctsTimeout) { @@ -183,6 +195,18 @@ return m_low->GetAckTimeout (); } +Time +QadhocWifiMac::GetBasicBlockAckTimeout (void) const +{ + return m_low->GetBasicBlockAckTimeout (); +} + +Time +QadhocWifiMac::GetCompressedBlockAckTimeout (void) const +{ + return m_low->GetCompressedBlockAckTimeout (); +} + Time QadhocWifiMac::GetCtsTimeout (void) const { @@ -353,7 +377,42 @@ } 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 ()) + { + /* 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 ()); + } + } + } } } @@ -401,6 +460,8 @@ edca->SetManager (m_dcfManager); edca->SetTypeOfStation (ADHOC_STA); edca->SetTxMiddle (m_txMiddle); + edca->SetAccessClass (ac); + edca->CompleteConfig (); m_queues.insert (std::make_pair(ac, edca)); } @@ -445,4 +506,59 @@ } } + +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->CreateBlockAckAgreement (&respHdr, originator, reqHdr->GetStartingSequence ()); + + //Better a management queue? + m_queues[QosUtilsMapTidToAc (reqHdr->GetTid ())]->PushFront (packet, hdr); +} } //namespace ns3