RLC_AM Mode LTE

3,991 views
Skip to first unread message

Koray Kokten

unread,
Sep 3, 2013, 7:02:03 PM9/3/13
to ns-3-...@googlegroups.com
Hey,
For a simple comparison purpose of a TCP application under RLC_UM and RLC_AM modes in LTE, I have written the sample script which is a kind of the combination of lena-simple-epc.cc and sixth.cc. However, when I check the .pcap file generated by ns-3 in the RL_AM mode scenario, I see a weird situation that a couple of seconds later, the TCP traffic is cut by the TCP stack, despite the application last until the end of the simulation (Sim. duration is 50 sec). On the other hand I don't see such a weird behavior  in RLC_UM mode. I can see TCP Flows between server and client (where client is the UE Device) until the end of the simulation. For examining what is going wrong with RLC_AM mode, I have included some additional packet based RLC tracing system into the source code, and I see that right after the sequence number variable of the LteRlcAm class overflows for the first time (I mean the Sequence number values in RLC PDUs are modulo 1024), the RLC_AM Mode peer at the ENB side starts sending the same PDU from the re-transmission buffer over and over again until the end of the sim. So is it about a bug in RLC_AM mode of LTE Module or am I doing something wrong?
Thanks in advance.
PS: The sample script file is attached to the e-mail.
  Koray
 
lena-simple-epc-tcp.cc

Koray Kokten

unread,
Sep 6, 2013, 1:01:55 PM9/6/13
to ns-3-...@googlegroups.com
This problem has been reported as a bug report. For those who have or already had similar problem, as well as the ones who use RLC AM mode in the RLC layer, it is advised to check the link out, below.
Best,
  Koray

Dipak Ghosal

unread,
Sep 12, 2013, 12:36:06 AM9/12/13
to ns-3-...@googlegroups.com
Hi Koray,

I have been having problems with the RLC AM mode for the past week. I started to debug and then I saw your posting. I tried the patch that you suggested but I still see a  problem,

I have a UE very close to eNB  and fading off. With UM mode, I get  the peak TCP throughput (~16.2 Mbps for 5Mhz) but with AM mode, I get less than 1/3 of the max throughput (~5.3 Mbps).

Did the patch  work for you?

Thank you.

Dipak

Koray Kokten

unread,
Sep 12, 2013, 3:31:48 AM9/12/13
to ns-3-...@googlegroups.com
Dipak,

Can you simply enlighten me about how you are  calculating the TCP throughput in your simulation. Is it an average throughput value or something? After this,  I think I can come up with a better explanation or maybe we can find out a possibly new bug? But as a first sight,  it doesn't make sense to me to have a lower throughput value in AM mode compared to UM Mode, no matter how you calculate it.  By the way, I just send a reply to Nicola in Bugzilla. Maybe you might wanna have a look at it at the link below.
Looking forward to hear from you.
Best,
  Koray
--
You received this message because you are subscribed to the Google Groups "ns-3-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ns-3-users+...@googlegroups.com.
To post to this group, send email to ns-3-...@googlegroups.com.
Visit this group at http://groups.google.com/group/ns-3-users.
For more options, visit https://groups.google.com/groups/opt_out.

Dipak Ghosal

unread,
Sep 12, 2013, 12:30:20 PM9/12/13
to ns-3-...@googlegroups.com
Hi Koray, 

I am using flowmon to calculate the throughput.  Yes, it is the average throughput. 

I have a simple scenario: 2 eNBs separated by a large distance. Each eNB has one UE placed close to it. Each UE  is connected to a different remote host. 
If I use UM I get  the max throughput ~16 Mbps (for 5Mhz) for each UE as expected. But with AM I get about ~4.9 Mbos (without the patch proposed for 1756) and ~5.3 Mbps after incorporating  the patch. 

There is most  likely some additional bug(s). 

Let me know if I should send you the code.  I am looking through the rlc_am code but I am sure you you know is much better. 

Thanks. 

Dipak 

Koray Kokten

unread,
Sep 12, 2013, 2:28:18 PM9/12/13
to ns-3-...@googlegroups.com, nba...@cttc.es
Dipak, 

I have just tried to implement a scenario similar to yours, where I have only 1 EnB, 1 UE and 1 RemoteHost and I see very similar results as you pointed, like in UM Mode I see an average throughput of 19Mbps of av. throughput, and in AM Mode, it becomes 7Mbps. I discussed this behavior with my advisor, but to be honest it does not still make much sense to both of us. I will try to investigate it by digging the trace files, as well as I am adding Nicola to cc list who may have an idea about it, hopefully.
Keep in touch.
Best.
  Koray

Dipak Ghosal

unread,
Sep 13, 2013, 1:39:53 AM9/13/13
to ns-3-...@googlegroups.com, nba...@cttc.es
Hi Koray, 

Thanks for trying it out. 

I am still looking at the code to get some understanding. I have not done much debugging yet. However, I noticed that in the congestion window plot there are periodic stalls of  ~8ms  after every 4 or 5 segments {I have set the core network and  the internet delay to be 1ms, so these stalls in a congestion free networks are substantial]. Furthermore, the stalls are  very very repetitive which suggest to me that there may be some counter and/or timer issue. 

If you find something please let me know. 

Thanks 

Dipak 

Nicola Baldo

unread,
Sep 17, 2013, 8:33:43 AM9/17/13
to ns-3-...@googlegroups.com, nba...@cttc.es
Could you try different TCP versions to see if they are also affected?
Also, could you please post the PHY RX stats? If there are many PHY errors not recovered by HARQ, the throughput performance might be affected by Bug 1757:
https://www.nsnam.org/bugzilla/show_bug.cgi?id=1757

Dipak Ghosal

unread,
Sep 17, 2013, 12:23:53 PM9/17/13
to ns-3-...@googlegroups.com, nba...@cttc.es

Hi Nicola,

I am attaching the DlTx, DlRx, UlRx and UlTx  There is only a single UE which is very close to the enB.  I have also set DataErrorEnabled to be false. So there should not be any any errors and mostly max MCS  as the stats show.

I have tried both TcpTahoe and TcpNewReno. They give the same results.  I have also attached the Cwnd log file. If you zoom in then you will notice my earlier comment.

I have been looking into lte_rlc-am.cc. What is curious is at te receiver RLC entity there are many  "PDU discards" due to SN falling outside the window. I am not sure why this should be the case in an almost error free scenario.  The logfile is too long. I have attached the code. You can generate the logfie and grep for "PDU discards".

Appreciate any help to debug this.

Thanks.

Dipak
Cwnd-UE1.log
DlRxPhyStats.txt
DlTxPhyStats.txt
UlRxPhyStats.txt
UlTxPhyStats.txt
tcp-over-lte-singleue.cc

Dipak Ghosal

unread,
Sep 28, 2013, 2:01:21 AM9/28/13
to ns-3-...@googlegroups.com, nba...@cttc.es

Hi Nicola, 

I think I  have figured out what  the problem is. It is to do with the transmission from the transmitted buffer and moving the packet to the retransmission buffer. However, I am not sure if is some issue with the standard. 

I am going through the standard now and  try to figure out a solution in the next few days. 

BTW, if you use the code that I had sent out earlier, please comment out the line in which I set the default pollretransmittimer to 1 ms. 

Thanks. 

Dipak 

Koray Kokten

unread,
Sep 28, 2013, 3:35:16 AM9/28/13
to ns-3-...@googlegroups.com
Hi Dipak,
Why do you think that moving the transmitted packet to the retransmission buffer is a bug?

Dipak Ghosal

unread,
Sep 28, 2013, 12:56:21 PM9/28/13
to ns-3-...@googlegroups.com
Hi Koray, 

When a packet is transmitted form the transmission buffer it is put in the transmitted buffer.  When the RLC gets a Txnotify again 1 ms later (there is only a single UE), it checks  all the buffers (Status control buffer, ReTX buffer, TXon buffer, and TXed buffer, in that order). Since there is nothing anywhere except in the TXed buffer, it transmits the same packet again and now moves it to the ReTX buffer. If the ack is not received and before next Txnotify is received, it will prioritize packets from the ReTX buffer over TxOn buffer.

The first transmission from the  TXed buffer is not a problem (since it is opportunistic) but the next transmission from the ReTX buffer is a problem because it  is done when there is actual data in the TXon buffer. This will cause a loss of throughput.  

As I said, I am not sure if this is what is intended by the standard. 

Hope this helps. 

Dipak 

Koray Kokten

unread,
Sep 28, 2013, 2:08:56 PM9/28/13
to ns-3-...@googlegroups.com
Dipak,
I see, you,re right. This is actually because, there is not any negative acknowledgement support in the current AM_RLC mode. So the transmitting side of RLC assumes that whenever a positive acknowledgement packet is received whose sequence number is VT(A) <= SN < VT(MS), it updates the transmitted buffer and retransmission bugger by deleting the RLC PDU packets whose sequence numbers are lower than the acknowledged sequence number. In other words the AM RLC initially assumes that every packet should be retransmitted until when a corresponding acknowledgement received whereas the standard says a RLC PDU is retransmitted if a negative acknowledgement is received for it. (Section 5.2.1 in TS 36.322)
What do you think Dipak. Do you think this will cause a significant decrease in throughput.
Thanks.
  Koray

Dipak Ghosal

unread,
Sep 28, 2013, 4:30:15 PM9/28/13
to ns-3-...@googlegroups.com
Hi Koray, 

I am not sure I completely understand. I am trying to read through the standard to understand this.  I will try to get back soon.  

Regarding your other question: Yes it cause a significant reduction in the throughput. The throughput is reduce by a factor of 3. 

Thanks. 

Dipak 

Dipak Ghosal

unread,
Sep 30, 2013, 2:22:34 AM9/30/13
to ns-3-...@googlegroups.com
HI Koray and Nicola, 

Reading the standards, it seems that only data from the TXon and ReTX buffer  should be transmitted. On further reflection,  it does not make sense to transmit from the TXed buffer since these are packets that you have already been transmitted and waiting for ACK/NACK. 

I revised  the code  to not transmit from the TXed buffer and saw a significant improvement (approximately 5.3 Mps to ~10 Mbps).  Since there are no errors and the UE is very close to the eNB, it should give the max  of 16.3 Mbps for 5 Mhz LTE system. So there is still some additional bugs in the implementation. I am still looking  into it.  I still see a number of packets being transmitted from the ReTX buffer;  This tends to some problem with the polling and the STATUS-POLL-PDU. 

Hi Nicola, 

Please let me know if you are already aware of this problem. Also if your were able to get in touch with the original developer of this code. 

Thanks. 

Dipak  

Madan Pande

unread,
Sep 30, 2013, 4:25:27 AM9/30/13
to ns-3-...@googlegroups.com
Hi Dipak,

               With respect to your findings, may I know whether you are i)  enabling HARQ,  ii) enabling any Error Mode,  iii) Fading Model , iv) Pathloss Model...pl

With Regards,
madan


Date: Sun, 29 Sep 2013 23:22:34 -0700
From: dipak....@gmail.com
To: ns-3-...@googlegroups.com
Subject: Re: RLC_AM Mode LTE

Koray Kokten

unread,
Sep 30, 2013, 4:46:20 AM9/30/13
to ns-3-...@googlegroups.com
Hi Dipak,
I am actually not really sure about what you say is exactly true about the current implementation of the RCL_AM Mode. Because as you might have noticed in the code, the data is transmitted from the TXed only when there is not any data awaiting for the transmission at the RETX buffer or TXion buffer, respectively. In other words if there is not any RLC PDU that may be in either TXon Buffer of RETX buffer, why not use the resource assigned by the MAC layer to send the RLC PDU(s) in the TXed buffer which is(are) not yet ACKED. This addresses the opportunistic kind of communication that you mentioned in your previous message I think.
Long story short ,I just could not figure out the way you changed the code and make the throughput increased.
Am I missing a point.
Best.
    Koray

Dipak Ghosal

unread,
Sep 30, 2013, 7:10:59 PM9/30/13
to ns-3-...@googlegroups.com
Hi Koray, 

Yes, I did look into the code and as I had indicated in an earlier e-mail, when the RLC gets notified of the TXOpportunity, it transmits for the TXed buffer if all the other buffers are empty. As I had mentioned that this is opportunistic and maybe OK [ However, I am concerned if this will  increase the interference when there are multiple UEs.]. 

In the code, when  a packet is transmitted from the TXed buffer it is moved into the ReTX buffer. I don't think this is correct.  Packets should be moved to the ReTX buffer only after it is determined that it should be re-transmitted (NACK  or observing a hole). 

I tried two things: 

1. First, I commented out the code where a packet is moved to the ReTX buffer after it is transmitted from the TXed buffer. This case there was some problem and simulation gave an error after transmitting about 15 packets. I believe this is some problem with the sequence numbers. I have not diagnosed this carefully. I should look in to this.  

