Table Of Contents
Table Of Contents

IEEE 802.11 Block Acknowledgment


IEEE 802.11 block acknowledgment is a feature of the Media Access Control (MAC) layer of the 802.11 protocol that is designed to increase throughput by reducing protocol overhead. It works by allowing a single block acknowledgment frame to acknowledge the reception of multiple packets, instead of individually acknowledging each packet with a separate acknowledgement (ACK) frame. This reduces the number of ACK frames and corresponding interframe spaces, resulting in increased throughput.

In this showcase, we will demonstrate the block acknowledgment feature in INET’s 802.11 model. By the end of this showcase, you will understand how to enable and configure block acknowledgment in INET to improve the performance of wireless networks that use the 802.11 protocol.

INET version: 4.1
Source files location: inet/showcases/wireless/blockack

About Block Acknowledgment

In 802.11, block acknowledgment frames (block acks or BAs) are used within block ack sessions. To establish a block ack session, one of the participants, the originator, sends an ADDBA request frame. The other participant, the recipient, replies with an ADDBA response frame. This exchange establishes the block ack session. The frames contain information about the capabilities of each participant, such as buffer size, or whether aggregation is supported. Each ADDBA frame is acked. The block ack session is for one direction only, i.e. a separate block ack session must be established for the reverse direction. Block ack sessions are terminated by the originator sending a DELBA frame.

The originator sends multiple data frames, then sends a block ack request frame. The recipient replies with a block ack frame, acknowledging the correctly received frames from the previous block. The block ack request frame and block ack frame are acked if delayed block ack is used, and not acked if immediate block ack is used. The frames or fragments of frames from the previous block which are not acked are retransmitted in the next block by the originator.

There are several kinds of block acks, such as normal, compressed, and multi-tid. INET currently only supports normal block ack. Normal block acks contain a bitmap, which contains up to 64 entries, each entry being a 16-bit array. The bitmap can acknowledge up to 64 MSDUs. Each MSDU can be fragmented to at most 16 fragments. The 16 bits in a bitmap entry are used to acknowledge the individual fragments of the MSDU.

Block Acknowledgment in INET

In INET, the block ack mechanism can be enabled by setting the isBlockAckSupported parameter of the MAC’s Hcf submodule to true (it is disabled by default).

Several submodules of Hcf are involved in the block ack mechanism. These modules have parameters controlling the block ack behavior. The following paragraphs list some of the main parameters.

The details of the block ack agreement, which is negotiated at the beginning of the block ack session, are specified by block ack agreement policy modules. There are two module types, one for the originator and one for the recipient direction. They have the same set of parameters. The parameters of OriginatorBlockAckAgreementPolicy (at mac.hcf.originatorBlockAckAgreementPolicy) and RecipientBlockAckAgreementPolicy (at mac.hcf.recipientBlockAckAgreementPolicy) are the following:

  • aMsduSupported: If true, aMSDUs are block acked; otherwise they are normal acked (default).

  • maximumAllowedBufferSize: Sets the buffer size, i.e. how many MSDUs can be acked with a block ack, 64 by default.

Ack policy modules control how packets are acked. There are two module types, one for each direction (originator and recipient), but settings are configured in the originator module. Parameters of OriginatorQosAckPolicy (at mac.hcf.originatorAckPolicy) are the following:

  • blockAckReqThreshold: The originator sends a block ack request after sending this many packets

  • maxBlockAckPolicyFrameLength: Only packets below this length are block acked (others are normal acked)

Currently, only immediate block ack is implemented. Also, block ack sessions cannot be enabled in one direction and disabled in the other.


The Model

The example simulation uses a network that contains two AdhocHost modules, an Ipv4NetworkConfigurator, an Ieee80211ScalarRadioMedium and an IntegratedVisualizer module. During simulation, host1 will send UDP packets to host2.


We’ll use three configurations to demonstrate various aspects of the block ack mechanism. The configurations in omnetpp.ini are the following:

  • NoFragmentation: Packets are sent without fragmentation or aggregation. Block ack requests are sent after five packets (default).

  • Fragmentation: Packets are fragmented to 16 pieces, block ack requests are sent after 16 fragments.

  • MixedTraffic: Two traffic sources in host1 generate packets below and above the maxBlockAckPolicyFrameLength threshold. Packets with size below the threshold are block acked; those above aren’t.

Parameter settings common to the three configurations are defined in the General configuration in omnetpp.ini. The rest of this section explains the most important settings.

host1 is configured to send 700B UDP packets to host2 with about 10Mbps:

*.host1.numApps = 1
*[0].typename = "UdpBasicApp"
*[0].destAddresses = "host2"
*[0].destPort = 1000
*[0].messageLength = 700B
*[0].sendInterval = 0.1ms     # 10 Mbps
*[0].packetName = "Data"

*.host2.numApps = 1
*[0].typename = "UdpSink"
*[0].localPort = 1000

802.11 QoS is enabled in both hosts, and a classifier is included:

*.host*.wlan[*].mac.qosStation = true
*.host*.wlan[*].classifier.typename = "QosClassifier"

Block ack support is enabled in both hosts:

*.host*.wlan[*].mac.hcf.isBlockAckSupported = true

The maximum block ack frame length is left on default, 1000B.

