Bug 2318 - MPDU Aggregation fails with TCP
MPDU Aggregation fails with TCP
Status: RESOLVED FIXED
Product: ns-3
Classification: Unclassified
Component: wifi
pre-release
All All
: P3 normal
Assigned To: sebastien.deronne
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2016-03-01 06:57 UTC by Hany
Modified: 2016-03-09 15:57 UTC (History)
2 users (show)

See Also:


Attachments
Script File which generates the error (8.16 KB, text/x-c++src)
2016-03-01 06:57 UTC, Hany
Details
patch file to solve tcp problem with ampdu (8.26 KB, patch)
2016-03-01 07:11 UTC, Hany
Details | Diff
patch to fix (1.50 KB, patch)
2016-03-02 07:47 UTC, sebastien.deronne
Details | Diff
Example file for TCP over Wifi (9.81 KB, text/x-c++src)
2016-03-02 10:28 UTC, Hany
Details
Example of TCP over 802.11n with A-MPDU enabled (7.68 KB, text/x-csrc)
2016-03-02 15:17 UTC, sebastien.deronne
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Hany 2016-03-01 06:57:02 UTC
Created attachment 2315 [details]
Script File which generates the error

I am doing some tests on TCP over 802.11n with MPDU aggregation enabled using the Wifi Module in the ns3-dev branch. However, I am getting the following error:

assert failed. cond="tid < 8", msg="Tid 8 out of range", file=../src/wifi/model/qos-utils.cc, line=30

I applied the patches for bug 2315 and 2313 on ns3-dev and I am still getting the same error. The error just appears at a later time in the simulation.

Please find the attached script for which I see the problem with its command line arguments:
./waf --run "test-ht --applicationType=bulk --socketType=ns3::TcpSocketFactory --payloadSize=1440 --simulationTime=100"
Comment 1 Hany 2016-03-01 07:10:36 UTC
I did the attached patch which seems to solve the problem. The patch includes patches for bug 2315 and bug 2313. In addition, it solves the cases where the previous error appears in the FowardDown and AggregateToAmpdu Functions in mac-low.cc file.
Comment 2 Hany 2016-03-01 07:11:15 UTC
Created attachment 2316 [details]
patch file to solve tcp problem with ampdu
Comment 3 sebastien.deronne 2016-03-01 08:31:16 UTC
Hany, could you please refine a bit the general description of the bug?
Thanks!
Comment 4 Hany 2016-03-01 12:03:19 UTC
Sebastien, in the scenario I attached I use TCP instead of UDP with bulk application. After running the simulation using 802.11n with HtMcs7 for data and HtMcs0 for control, I get an error related to TID value being not in the correct range. I did multiple debug printing across mac-low.cc and I found that the problem happens at two places:

1. In the ForwardDown function, whenever you transmit BlockAckResponse, the a_mpdu flag is always set to 0. As a result, the YansWifiPhy transmit it directly it in the current implementation. However, there is one case in which the a_mpdu flag is set to 1 and we want to transmit BlockAckResponse, so in the ForwardDown function we start to send BlockAckResponse as part of aggregated MPDU which is not correct i.e. we do not aggregate BlockAckResponse with other MPDUs. This case cause the problem related to TID value being not in the correct range. So this is why I added the third check:

if (!m_ampdu || hdr->IsRts () || hdr->IsBlockAck ())

I am not sure why the a_mpdu flag is set to 1 in this case and not updated to zero.

2. After solving the previous problem another bug appeared in AggregatedToAmpdu Function in mac-low.cc. In this bug, we send an BlockAckRequest frame and we try to aggregate it with the other MPDUs, however there are no packets in the queue related to AC_BE so the function StopMpduAggregation tries to check the header of peekedPacket which is 0. So this is why I added another check before entering the body of the AggregatedToAmpdu function as following:

      if (!hdr.GetAddr1 ().IsBroadcast ()
          && (listenerIt->second->GetMpduAggregator () != 0)
          && (queue->GetNPacketsByTidAndAddress (tid, WifiMacHeader::ADDR1, hdr.GetAddr1 ()) != 0))

After adding the additional checks together with the previously mentioned patches, the scenario worked for me for long simulation time of 100 seconds with different seeds. 

If you need more information, please don't hesitate to ask me.
Comment 5 sebastien.deronne 2016-03-01 13:42:42 UTC
Hany, I mean the title is not ok, every bug needs to be more explicit
Comment 6 sebastien.deronne 2016-03-02 07:47:38 UTC
Created attachment 2319 [details]
patch to fix

I see indeed two issues when using TCP:

1/ As you did in your patch, m_phy->SendPacket (packet, txVector, preamble) should always be called for transmitting a Block ACK, and the latter should never be handled as an A-MPDU (here it is due to the previous A-MPDU transmission that is not terminated).

2/ In MacLow::StopMpduAggregation, we first check the TID of the peekedPacket. This is incorrect when there is no peeked packet. In that case, we should return immediately that A-MPDU aggregation can be stopped (no more packets).

The attached patch addresses those two issues.
Comment 7 sebastien.deronne 2016-03-02 07:48:41 UTC
If patch confirmed ok, I will deliver in ns-3-dev by the end of the day.
Comment 8 Hany 2016-03-02 08:55:39 UTC
Sebastien, I just tested your final patch and it is OK. In the second case, it is correct to check for the peeked packet at the beginning of MacLow::StopMpduAggregation function instead of what I proposed to check the queue size at the beginning of MacLow::AggregateToAmpdu function. I found some cases in my previous patch in which the module does not behave correctly. However, for the first case I was not able to find why a_mpdu was set to true and we are just sending BlockAckResponse. Was it set due to a previous transmission?
Comment 9 sebastien.deronne 2016-03-02 08:59:34 UTC
(In reply to Hany from comment #8)
> Sebastien, I just tested your final patch and it is OK. In the second case,
> it is correct to check for the peeked packet at the beginning of
> MacLow::StopMpduAggregation function instead of what I proposed to check the
> queue size at the beginning of MacLow::AggregateToAmpdu function. I found
> some cases in my previous patch in which the module does not behave
> correctly. However, for the first case I was not able to find why a_mpdu was
> set to true and we are just sending BlockAckResponse. Was it set due to a
> previous transmission?

This was set to true because your station started to transmit an A-MPDU, but in the time waiting for its block ack it received a block ack request, so the A-MPDU exchange was not terminated (it is terminated once the block ack is either received or missed)
Comment 10 Tom Henderson 2016-03-02 09:46:45 UTC
We should also consider to add this test program to examples/wireless and instrument it for some regression testing.  Hany, could we put a GPL license on it and adapt it to become a wireless example?
Comment 11 Hany 2016-03-02 10:28:14 UTC
Created attachment 2320 [details]
Example file for TCP over Wifi

Hi Tom, I modified the script and adapted it to be more like wireless example. Additionally, I added the GPL license to it.
Comment 12 sebastien.deronne 2016-03-02 13:35:24 UTC
Tom, do you prefer we add a check on the expected output?
Comment 13 sebastien.deronne 2016-03-02 15:17:31 UTC
Created attachment 2321 [details]
Example of TCP over 802.11n with A-MPDU enabled

Slightly reworked example.

Tom, I suggest to make a check on the average throughput with default parameters and make regression fails if we are out of range.
Comment 14 sebastien.deronne 2016-03-09 15:57:05 UTC
fix pushed in changeset 11994:710403681408, example pushed in changeset 11995:2d105131a6cb