2. In LteRlcAm::DoNotifyTxOpportunity I set the condition so that that it never transmits from the TXed buffer. [ else if ( m_txedBufferSize < 0 ) //dg: Making sure this part never gets executed]. This gives the results the I mentioned in my previous e-mail. 

Let me know if this makes sense and/or if you see any problems. 

If you see 3GPP TS 36.322 version 10.0.0 Release 10, in many places it distinguishes between the three buffers and "the transmission buffer and the retransmission buffer becomes empty (excluding transmitted RLC data PDU awaiting for acknowledgements) after the transmission of the RLC data PDU." 

Unfortunately, I donot have the final answer as to how this should be fixed. Any help is appreciated. 

Thanks. 

Dipak Ghosal

unread,
Sep 30, 2013, 7:15:00 PM9/30/13
to ns-3-...@googlegroups.com
Hi Madan, 


Fading model: off
Path Loss: Friis
HarqEnabled: true
DataErrorModelEnabled: False

Thanks. 

Dipak

Koray Kokten

unread,
Sep 30, 2013, 8:06:31 PM9/30/13
to ns-3-...@googlegroups.com
Hello again Dipak,
Thanks for the clear explanation. Now it makes sense, and I think you're right about what you are saying. I am quite shocked that how come I missed that lines. Thanks for letting us be aware of that. I will try to come up with a good solution for that, and let you know.
Additionally I came across with possible bugs (seems like bugs to me but I am not totally sure. I appreciate if you could share your opinion) that I wanna share with you and I think along with the solutions of them including yours, the throughput problem could be tackled. The first one is about the re-transmission condition in the code. What I mean is, the standard document TS 36.322 says that, "if the RLC data PDU to be retransmitted does not fit within the total size of RLC PDU(s) indicated by lower layer at the particular transmission opportunity notified by lower layer, the AM RLC entity can re-segment the RLC data 
PDU into AMD PDU segments", however, current implementation does not support that functionality, and just waits for a TX opportunity which is gonna fit RLC_PDU in size, that may not be possible forever. Since both the ENB and UE are stable in my sample scripts, both the UL and DL channel quality indicator values are not fluctuating, so that kind of error never happened to me. 
Secondly, I have just discovered a weird behavior at MAC layer in the DL side (in LteEnbMac class) which is, if the mac layer reports a TxOpportunity to RLC layer and if the RLC layer has a status PDU awaiting for the transmission, it first sends it to MAC since status pdu's have the highest priority. That's OK but, after that, the problem is, the remaining resource is not being used by the RLC layer although there are RLC pdu's waiting in the Txion buffer. As I said this occurs only in DL side, whereas in UL side it works perfectly (LteUeMac class checks whether there is still available remaining resource after sending the status pdu or not, and if there is, it calls the TxOpportunity function of RLC again). So this causes a wasting of the available resources. And I think that is the reason why, we are not still able to see as highest throughput as in the UM Mode.
Feedback is appreciated.
Thanks,
Best
  Koray

Brett

unread,
Oct 1, 2013, 3:29:03 PM10/1/13
to ns-3-...@googlegroups.com

Hello, my name is Brett and I would like to say that I have seen similar issues with throughput when using RLC AM mode. I had setup a simulation that was just to see how much data I could push through (no errors, 100 resource blocks downlink, 1 eNodeB, 1 phone, 1 remote server, UDP application). When I did this using RLC UM I could get a downlink throughput of about 60 Mbps. However when I tried RLC AM I only got about 12 Mbps. When I looked into this I came across the same issues mentioned here:

  • Receiver could not ACK the last packet of the transmission window since it could not represent a number larger than 1023.
  • The system retransmitted a lot of PDUs since NACK is not implemented and all in transit PDUs not ACKed are retransmitted.

After this I decided to make some modifications to RLC AM and I was wondering if these changes seem appropriate based on the LTE specification. I checked the spec and my changes seemed fine to me but I wanted to get a second opinion. I added partial support for NACKs in the AM header. By partial I mean I added the ability for the receiver to NACK entire PDUs but not portions of PDUs. In the RLC spec the AM header can contain SO start and end fields to indicate that just part of a PDU is lost. I did not do this since it is not needed for my thesis work and instead just added code so a list of NACKs could be given to the header and serialized/deserialized properly. I then changed the transmitting side so that only PDUs that have been NACKed can be put into the retransmission buffer. I modified the transmission window so that once the window wraps around an ACK for a smaller sequence number would also ACK everything up to and including SN 1023. I also commented out the code for moving items from the TXed buffer to the retransmission buffer when there was no other data to send. When I re-ran my tests I found that my modified RLC AM got me the same throughput as when I used RLC UM. Since my simulation had no errors I had no retransmissions while using AM. I also ran some tests where I dropped certain PDUs and the NACKs reported in the header and the retransmission seemed to work fine. If anyone could indicate if my changes seem appropriate or if I missed some aspect of the specification then that would be greatly appreciated. Thank you.


-Brett

Koray Kokten

unread,
Oct 1, 2013, 6:17:07 PM10/1/13
to ns-3-...@googlegroups.com
Hi Brett,
Thanks for sharing your findings and solutions with us. At this point let me share my opinions about what you have explained in you message. 

First of all, I actually don't really understand why the receiver side RLC entity cannot ACK the PDU whose sequence number is 1023. I think in this case receiver side RLC will send a status PDU whose ACK SN field is equal to zero. When the transmitting side RLC receives that RLC status PDU with ACK SN= 0, it will understand that the data PDU with 1023 has been received by the receiver side, according to my understanding when I read the source code. I may be missing something by the way. Could you elaborate your claim. For example have you ever noticed this problem in this logging messages of RLC entity?

About the NACK issue, you're right. Lack of NACK support dramatically reduces the performance. But here, the definition of "when the data should be retransmitted?" or "when should the negative acknowledgement be sent to transmitter side?" questions are critical I believe. I am quite sure that the standard does not explain the cases of NACK state in a very detailed way, since because it ,at the same time, aims to leave some free space to the vendors but I am also pretty sure that it draws a general border for them I will go through the spec in order to refresh my knowledge about it and get back to you with a detailed answer as soon as possible. Also can you explain how do you decide to send a NACK PDU to the transmitter side? By the way if you can share you modified source files that would be appreciated, to make it run and see what it does, our machines too.
Thanks
Best, 
 Koray

Koray Kokten

unread,
Oct 1, 2013, 9:21:31 PM10/1/13
to ns-3-...@googlegroups.com
Brett,
I also need to add that, there is not any segmentation mechanism support in the current RLC AM mode, and since the class RlcAmHeader realizes  AMD PDU data structure (not AMD PDU Segment), there is not any field named as SO too, if I am not missing anything. So actually, your 'partial' implementation of the re-transmission mechanism is the only one that can be added right now as a first attempt. 


On Tuesday, October 1, 2013 12:29:03 PM UTC-7, Brett wrote:

Brett

unread,
Oct 1, 2013, 10:21:56 PM10/1/13
to ns-3-...@googlegroups.com
Hi Koray,

So for the transmission window wrapping around in the simulation code however I saw this line inside of the DoReceivePdu method of lte-rlc-am.cc:

Line #
965  while (m_vtA < ackSn && m_vtA < m_vtS)

ackSn is a unsigned 10 bit integer so it can only go as high as 1023 and since the while loop to ACK packets only executes when m_vtA is less than the ackSn it looks like there would be a problem with the window wrap. Now I only saw this after I set the poll PDU and poll bytes larger than 1 PDU so that I could send several PDUs before forcing the STATUS message. I need to look for some example log output that showed this happening but for now I have attached two plots I made that show the time of transmission of a PDU, when it was received and then when the ACK for it got back to the sender. In the graphs you can see the window starts to wrap around and new data is sent but the ACK that comes back is for one of the wrapped around sequence numbers (since I allow multiple PDUs before I send back an ACK). The ACK counts for the low sequence number but it never ACKs the remaining higher sequence numbers in the window. As a result the higher sequence number keeps resending but the receiver is ACKing the most recent PDU received which was one of the small sequence numbers.

In terms of NACKing and the use of the retransmission buffer I agree that the spec seems vague. The only mention I saw on things being placed into the retransmission buffer was in section 5.2.1 of 36.322 (I am looking at a copy from version 8.8.0) where it says that either retransmit a PDU that for which a NACK is received and that is also in the transmission window or in section 5.2.2.3 when t-PollRetransmit expires and there is nothing in the transmission and retransmission buffer then consider any un-acknowledged packets for retransmission. For when a NACK should be sent I had made the assumption that the STATUS message would contain all known information at that time, which would include the most recent ACK and any known NACKs. I could be completely off base on that but that was my first guess.

To send my NACKs from the receiver to the sender I added them in the lte-rlc-am-header class. I just created a list to hold the NACK numbers. Then when a STATUS PDU is being created I parse over the reception window and identify each empty space in the buffer up to the largest ACK. I then add these to the list. When the lte-rlc-am-header object is serialized I have code to encode the NACK numbers similar to how they are in the real header. I have an E1 bit that indicates there is a NACK, an E2 bit that indicates there is no SO start or end and then I list the sequence number. The receiving side deserializes this back into a regular lte-rlc-am-header object.

I attached a file nack_updates.txt that is a Mercurial diff between the normal version ns-3.18 and my changes. This is my first draft of changes so the they are not nice looking yet and there are a few things I just left commented out.

-Brett
sn_all.png
sn.png
nack_updates.txt

Dipak Ghosal

unread,
Oct 2, 2013, 2:36:38 AM10/2/13
to ns-3-...@googlegroups.com
Hi Brett, 

Thank you for sharing your results and the modifications.  

I realized that there was some problems with the sequence numbers and that the lack of NACK support was causing the loss of throughput but did not get time to completely work it out. It is great that you have working solution.  I also agree regarding  "comment(ing) out the code for moving items from the TXed buffer to the retransmission buffer when there was no other data to send." I agree this was not correct. 

I will try out your code soon.  I am new to some of these tools. Is there a simple way to incorporate your changes into into my source code (besides copy-and-paste)? 

Thanks. 

Dipak 

Brett

unread,
Oct 2, 2013, 7:25:20 AM10/2/13
to ns-3-...@googlegroups.com
The ns-3 distribution comes as a Mercurial repository (or at least the one I grabbed did). So if you have the Mercurial program installed you can use it to view changes made to the source code for the project. In this case I made the attached file using the command "hg diff" to just print out what I had done differently from the original version. To apply these changes to your project (if it is also Mercurial repository, which I think it should be) then you just need the Mercurial program and run the command "hg import nack_updates.txt". That should apply all the same changes. Sorry if this makes it more difficult. I am at work right now but I can post the complete copies of the files I modified after I get home later.

-Brett

Madan Pande

unread,
Oct 2, 2013, 7:54:02 AM10/2/13
to ns-3-...@googlegroups.com
Hi Dipak,

These were my doubts...
I have throughly enjoyed the discussions on RLC_AM mode..
Thanks again for starting it ...also Koray and Brett ...

With Regards,
madan


Date: Mon, 30 Sep 2013 16:15:00 -0700

Koray Kokten

unread,
Oct 2, 2013, 1:44:04 PM10/2/13
to ns-3-...@googlegroups.com
Brett,

Thanks for long and informative reply. I will try to go through about your doubts.
In the first problem about sequence numbers I am not totally sure that I clearly understood what you mean, but let me give an example according to my understanding of your explanation. For example let's assume that m_vtA = 1020 and m_vtS = m_vtA+512 = 508, as well as assume that the last received status PDU has a ACKED SN = 0. This condition is possible since the transmitter side RLC is capable of sending burst of RLC PDU's upper bounded by the Window_size = 512. So in this case you are saying that the inside of while statement starting at line 965 never executes since;

while (1020 < 0 && 1020 < 508) never terminates true. Do I understand right?

If you mean this, yes're right. This while statement returns false. However it returns false not because 1020 is not smaller than the zero, but the proper equivalent of this statement also returns false. Let me make it more clear.

Sequence numbers in RLC implementation are of class SequenceNumber10, which is a class representation of a 10 bit unsigned integer. When we look a the operator < overloading of this class we see that, it calls the operator > and operator != overloads of the class and return the result by taking the AND operation of the return values of them (as seen in line 134) .

132  bool operator < (const SequenceNumber10 &other) const
133  {
134  return !this->operator> (other) && m_value != other.m_value;
135  }

Now, here operator != overload is kind of straightforward, but if we look at the operator > overload, we see
such lines as shown below.

105  bool operator > (const SequenceNumber10 &other) const
106  {
107  SequenceNumber10 v1 ((m_value - m_modulusBase) % 1024);
108  SequenceNumber10 v2 ((other.m_value - other.m_modulusBase) % 1024);
109  return ( v1.GetValue () > v2.GetValue () );
110  }

As you can see, we compare two SequenceNumber10 values by first subtracting the m_modulusBase value from
m_value (which are both of type uint16_t) and then taking the modulus of them. (By the way, m_modulusBase
values is set to the 0(zero) in the constructor of SequenceNumber10 class, and never set to another value in
the current implementation of lte-rlc-am.cc file). Now let me re-write the while statement under the light
of that information.

while (1020 < 0 && 1020 < 508) equivalent to

while((1020-m_modulusBase)%1024 < (0-m_modulusBase)%1024 && (1020-m_modulusBase)%1024 < (508-m_modulusBase)%1024) ,where m_modulusBase = 0
  
=  while (1020%1024 < 0%1024 && 1020%1024 < 508%1024)
= while (1020 < 0 && 1020 < 508)

which is exactly the same with the first one. It returns the same because there is a bug, and it was already
reported and the solution has been also suggested under bugzilla that you can find here: https://www.nsnam.org/bugzilla/show_bug.cgi?id=1756

The suggestion is simply setting the m_modulusBase values to m_vtA values just before the while statement.
If we do that the while statement becomes;

while((1020-m_modulusBase)%1024 < (0-m_modulusBase)%1024 && (1020-m_modulusBase)%1024 < (508-m_modulusBase)%1024)

,where m_moduluesBase = m_vtA = 1020

while ((1020-1020)%1024 < (0-1020)%1024 && (1020-1020)%1024 < (508-1024)%1024)
=  while ((0 < 4 && 0 < 512)

which terminates true as it is expected to be.


Regarding with the NACK issue, I understand almost all of your points except that there are still couple of
unclear points in my mind. Once reading your modifications in the source code, I think I can have better
explanations hopefully.
Best
Koray


On Tuesday, October 1, 2013 7:21:56 PM UTC-7, Brett wrote:

Dipak Ghosal

unread,
Oct 2, 2013, 6:18:23 PM10/2/13
to ns-3-...@googlegroups.com
Hi Brett,

I tried what you suggested  but I get the following errors: 

Hunk #9 FAILED at 1033
1 out of 10 hunks FAILED -- saving rejects to file src/lte/model
abort: patch failed to apply

Maybe my Mecurial repository is not properly setup. 

Can you please post the code? 

Thanks. 

Dipak 

Brett

unread,
Oct 2, 2013, 7:09:31 PM10/2/13
to ns-3-...@googlegroups.com
Dipak,

Here are the files.

-Brett
lte-rlc-am-header.cc
lte-rlc-am-header.h
lte-rlc-am.cc

Brett

unread,
Oct 2, 2013, 7:18:27 PM10/2/13
to ns-3-...@googlegroups.com
Koray,

Thank you for that in depth explanation. I had no idea that some operators had been overwritten. I should have have taken a closer look at the supporting classes involved.

-Brett

Dipak Ghosal

unread,
Oct 2, 2013, 11:47:26 PM10/2/13
to ns-3-...@googlegroups.com
Hi Brett,

Thank you for the files.  I did run it for a single UE placed close to the eNB and  without fading. I am running TCP and I get  throughput of 10.8 Mbps (for the UM mode, I get 16.3 Mbps).  So there is still some bug. I took log of lte-rlc-am and did a quick scan of it.

1. I see the NACK number becoming large, "Current NACK is 6553565"
2. I also noticed that the Txon and Txed  buffers becoming very large periodically
    1.26493s LteRlcAm:DoReportBufferStatus(): txonBufferSize = 19379
    1.26493s LteRlcAm:DoReportBufferStatus(): retxBufferSize = 0
    1.26493s LteRlcAm:DoReportBufferStatus(): txedBufferSize = 10980

3. It seems unlikely that the buffer should become so large for this case.
4.  In the TCP layer I noticed periodic 10 ms stalls in window growth in the congestion avoidance phase. I am not sure if this is to do with TXNotify form the MAC layer. Koray had mentioned that he had seen something strange.

I will not have much time in the next few days but will look through your code whatever time  I get. It is really good that you have created the framework to incorporate NACKs. Unlike traditional ARQ, AM does not use sender side timer to determine loss/error. My understanding is that this purpose is served by the polls and the NACKs. Hence, the NACKs are important.

Thank you.

Dipak

Dipak Ghosal

unread,
Oct 2, 2013, 11:51:42 PM10/2/13
to ns-3-...@googlegroups.com

There was a small copy paste error: For 1 below,

"1.26593s LteRlcAm:DoReceivePdu(): Brett - Current NACK is 65535"

Brett Levasseur

unread,
Oct 3, 2013, 9:16:23 AM10/3/13
to ns-3-...@googlegroups.com
Dipak,

Well it's a first draft so I am not surprised that it has errors. The issue with the NACK being reported as 65535 is not an actual NACK number or at least it is not supposed to be. The NACKs are stored in a list and I was trying to have a special case when the list became empty. My NACKs are just regular integers so when the list of NACKs in the header was empty I am just returning -1, however I just noticed in the code that when I take it out of the list I make it an unsigned integer data type. That is probably why that large NACK value shows up. Either way my changes needs to be cleaned up a lot more.

-Brett


--
You received this message because you are subscribed to a topic in the Google Groups "ns-3-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ns-3-users/CEfmMX3IRBw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ns-3-users+...@googlegroups.com.

Dipak Ghosal

unread,
Oct 4, 2013, 12:48:17 AM10/4/13
to ns-3-...@googlegroups.com
Hi Brett, 

Thanks for the explanation. I will look through it carefully next week.

Dipak

Nicola Baldo

unread,
Oct 16, 2013, 12:31:56 PM10/16/13
to ns-3-...@googlegroups.com
Hi all,

I'm very glad of seeing so much activity on this issue! I think it would be very nice if we could gather all this effort collaboratively to come up with a satisfactory RLC AM NACK implementation, to be merged possibly into the next ns-3 release.

To this aim, I've just published a new mercurial repository here:
http://code.nsnam.org/nbaldo/ns-3-lena-rlc-am-nack/

The repository currently includes:
  1. Brett's latest files (omitting some irrelevant parts, and adapting them to the latest lena-dev code)
  2. a new test suite lte-rlc-header that I wrote, featuring a new test case class RlcAmStatusPduTestCase that aims at checking the correct serialization and deserialization of RLC AM STATUS PDUs (thereby covering the new NACK feature)

you can run the new test suite like this:

NS_LOG=TestLteRlcHeader ./waf --run test-runner --command="%s --suite=lte-rlc-header"

Currently the test fails. I suspect that the deserialization of the NACK is not done correctl, In fact, looking at the code, my impression is that deserialization might not handle correctly odd vs even NACK SN.

If anyone could give this a try, and provide further feedback, it would be very much appreciated!


Regards,

Nicola









Brett

unread,
Oct 17, 2013, 10:07:57 AM10/17/13
to ns-3-...@googlegroups.com
Nicola,

Thanks for looking at my work to add, buggy as it is. I am trying to run the test but I must be doing something wrong. I set the NS_LOG value and ran the waf command that you listed but the test fails while trying to serialize the header. The error seems to be that the header length was wrong:

assert failed. cond="Check (m_current)", msg="You have attempted to write after the end of the available buffer space. This usually indicates that Header::GetSerializedSize returned a size which is too small compared to what Header::Serialize is actually using.", file=./ns3/buffer.h, line=693

terminate called without an active exception

When I looked into this I found that the m_headerLength was equal to 0. I think this is because line 122 of the test class test-lte-rlc-header.cc creates the LteRlcAmHeader object but it never calls SetControlPdu to set the base m_headerLength to 2. As a result the test sets an ACK number and appears to have no NACKs to set (at least when I ran it the for loop did not have any NACKs to add). Then line 130 calls p->AddHeader, which fails since the m_headerLength is still 0. Was there something that I missed about running this test?

-Brett

Brett

unread,
Oct 17, 2013, 11:34:21 AM10/17/13
to ns-3-...@googlegroups.com
Nicola,

I think there is an issue with my PushNack method over adding to the length of the header. The code is written like:

if (m_nackSnList.size () % 2 != 0)

but I think it should be

if (m_nackSnList.size () % 2 == 0)

The reason for this is that if we add a new NACK and this gives us an even number of NACKs the header length should increase by 1. If adding the new NACK gives us an odd number of NACKs then the header length should be increased by 2.

For each NACK we need to follow with an E1 and E2 value, the NACK is 10 bits long so each new NACK is 12 more bits in the header. The initial header for the STATUS message is of size 2 because the D/C, CPT and ACK make up 14 bits. Then we have an E1 value and the list of NACKSs. So for the first NACK the size of the list is 1 and we add 2 to the size of the header to make the header length 4. The 12 bits for the first NACK, E1 and E2 gives us a header like (note following is an ACK of 8 and NACK of 1, E1 is 1 because I am going to continue the example):

00000000

00100010

00000000

110

In the current code using != in the PushNack means an odd number of NACKs would only add 1 octet to the header. If that was used then the header length would have come up as 3 and the last bit of the NACK along with the E1 and E2 fields would have been lost.

Back to using == in PushNack if we add another NACK to the list we have an even number so we add 1 to the size of the header to make 5. The header is now (same as before but my new NACK is 2 and its following E1 is 0):

00000000

00100010

00000000

11000000

0001000

This creates a pattern where an odd number of NACKs will require 2 more octets to the header and adding an even number of NACKs requires 1 more octet. This only works because the SOstart and SOend fields of the RLC AM header are not in use. So I think the error over having odd and even number NACKs is at least in part due to the if statement in the PushNack method. I need to look into this more to find any other issues but I think this is one of the current bugs.

-Brett Levasseur


On Wednesday, October 16, 2013 12:31:56 PM UTC-4, Nicola Baldo wrote:

Nicola Baldo

unread,
Oct 21, 2013, 8:47:20 AM10/21/13
to ns-3-...@googlegroups.com
Hi Brett,

I applied your fix to the PushNack method, and also fixed a bug in the test (LteRlcAmHeader::SetControlPdu was not being called).
Finally, I've added more test cases with up to  4 NACK SNs in the same STATUS PDU. All these changes are in the mercurial repo that I previously indicated.

Now if you run this

NS_LOG=TestLteRlcHeader ./waf --run test-runner --command="%s --suite=lte-rlc-header"
all the test cases pass. Hence we can now be reasonably confident that the serialization and deserialization of NACK_SN is done correctly.

The next step is to check the NACK-related code in LteRlcAm. To this aim, I've been running this other test case:
./waf --run test-runner --command="%s --suite=lte-rlc-am-e2e"
this test crashes. The crash is at lte-rlc-am.cc line 1681. Apparently SN m_vtA is not in m_txedBuffer, unlike expected.

I suspect that this could be due to the modifications done to the buffer management as part of the NACK patch.
Do you have any comment on this?



Brett Levasseur

unread,
Oct 21, 2013, 11:16:26 AM10/21/13
to ns-3-...@googlegroups.com
Hi Nicola,

I think I found the problem here. I was not updating the value of m_vtA properly in the DoReceivePdu method. First near line 1134 I have a block of code like:

                 if (!foundNack)
                   {
                     m_vtA++;
                   }

I should not be incrementing m_vtA here because it already gets updated earlier in the method near line 1078. So we can remove this if(!foundNack) statement entirely. Once I made this change the test got further along before failing again, also over the value of m_vtA. When I looked into the code I found that I was incrementing m_vtA after a NACK is found. This happens near line 1078 with:

          m_vtA++;
          m_vtA.SetModulusBase (m_vtA);
          m_vtS.SetModulusBase (m_vtA);
          ackSn.SetModulusBase (m_vtA);

I changed this code to include my if ( !foundNack ) statement and when I reran the test it came back saying it passed. So to summarize I made the following changes in lte-rlc-am.cc:

diff -r 5dd999139798 src/lte/model/lte-rlc-am.cc
--- a/src/lte/model/lte-rlc-am.cc    Mon Oct 21 14:27:50 2013 +0200
+++ b/src/lte/model/lte-rlc-am.cc    Mon Oct 21 11:09:21 2013 -0400
@@ -1078,10 +1078,14 @@
                 m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
               }
 
-          m_vtA++;
-          m_vtA.SetModulusBase (m_vtA);
-          m_vtS.SetModulusBase (m_vtA);
-          ackSn.SetModulusBase (m_vtA);
+            if ( !foundNack )
+              {
+                m_vtA++;
+                NS_LOG_INFO ("Brett -- Updated VT(A) = " << m_vtA);
+                m_vtA.SetModulusBase (m_vtA);
+                m_vtS.SetModulusBase (m_vtA);
+                ackSn.SetModulusBase (m_vtA);
+              }
             }
           else
             {
@@ -1131,11 +1135,7 @@
               }
             else
               {
-                loopCount++;
-                if (!foundNack)
-                  {
-                    m_vtA++;
-                  }
+                loopCount++;               
               }
         }