Fragmentation and aggregation is disabled by raising the thresholds:

**.hcf.originatorMacDataService.fragmentationPolicy.fragmentationThreshold = 10000B
**.hcf.originatorMacDataService.msduAggregationPolicy.aggregationLengthThreshold = 10000

The transmitter power is lowered to make the communication more noisy, in order to get some lost packets:

*.host*.wlan[*].radio.transmitter.power = 0.12mW

In the next sections, we’ll look at the three configurations and their results.

No Fragmentation

In this simulation, packets are sent unfragmented, and host1 sends a block ack request after sending five frames (the default). The configuration in omnetpp.ini (NoFragmentation) is empty:

[Config NoFragmentation]
description = "Packets are not fragmented, block ack after 5 packet transmissions (default)"

Here is the starting frame sequence at the beginning of the simulation displayed in Qtenv’s packet traffic view:


First, host1 sends an UDP packet, then an ADDBA request frame. host2 replies with an ADDBA response frame (both frames are acked). This frame exchange establishes the block ack session, and host2 doesn’t normal ack the frames from this point forward but waits for a block ack request.

Here are the ADDBA request and ADDBA response frames displayed in the packet traffic view:


It indicates that aggregate MSDUs (aMSDUs) are supported, and the buffer size in both hosts is 64.

After sending five UDP packets, host1 sends a block ack request, host2 replies with a block ack. The block ack frame acks the five previous frames. Here is the block ack request frame displayed in Qtenv’s packet inspector:


The block ack request contains the starting sequence number, which indicates the first packet to be acked. Here is the block ack response frame:


It contains the starting sequence number as well, and the bitmap which specifies which packets were received correctly. Here is the bitmap:


The first five entries are used. It acks the five packets, starting from sequence number 1.


When there is no fragmentation, only the first bit of the 16-bit entry is used to ack the frame. Here, the first three entries are all ones because the MAC already passed those packets to the higher layers, and has no information about the number of fragments, but still it indicates that the packets were successfully received. (This is an implementation detail.)

It is indicated in the block ack when some of the frames in a block were not received correctly. The MAC retransmits those in the next block. Here is a retransmission in the packet traffic view:


First, host1 sends five packets, Data-16 to Data-20. Two of the frames, Data-17 and Data-18 are not received correctly, indicated in the block ack’s bitmap (starting sequence number is 16, corresponding to Data-16):


The next block starts with host1 retransmitting these two frames, then transmitting three new ones.


In this simulation, 1080B packets are fragmented to 16 pieces, each 100B. Block ack requests are sent after 16 frames. It is defined in the Fragmentation configuration in omnetpp.ini:

[Config Fragmentation]
description = "Packets are fragmented to 16 pieces, block ack after 16 packet transmissions"

**.hcf.originatorMacDataService.fragmentationPolicy.fragmentationThreshold = 100B
*[0].messageLength = 1080B

*.host*.wlan[*].mac.hcf.originatorAckPolicy.blockAckReqThreshold = 16

Here is how the simulation starts displayed in the packet traffic view:


After sending a fragment, the block ack session is negotiated. After that, host1 transmits the remaining fragments of Data-0, which are normal acked. However, the fragments of the next packet, Data-1, are block acked:


In the next block, two fragments of Data-1 are retransmitted, then several fragments of Data-2 are sent:


Here is the block ack bitmap for this block:


The first entry of the bitmap is all ones, indicating that Data-1 was completely received (all fragments), even though only two fragments of it were sent in this block. The second entry has three zeros. The first zero indicates a lost fragment of Data-2; the last two correspond to fragments that haven’t been sent yet.

Mixed Traffic

In this configuration, there are two UDP apps in host1, sending 1700B and 700B packets. The maxBlockAckPolicyFrameLength parameter is set to 1000B (default), so the large packets are individually acked, while the smaller ones are block acked. The simulation is defined in the MixedTraffic configuration in omnetpp.ini:

[Config MixedTraffic]
description = "Mixed traffic of packets shorter and longer than blockAckReqThreshold"

*.host1.numApps = 2
*[1].typename = "UdpBasicApp"
*[1].destAddresses = "host2"
*[1].destPort = 2000
*[1].messageLength = 1700B
*[1].sendInterval = 0.1ms     # 10 Mbps
*[1].packetName = "Large"

*.host2.numApps = 2
*[1].typename = "UdpSink"
*[1].localPort = 2000

The smaller and larger packets are created at the same rate, so host1 sends them alternately. However, only the smaller ones are considered when sending block ack requests (sent after five of the 700B packets). The larger packets are normal acked immediately:


Here, the block starts with Data-6. Data-6 to Data-10, and also some large packets, are sent. Large-8 and Large-9, for example, are sent twice because they weren’t correctly received for the first time (there was no ack). The 802.11 MAC sequence numbers are contiguous between all the packets sent by the MAC, so the block ack bitmap contains (the already acked) large packets as well:


Also, the block ack is lost, so the not-yet-acked packets in the previous block (Data-6 to Data-10) are retransmitted.


Instead of retransmitting the data frames, the originator could send the block ack request again if it didn’t receive a block ack. This is currently a limitation of the implementation.

Sources: omnetpp.ini, BlockAckShowcase.ned


Use this page in the GitHub issue tracker for commenting on this showcase.