650 { |
732 { |
651 m_waitSifsEvent = Simulator::Schedule (GetSifs (), |
733 m_waitSifsEvent = Simulator::Schedule (GetSifs (), |
652 &MacLow::WaitSifsAfterEndTx, this); |
734 &MacLow::WaitSifsAfterEndTx, this); |
653 } |
735 } |
654 } |
736 } |
|
737 else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self && |
|
738 (m_txParams.MustWaitBasicBlockAck () || m_txParams.MustWaitCompressedBlockAck ()) && |
|
739 m_blockAckTimeoutEvent.IsRunning ()) |
|
740 { |
|
741 NS_LOG_DEBUG ("got block ack from "<<hdr.GetAddr2 ()); |
|
742 CtrlBAckResponseHeader blockAck; |
|
743 packet->RemoveHeader (blockAck); |
|
744 m_blockAckTimeoutEvent.Cancel (); |
|
745 m_listener->GotBlockAck (&blockAck, hdr.GetAddr2 ()); |
|
746 } |
|
747 else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self) |
|
748 { |
|
749 CtrlBAckRequestHeader blockAckReq; |
|
750 packet->RemoveHeader (blockAckReq); |
|
751 if (!blockAckReq.IsMultiTid ()) |
|
752 { |
|
753 AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), blockAckReq.GetTidInfo ())); |
|
754 if (it != m_bAckAgreements.end ()) |
|
755 { |
|
756 NS_ASSERT (m_sendAckEvent.IsExpired ()); |
|
757 /* See section 11.5.3 in IEEE802.11 for mean of this timer */ |
|
758 ResetBlockAckInactivityTimerIfNeeded (it->second.first); |
|
759 if ((*it).second.first.IsImmediateBlockAck ()) |
|
760 { |
|
761 NS_LOG_DEBUG ("rx blockAckRequest/sendImmediateBlockAck from="<< hdr.GetAddr2 ()); |
|
762 m_sendAckEvent = Simulator::Schedule (GetSifs (), |
|
763 &MacLow::SendBlockAckAfterBlockAckRequest, this, |
|
764 blockAckReq, |
|
765 hdr.GetAddr2 (), |
|
766 hdr.GetDuration (), |
|
767 txMode); |
|
768 } |
|
769 else |
|
770 { |
|
771 NS_FATAL_ERROR ("Delayed block ack not supported."); |
|
772 } |
|
773 } |
|
774 else |
|
775 { |
|
776 NS_LOG_DEBUG ("There's not a valid agreement for this block ack request."); |
|
777 } |
|
778 } |
|
779 else |
|
780 { |
|
781 NS_FATAL_ERROR ("Multi-tid block ack is not supported."); |
|
782 } |
|
783 } |
655 else if (hdr.IsCtl ()) |
784 else if (hdr.IsCtl ()) |
656 { |
785 { |
657 NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ()); |
786 NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ()); |
658 } |
787 } |
659 else if (hdr.GetAddr1 () == m_self) |
788 else if (hdr.GetAddr1 () == m_self) |
660 { |
789 { |
661 m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr, |
790 m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr, |
662 rxSnr, txMode); |
791 rxSnr, txMode); |
663 |
792 |
664 if (hdr.IsQosData () && hdr.IsQosNoAck ()) |
793 if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr)) |
|
794 { |
|
795 /* From section 9.10.4 in IEEE802.11: |
|
796 Upon the receipt of a QoS data frame from the originator for which |
|
797 the Block Ack agreement exists, the recipient shall buffer the MSDU |
|
798 regardless of the value of the Ack Policy subfield within the |
|
799 QoS Control field of the QoS data frame. */ |
|
800 if (hdr.IsQosAck ()) |
|
801 { |
|
802 AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ())); |
|
803 RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), |
|
804 hdr.GetAddr2 (), hdr.GetQosTid ()); |
|
805 RxCompleteBufferedPackets (hdr.GetAddr2 (), hdr.GetQosTid ()); |
|
806 NS_ASSERT (m_sendAckEvent.IsExpired ()); |
|
807 m_sendAckEvent = Simulator::Schedule (GetSifs (), |
|
808 &MacLow::SendAckAfterData, this, |
|
809 hdr.GetAddr2 (), |
|
810 hdr.GetDuration (), |
|
811 txMode, |
|
812 rxSnr); |
|
813 } |
|
814 else if (hdr.IsQosBlockAck ()) |
|
815 { |
|
816 AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ())); |
|
817 /* See section 11.5.3 in IEEE802.11 for mean of this timer */ |
|
818 ResetBlockAckInactivityTimerIfNeeded (it->second.first); |
|
819 } |
|
820 return; |
|
821 } |
|
822 else if (hdr.IsQosData () && hdr.IsQosBlockAck ()) |
|
823 { |
|
824 /* This happens if a packet with ack policy Block Ack is received and a block ack |
|
825 agreement for that packet doesn't exist. |
|
826 |
|
827 From section 11.5.3 in IEEE802.11e: |
|
828 When a recipient does not have an active Block ack for a TID, but receives |
|
829 data MPDUs with the Ack Policy subfield set to Block Ack, it shall discard |
|
830 them and shall send a DELBA frame using the normal access |
|
831 mechanisms. */ |
|
832 AccessClass ac = QosUtilsMapTidToAc (hdr.GetQosTid ()); |
|
833 m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ()); |
|
834 return; |
|
835 } |
|
836 else if (hdr.IsQosData () && hdr.IsQosNoAck ()) |
665 { |
837 { |
666 NS_LOG_DEBUG ("rx unicast/noAck from="<<hdr.GetAddr2 ()); |
838 NS_LOG_DEBUG ("rx unicast/noAck from="<<hdr.GetAddr2 ()); |
667 } |
839 } |
668 else if (hdr.IsData () || hdr.IsMgt ()) |
840 else if (hdr.IsData () || hdr.IsMgt ()) |
669 { |
841 { |
1246 packet->AddPacketTag (tag); |
1485 packet->AddPacketTag (tag); |
1247 |
1486 |
1248 ForwardDown (packet, &ack, ackTxMode); |
1487 ForwardDown (packet, &ack, ackTxMode); |
1249 } |
1488 } |
1250 |
1489 |
|
1490 bool |
|
1491 MacLow::StoreMpduIfNeeded (Ptr<Packet> packet, WifiMacHeader hdr) |
|
1492 { |
|
1493 AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ())); |
|
1494 if (it != m_bAckAgreements.end ()) |
|
1495 { |
|
1496 WifiMacTrailer fcs; |
|
1497 packet->RemoveTrailer (fcs); |
|
1498 BufferedPacket bufferedPacket (packet, hdr); |
|
1499 |
|
1500 uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096; |
|
1501 uint16_t mappedSeqControl = QosUtilsMapSeqControlToUniqueInteger (hdr.GetSequenceControl () ,endSequence); |
|
1502 |
|
1503 BufferedPacketI i = (*it).second.second.begin (); |
|
1504 for (; i != (*it).second.second.end () && |
|
1505 QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceControl (), endSequence) < mappedSeqControl; i++); |
|
1506 (*it).second.second.insert (i, bufferedPacket); |
|
1507 return true; |
|
1508 } |
|
1509 return false; |
|
1510 } |
|
1511 |
|
1512 void |
|
1513 MacLow::CreateBlockAckAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Address originator, |
|
1514 uint16_t startingSeq) |
|
1515 { |
|
1516 uint8_t tid = respHdr->GetTid (); |
|
1517 BlockAckAgreement agreement (originator, tid); |
|
1518 if (respHdr->IsImmediateBlockAck ()) |
|
1519 { |
|
1520 agreement.SetImmediateBlockAck (); |
|
1521 } |
|
1522 else |
|
1523 { |
|
1524 agreement.SetDelayedBlockAck (); |
|
1525 } |
|
1526 agreement.SetAmsduSupport (respHdr->IsAmsduSupported ()); |
|
1527 agreement.SetBufferSize (respHdr->GetBufferSize ()); |
|
1528 agreement.SetTimeout (respHdr->GetTimeout ()); |
|
1529 agreement.SetStartingSequence (startingSeq); |
|
1530 |
|
1531 std::list<BufferedPacket> buffer (0); |
|
1532 AgreementKey key (originator, respHdr->GetTid ()); |
|
1533 AgreementValue value (agreement, buffer); |
|
1534 m_bAckAgreements.insert (std::make_pair (key, value)); |
|
1535 |
|
1536 if (respHdr->GetTimeout () != 0) |
|
1537 { |
|
1538 AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ())); |
|
1539 Time timeout = MicroSeconds (1024 * agreement.GetTimeout ()); |
|
1540 |
|
1541 AccessClass ac = QosUtilsMapTidToAc (agreement.GetTid ()); |
|
1542 |
|
1543 it->second.first.m_inactivityEvent = Simulator::Schedule (timeout, |
|
1544 &MacLowBlockAckEventListener::BlockAckInactivityTimeout, |
|
1545 m_edcaListeners[ac], |
|
1546 originator, tid); |
|
1547 } |
|
1548 } |
|
1549 |
|
1550 void |
|
1551 MacLow::DestroyBlockAckAgreement (Mac48Address originator, uint8_t tid) |
|
1552 { |
|
1553 AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid)); |
|
1554 if (it != m_bAckAgreements.end ()) |
|
1555 { |
|
1556 RxCompleteBufferedPacketsWithSmallerSequence (it->second.first.GetStartingSequence (), originator, tid); |
|
1557 RxCompleteBufferedPackets (originator, tid); |
|
1558 m_bAckAgreements.erase (it); |
|
1559 } |
|
1560 } |
|
1561 |
|
1562 void |
|
1563 MacLow::RxCompleteBufferedPacketsWithSmallerSequence (uint16_t seq, Mac48Address originator, uint8_t tid) |
|
1564 { |
|
1565 AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid)); |
|
1566 if (it != m_bAckAgreements.end ()) |
|
1567 { |
|
1568 BufferedPacketI i = (*it).second.second.begin (); |
|
1569 uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096; |
|
1570 uint16_t mappedStart = QosUtilsMapSeqControlToUniqueInteger (seq, endSequence); |
|
1571 uint16_t guard = (*it).second.first.GetStartingSequence (); |
|
1572 BufferedPacketI last = (*it).second.second.begin (); |
|
1573 |
|
1574 for (; i != (*it).second.second.end () && |
|
1575 QosUtilsMapSeqControlToUniqueInteger ((*i).second.GetSequenceNumber (), endSequence) < mappedStart;) |
|
1576 { |
|
1577 while (i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl ()) |
|
1578 { |
|
1579 if (!(*i).second.IsMoreFragments ()) |
|
1580 { |
|
1581 while (last != i) |
|
1582 { |
|
1583 m_rxCallback ((*last).first, &(*last).second); |
|
1584 last++; |
|
1585 } |
|
1586 m_rxCallback ((*last).first, &(*last).second); |
|
1587 last++; |
|
1588 } |
|
1589 guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0); |
|
1590 } |
|
1591 /* go to next packet */ |
|
1592 while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ()) |
|
1593 { |
|
1594 i++; |
|
1595 } |
|
1596 if (i != (*it).second.second.end ()) |
|
1597 { |
|
1598 guard = (*i).second.GetSequenceControl () & 0xfff0; |
|
1599 last = i; |
|
1600 } |
|
1601 } |
|
1602 (*it).second.second.erase ((*it).second.second.begin (), i); |
|
1603 } |
|
1604 } |
|
1605 |
|
1606 void |
|
1607 MacLow::RxCompleteBufferedPackets (Mac48Address originator, uint8_t tid) |
|
1608 { |
|
1609 AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid)); |
|
1610 if (it != m_bAckAgreements.end ()) |
|
1611 { |
|
1612 uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence ()<<4) & 0xfff0; |
|
1613 uint16_t guard = startingSeqCtrl; |
|
1614 |
|
1615 BufferedPacketI lastComplete = (*it).second.second.begin (); |
|
1616 BufferedPacketI i = (*it).second.second.begin (); |
|
1617 for (;i != (*it).second.second.end() && guard == (*i).second.GetSequenceControl (); i++) |
|
1618 { |
|
1619 if (!(*i).second.IsMoreFragments ()) |
|
1620 { |
|
1621 while (lastComplete != i) |
|
1622 { |
|
1623 m_rxCallback ((*lastComplete).first, &(*lastComplete).second); |
|
1624 lastComplete++; |
|
1625 } |
|
1626 m_rxCallback ((*lastComplete).first, &(*lastComplete).second); |
|
1627 lastComplete++; |
|
1628 } |
|
1629 guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0); |
|
1630 } |
|
1631 (*it).second.first.SetStartingSequence ((guard>>4)&0x0fff); |
|
1632 /* All packets already forwarded to WifiMac must be removed from buffer: |
|
1633 [begin (), lastComplete) */ |
|
1634 (*it).second.second.erase ((*it).second.second.begin (), lastComplete); |
|
1635 } |
|
1636 } |
|
1637 |
|
1638 void |
|
1639 MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Address originator, bool immediate, |
|
1640 Time duration, WifiMode blockAckReqTxMode) |
|
1641 { |
|
1642 Ptr<Packet> packet = Create<Packet> (); |
|
1643 packet->AddHeader (*blockAck); |
|
1644 |
|
1645 WifiMacHeader hdr; |
|
1646 hdr.SetType (WIFI_MAC_CTL_BACKRESP); |
|
1647 hdr.SetAddr1 (originator); |
|
1648 hdr.SetAddr2 (GetAddress ()); |
|
1649 hdr.SetDsNotFrom (); |
|
1650 hdr.SetDsNotTo (); |
|
1651 hdr.SetNoRetry (); |
|
1652 hdr.SetNoMoreFragments (); |
|
1653 |
|
1654 m_currentPacket = packet; |
|
1655 m_currentHdr = hdr; |
|
1656 if (immediate) |
|
1657 { |
|
1658 m_txParams.DisableAck (); |
|
1659 duration -= GetSifs (); |
|
1660 if (blockAck->IsBasic ()) |
|
1661 { |
|
1662 duration -= GetBlockAckDuration (originator, blockAckReqTxMode, BASIC_BLOCK_ACK); |
|
1663 } |
|
1664 else if (blockAck->IsCompressed ()) |
|
1665 { |
|
1666 duration -= GetBlockAckDuration (originator, blockAckReqTxMode, COMPRESSED_BLOCK_ACK); |
|
1667 } |
|
1668 else if (blockAck->IsMultiTid ()) |
|
1669 { |
|
1670 NS_FATAL_ERROR ("Multi-tid block ack is not supported."); |
|
1671 } |
|
1672 } |
|
1673 else |
|
1674 { |
|
1675 m_txParams.EnableAck (); |
|
1676 duration += GetSifs (); |
|
1677 duration += GetAckDuration (originator, blockAckReqTxMode); |
|
1678 } |
|
1679 m_txParams.DisableNextData (); |
|
1680 |
|
1681 StartDataTxTimers (); |
|
1682 |
|
1683 NS_ASSERT (duration >= MicroSeconds (0)); |
|
1684 hdr.SetDuration (duration); |
|
1685 //here should be present a control about immediate or delayed block ack |
|
1686 //for now we assume immediate |
|
1687 packet->AddHeader (hdr); |
|
1688 WifiMacTrailer fcs; |
|
1689 packet->AddTrailer (fcs); |
|
1690 ForwardDown (packet, &hdr, blockAckReqTxMode); |
|
1691 m_currentPacket = 0; |
|
1692 } |
|
1693 |
|
1694 void |
|
1695 MacLow::SendBlockAckAfterBlockAckRequest (const CtrlBAckRequestHeader reqHdr, Mac48Address originator, |
|
1696 Time duration, WifiMode blockAckReqTxMode) |
|
1697 { |
|
1698 NS_LOG_FUNCTION (this); |
|
1699 CtrlBAckResponseHeader blockAck; |
|
1700 uint8_t tid; |
|
1701 bool immediate = false; |
|
1702 if (!reqHdr.IsMultiTid ()) |
|
1703 { |
|
1704 blockAck.SetStartingSequence (reqHdr.GetStartingSequence ()); |
|
1705 blockAck.SetTidInfo (reqHdr.GetTidInfo ()); |
|
1706 |
|
1707 tid = reqHdr.GetTidInfo (); |
|
1708 AgreementsI it; |
|
1709 it = m_bAckAgreements.find (std::make_pair (originator, tid)); |
|
1710 if (it != m_bAckAgreements.end ()) |
|
1711 { |
|
1712 immediate = (*it).second.first.IsImmediateBlockAck (); |
|
1713 uint16_t startingSeqCtrl = reqHdr.GetStartingSequenceControl (); |
|
1714 |
|
1715 /* All packets with smaller sequence than starting sequence control must be passed up to Wifimac |
|
1716 * See 9.10.3 in IEEE8022.11e standard. |
|
1717 */ |
|
1718 RxCompleteBufferedPacketsWithSmallerSequence ((startingSeqCtrl>>4)&0xfff0, originator, tid); |
|
1719 |
|
1720 std::list<BufferedPacket>::iterator i = (*it).second.second.begin (); |
|
1721 |
|
1722 /* For more details about next operations see section 9.10.4 of IEEE802.11e standard */ |
|
1723 if (reqHdr.IsBasic ()) |
|
1724 { |
|
1725 blockAck.SetType (BASIC_BLOCK_ACK); |
|
1726 uint16_t guard = startingSeqCtrl; |
|
1727 std::list<BufferedPacket>::iterator lastComplete = (*it).second.second.begin (); |
|
1728 for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++) |
|
1729 { |
|
1730 blockAck.SetReceivedFragment ((*i).second.GetSequenceNumber (), |
|
1731 (*i).second.GetFragmentNumber ()); |
|
1732 /* Section 9.10.4 in IEEE802.11n: the recipient shall pass up to WifiMac the |
|
1733 * MSDUs and A-MSDUs starting with the starting sequence number |
|
1734 * sequentially until there is an incomplete MSDU or A-MSDU in the buffer */ |
|
1735 if (!(*i).second.IsMoreFragments ()) |
|
1736 { |
|
1737 while (lastComplete != i) |
|
1738 { |
|
1739 m_rxCallback ((*lastComplete).first, &(*lastComplete).second); |
|
1740 lastComplete++; |
|
1741 } |
|
1742 m_rxCallback ((*lastComplete).first, &(*lastComplete).second); |
|
1743 lastComplete++; |
|
1744 } |
|
1745 guard = (*i).second.IsMoreFragments () ? (guard + 1) : (guard + 16) & 0xfff0; |
|
1746 } |
|
1747 (*it).second.first.SetStartingSequence ((guard>>4)&0x0fff); |
|
1748 /* All packets already forwarded to WifiMac must be removed from buffer: |
|
1749 [begin (), lastComplete) */ |
|
1750 (*it).second.second.erase ((*it).second.second.begin (), lastComplete); |
|
1751 for (i = lastComplete; i != (*it).second.second.end (); i++) |
|
1752 { |
|
1753 blockAck.SetReceivedFragment ((*i).second.GetSequenceNumber (), |
|
1754 (*i).second.GetFragmentNumber ()); |
|
1755 } |
|
1756 } |
|
1757 else if (reqHdr.IsCompressed ()) |
|
1758 { |
|
1759 blockAck.SetType (COMPRESSED_BLOCK_ACK); |
|
1760 uint16_t guard = startingSeqCtrl; |
|
1761 std::list<BufferedPacket>::iterator lastComplete = (*it).second.second.begin (); |
|
1762 for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++) |
|
1763 { |
|
1764 if (!(*i).second.IsMoreFragments ()) |
|
1765 { |
|
1766 blockAck.SetReceivedPacket ((*i).second.GetSequenceNumber ()); |
|
1767 while (lastComplete != i) |
|
1768 { |
|
1769 m_rxCallback ((*lastComplete).first, &(*lastComplete).second); |
|
1770 lastComplete++; |
|
1771 } |
|
1772 m_rxCallback ((*lastComplete).first, &(*lastComplete).second); |
|
1773 lastComplete++; |
|
1774 } |
|
1775 guard = (*i).second.IsMoreFragments () ? (guard + 1) : (guard + 16) & 0xfff0; |
|
1776 } |
|
1777 (*it).second.first.SetStartingSequence ((guard>>4)&0x0fff); |
|
1778 /* All packets already forwarded to WifiMac must be removed from buffer: |
|
1779 [begin (), lastcomplete) */ |
|
1780 (*it).second.second.erase ((*it).second.second.begin (), lastComplete); |
|
1781 i = lastComplete; |
|
1782 if (i != (*it).second.second.end ()) |
|
1783 { |
|
1784 guard = (*i).second.GetSequenceControl () & 0xfff0; |
|
1785 } |
|
1786 for (; i != (*it).second.second.end ();) |
|
1787 { |
|
1788 for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++) |
|
1789 { |
|
1790 if (!(*i).second.IsMoreFragments ()) |
|
1791 { |
|
1792 guard = (guard + 16) & 0xfff0; |
|
1793 blockAck.SetReceivedPacket ((*i).second.GetSequenceNumber ()); |
|
1794 } |
|
1795 else |
|
1796 { |
|
1797 guard += 1; |
|
1798 } |
|
1799 } |
|
1800 while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ()) |
|
1801 { |
|
1802 i++; |
|
1803 } |
|
1804 if (i != (*it).second.second.end ()) |
|
1805 { |
|
1806 guard = (*i).second.GetSequenceControl () & 0xfff0; |
|
1807 } |
|
1808 } |
|
1809 } |
|
1810 } |
|
1811 else |
|
1812 { |
|
1813 NS_LOG_DEBUG ("there's not a valid block ack agreement with "<<originator); |
|
1814 } |
|
1815 } |
|
1816 else |
|
1817 { |
|
1818 NS_FATAL_ERROR ("Multi-tid block ack is not supported."); |
|
1819 } |
|
1820 |
|
1821 SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode); |
|
1822 } |
|
1823 |
|
1824 void |
|
1825 MacLow::ResetBlockAckInactivityTimerIfNeeded (BlockAckAgreement &agreement) |
|
1826 { |
|
1827 if (agreement.GetTimeout () != 0) |
|
1828 { |
|
1829 NS_ASSERT (agreement.m_inactivityEvent.IsRunning ()); |
|
1830 agreement.m_inactivityEvent.Cancel (); |
|
1831 Time timeout = MicroSeconds (1024 * agreement.GetTimeout ()); |
|
1832 |
|
1833 AccessClass ac = QosUtilsMapTidToAc (agreement.GetTid ()); |
|
1834 //std::map<AccessClass, MacLowTransmissionListener*>::iterator it = m_edcaListeners.find (ac); |
|
1835 //NS_ASSERT (it != m_edcaListeners.end ()); |
|
1836 |
|
1837 agreement.m_inactivityEvent = Simulator::Schedule (timeout, |
|
1838 &MacLowBlockAckEventListener::BlockAckInactivityTimeout, |
|
1839 m_edcaListeners[ac], |
|
1840 agreement.GetPeer (), |
|
1841 agreement.GetTid ()); |
|
1842 } |
|
1843 } |
|
1844 |
|
1845 void |
|
1846 MacLow::RegisterBlockAckListenerForAc (enum AccessClass ac, MacLowBlockAckEventListener *listener) |
|
1847 { |
|
1848 m_edcaListeners.insert (std::make_pair (ac, listener)); |
|
1849 } |
|
1850 |
1251 } // namespace ns3 |
1851 } // namespace ns3 |