-Brett

Nicola Baldo

unread,
Oct 22, 2013, 7:40:00 AM10/22/13
to ns-3-...@googlegroups.com
Hi Brett,

thanks for the patch, I just committed it and pushed to the repo.
With the patch, all the tests pass with the default fullness level (-f QUICK), however when running all tests (-f TAKES_FOREVER) there is some test that fails:

./waf --run test-runner --command="%s --suite=lte-rlc-am-e2e --fullness=TAKES_FOREVER --verbose"Waf: Entering directory `/locale/ns-3-lena-rlc-am-nack/build'
Waf: Leaving directory `/locale/ns-3-lena-rlc-am-nack/build'
'build' finished successfully (1.117s)
FAIL lte-rlc-am-e2e 2.680 s
  PASS  Losses = 0%. Seed = 1111 0.250 s
  PASS  Losses = 0%. Seed = 2222 0.200 s
  PASS  Losses = 0%. Seed = 3333 0.200 s
  PASS  Losses = 0%. Seed = 4444 0.200 s
  PASS  Losses = 0%. Seed = 5555 0.200 s
  PASS  Losses = 0%. Seed = 6666 0.200 s
  PASS  Losses = 0%. Seed = 7777 0.200 s
  PASS  Losses = 0%. Seed = 8888 0.200 s
  PASS  Losses = 0%. Seed = 9999 0.200 s
  PASS  Losses = 0%. Seed = 10101 0.200 s
  PASS  Losses = 10%. Seed = 1111 0.210 s
  PASS  Losses = 10%. Seed = 2222 0.210 s
  FAIL  Losses = 10%. Seed = 3333 0.210 s
      got="txEnbRrcPdus (actual) == rxUeRrcPdus (limit)" expected="1000" in="../src/lte/test/lte-test-rlc-am-e2e.cc:220" TX PDUs (1000) != RX PDUs (999)

apparently, in the last test case, one RLC SDU out of 1000 does not get delivered to the end point.

Nicola Baldo

unread,
Oct 22, 2013, 8:31:55 AM10/22/13
to ns-3-...@googlegroups.com
Looking at the LteRlcAm code with your modifications, I found a fundamental error. For instance see this comment of yours:

      // Check the reception buffer and find which Sequence Numbers are missing
      // based on what is being ACKed. All SNs missing from the reception
      // buffer that come before the SN number that is being ACKed are going to
      // be NACKed packets.

That's not correct: according to the specs, ACK SN is the lowest edge of the transmission window. Hence the reported NACK SN values will be higher than ACK SN.
Also note this:

//      rlcAmHeader.SetAckSn (m_vrR); // Brett, need to change this
      rlcAmHeader.SetAckSn (m_vrH); // Brett, is this right?

According to the specs, ACK SN should be set to VR(MS). I am not sure about the difference between VR(MS) and VR(R), they look very similar to me. Anyway, it is clear that both are very different from VR(H).

I tried changing the above to

      rlcAmHeader.SetAckSn (m_vrMs);

however it is not sufficient. I think more work is needed to get the NACK procedure right.

Nicola Baldo

unread,
Oct 22, 2013, 8:51:54 AM10/22/13
to ns-3-...@googlegroups.com
Furthermore, there is the issue of the "window wrap around". I see you added some new custom code to handle this. However, I think it is more appropriate to use SequenceNumber10 instead, as it handles correctly the modulo calculations as per 3GPP TS 36.322 section 7.1. See also the previous post by Koray on this thread.

Brett Levasseur

unread,
Oct 22, 2013, 10:23:37 AM10/22/13
to ns-3-...@googlegroups.com
Nicola,

I originally made my changes to the window wrap around before I found out that the SequenceNumber10 object overloaded the < operator. This was something pointed out to me by Koray Kokten who also pointed out that there was a bug related to this that was reported and fixed in https://www.nsnam.org/bugzilla/show_bug.cgi?id=1756. Koray pointed this out after I posted my code so I did not get a chance to change it. So since this is already working properly my code towards the window wrapping can be removed.

As to my misunderstanding on the use of ACK and NACK perhaps you can help me. I originally thought that the ACK_SN was to acknowledge the largest sequence number received so far and that the NACK_SNs were to negatively acknowledge any PDUs that the receiver side knew was missing. I think I developed this misunderstanding from miss-reading the specification.

I was reading about the receiver side in status reporting in 3GPP TS 36.322 V8.8.0 section 5.2.3 and it says that the ACK_SN of the status message is set to the SN of the next not received RLC Data PDU which is not indicated as missing in the resulting STATUS PDU. According to section 5.2.3 the values for NACK_SN are found by examining the receiving side reception window from VR(R) <= SN < VR(MS). Each AMD PDU in this range that has no byte segments received gets a NACK and any PDU that is not completely received gets a NACK with an SO start and SO end. VR(MS) is according to section 7.1 the highest possible value of the SN which can be indicated by ACK_SN. Based on this I thought it was possible to have an ACK_SN which is equal to VR(MS) but still have NACK_SNs that are smaller than the ACK_SN.

You say that the spec shows that ACK_SN is the lower bound of the transmit window. In section 7.1 it says that VT(A) is the Acknowledgmenet state variable and that this variable holds the value of the SN of the next AMD PDU for which a positive acknowledgment is to be received in-sequence and that it is updated whenever the AM RLC entity receives a positive acknowledgment for an AMD PDU with SN=VT(A). So I thought that VT(A) was the SN after the last in sequence PDU, which indicated to me that you could have an ACK for a higher sequence number but you also received a NACK that was smaller than that ACK. For instance I thought you could have VT(A) = 5 and get a status message that with an ACK_SN of 10 and a NACK_SN of 8. Then I thought you would increment VT(A) to 8 as you have ACKEd SN 5, 6, 7 and 9 but you increment VT(A) to go after the last in sequence ACK. A future status message that does not NACK SN 8 would then allow you to grow VT(A) past this point. If you can only NACK sequence numbers that are larger than the ACK then I would assume this passage would be re-worded to just say that you set VT(A) to the ACK. Why would the speck mention that VT(A) must be the in-sequence ACKs. If you can only NACK a sequence number larger than the ACK? In that case there would never be a situation where you can have an ACK that was out of sequence.

Also only ACKing the last in sequence received PDU seems very wasteful. If the receiver gets PDUs 1, 2, 3, 5, 6, 7, 8, 9, 10 and they are missing PDU 4 then they would send back an ACK of 4 indicating that they got PDUs 1 - 3 in sequence. The transmitter would then have to retransmit 4, 5, 6, 7, 8, 9 and 10. You are retransmitting 6 PDUs that the receiver already got. I thought the purpose of negative acknowledgements was so you could send back an ACK of 11 and NACK of 4 so the transmitter knows they only have to resend 4?

As to my use of VR(H) the spec says that VR(H) is the highest received state variable. It is the SN following the SN of the PDU with the highest SN among the received RLC data PDUs. If ACKs and NACKs worked the way I thought they did then this seems like the correct value for the ACK. In some cases I think VR(H) would be equal to VR(MS) but not always.

Could you please point out where I made mistakes in this train of thought, it would help me a lot. Thank you.

-Brett

Nicola Baldo

unread,
Oct 23, 2013, 6:28:22 AM10/23/13
to ns-3-...@googlegroups.com
Hi Brett, see inline


On Tuesday, October 22, 2013 4:23:37 PM UTC+2, Brett Levasseur wrote:
Nicola,

I originally made my changes to the window wrap around before I found out that the SequenceNumber10 object overloaded the < operator. This was something pointed out to me by Koray Kokten who also pointed out that there was a bug related to this that was reported and fixed in https://www.nsnam.org/bugzilla/show_bug.cgi?id=1756. Koray pointed this out after I posted my code so I did not get a chance to change it. So since this is already working properly my code towards the window wrapping can be removed.

ok
 

As to my misunderstanding on the use of ACK and NACK perhaps you can help me. I originally thought that the ACK_SN was to acknowledge the largest sequence number received so far and that the NACK_SNs were to negatively acknowledge any PDUs that the receiver side knew was missing. I think I developed this misunderstanding from miss-reading the specification.

well it's also possible that I misunderstood some parts of the specs. Let's discuss this further to clarify it.

 

I was reading about the receiver side in status reporting in 3GPP TS 36.322 V8.8.0 section 5.2.3 and it says that the ACK_SN of the status message is set to the SN of the next not received RLC Data PDU which is not indicated as missing in the resulting STATUS PDU. According to section 5.2.3 the values for NACK_SN are found by examining the receiving side reception window from VR(R) <= SN < VR(MS). Each AMD PDU in this range that has no byte segments received gets a NACK and any PDU that is not completely received gets a NACK with an SO start and SO end. VR(MS) is according to section 7.1 the highest possible value of the SN which can be indicated by ACK_SN. Based on this I thought it was possible to have an ACK_SN which is equal to VR(MS) but still have NACK_SNs that are smaller than the ACK_SN.

I agree that looking at 5.2.3 it seems that ACK SN is set to a number higher than all the NACKs. But then, look at how VR(MS) is incremented in section 5.1.3.2.3. To my understanding it will never be incremented past a SN that is missing, i.e., to be NACKed. It says:

When a RLC data PDU with SN = x is placed in the reception buffer, the receiving side of an AM RLC entity shall:
  •  if all byte segments of the AMD PDU with SN = VR(MS) are received:
    •  update VR(MS) to the SN of the first AMD PDU with SN > current VR(MS) for which not all byte segments have been received;
Example: at the beginning, VR(R) = 0 and VR(MS) = 0, and we receive a PDU with SN 4. The first contition is false (PDU with SN = VR(MS) still missing), so VR(MS)  is not updated and stays 0. Then, when we build a STATUS PDU, we consider VR(R) <= SN < VR(MS) for sending NACKs. But since VR(R) = 0 = VR(MS), we won't send any NACK!!

I've been checking bot Rel 8 and Rel 11 docs, and I don't see any relevant difference on this respect.

I've been googling for this, and I found someone with a similar doubt:
http://lteuniversity.com/ask_the_expert/f/59/t/2667.aspx

 

You say that the spec shows that ACK_SN is the lower bound of the transmit window. In section 7.1 it says that VT(A) is the Acknowledgmenet state variable and that this variable holds the value of the SN of the next AMD PDU for which a positive acknowledgment is to be received in-sequence and that it is updated whenever the AM RLC entity receives a positive acknowledgment for an AMD PDU with SN=VT(A). So I thought that VT(A) was the SN after the last in sequence PDU, which indicated to me that you could have an ACK for a higher sequence number but you also received a NACK that was smaller than that ACK. For instance I thought you could have VT(A) = 5 and get a status message that with an ACK_SN of 10 and a NACK_SN of 8. Then I thought you would increment VT(A) to 8 as you have ACKEd SN 5, 6, 7 and 9 but you increment VT(A) to go after the last in sequence ACK. A future status message that does not NACK SN 8 would then allow you to grow VT(A) past this point.

in section 7.1, it says explicitly that VT(A) is "the lower edge of the transmitting window". I think the confusion arises from the fact that "positive acknowledge" does not mean ACK SN.

 
If you can only NACK sequence numbers that are larger than the ACK then I would assume this passage would be re-worded to just say that you set VT(A) to the ACK.

good point, I was wondering exactly this.
 


Also only ACKing the last in sequence received PDU seems very wasteful. If the receiver gets PDUs 1, 2, 3, 5, 6, 7, 8, 9, 10 and they are missing PDU 4 then they would send back an ACK of 4 indicating that they got PDUs 1 - 3 in sequence. The transmitter would then have to retransmit 4, 5, 6, 7, 8, 9 and 10. You are retransmitting 6 PDUs that the receiver already got. I thought the purpose of negative acknowledgements was so you could send back an ACK of 11 and NACK of 4 so the transmitter knows they only have to resend 4?

good points again. Actually, section 6.2.2.14 clearly supports your interpretation.
 

As to my use of VR(H) the spec says that VR(H) is the highest received state variable. It is the SN following the SN of the PDU with the highest SN among the received RLC data PDUs. If ACKs and NACKs worked the way I thought they did then this seems like the correct value for the ACK. In some cases I think VR(H) would be equal to VR(MS) but not always.

makes sense, but still the update procedure for VR(MS) in section 5.2.3 does not seem to be compatible with this.


I've been googling a bit to clarify this issue, and I found this presentation which supports your interpretation:
lgeran2.tistory.com/attachment/cfil...@16577C334F6B1F0C10DE51.ppsx


To summarize:
  • I now agree that ACK SN shall be higher than NACKs
  • I still think that VT(A) is the lower edge of the transmission window
  • We need to clarify how VR(MS) works

Nicola Baldo

unread,
Oct 23, 2013, 6:51:58 AM10/23/13
to ns-3-...@googlegroups.com
Ok maybe I finally found the key. VR(MS) is also to be updated upon expiration of T_reordering as per section 5.1.3.2.4. This allows VR(MS) to grow past missing SNs.

Nicola Baldo

unread,
Oct 23, 2013, 9:24:54 AM10/23/13
to ns-3-...@googlegroups.com
I just pushed a new version to the repo addressing the wrap around and the ACK SN issue. Still it doesn't work, if you could take a look it would be very much appreciated.
You can try with
NS_LOG=LteRlcAm ./waf --run test-runner --command="%s --suite=lte-rlc-am-e2e --fullness=TAKES_FOREVER --verbose"
it will run the test case that fails (1000 SDUs are transmitted but only 4 received).

Brett Levasseur

unread,
Oct 24, 2013, 11:03:53 AM10/24/13
to ns-3-...@googlegroups.com
Nicola,

Thanks for the explanation. I see my errors with the state variables now. I completely looked over that VT(A) was the lower bound on the transmit window. Not sure how I missed that but you are completely right.

I looked at the test and it appears that the first missing PDU is 4. 0, 1, 2 and 3 are received fine but the next PDU received is 5. Right off the bat there is a problem with how NACKs are being reported. We have to wait until the reordering timer expires to grow VR(MS) past our missing PDU 4, however the first status message is the following:

0.165s -1 LteRlcAm:DoNotifyTxOpportunity(): [LOGIC] RLC header: Len=4 D/C=0 ACK_SN=4 NACK_SN=4

Since the timer has not yet expired we should be ACKing 4 and not have any NACKs. This problem persists and we start to see status messages like:

0.18s 0 LteRlcAm:DoReceivePdu(): [LOGIC] RLC header: Len=5 D/C=0 ACK_SN=4 NACK_SN=4 NACK_SN=6

On line 203 of lte-rlc-am.cc we are checking for NACKs in the loop:

for (sn = m_vrR; sn < m_vrH; sn++)

where the upper bound is VR(H). My guess is that this should be VR(MS). That would seem to line up with section 5.2.3 of the spec.

Further in this example we eventually have the timer expiration:

0.255s 1 LteRlcAm:ExpireReorderingTimer(): [LOGIC] Reordering Timer has expired
0.255s 1 LteRlcAm:ExpireReorderingTimer(): [LOGIC] New VR(MS) = 6
0.255s 1 LteRlcAm:ExpireReorderingTimer(): [LOGIC] Start reordering timer

but the next STATUS PDU sent is:

0.27s -1 LteRlcAm:DoNotifyTxOpportunity(): [LOGIC] RLC header: Len=5 D/C=0 ACK_SN=4 NACK_SN=4 NACK_SN=6

Here since VR(MS) is 6 I would expect us to ACK 6 since we got PDU 5 and NACK 4. Section 5.2.3 of the spec says to set the "ACK_SN to the SN of the next not received RLC Data PDU which is not indicated as missing in the resulting STATUS PDU". So we update VR(MS) and our NACK of 4 is valid, I think that NACK of 6 is invalid, but the last received PDU not NACKed should be 5. On line 232 of lte-rlc-am.cc the value of the ACK is set as:

rlcAmHeader.SetAckSn (m_vrR);

VR( R) is the lower edge of the receiving window which I am guessing should not move yet since we have not received PDU 4. My guess is we should se the ACK to VR(MS)

Fixing the for loop to be bounded by VR(MS) instead of VR(H) now gets the status messages after the lost PDU 4 like the following:

0.255s 0 LteRlcAm:DoReceivePdu(): [LOGIC] RLC header: Len=2 D/C=0 ACK_SN=4

which I believe should be correct. Then the timer expires and VR(MS) is finally updated:

0.255s 1 LteRlcAm:ExpireReorderingTimer(): [LOGIC] Reordering Timer has expired
0.255s 1 LteRlcAm:ExpireReorderingTimer(): [LOGIC] New VR(MS) = 6
0.255s 1 LteRlcAm:ExpireReorderingTimer(): [LOGIC] Start reordering timer

the next status message shows:

0.27s -1 LteRlcAm:DoNotifyTxOpportunity(): [LOGIC] RLC header: Len=4 D/C=0 ACK_SN=4 NACK_SN=4

and this is because the value of the ACK SN is being set to VR( R). So then I changed this to be VR(MS) as this should be the largest ACK we can use until a reordering timer expires again.

When I reran the test I got a SIGSEGV fault from sending data from the retransmission buffer. Specifically the error was caused by line 256 if lte-rlc-am.cc:

Ptr<Packet> packet = m_retxBuffer.at (m_vtA.GetValue ()).m_pdu->Copy ();

This failed because the value of VT(A) = 0, which was not in the retransmission buffer. Currently the only PDU in the retransmission buffer is PDU 4. I cannot see where VT(A) gets updated in the code. Other than:

m_vtA  = 0; at 52
m_vtA.SetModulusBase (m_vtA); at 1016
m_vtA.SetModulusBase (m_vtA); at 1084

I do not see any code writing to m_vtA. All the rest of the time it is just read. I do see that on line 1081 there is an if statement to update VT(A):

          if (incrementVtA)
            {
              NS_LOG_INFO ("New VT(A) = " << m_vtA);

              m_vtA.SetModulusBase (m_vtA);
              m_vtS.SetModulusBase (m_vtA);
              ackSn.SetModulusBase (m_vtA);
              sn.SetModulusBase (m_vtA);
            }

however my log output only ever says that "New VT(A) = 0" so the code to update VT(A) is missing. Based on everything my guess is that when a STATUS PDU is received VT(A) should be incremented until you either come across the ACK_SN or a NACK, which ever comes first. At line 1081 I added:

         if (incrementVtA)
           {
             m_vtA++;
           }

Now as long as incrementVtA is true we add one to VT(A) per loop. The first NACK sets incrementVtA to false.

After this change the test still fails but now it fails after receiving 982 of the 1000 PDUs. This is where I am now getting stuck. It looks like not all of the PDUs received are getting reassembled and passed up to the higher layers. According to the log the last PDU put in the reception buffer is SN 985 (note some of the RRC PDUs were packed into the RLC PDUs so even though this is SN 985 I think it still represents all 1000 RRC PDUs) but the last one reassembled is SN 968. Now I am not sure but I think the reason for none of the other PDUs being reassembled and passed up is because of VT(MS) and the reordering timer. According to the log it looks like PDU 969 is missing so VR(MS) does not grow past this. Eventually the timer expires and VT(MS) is updated properly to 986:

10.115s 1 LteRlcAm:ExpireReorderingTimer(): [LOGIC] Reordering Timer has expired
10.115s 1 LteRlcAm:ExpireReorderingTimer(): [LOGIC] New VR(MS) = 986

The problem is that the timer expired after the program sent its last PDU. Also since no NACK for PDU 969 was ever received the code never placed it into the retransmission buffer. As such there was never any data for the transmitter to send. Since the receiver did not get any more data it did not get any poll requests for status messages. It seems like the receiver is waiting for another poll so it can send a STATUS with the NACK, get the correct PDU and then reassemble and pass up the rest. Is there anything in the specification that is supposed to handle this situation?


Here are the changes I made to lre-rlc-am.cc:


diff -r b81502a7dae8 src/lte/model/lte-rlc-am.cc
--- a/src/lte/model/lte-rlc-am.cc    Wed Oct 23 15:21:13 2013 +0200
+++ b/src/lte/model/lte-rlc-am.cc    Thu Oct 24 10:28:08 2013 -0400
@@ -196,11 +196,11 @@
       LteRlcAmHeader rlcAmHeader;
       rlcAmHeader.SetControlPdu (LteRlcAmHeader::STATUS_PDU);
     
-      NS_LOG_LOGIC ("Check for SNs to NACK from " << m_vrR.GetValue() << " to " << m_vrH.GetValue());
+      NS_LOG_LOGIC ("Check for SNs to NACK from " << m_vrR.GetValue() << " to " << m_vrMs.GetValue());
       SequenceNumber10 sn;
       sn.SetModulusBase (m_vrR);
       std::map<uint16_t, PduBuffer>::iterator pduIt;
-      for (sn = m_vrR; sn < m_vrH; sn++)
+      for (sn = m_vrR; sn < m_vrMs; sn++)
         {
           if (!rlcAmHeader.OneMoreNackWouldFitIn (bytes))
             {
@@ -229,7 +229,7 @@
         {
           NS_LOG_WARN ("SN=" << sn << ", VR(MS)=" << m_vrMs);
         }     
-      rlcAmHeader.SetAckSn (m_vrR);
+      rlcAmHeader.SetAckSn (m_vrMs);
 
 
       NS_LOG_LOGIC ("RLC header: " << rlcAmHeader);
@@ -1080,13 +1080,18 @@
 
           if (incrementVtA)
             {
+              m_vtA++;
+            }
+
+          if (incrementVtA)
+            {
               NS_LOG_INFO ("New VT(A) = " << m_vtA);

               m_vtA.SetModulusBase (m_vtA);
               m_vtS.SetModulusBase (m_vtA);
               ackSn.SetModulusBase (m_vtA);
               sn.SetModulusBase (m_vtA);
             }
-         
+
         } // loop over SN : VT(A) <= SN < ACK SN
      
       return;

Nicola Baldo

unread,
Nov 3, 2013, 3:16:28 PM11/3/13
to ns-3-...@googlegroups.com
Hi Brett,

thanks for your patch and for your very detailed and useful commments!

I've updated the repository with your latest patch. I've done some more debugging and based on this I did a few more changes, to fix the code that determines the ACK SN (it did not cover properly the case where not all NACKs fitted in the STATUS), added more calls to SetModulusBase (I felt they were causing some strange behavior).

But after all this I was still experiencing the last behavior that you reported, i.e., that the sender and receiver can get stalled when no more new PDUs are to be transmitted. So far I have not been able to find how to handle this case in the standard. Anyway, it seems to me that the pre-existing code that sent PDUs from the "Transmitted buffer" (the code that we commented out as part of the NACK development) would handle this case. In fact, enabling it, all tests finally pass. I've enabled this code in the latest version in the repository.

About whether this solution is acceptable: in some sense, if the sender RLC instance receives some TxOpportunities when no new PDU is to be TXed, no NACKed PDU is pending retransmission, and no STATUS is to be sent, it could be acceptable that, rather than wasting the TX opportunity, some data from the Transmitted buffer is sent. With this respect, the test lte-rlc-am-e2e is a bit unrealistic in that it issues far more TxOpportunities than necessary, without considering the buffer status. So this procedure gets involved a lot of times; however, in a real system, the scheduler would only issue the TxOpportunities that are needed to send the amount of data indicated in the buffer status report.

Not that I like this "Send data from Transmission buffer" solution very much, but if that's the only one we have, I would eventually be fine with pushing it to the lena-dev repo, so that we can finally push the code for the RLC AM NACK support. So, does anyone have a better idea on this respect? Or any comment?

Regards,

Nicola

Brett Levasseur

unread,
Nov 4, 2013, 9:39:17 AM11/4/13
to ns-3-...@googlegroups.com
I took another look at the spec and I might have found something about the stalling behavior at the end of a transmission. In section 5.2.3 of 36.322 v8.8.0 it covers status reporting. At first it refers to status reports due to poll requests from the transmitter but then under NOTE 1 it says:

-     Detection of reception failure of an RLC data PDU:

      -  The receiving side of an AM RLC entity shall trigger a STATUS report when t-Reordering expires.

If I understand this correctly then I think it means that when t-Reordering expires if there is a missing RLC PDU then the receiver will send a Status report without needing to receive a poll request. If that is correct then we can probably fix this without the need of sending PDUs from the transmitted buffer. However if my interpretation of this part of the spec is incorrect and this does not fix this last issue then I think it would be better to push what is currently available for supporting NACKs. Could you check this part of the spec and let me know what you think it is referring to?

-Brett Levasseur

Dipak Ghosal

unread,
Nov 19, 2013, 2:28:01 AM11/19/13
to ns-3-...@googlegroups.com

Hi Brett,

I looked over this for a while and it is seems confusing. My understanding is that when t_Reordering expires,  the RX side will create  an STATUS PDU. For me the confusing part is that this action is not in the logic which describes when t_Reordering expires in section 5.1.3.2.4.   Intuitively, it makes sense otherwise  the sender may be stalled

Thanks.

Dipak

Dipak Ghosal

unread,
Nov 19, 2013, 2:39:48 AM11/19/13
to ns-3-...@googlegroups.com
Hi Nicola,

I have been away from this list the past three weeks and so I am behind catching up with all the dialogue.

In my opinion the problem of transmitting from the transmitted buffer is the following:

When something is transmitted from the transmitted buffer it automatically moved to the retransmission. Consequently, event if  data arrives before the next Tx opportunity, the data form the retransmitted buffer  is again transmitted before data from the transmission buffer.  This is not correct logic since the data has nit yet been acked or nacked.

Is there an issue if the Tx opportunity is just let go?

One novice question: To incorporate the current changest on lte-rlc-am, I should be working on the dev release, right?

Thanks.

Dipak

Nicola Baldo

unread,
Nov 22, 2013, 3:09:27 PM11/22/13
to ns-3-...@googlegroups.com


Hi all,

I agree with Brett that a STATUS PDU shall be sent when T_reordering expired. I've just pushed changeset 246fcc3690b8 which implements this, and also re-disables the "Send from transmitted buffer behavior".

Anyway, some test still fails for getting stalled at the end of the simulation when there is no more data to send. For example, in the lte-rlc-am-e2e test suite, the test case for (Losses = 10%, Run = 1111) fails with TX PDUs (1000) != RX PDUs (998). Please find attached a plot of the RLC AM RX state variables in this situation. Any suggestion on what could be the cause?



On Tuesday, November 19, 2013 8:39:48 AM UTC+1, Dipak Ghosal wrote:
In my opinion the problem of transmitting from the transmitted buffer is the following:

When something is transmitted from the transmitted buffer it automatically moved to the retransmission. Consequently, event if  data arrives before the next Tx opportunity, the data form the retransmitted buffer  is again transmitted before data from the transmission buffer.  This is not correct logic since the data has nit yet been acked or nacked.

It also depends on the policy for selecting packets from the retransmission buffer to be actually retransmitted.
By the way, I've looked at the current implementation of this aspect, and my understanding is that the PDU with VT(A) is always retransmitted. Maybe we should consider changing this?

 

Is there an issue if the Tx opportunity is just let go?

Well, it's a waste of radio resources that were already allocated, but other than this it should be ok. Anyway, the lte-rlc-am-e2e test is a bit artificial in this respect, as it uses pre-scheduled TX opportunities. Normally, the MAC scheduler would only assign TX opportunities if at least one of the RLC AM buffers (tx, retx, status) is non-empty.


 
One novice question: To incorporate the current changest on lte-rlc-am, I should be working on the dev release, right?


I am using a separate mercurial repository for this work-in-progress, here is the link:
http://code.nsnam.org/nbaldo/ns-3-lena-rlc-am-nack/
log-test-that-fails.png

Dipak Ghosal

unread,
Nov 27, 2013, 12:29:28 AM11/27/13
to ns-3-...@googlegroups.com
Hi Nicola, 

Thanks.  

By the way, is the AM supposed to guarantee that all errors will be corrected?Is it  a full fledged reliable protocol such as TCP? 
I am not sure of this. If that is not the case then the test is simply saying that 2 packets out of 100 was lost when the error rate is set to 10%. Which is correcting most of the error but not all.  Why would it be called Acknowledged Mode and not Reliable Mode? 

Anyway, I will look into it. 

1. I downloaded the relevant files lte-rlc-am.cc/h and lte-rlc-am-header.cc/h and  replaced the local copy and wafed it.  I am still learning the project tool. Is there an easier way tp do this? 

Thanks. 

Dipak  

Dipak Ghosal

unread,
Nov 27, 2013, 12:36:48 AM11/27/13
to ns-3-...@googlegroups.com
Correction:  2 out of 1000 were lost not 2 out of 100. 

Dipak 

Nicola Baldo

unread,
Nov 29, 2013, 6:38:19 AM11/29/13
to ns-3-...@googlegroups.com


On Wednesday, November 27, 2013 6:29:28 AM UTC+1, Dipak Ghosal wrote:

By the way, is the AM supposed to guarantee that all errors will be corrected?Is it  a full fledged reliable protocol such as TCP? 
I am not sure of this. If that is not the case then the test is simply saying that 2 packets out of 100 was lost when the error rate is set to 10%. Which is correcting most of the error but not all.  Why would it be called Acknowledged Mode and not Reliable Mode? 

RLC AM is error free except for when the SDU discard procedure is triggered. This test in particular is expected to be error free.
 

Anyway, I will look into it. 

1. I downloaded the relevant files lte-rlc-am.cc/h and lte-rlc-am-header.cc/h and  replaced the local copy and wafed it.  I am still learning the project tool. Is there an easier way tp do this? 

Yes definitely, the easier and recommended way is to use mercurial.
If you are not familiar with it, I recommend to check out one of the several mercurial tutorials available on the web.

Dipak Ghosal

unread,
Dec 1, 2013, 4:25:27 PM12/1/13
to ns-3-...@googlegroups.com
OK.   Thanks. I figure it out and have created a separate branch using mercurial to pull from the site you had mentioned. 

Yes, There are still errors. One error occurs when  the sequence number reaches 511. Since the window size is 512 and  the sequence number is range is 1024, it seems likely due to some wrap around problem.

Thanks. 

Dipak 

Brett Levasseur

unread,
Dec 2, 2013, 2:26:17 PM12/2/13
to ns-3-...@googlegroups.com
Hi Dipak and Nicola,

I am not sure why but when I run this test I get a different result. Instead of missing 2 out of 1000 PDUs I am only missing 1. I am not sure why I would be getting a different result then the two of you. I tried checking out a brand new copy of this branch to make sure I had no changes on my end but I still only get 1 PDU missing out of 1000.

In my case it looks like the 1 missing PDU is the last one sent. My sender makes the final PDU with SN = 917

10.095s AM RLC header: Len=4 D/C=1 RF=0 P=1 FI=0 E=0 SN=917 LSF=1 SO=0
10.095s Put transmitted PDU in the txedBuffer

This PDU is lost before it reaches the receiver. However since the receiver has gotten all of the other PDUs it does not know that there is one more that was not received. Since nothing is currently out of order there is no t-Reordering running to expire and force the receiver to send a status message that would alert the transmitter to re-send the last PDU.

From what I can tell the transmitter is supposed to use the t-PollRetransmit timer to take care of this situation. Specifically in 3GPP TS 36.322 version 8.8.0 section 5.2.1 indicates that this timer should be running. In my test simulation run this timer does expire so that part appears working:
 
10.195s LteRlcAm:ExpirePollRetransmitTimer(0x2482be0)
10.195s PollRetransmit Timer has expired
10.195s txonBufferSize = 0
10.195s retxBufferSize = 0
10.195s txedBufferSize = 106
10.195s statusPduRequested = 0
10.195s LteRlcAm:DoReportBufferStatus(0x2482be0)
10.195s txonBufferSize = 0
10.195s retxBufferSize = 0
10.195s txedBufferSize = 106
10.195s VT(A) = 917
10.195s VT(S) = 918
10.195s Send ReportBufferStatus: 0, 0, 106, 0, 0

However while the timer expires nothing seems to happen. According to section 5.2.2.3 when this timer expires if the window is stalled because there is nothing in the transmission or retransmission buffer to send then, "consider the AMD PDU with SN=VT(S) - 1 for retransmission". Currently VT(S) = 918 so SN = 917, (which is the PDU that went missing) should be considered for retransmission. I checked the code and it looks like the method ExpirePollRetransmitTimer currently logs information and calls the method DoReportBufferStatus.

I edited the ExpirePollRetransmitTimer method so it would check to see if the transmission and retransmission buffer are empty and if there is a packet in the transmitted buffer at VT(S) -1 and if the value of VT(A) is equal to VT(S) - 1 (I did this to avoid an error where a transmission attempts to retransmit SN VT(A) but VT(S) -1 was not VT(A)). If that is all true then I move the packet VT(S) -1 from the transmitted to the retransmission buffer. After I made this change and re-ran the tests and I got past the point where I failed before.

However after that change I did come up on a test where I only got 998 PDUs out of 1000. I assume this is the test that the two of you are also at. I am not sure why we are seeing different results. Before I made my change to ExpirePollRetransmitTimer my test ended with the following report:

FAIL lte-rlc-am-e2e 45.620 s
  PASS  Losses = 0%. Run = 1111 3.210 s
  PASS  Losses = 0%. Run = 2222 3.070 s
  PASS  Losses = 0%. Run = 3333 3.060 s
  PASS  Losses = 0%. Run = 4444 3.070 s
  PASS  Losses = 0%. Run = 5555 3.070 s
  PASS  Losses = 0%. Run = 6666 3.060 s
  PASS  Losses = 0%. Run = 7777 3.060 s
  PASS  Losses = 0%. Run = 8888 3.060 s
  PASS  Losses = 0%. Run = 9999 3.050 s
  PASS  Losses = 0%. Run = 10101 3.060 s
  PASS  Losses = 10%. Run = 1111 4.520 s
  PASS  Losses = 10%. Run = 2222 3.440 s
  PASS  Losses = 10%. Run = 3333 3.500 s
  FAIL  Losses = 10%. Run = 4444 3.390 s
      got="txEnbRrcPdus (actual) == rxUeRrcPdus (limit)" expected="1000" in="../src/lte/test/lte-test-rlc-am-e2e.cc:222" TX PDUs (1000) != RX PDUs (999)

After my change to the poll timer my output is the following:

FAIL lte-rlc-am-e2e 125.900 s
  PASS  Losses = 0%. Run = 1111 4.590 s
  PASS  Losses = 0%. Run = 2222 4.480 s
  PASS  Losses = 0%. Run = 3333 8.300 s
  PASS  Losses = 0%. Run = 4444 7.080 s
  PASS  Losses = 0%. Run = 5555 6.880 s
  PASS  Losses = 0%. Run = 6666 8.990 s
  PASS  Losses = 0%. Run = 7777 7.150 s
  PASS  Losses = 0%. Run = 8888 6.840 s
  PASS  Losses = 0%. Run = 9999 7.140 s
  PASS  Losses = 0%. Run = 10101 7.470 s
  PASS  Losses = 10%. Run = 1111 14.800 s
  PASS  Losses = 10%. Run = 2222 8.030 s
  PASS  Losses = 10%. Run = 3333 8.170 s
  PASS  Losses = 10%. Run = 4444 8.350 s
  PASS  Losses = 10%. Run = 5555 9.580 s
  FAIL  Losses = 10%. Run = 6666 8.050 s
      got="txEnbRrcPdus (actual) == rxUeRrcPdus (limit)" expected="1000" in="../src/lte/test/lte-test-rlc-am-e2e.cc:222" TX PDUs (1000) != RX PDUs (998)

So now I have a test that fails with two missing PDUs but this is not the same as what Dipack describes. For me this test is also failing because of the t-PollRetransmit timer. In this case there are two packets missing at the end and since my first pass to modify the code only considered VT(S) - 1 for retransmission I get this test failure. Specifically I have VT(A) == 909 and VT(S) = 911 and since VT(S) - 1 is not VT(A) my code does not move any of the PDUs into the retransmission buffer.

Now section 5.2.2.3 says that other PDUs not acknowledged could be considered for retransmission other than just VT(S) - 1. So I modified my code again so that when t-PollRetransmit expires and the transmission and retransmission buffers are empty then all PDUs from VT(A) to VT(S) - 1 are moved from the transmitted to the retransmission buffer. After I made this change I ran the test again and this time I get further along before a test failed with only 997 PDUs received out of 1000.

FAIL lte-rlc-am-e2e 300.670 s
  PASS  Losses = 0%. Run = 1111 7.680 s
  PASS  Losses = 0%. Run = 2222 7.810 s
  PASS  Losses = 0%. Run = 3333 6.700 s
  PASS  Losses = 0%. Run = 4444 7.110 s
  PASS  Losses = 0%. Run = 5555 6.850 s
  PASS  Losses = 0%. Run = 6666 6.900 s
  PASS  Losses = 0%. Run = 7777 7.180 s
  PASS  Losses = 0%. Run = 8888 6.680 s
  PASS  Losses = 0%. Run = 9999 7.380 s
  PASS  Losses = 0%. Run = 10101 7.150 s
  PASS  Losses = 10%. Run = 1111 7.580 s
  PASS  Losses = 10%. Run = 2222 7.940 s
  PASS  Losses = 10%. Run = 3333 8.320 s
  PASS  Losses = 10%. Run = 4444 6.910 s
  PASS  Losses = 10%. Run = 5555 7.160 s
  PASS  Losses = 10%. Run = 6666 7.220 s
  PASS  Losses = 10%. Run = 7777 7.880 s
  PASS  Losses = 10%. Run = 8888 8.110 s
  PASS  Losses = 10%. Run = 9999 8.190 s
  PASS  Losses = 10%. Run = 10101 8.040 s
  PASS  Losses = 25%. Run = 1111 8.860 s
  PASS  Losses = 25%. Run = 2222 9.110 s
  PASS  Losses = 25%. Run = 3333 9.290 s
  PASS  Losses = 25%. Run = 4444 8.500 s
  PASS  Losses = 25%. Run = 5555 10.780 s
  PASS  Losses = 25%. Run = 6666 15.710 s
  PASS  Losses = 25%. Run = 7777 9.060 s
  PASS  Losses = 25%. Run = 8888 8.520 s
  PASS  Losses = 25%. Run = 9999 12.700 s
  PASS  Losses = 25%. Run = 10101 5.410 s
  PASS  Losses = 50%. Run = 1111 6.340 s
  PASS  Losses = 50%. Run = 2222 6.440 s
  PASS  Losses = 50%. Run = 3333 5.280 s
  PASS  Losses = 50%. Run = 4444 12.760 s
  PASS  Losses = 50%. Run = 5555 10.120 s
  FAIL  Losses = 50%. Run = 6666 12.990 s
      got="txEnbRrcPdus (actual) == rxUeRrcPdus (limit)" expected="1000" in="../src/lte/test/lte-test-rlc-am-e2e.cc:222" TX PDUs (1000) != RX PDUs (997)

Again in this case the problem is that the 3 PDUs not received are the last ones transmitted. In this case  the poll retransmit timer was running while these 3 PDUs were in the transmitted buffer. However there was also a PDU in the retransmission buffer so nothing was moved. At the next transmission opportunity the PDU in the retransmission buffer was sent and an ACK was received for it but the final 3 PDUs are still sitting in the transmitted buffer. It looks like the t-PollRetransmit timer was not reset so it never expires and the final 3 PDUs are never moved to the retransmission buffer.

Looking at the code it looks like the t-PollRetransmit timer is set towards the bottom of the method DoNotifyTxOpportunity, however if there is something in the retransmission buffer (as there is in this test) then the method exits after re-sending the PDU in the retransmission buffer and the code that sets the t-PollRetransmit timer is never called.

So as a summary all of the problems I found are due to PDUs sitting in the transmitted buffer that are lost at the end of the communication. I tried adding code to the ExpirePollRetransmission method to moved PDUs into the retransmission buffer as suggested by section 5.2.2.3 of 36.322 (though I think there could be other interpretations of which PDUs should be moved). This fixed some of the issues but currently there is a problem where t-PollRetransmit is not set. I am not sure if this is a bug in the simulation code in setting t-PollRetransmit or if the code is correct and there is something up with the spec. Either way I have some other things to get done today so this is as far as I can go for now. Let me know what you think. I will try to look into this again soon. Following I have the mercurial diff of the changes I made:

diff -r 246fcc3690b8 src/lte/model/lte-rlc-am.cc
--- a/src/lte/model/lte-rlc-am.cc       Fri Nov 22 20:33:30 2013 +0100
+++ b/src/lte/model/lte-rlc-am.cc       Mon Dec 02 14:18:23 2013 -0500
@@ -1727,6 +1727,27 @@
   NS_LOG_LOGIC ("statusPduRequested = " << m_statusPduRequested);

   DoReportBufferStatus ();
+
+
+  if ( m_txonBufferSize == 0 && m_retxBufferSize == 0 )
+    {
+      NS_LOG_INFO ("txonBuffer and retxBuffer empty. Move PDUs up to = " << m_vtS.GetValue () - 1 << " to retxBuffer");
+      uint16_t sn = 0;
+      for ( sn = m_vtA.GetValue(); sn < m_vtS.GetValue (); sn++ )
+        {
+           bool pduAvailable = m_txedBuffer[ sn ]->GetSize () > 0;
+
+           if ( pduAvailable )
+             {
+               m_retxBuffer.at (sn).m_pdu = m_txedBuffer.at (sn)->Copy ();
+               m_retxBuffer.at (sn).m_retxCount = 0;
+               m_retxBufferSize += m_retxBuffer.at (sn).m_pdu->GetSize ();
+
+               m_txedBufferSize -= m_txedBuffer.at (sn)->GetSize ();
+               m_txedBuffer.at (sn) = 0;
+             }
+        }
+    }
 }


-Brett Levasseur

Dipak Ghosal

unread,
Dec 9, 2013, 4:26:58 PM12/9/13
to ns-3-...@googlegroups.com
Hi Brett,

Thank you for you thorough debugging. i am not sure why our results were different. However, if I incorporate your changes, it does go further along in the test as you said but there is only one PDU sitting in the end. Here is the output:


FAIL: Test Suite "lte-rlc-am-e2e" (4.770)
PASS: Test Suite " Losses = 0%. Run = 1111" (0.190)
PASS: Test Suite " Losses = 0%. Run = 2222" (0.130)
PASS: Test Suite " Losses = 0%. Run = 3333" (0.120)
PASS: Test Suite " Losses = 0%. Run = 4444" (0.130)
PASS: Test Suite " Losses = 0%. Run = 5555" (0.130)
PASS: Test Suite " Losses = 0%. Run = 6666" (0.120)
PASS: Test Suite " Losses = 0%. Run = 7777" (0.130)
PASS: Test Suite " Losses = 0%. Run = 8888" (0.130)
PASS: Test Suite " Losses = 0%. Run = 9999" (0.120)
PASS: Test Suite " Losses = 0%. Run = 10101" (0.130)
PASS: Test Suite " Losses = 10%. Run = 1111" (0.140)
PASS: Test Suite " Losses = 10%. Run = 2222" (0.140)
PASS: Test Suite " Losses = 10%. Run = 3333" (0.150)
PASS: Test Suite " Losses = 10%. Run = 4444" (0.130)
PASS: Test Suite " Losses = 10%. Run = 5555" (0.140)
PASS: Test Suite " Losses = 10%. Run = 6666" (0.140)
PASS: Test Suite " Losses = 10%. Run = 7777" (0.140)
PASS: Test Suite " Losses = 10%. Run = 8888" (0.140)
PASS: Test Suite " Losses = 10%. Run = 9999" (0.150)
PASS: Test Suite " Losses = 10%. Run = 10101" (0.140)
PASS: Test Suite " Losses = 25%. Run = 1111" (0.160)
PASS: Test Suite " Losses = 25%. Run = 2222" (0.180)
PASS: Test Suite " Losses = 25%. Run = 3333" (0.170)
PASS: Test Suite " Losses = 25%. Run = 4444" (0.160)
PASS: Test Suite " Losses = 25%. Run = 5555" (0.160)
PASS: Test Suite " Losses = 25%. Run = 6666" (0.160)
PASS: Test Suite " Losses = 25%. Run = 7777" (0.170)
PASS: Test Suite " Losses = 25%. Run = 8888" (0.160)
PASS: Test Suite " Losses = 25%. Run = 9999" (0.170)
PASS: Test Suite " Losses = 25%. Run = 10101" (0.160)
PASS: Test Suite " Losses = 50%. Run = 1111" (0.190)
FAIL: Test Suite " Losses = 50%. Run = 2222" (0.190)
    Details:
      Message:   TX PDUs (1000) != RX PDUs (999)
      Condition: txEnbRrcPdus (actual) == rxUeRrcPdus (limit)
      Actual:    1000
      Limit:     999
      File:      ../src/lte/test/lte-test-rlc-am-e2e.cc
      Line:      222

I am not yet sure, why the results are different.  I will look through the poll-retransmittimer part  in the standard  later today.


Thanks.

Dipak

Dipak Ghosal

unread,
Dec 10, 2013, 7:21:47 PM12/10/13
to ns-3-...@googlegroups.com
Hi Brett and Nicola,

I am still trying to figure out the issue with the poll-retransmit-timer, but there is definitely an error with the status prohibit timer.  The issue is that when the timer  expires nothing is done. If the timer is on and data arrives from pdcp layer, then the rlc entity will not report  the buffer status to the MAC layer and hence get no transmit opportunity. It will come out of this state only when new data arrives. My understanding is that when this timer expires, it should report buffer status to the MAC layer.

I have been trying to debug the code using a single TCP flow and I was getting very low throughout. WHat was happening is that, the UE which is sending back ACK would in some cases stall, the ACK would arrive in  TXbuffer  when the timer is on, so no buffer status would be reported and nothing would be done when timer expires.  The sender would timeout and resend the packet which would release the UE from this state.

With this change, I get close to the ideal throughput with when the UE is placed close to the eNB.

The extensive test however still fails for 50% error as below.

FAIL: Test Suite "lte-rlc-am-e2e" (7.750)
PASS: Test Suite " Losses = 0%. Run = 1111" (0.270)
PASS: Test Suite " Losses = 0%. Run = 2222" (0.170)
PASS: Test Suite " Losses = 0%. Run = 3333" (0.170)
PASS: Test Suite " Losses = 0%. Run = 4444" (0.180)
PASS: Test Suite " Losses = 0%. Run = 5555" (0.160)
PASS: Test Suite " Losses = 0%. Run = 6666" (0.160)
PASS: Test Suite " Losses = 0%. Run = 7777" (0.190)
PASS: Test Suite " Losses = 0%. Run = 8888" (0.170)
PASS: Test Suite " Losses = 0%. Run = 9999" (0.160)
PASS: Test Suite " Losses = 0%. Run = 10101" (0.190)
PASS: Test Suite " Losses = 10%. Run = 1111" (0.180)
PASS: Test Suite " Losses = 10%. Run = 2222" (0.180)
PASS: Test Suite " Losses = 10%. Run = 3333" (0.200)
PASS: Test Suite " Losses = 10%. Run = 4444" (0.180)
PASS: Test Suite " Losses = 10%. Run = 5555" (0.180)
PASS: Test Suite " Losses = 10%. Run = 6666" (0.200)
PASS: Test Suite " Losses = 10%. Run = 7777" (0.180)
PASS: Test Suite " Losses = 10%. Run = 8888" (0.210)
PASS: Test Suite " Losses = 10%. Run = 9999" (0.170)
PASS: Test Suite " Losses = 10%. Run = 10101" (0.190)
PASS: Test Suite " Losses = 25%. Run = 1111" (0.420)
PASS: Test Suite " Losses = 25%. Run = 2222" (0.360)
PASS: Test Suite " Losses = 25%. Run = 3333" (0.210)
PASS: Test Suite " Losses = 25%. Run = 4444" (0.220)
PASS: Test Suite " Losses = 25%. Run = 5555" (0.210)
PASS: Test Suite " Losses = 25%. Run = 6666" (0.230)
PASS: Test Suite " Losses = 25%. Run = 7777" (0.210)
PASS: Test Suite " Losses = 25%. Run = 8888" (0.220)
PASS: Test Suite " Losses = 25%. Run = 9999" (0.210)
PASS: Test Suite " Losses = 25%. Run = 10101" (0.210)
PASS: Test Suite " Losses = 50%. Run = 1111" (0.270)
PASS: Test Suite " Losses = 50%. Run = 2222" (0.250)
PASS: Test Suite " Losses = 50%. Run = 3333" (0.270)
PASS: Test Suite " Losses = 50%. Run = 4444" (0.250)
PASS: Test Suite " Losses = 50%. Run = 5555" (0.260)
FAIL: Test Suite " Losses = 50%. Run = 6666" (0.260)
    Details:
      Message:   TX PDUs (1000) != RX PDUs (997)
      Condition: txEnbRrcPdus (actual) == rxUeRrcPdus (limit)
      Actual:    1000
      Limit:     997
      File:      ../src/lte/test/lte-test-rlc-am-e2e.cc
      Line:      222



Thanks.

Dipak

On Monday, December 2, 2013 11:26:17 AM UTC-8, Brett Levasseur wrote:

Nicola Baldo

unread,
Dec 11, 2013, 7:41:06 AM12/11/13
to ns-3-...@googlegroups.com


Hi Brett, Dipak,

thanks for the investigation and explanations. I agree with Brett's latest modifications to LteRlcAm::ExpirePollRetransmitTimer(), so I incorporated them in the repository.

I investigated the issue about t-PollRetransmit not being set. I found that not only the time was not set upon retransmission, but also the polling bit was not set in this case (the headers of the previously transmitted PDU were just copied). This is now fixed as well, and available in the repository.

I additionally fixed some other things:

- changed the retransmission policy: before, only the PDU with VT(A) was (repeatedly) retransmitted, whereas now PDUs are moved back and forth the txed/retx buffer as they are retransmitted/NACKed. I think this is more in line with the specs (allows a clear distintion between PDUs that are NACKed and PDUs for which an ACK is pending (transmitted or retransmitted);

- fixed the detection for duplicated PDU segments which was not working properly

- added a Report Buffer Status timer (see Bug 1438 on bugzilla)

- changed the LteTestMac to AUTOMATIC_MODE for the lte-rlc-am-e2e test, so that we are testing with a more realistic TxOpportunity behavior (a few modifications to LteTestMac were needed)


All the above is included in the repository. Now the current test results are these:

FAIL lte-rlc-am-e2e 61.140 s
  PASS  Losses = 0%. Run = 1111 0.140 s
  PASS  Losses = 0%. Run = 2222 0.120 s
  PASS  Losses = 0%. Run = 3333 0.100 s
  PASS  Losses = 0%. Run = 4444 0.110 s
  PASS  Losses = 0%. Run = 5555 0.120 s
  PASS  Losses = 0%. Run = 6666 0.110 s
  PASS  Losses = 0%. Run = 7777 0.110 s
  PASS  Losses = 0%. Run = 8888 0.110 s
  PASS  Losses = 0%. Run = 9999 0.100 s
  PASS  Losses = 0%. Run = 10101 0.110 s
  PASS  Losses = 10%. Run = 1111 0.110 s
  PASS  Losses = 10%. Run = 2222 0.120 s
  PASS  Losses = 10%. Run = 3333 0.130 s
  PASS  Losses = 10%. Run = 4444 0.120 s
  PASS  Losses = 10%. Run = 5555 0.120 s
  PASS  Losses = 10%. Run = 6666 0.120 s
  PASS  Losses = 10%. Run = 7777 0.110 s
  PASS  Losses = 10%. Run = 8888 0.120 s
  PASS  Losses = 10%. Run = 9999 0.110 s
  PASS  Losses = 10%. Run = 10101 0.120 s
  PASS  Losses = 25%. Run = 1111 0.130 s
  PASS  Losses = 25%. Run = 2222 0.120 s
  PASS  Losses = 25%. Run = 3333 0.130 s
  PASS  Losses = 25%. Run = 4444 0.130 s
  PASS  Losses = 25%. Run = 5555 0.160 s
  PASS  Losses = 25%. Run = 6666 0.130 s
  PASS  Losses = 25%. Run = 7777 0.130 s
  PASS  Losses = 25%. Run = 8888 0.130 s
  PASS  Losses = 25%. Run = 9999 0.130 s
  PASS  Losses = 25%. Run = 10101 0.130 s
  PASS  Losses = 50%. Run = 1111 0.150 s
  PASS  Losses = 50%. Run = 2222 0.150 s
  PASS  Losses = 50%. Run = 3333 0.150 s
  PASS  Losses = 50%. Run = 4444 0.140 s
  PASS  Losses = 50%. Run = 5555 0.160 s
  PASS  Losses = 50%. Run = 6666 0.140 s
  PASS  Losses = 50%. Run = 7777 0.150 s
  PASS  Losses = 50%. Run = 8888 0.150 s
  PASS  Losses = 50%. Run = 9999 0.150 s
  PASS  Losses = 50%. Run = 10101 0.150 s
  PASS  Losses = 75%. Run = 1111 0.270 s
  PASS  Losses = 75%. Run = 2222 0.280 s
  PASS  Losses = 75%. Run = 3333 0.330 s
  PASS  Losses = 75%. Run = 4444 0.230 s
  PASS  Losses = 75%. Run = 5555 0.300 s
  PASS  Losses = 75%. Run = 6666 0.350 s
  PASS  Losses = 75%. Run = 7777 0.300 s
  PASS  Losses = 75%. Run = 8888 0.280 s
  PASS  Losses = 75%. Run = 9999 0.340 s
  PASS  Losses = 75%. Run = 10101 0.290 s
  PASS  Losses = 90%. Run = 1111 2.670 s
  PASS  Losses = 90%. Run = 2222 2.560 s
  PASS  Losses = 90%. Run = 3333 2.590 s
  PASS  Losses = 90%. Run = 4444 2.510 s
  PASS  Losses = 90%. Run = 5555 2.740 s
  PASS  Losses = 90%. Run = 6666 2.380 s
  PASS  Losses = 90%. Run = 7777 2.480 s
  PASS  Losses = 90%. Run = 8888 2.560 s
  PASS  Losses = 90%. Run = 9999 2.470 s
  PASS  Losses = 90%. Run = 10101 2.140 s
  PASS  Losses = 95%. Run = 1111 6.350 s
  PASS  Losses = 95%. Run = 2222 6.540 s
  PASS  Losses = 95%. Run = 3333 7.510 s
  FAIL  Losses = 95%. Run = 4444 7.550 s
      got="txEnbRrcPdus (actual) == rxUeRrcPdus (limit)" expected="1000" in="../src/lte/test/lte-test-rlc-am-e2e.cc:222" TX PDUs (1000) != RX PDUs (415)
Command ['/locale/ns-3-lena-rlc-am-nack/build/utils/ns3-dev-test-runner-debug', '--suite=lte-rlc-am-e2e', '--verbose', '--fullness=EXTENSIVE'] exited with code 1


so it's an improvement (it works correctly up to very high error rates), however something is still not working correctly. Any hint?


Regards,

Nicola

Dipak Ghosal

unread,
Dec 11, 2013, 7:29:49 PM12/11/13
to ns-3-...@googlegroups.com
Hi Nicola, 

Looks like it is almost there  but not quite :) 

Is the  Report Buffer Status timer part of the standard?  I do not see it in 3GPP TS 36.322 version 10.0.0 Release 10. Perhaps I am looking at the wrong version. 

I looked at Bug 1438. My understanding is that it can be solved by forcing a DoBufferStatusReport()  when the StatusProhibit timer expires.  I think the standard is somewhat confusing "at the first transmission opportunity indicated by lower layer after t-StatusProhibit expires, construct a single STATUS PDU even if status reporting was triggered several times while t-StatusProhibit was running and deliver it to lower layer." 

Thanks. 

Dipak 

Dipak Ghosal

unread,
Dec 17, 2013, 7:15:55 PM12/17/13
to ns-3-...@googlegroups.com
Hi Nicola and Brett,

When a new pdu is addded in to the rxbuffer, no check is made to see if it a duplicate. If we discard duplicates, then I donot get the error on my own test (I am unable to run the new version of of lte-rlc-am-e2e test. I get errors, that I have not yet had time to look into). I have attached the hg diff of the proposed changes. The second change is forcing a bufferreportstatus when statusprohibittimer expires.  Can you please check if this passes the lte-rlc-am-e2e test?

Thanks.

Dipak
diff.txt

Dipak Ghosal

unread,
Dec 20, 2013, 12:04:06 PM12/20/13
to ns-3-...@googlegroups.com
Hi Nicola and Brett, 

In the current implementation of RLC AM, the data from the retransmission queue is not segmented. While this not what the standard specifies, this by itself may not be so bad. What is not good, is that the transmitter forgoes the transmission opportunity even if there is data in the transmission buffer. Consequently, the performance of RLC AM is even worse than RLC UM in high interference scenario which is particularly the scenario where local recovery using AM should be helping. 

Ideally, one should re-fragment, if required, from the re-transmission buffer but this likely to make the reassembly quite complex. I suggest that we  first at least implement using the transmission opportunity to send data from the transmission buffer if it is not empty. 

I wanted to know if there is already any effort to do this. 

Thanks. 

Dipak 

Brett Levasseur

unread,
Feb 5, 2014, 9:21:09 AM2/5/14
to ns-3-...@googlegroups.com
Dipack and Nicola,

Sorry I have been away from this for so long. Ending last academic semester and starting the current one took a lot of my time.

I tried running the lte-rlc-am-e2e test and saw the problem over duplicate PDUs in the rxbuffer that Dipcak described. I then tried Dipack's change for LteRlcAm.cc and that fixed the problem. I did not see any other problems while running the test though. For me the test lte-rlc-am-e2d comes back as passing so I am not sure what other errors you were seeing Dipak. Nicola, with Dipack's changes are you seeing this test pass as well?

-Brett Levasseur

Dipak Ghosal

unread,
Feb 7, 2014, 5:23:58 PM2/7/14
to ns-3-...@googlegroups.com
Hi Brett, 

Good to hear from you.  Everything  works now. The issue is that the code does not quite follow the standard and I think because of that the performance of of AM is only marginally better than UM (for end-to-end TCP flows). 

I think the code needs some amount of rework.  If you have sometime, we can talk and work on it together. 

Thanks. 

Dipak 

ghufran siddiqui

unread,
Feb 7, 2014, 6:57:59 PM2/7/14
to ns-3-...@googlegroups.com
I need some error while adding a new module to NS3, I am recieving error failed to find header files when i use $ ./waf and when I use ./waf configure I get Could not find a task generator for the name 'ns3-gppon


On Wednesday, September 4, 2013 4:02:03 AM UTC+5, Koray Kokten wrote:
Hey,
For a simple comparison purpose of a TCP application under RLC_UM and RLC_AM modes in LTE, I have written the sample script which is a kind of the combination of lena-simple-epc.cc and sixth.cc. However, when I check the .pcap file generated by ns-3 in the RL_AM mode scenario, I see a weird situation that a couple of seconds later, the TCP traffic is cut by the TCP stack, despite the application last until the end of the simulation (Sim. duration is 50 sec). On the other hand I don't see such a weird behavior  in RLC_UM mode. I can see TCP Flows between server and client (where client is the UE Device) until the end of the simulation. For examining what is going wrong with RLC_AM mode, I have included some additional packet based RLC tracing system into the source code, and I see that right after the sequence number variable of the LteRlcAm class overflows for the first time (I mean the Sequence number values in RLC PDUs are modulo 1024), the RLC_AM Mode peer at the ENB side starts sending the same PDU from the re-transmission buffer over and over again until the end of the sim. So is it about a bug in RLC_AM mode of LTE Module or am I doing something wrong?
Thanks in advance.
PS: The sample script file is attached to the e-mail.
  Koray
 

Brett Levasseur

unread,
Feb 10, 2014, 2:38:45 PM2/10/14
to ns-3-...@googlegroups.com
Dipak,

Could you elaborate on where the code currently does not follow the standard. The initial issue I was considered with was getting NACKs implemented so I have not looked much farther into the RLC code than just that.

-Brett

Dipak Ghosal

unread,
Feb 11, 2014, 7:21:50 PM2/11/14
to ns-3-...@googlegroups.com
Hi Brett,

I think one of the important one is the following:

suppose  the transmitter transmits amd pdu(i) which has a size s. Suppose the pdu is is lost and NACK is received. The amd pdu(i) is placed in the retransmission buffer. Now suppose the next transmission opportunity is less than s. Then in the simulation, the transmission opportunity is let go and the transmitter waits for transmission opportunity greater than equal to s. According to the standard, pdu in the retransmission buffer could also be segmented just like it is done from the transmission buffer. 

In high interference scenario, where  the size of the transmission opportunity may vary a lot, this results  in further waste of capacity resulting in lower throughput.


Does this makes sense?

I did not get much time the past few weeks, but  I was trying to figure out the the best way to implement this.  Let me know if you have any thoughts on this.


Dipak

Brett Levasseur

unread,
Feb 14, 2014, 2:33:10 PM2/14/14
to ns-3-...@googlegroups.com

Dipak,

I see what you are saying and I agree. The RLC spec does say that the PDU gets re-segmented so that a portion of it can be sent during that transmission opportunity. To get this to work the code needs to be changed to allow the segmentation to happen. Also the code for setting up the ACK/NACK in the status message would need to change so it would support the SOstart and SOend fields to indicate NACKs of specific portions of PDUs. At the moment I am working on finishing my thesis so I am not sure how much time I have to make further changes to the code. However I would be happy to do what I can.

I can see in the RLC code that there are some references to FIRST_SEGMENT, MIDDLE_SEGMENT and LAST_SEGMENT for sending data from the transmission buffer. Is this segmentation already working for the transmission buffer and just needs to be added to the retransmission buffer?

-Brett Levasseur

Dipak Ghosal

unread,
Feb 15, 2014, 4:01:54 PM2/15/14
to ns-3-...@googlegroups.com
Brett, 

I am completely swamped with teaching a large class this quarter but  I will try to find some time to work on this. 

1. Yes, the existing code already segments data from  the TxOn buffer. I was thinking that we could reuse  that code.  I need to read that code to make sure that it is indeed possible
2.  You are right that the NACK has to be changed to indicate the amd pdu portion that is being acked/nacked. 

I will go through it end of next week  and send you  a more detailed message. 

Dipak 

Carlos Bello

unread,
Mar 13, 2014, 11:25:53 AM3/13/14
to ns-3-...@googlegroups.com
Hi All,

I am trying to test RLC_AM against RLC_UM. I started with NS-3.17, but also tested with NS-3.18 and NS-3.19. I am using lena.simple.epc script as reference. Bellow you can see the main attributes:

Parameter

Value

Number of RB

RB = 25

Antenna mode

 SISO

RLC mode

 UM or AM

Error mode of control

 Deactivate

Error mode of data

 Deactivate

HARQ

 Enabled

MAC Scheduler

Proportional Fair

MSS

536 bytes

TCP

Westwood Plus, Tahoe, New Reno, Reno

Simulation time

60s


The throughput results showed always RLC_UM (~16Mbps) better than RLC_AM (~10Mbps) without errors for all TCP types.

If this is a Issue should I solve it with a  patch? Can you please help?


Best Regards,

Carlos





  PASS&nbsp
...

William Diego

unread,
May 5, 2014, 5:32:12 AM5/5/14
to ns-3-...@googlegroups.com
Hi All,

There are anyone who is working in solution for RLC_AM? 

Regards

William



Dipak Ghosal

unread,
May 15, 2014, 1:23:53 PM5/15/14
to ns-3-...@googlegroups.com
I have a version of RLC_AM that is somewhat accurate. You can download the  patches  from previous posting in the discussion thread. 

There are still some known issues with the current version.  I am still trying to understand the code and learn the structure to make changes. Mostly, I haven't had time. 

If you are interested in fixing it I am happy to work with you. 

Thanks. 

Dipak 

Dipak Ghosal

unread,
May 15, 2014, 1:39:01 PM5/15/14
to ns-3-...@googlegroups.com
If you follow the discussion thread then you can download  the changes that will partly fix the problem with RLC_AM. With the modifications you will get RLC_AM throughputs which are at least at par with that of RLC_UM.  I have tried with TCP New_Reno and it seems to work fine. 

However, there are still known problems which makes the performance only marginally better. I think because of errors in the transmission logic, the delays become very large which cause loss of application layer throughput. Unfortunately, my lack of programming skills, my (still) limited understanding of the structure of the code and finally time  are major impediments to create a cleaner version of the RLC_AM code. I will try to work on it over the summer. 

Thank you. 

Dipak 

senthil kumar

unread,
Dec 26, 2014, 2:46:47 AM12/26/14
to ns-3-...@googlegroups.com
Hai Koray Kokten ,

           i tried to run your code but i got these type of error...also i got some pcap files..so can you help me to solve?

i will post error here..


[2048/2406] cxx: scratch/epc-sixth.cc -> build/scratch/epc-sixth.cc.9.o
In file included from ./ns3/object-factory.h:24:0,
                 from ./ns3/simulator.h:30,
                 from ./ns3/lte-helper.h:25,
                 from ../scratch/epc-sixth.cc:21:
./ns3/object.h: In instantiation of ‘ns3::Ptr<T> ns3::CreateObject() [with T = ns3::EpcHelper]’:
../scratch/epc-sixth.cc:180:56:   required from here
./ns3/object.h:423:37: error: cannot allocate an object of abstract type ‘ns3::EpcHelper’
   return CompleteConstruct (new T ());
                                     ^
In file included from ../scratch/epc-sixth.cc:22:0:
./ns3/epc-helper.h:48:7: note:   because the following virtual functions are pure within ‘ns3::EpcHelper’:
 class EpcHelper : public Object
       ^
./ns3/epc-helper.h:75:16: note: virtual void ns3::EpcHelper::AddEnb(ns3::Ptr<ns3::Node>, ns3::Ptr<ns3::NetDevice>, uint16_t)
   virtual void AddEnb (Ptr<Node> enbNode, Ptr<NetDevice> lteEnbNetDevice, uint16_t cellId) = 0;
                ^
./ns3/epc-helper.h:83:16: note: virtual void ns3::EpcHelper::AddUe(ns3::Ptr<ns3::NetDevice>, uint64_t)
   virtual void AddUe (Ptr<NetDevice> ueLteDevice, uint64_t imsi) = 0;
                ^
./ns3/epc-helper.h:91:16: note: virtual void ns3::EpcHelper::AddX2Interface(ns3::Ptr<ns3::Node>, ns3::Ptr<ns3::Node>)
   virtual void AddX2Interface (Ptr<Node> enbNode1, Ptr<Node> enbNode2) = 0;
                ^
./ns3/epc-helper.h:104:16: note: virtual void ns3::EpcHelper::ActivateEpsBearer(ns3::Ptr<ns3::NetDevice>, uint64_t, ns3::Ptr<ns3::EpcTft>, ns3::EpsBearer)
   virtual void ActivateEpsBearer (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<EpcTft> tft, EpsBearer bearer) = 0;
                ^
./ns3/epc-helper.h:115:21: note: virtual ns3::Ptr<ns3::Node> ns3::EpcHelper::GetPgwNode()
   virtual Ptr<Node> GetPgwNode () = 0;
                     ^
./ns3/epc-helper.h:124:34: note: virtual ns3::Ipv4InterfaceContainer ns3::EpcHelper::AssignUeIpv4Address(ns3::NetDeviceContainer)
   virtual Ipv4InterfaceContainer AssignUeIpv4Address (NetDeviceContainer ueDevices) = 0;
                                  ^
./ns3/epc-helper.h:131:23: note: virtual ns3::Ipv4Address ns3::EpcHelper::GetUeDefaultGatewayAddress()
   virtual Ipv4Address GetUeDefaultGatewayAddress () = 0;
                       ^
In file included from ./ns3/object-factory.h:24:0,
                 from ./ns3/simulator.h:30,
                 from ./ns3/lte-helper.h:25,
                 from ../scratch/epc-sixth.cc:21:
./ns3/object.h: In function ‘ns3::Ptr<T> ns3::CreateObject() [with T = ns3::EpcHelper]’:
./ns3/object.h:424:1: error: control reaches end of non-void function [-Werror=return-type]
 }
 ^
cc1plus: all warnings being treated as errors
Waf: Leaving directory `/home/senthil/ns3/ns-allinone-3.21/ns-3.21/build'
Build failed
 -> task in 'epc-sixth' failed (exit status 1): 
{task 140219627618128: cxx epc-sixth.cc -> epc-sixth.cc.9.o}
['/usr/bin/g++', '-O0', '-ggdb', '-g3', '-Wall', '-Werror', '-Wno-error=deprecated-declarations', '-fstrict-aliasing', '-Wstrict-aliasing', '-pthread', '-pthread', '-fno-strict-aliasing', '-fwrapv', '-fstack-protector', '-fno-strict-aliasing', '-I.', '-I..', '-I/usr/include/gtk-2.0', '-I/usr/lib/x86_64-linux-gnu/gtk-2.0/include', '-I/usr/include/atk-1.0', '-I/usr/include/cairo', '-I/usr/include/gdk-pixbuf-2.0', '-I/usr/include/pango-1.0', '-I/usr/include/gio-unix-2.0', '-I/usr/include/freetype2', '-I/usr/include/glib-2.0', '-I/usr/lib/x86_64-linux-gnu/glib-2.0/include', '-I/usr/include/pixman-1', '-I/usr/include/libpng12', '-I/usr/include/harfbuzz', '-I/usr/include/libxml2', '-I/usr/include/python2.7', '-I/usr/include/x86_64-linux-gnu/python2.7', '-DNS3_ASSERT_ENABLE', '-DNS3_LOG_ENABLE', '-DHAVE_SYS_IOCTL_H=1', '-DHAVE_IF_NETS_H=1', '-DHAVE_NET_ETHERNET_H=1', '-DHAVE_PACKET_H=1', '-DHAVE_SQLITE3=1', '-DHAVE_IF_TUN_H=1', '-DHAVE_GSL=1', '-DNDEBUG', '-D_FORTIFY_SOURCE=2', '../scratch/epc-sixth.cc', '-c', '-o', 'scratch/epc-sixth.cc.9.o']

Nicola Baldo

unread,
Apr 16, 2015, 12:17:59 PM4/16/15
to ns-3-...@googlegroups.com
I just manage to finalize and push a fix for this bug, changeset 77244b8e7046 in ns-3-dev.


Reply all
Reply to author
Forward
0 new messages