Personally to me, RLC layer is one of the trickest area to understand in very detail. At the beginning it seems to be simple, but as I getting deeper and deeper into this layer I get more and more confused. Another difficulties is that I don't find any books or other training material explaining very detail on this area, whereas you would find a lot of books and materials digging very deeplyinto other layer
RLC sits between PDCP and MAC, and TS 36.322 defines it for LTE. It works in one of three modes. TM passes an SDU through untouched. UM adds a header, so that SDUs can be segmented, concatenated and put in order again at the receiver. AM adds ARQ on top of UM, so the receiver reports lost PDUs and the transmitter sends them again.
Let's use this page in the order it is written. The first sections follow the data flow of each mode and the RRC parameters behind it. The middle sections explain the PDU formats field by field and decode real captures bit by bit. The last sections cover the state variables and the UM and AM procedures of 36.322 v19.0.0, with the RRC listing from 36.331 v19.3.0.
Overview
As far as I experienced, there are three main topics we have to master on this layer to make our knowledge practical enough to the development or troubleshooting.
i) Understanding three types of RLC Mode : TM, UM, AM
ii) Segmentation (Splitting) and Concatenation (Combining) mechanism
iii) RLC Timers
I will not explain on these topics right now. It will be explained as you go along with this section.. but this part will be updated forever as I get more and more insight on this layer.
As in the section for other layer, let's start by "Reading (Verbalizing)" the pictures from the specification. The first diagram you will see in LTE RLC specification(TS 36.322) is as follows:
< 36.322 Figure 4.2.1-1: Overview model of the RLC sub layer >
What do you read from the diagram above ? First you will see the layers labeled 'upper layer' and 'lower layer' ? What does these layer specifically mean ? 'Upper layer' in this case would mean 'RRC layer' or 'PDCP Layer' or in some case (especially in the simulation or testing environment' it can be a TE port ( a kind of data Input/Output port).
Then, in which case the upper layer should be RRC Layer and in which case it should be PDCP or TE port ? These are what you have to figure out as you go along this document.
And then.. you see another layer labelled 'lower layer'. What is the lower layer in this case ? It is simple. It means 'MAC' layer in most case.
There are another small issues that scared me.. it was the term 'entity' which sounded too abstract to me. (it may not be the case for others). I just take the term 'entity' as a kind of 'thread' or 'task' in software terminology. It may not be a perfect analogy but this terminology change made me much more comfortable when I am reading the specs.
What else you can read from the diagram above ?
One thing I notice is.. There are separate entity (thread or task) for Uplink and Downlink RLC for TM and UM. But in AM, both Uplink and Downlink path are merged into a single entity. Why ? This is also what you have to figure out later.
Another picture that I want you to keep in mind is shown below. Most of signaling message is using RLC and each of the message is a specific types of RLC mode, TM/UM/AM. Unlike the channel mapping, the association between each message and RLC type is not so tight meaning that network can allocate RLC types a little bit different from what is shown below, but I would say the following mapping would be a kind of 'Textbook' mapping.
As we go through this section, you will see the detailed behavior of each RLC mode. If you try to associate this diagram and the RLC description you will have more practical understanding of RLC and will help you greatly for protocol stack implementation and troubleshooting.
Interaction with other Layers
RLC sits between PDCP and MAC layer. I would suggest you to understand how user data follow through these layers. This data flow can be illustrated as below. The illustrations shown here are examples for a specific case (typical max throughput condition). The illustration and comments would need to be changes if the test condition gets different.
For now, I am illustrating only one specific cases but you can draw varying illustrations depending on situation. I often see people underestimate the importance of RLC operation and they think RLC is working in a very simple logic. But this may hold trun only before you see some problem. Once you see the problems it would not be easy to troubleshoot. In many case you would see lack of detailed information in both UE log nor in network log. My recommendation for you is to draw this kind of illustrations for as many diverse case as possible and get clear understandings for each case in your own words before you come across any issues.
Data Flow at the Transmitter
The transmitting flow can be summarized as illustrated below. In this illustration, a lot of details for each layers are not mentioned. I focused only on data flow and how multiple IP packets get merged as it goes through lower layer. More specifically, in this illustration I assume that very large amount of resources (just assume that maximum possible resources) are allocated for MAC/PHY layer.
(A) A lot of IP packets are comining into PDCP layer from outside of eNB. (NOTE : You see multiple arrows coming in parallel at this step, but this doesn't mean that the multiple packets are comining in simultaneously. In reality, each of the arrows comes in one by one in sequence.)
(B) PDCP layer add PDCP header to each of incoming IP packet and send them out.
(C) A lot of PDCP packets are coming into RLC layer (NOTE : You see multiple arrows coming in parallel at this step, but this doesn't mean that the multiple packets are comining in simultaneously. In reality, each of the arrows comes in one by one in sequence.)
(D) RLC layer concatenate (combine) these multiple packets (SDU) into a single/huge packets and add a RLC header containing the detailed information(e.g, Length Indicator) that is required to split it into original packets at the reciever side. (The example DL AMD : 8C 00, DL AMD : 9C 02 are the RLC PDU of this type)
(E) The concatenated RLC packet (PDU) is forwarded to MAC layer once it gets the signal from the MAC layer. The maximum data size of the RLC output is determined by MAC layer TBS(Transport Block Size)
NOTE : If MAC TBS size is assigned to be very small (smaller than the single IP packet), the IP packet gets segmented (as opposed to being concatenated) and requires multiple times of RLC/MAC transmission to send out a whole IP packet.
< RLC Dowlink Data Flow Example >

Data Flow at the Reciever
The Recieving flow can be summarized as illustrated below. In this illustration, a lot of details for each layers are not mentioned. I focused only on data flow and how a big packets received at PHY/MAC get splitted into individual IP packets as it goes through higher layer. More specifically, in this illustration I assume that very large amount of resources (just assume that maximum possible resources) are allocated for MAC/PHY layer.
(A) MAC layer received a huge packet carrying many IP packets in it and forward it to RLC layer.
(B) RLC layer splits (segments) the huge packets into multiple SDUs based on the information carried by RLC header. After this segmentation, RLC header is removed.
(C) Each of the RLC SDUs from RLC is forwarded to PDCP(NOTE : You see multiple arrows coming in parallel at this step, but this doesn't mean that the multiple packets are forwarded simultaneously. In reality, each of the arrows are forwarded one by one in sequence.)
(D) Each of the packets coming into PDCP is now stripped of PDCP header.
(E) Each of the packets stripped of PDCP header produces individual IP packets and forwarded up to IP layer. (NOTE : You see multiple arrows coming in parallel at this step, but this doesn't mean that the multiple packets are forwarded simultaneously. In reality, each of the arrows are forwarded one by one in sequence.)
< RLC Uplink Data Flow Example >

Overall Data Flow for TM RLC
TM is the simplest of the three modes, and it is also the one a UE meets first. The MIB, the SIBs, paging and the RRC Connection Request and Setup on CCCH all travel through a TM entity. So you'll see TM on every attach, even though it does almost nothing to the data.
For this section as well, let's start reading diagram from the specification.
Let's begin with TM mode. As you see in the following diagram, TM is the simplest RLC mode. TM stands for 'Transparent Mode'. The term 'Transparent' may have many different meaning. In this case, it would mean 'the contents goes through this layer without any modification'.
What does it mean by 'modification' ? In this context, it would mean
i) It does not add or remove any header to the input data
ii) It does not split the input data into multiple segment
iii) It does not combine the multiple input data into a single big chunk
The only operation operation being done in this mode is a buffering operation, but even this buffering operation is also very simple. It just keeps the input data for a certain amount of time or until next input data come in, it just discard it if it does not get transmitted within a certain time frame.
As you see in the diagram, BCCH, PCCH, CCCH goes through this type of RLC process. In WCDMA, Voice call traffic used this RLC mode as well. It means that even some type of DTCH (voice traffic) uses this mode in WCDMA. However it is technically possible to use TM mode for DTCH as well.
< 36.322 Figure 4.2.1.1.1-1: Model of two transparent mode peer entities >
36.322 v19.0.0 lists the logical channels that a TM entity can serve: BCCH, BR-BCCH, DL/UL CCCH, PCCH and SBCCH. BR-BCCH carries system information for bandwidth reduced UEs, and SBCCH is the sidelink broadcast channel. The rules for the entity itself are short. The transmitting side neither segments nor concatenates the SDUs, and it adds no RLC header. The receiving side delivers each TMD PDU, which is simply the RLC SDU, to upper layer.
This has a practical consequence for scheduling. A TM entity cannot split an SDU, so the eNB has to give a grant that is large enough for the whole message. The same holds on the UE side for the RRC Connection Request on UL CCCH, which has to fit into the grant of the random access response. At RLC re-establishment, the transmitting TM entity simply discards all of its SDUs.
TM adds nothing to the SDU : there is no header, no segmentation and no concatenation, so a TMD PDU is the RLC SDU itself.Only broadcast and common control channels use TM : BCCH, BR-BCCH, DL/UL CCCH, PCCH and SBCCH.The grant must fit the whole SDU : TM cannot split a message, so the scheduler has to size the grant for it.
Overall Data Flow for UM RLC
Next, let's look into UM mode. UM stands for 'Unacknowledged Mode'. 'Unacknowledged Mode' means 'it does not require any reception response from the other party'. 'Reception response' simply mean 'ACK' or 'NACK' from the other party. (UM mode is similar to TM mode in that it does not require any ACK/NACK from the other party, but it is different from TM in that I has it's own header)
What is the difference between UM mode and TM mode we saw above ? It seems that UM mode is doing more operation than TM mode.
What kind of operation UM mode do ? You can just 'read' diagram for the answer. The answer would be a little bit different with transmitter side and reciever side.
Let's read the operation on transmitting side first. If you just read (verbalize) the diagram
i) Buffering
ii) Segmetation (Split a big chunk into a multiple small chunk)
iii) Concatenation (Combine a multiple small chunk into a large single chunk)
iv) Add RLC header (If you combine or split something, you have to be able to re-split or re-combine them into orignal chunk on the reciever side. For this, you have to put some tag(header) to those chunk)
Then, read the operation on recieving side. If you just read (verbalize) the diagram
i) Buffering
ii) Reordering (Sometimes the chunks transmitted earlier from transmitter may arrive late at the reciever. In this case you have to reorder the incoming chunks into proper order for reassembly).
iii) Remove the RLC header (you would remember that the transmitter put the header to each of the chunk. So you have to remove this before you reassemble the data).
iv) Reassembly
As you see, DTCH, MTCH. MCCH use this type of RLC process. Again, this is also a matter of choice. You can use AM or UM mode for DTCH.
< 36.322 Figure 4.2.1.2.1-1: Model of two unacknowledged mode peer entities >
Summary of RLC UM Data Flow - Transmission
This list follows the left half of 36.322 Figure 4.2.1.2.1-1 from top to bottom. Notice that nothing happens until MAC signals a transmission opportunity. RLC builds the UMD PDU only at that moment, because MAC then tells it how many bytes it can send.
i) Receive an Higher Layer Data (SDU) from PDCP or RRC
ii) Put the SDU into the transmission Buffer
iii) Segment or Concatenate the SDU into RLC PDU when MAC permit transmission
iv) Add a RLC header to the RLC PDU
v) Send the RLC PDU to the next layer (MAC)
Summary of RLC UM Data Flow - Reception
The receiving side uses the same boxes in the opposite order. The list below is simplified, because it leaves out one step. The receiving UM entity also discards duplicates and reorders out-of-sequence PDUs by SN before reassembly, as the Process of RLC UM Reception section shows.
i) The MAC layer passes the received RLC PDU to the RLC layer.
ii) The RLC layer removes the RLC header from the PDU.
iii). The RLC layer assembles the PDUs into a upper layer SDU
iv). Pass the assembled SDUs to the PDCP or RRC layers.
Major RLC UM Parameters
RRC configures a UM entity with very few fields. The capture below shows a DRB in RRC Connection Reconfiguration with rlc-Config set to um-Bi-Directional. Only sn-FieldLength and t-Reordering appear, and the table after the capture explains both.
Decoded RRC message,
+-rrcConnectionReconfiguration-r8 ::= SEQUENCE [001100] +-radioResourceConfigDedicated ::= SEQUENCE [110101] OPTIONAL:Exist | +-srb-ToAddModList ::= SEQUENCE OF SIZE(1..2) [1] OPTIONAL:Exist | +-drb-ToAddModList ::= SEQUENCE OF SIZE(1..maxDRB[11]) [1] OPTIONAL:Exist | | +-DRB-ToAddMod ::= SEQUENCE [11111] | | +-eps-BearerIdentity ::= INTEGER (0..15) [5] OPTIONAL:Exist | | +-drb-Identity ::= INTEGER (1..32) [1] | | +-pdcp-Config ::= SEQUENCE [110] OPTIONAL:Exist | | +-rlc-Config ::= CHOICE [um-Bi-Directional] OPTIONAL:Exist | | | +-um-Bi-Directional ::= SEQUENCE | | | +-ul-UM-RLC ::= SEQUENCE | | | | +-sn-FieldLength ::= ENUMERATED [size5] | | | +-dl-UM-RLC ::= SEQUENCE | | | +-sn-FieldLength ::= ENUMERATED [size5] | | | +-t-Reordering ::= ENUMERATED [ms0]
|
Information Element |
Description |
|
sn-FieldLength |
This parameter indicates the length of Sequence Number field of RLC-UMD. |
|
t-Reordering |
This timer is used by the receiving side of an UM RLC entity and receiving UM RLC entity in order to detect loss of RLC PDUs at lower layer. Unit = ms |
Overall Data Flow for AM RLC
Now let's look at AM mode which is the most complicated RLC type. 'AM' stands for 'Acknowledge Mode'. As it's name implies it requires ACK/NACK from the other party. It is more like TCP packet in IP world, whereas RLC UM is more like UDP in IP world.
Is it expecting the ACK/NACK for every transmission ? If it is the case, isn't it too much overhead ? Good question. Yes.. it is too much overhead. That's why we have RLC window concept (like TCP Window in IP traffic) and Polling bit concept and all sorts of ACK/NACK scheduling mechanism which makes it extremely difficult to understand full details of RLC AM operation. (This kind of detailed procedure would not be explained now.. but not sure by when I can get to the level of details -:)
Now just look into the diagram from the specification. If you go through the left column and the right colum, you will see the same procedures you saw in UM mode. so I don't want to verbalize that part again. What is different from UM mode lies in the middle column, namely 'Retransmission buffer' and 'RLC control' procedure.
Let's just follow the arrrows. What is coming into the retransmission buffer ? i.e, what is the input to the retransmission buffer ?
After RLC transmitter do the segmentation/concatenation process, it adds RLC header and then it creates two identical copies and transmit the one copy of the data out to lower layer (MAC) and send another copy to Retransmission buffer.
If the RLC get Nack or does not get any response from the other party for a certain period of time, the RLC packet (we call this RLC PDU) in the retransmission buffer gets transmitted again. If the RLC get ACK, the ones in retransmission buffer would be discarded.
< 36.322 Figure 4.2.1.3.1-1: Model of an acknowledged mode enttiy >
Summary of RLC AM Data Flow - Transmission
AM transmission repeats the UM steps and adds one more. After RLC adds the header, it keeps a copy of the PDU in the retransmission buffer. That copy stays there until a STATUS PDU from the peer acknowledges it, as 36.322 Figure 4.2.1.3.1-1 shows.
i) Receive an Higher Layer Data (SDU) from PDCP or RRC
ii) Put the SDU into the transmission Buffer
iii) Segment or Concatenate the SDU into RLC PDU when MAC permit transmission
iv) Add a RLC header to the RLC PDU
v) Make a copy of the transmission buffer for a possible retransmission
vi) Send the RLC PDU to the next layer (MAC)
Summary of RLC AM Data Flow - Reception
On the receiving side, AM differs from UM in what it reports back. Besides reassembly, the receiving side tracks which SNs are missing. It reports them to the peer in a STATUS PDU, and that report decides which PDUs the other side retransmits.
i) The MAC layer passes the received RLC PDU to the RLC layer.
ii) The RLC layer removes the RLC header from the PDU.
iii) If the received RLC PDU does not have any problem, mark it as positive ACK (but whether the ACK is sent now or sometime later or omitted is determined by some other RLC parameters).
iv). The RLC layer assembles the PDUs into a upper layer SDU
v). Pass the assembled SDUs to the PDCP or RRC layers.
Major Functions of RLC AM
I think this list can give you another aspect of reading Figure 4.2.1.3.1-1 shown above. This is one way to learn new things. Try to describe it from many different perspective. There will be many things overlapped by multiple perspectives and there will be many things that looks different depending on the perspectives. It will help you to learn it in either ways. In some case, you will learn many things because they are similar and in other case you will learn things because they are different.
- Segmentation, concatenation, and reassembly: RLC service data units (SDUs) coming from the upper layer are segmented or concatenated to RLC protocol data units (PDUs) which has a predefined size. Each PDU is assigned its own sequence number (SN). RLC AM on reciever side will reassemble these PDUs into SDUs using the sequence number. So allocating the proper Sequence Number is very important in RLC operation.
- Error correction by ARQ: In AM RLC, if the sender does not receive ACK from the reciever it automatically send the same data again and if the sender recieves the ACK in a predefined time frame it sends the next data. This process is called ARQ. But if RLC is using this ARQ for every transmission, it would create a lot of overhead for the data transmission. So in reality AM RLC is applying ARQ based on a special rules and this rule is defined by various factors like some special timers, polling request etc. These factors will be explained below.
- Flow control: By changing the window size, RLC can do a kind of flow control.
Major RLC AM Parameters
I think it will be helpful to look into some of high level RLC AM parameters (RRC parameters) and correlate these parameters with RLC AM operation process.
Decoded RRC message,
+-rrcConnectionSetup-r8 ::= SEQUENCE [0] +-radioResourceConfigDedicated ::= SEQUENCE [100101] | +-srb-ToAddModList ::= SEQUENCE OF SIZE(1..2) [1] OPTIONAL:Exist | | +-SRB-ToAddMod ::= SEQUENCE [11] | | +-srb-Identity ::= INTEGER (1..2) [1] | | +-rlc-Config ::= CHOICE [explicitValue] OPTIONAL:Exist | | | +-explicitValue ::= CHOICE [am] | | | +-am ::= SEQUENCE | | | +-ul-AM-RLC ::= SEQUENCE | | | | +-t-PollRetransmit ::= ENUMERATED [ms5] | | | | +-pollPDU ::= ENUMERATED [p4] | | | | +-pollByte ::= ENUMERATED [kB25] | | | | +-maxRetxThreshold ::= ENUMERATED [t1] | | | +-dl-AM-RLC ::= SEQUENCE | | | +-t-Reordering ::= ENUMERATED [ms35] | | | +-t-StatusProhibit ::= ENUMERATED [ms35] | | +-logicalChannelConfig ::= CHOICE [defaultValue] OPTIONAL:Exist | +-drb-ToAddModList ::= SEQUENCE OF OPTIONAL:Omit | +-drb-ToReleaseList ::= SEQUENCE OF OPTIONAL:Omit | +-mac-MainConfig ::= CHOICE [explicitValue] OPTIONAL:Exist | +-sps-Config ::= SEQUENCE OPTIONAL:Omit | +-physicalConfigDedicated ::= SEQUENCE [1111001011] OPTIONAL:Exist
|
Information Element |
Description |
|
t-PollRetransmit |
This timer is used by the transmitting side of an AM RLC entity in order to retransmit a poll. Unit = ms |
|
pollPDU |
In most typical condition, the poll bit is inserted after the number transmitted RLC PDU gets larger than this value. See 36.322 5.2.2.1 |
|
pollByte |
In most typical condition, the poll bit is inserted after the transmited RLC data is greater than (this value x 1000 bytes). See 36.322 5.2.2.1 |
|
maxRetxThreshold |
This parameter limits the number of retransmissions of an AMD PDU. Value t1 means 1 retransmission, t2 means 2 retransmissions and so on. When the limit is reached, RLC informs RRC. See 36.322 5.2.1 |
|
t-Reordering |
This timer is used by the receiving side of an AM RLC entity and receiving AM RLC entity in order to detect loss of RLC PDUs at lower layer. Unit = ms |
|
t-StatusProhibit |
This timer is used by the receiving side of an AM RLC entity in order to prohibit transmission of a STATUS PDU. Unit = ms |
Polling for RLC AM ARQ
As I mentioned above, one of the most important feature for RLC AM is ARQ which is designed for reliable data traffic and the key factors for RLC ARQ are various Polling mechanism.
This mechanism involves two main part as follows :
i) Transmitter side : Poll Request
ii) Receiver side : Status Report carrying ACK, NACK etc
Now the question is to figure out the best timing/situation for Poll Request and the best timing/situation for Satus Report.
Polling Parameter for LTE
In LTE, only four RRC fields in UL-AM-RLC control polling: t-PollRetransmit, pollPDU, pollByte and maxRetxThreshold. The capture below is the same SRB1 configuration shown under Major RLC AM Parameters. The five cases after the table show how these fields behave on the air.
Decoded RRC message,
+-rrcConnectionSetup-r8 ::= SEQUENCE [0] +-radioResourceConfigDedicated ::= SEQUENCE [100101] | +-srb-ToAddModList ::= SEQUENCE OF SIZE(1..2) [1] OPTIONAL:Exist | | +-SRB-ToAddMod ::= SEQUENCE [11] | | +-srb-Identity ::= INTEGER (1..2) [1] | | +-rlc-Config ::= CHOICE [explicitValue] OPTIONAL:Exist | | | +-explicitValue ::= CHOICE [am] | | | +-am ::= SEQUENCE | | | +-ul-AM-RLC ::= SEQUENCE | | | | +-t-PollRetransmit ::= ENUMERATED [ms5] | | | | +-pollPDU ::= ENUMERATED [p4] | | | | +-pollByte ::= ENUMERATED [kB25] | | | | +-maxRetxThreshold ::= ENUMERATED [t1] | | | +-dl-AM-RLC ::= SEQUENCE | | | +-t-Reordering ::= ENUMERATED [ms35] | | | +-t-StatusProhibit ::= ENUMERATED [ms35] | | +-logicalChannelConfig ::= CHOICE [defaultValue] OPTIONAL:Exist
|
Information Element |
Description |
|
t-PollRetransmit |
This timer is used by the transmitting side of an AM RLC entity in order to retransmit a poll. Unit = ms |
|
pollPDU |
In most typical condition, the poll bit is inserted after the number transmitted RLC PDU gets larger than this value. See 36.322 5.2.2.1 |
|
pollByte |
In most typical condition, the poll bit is inserted after the transmited RLC data is greater than (this value x 1000 bytes). See 36.322 5.2.2.1 |
I think some typical example operation would help you understand these parameters and Poll bit operation more intuitively.
Case 1 : Basic Poll Bit Handling

Case 2 : Poll bit and RLC ACK operates by sequence number

Case 3 : Retransmission due to t-PollRetransmit timeout

Case 4 : Retransmission due to RLC NACK

Case 5 : RLF(Radio Link Failure) due to Max Retransmission Failure

These five cases are simplified. Keep four details of 36.322 in mind when you compare them with a real log.
ACK_SN is the next SN not yet received : a STATUS PDU acknowledges every SN below ACK_SN, except the ones it lists as NACK_SN. So in Case 2, if SN 1 to 3 had already arrived, the STATUS PDU would carry ACK_SN = 4.A gap does not trigger the NACK at once : in Case 4 the receiver starts t-Reordering when SN 2 arrives before SN 1. The STATUS PDU with NACK_SN = 1 is triggered when t-Reordering expires. After the retransmission, SN 0 to 2 are all received, so the next STATUS PDU would carry ACK_SN = 3.maxRetxThreshold is a count, not a timer : the transmitter increments RETX_COUNT each time the PDU is considered for retransmission again. When RETX_COUNT reaches maxRetxThreshold, RLC indicates this to upper layers, and RRC in the UE then declares radio link failure.Every poll restarts t-PollRetransmit : the transmitter sets POLL_SN to VT(S) - 1 each time it sends P=1. It stops the timer only when a STATUS PDU acknowledges or negatively acknowledges POLL_SN.
Polling Parameter for UMTS
Following is the list of several important factors to trigger for Poll Request and Satus Report. Following table is based on UMTS RLC AM operation and this triggering mechanism seems to get simpler in LTE. However I would list up more complicated case (UMTS case) togive you more detailed picture.
|
Trigger for Poll |
Description |
|
Timer-based polling (timerPollPeriodic) |
This configure the sender to transmit Poll periodically (once in a predefined time period) |
|
Poll timer (timerPoll) |
This is the maximum waiting time for Status Report from the other party after it sent a Poll. If Status Report does not arrive until this timer expires after the transmission of a polling request, the sender send Polling Request again. |
|
Last PDU in buffer (lastTransmissionPDU-Poll) |
If this is configured, the poll should be sent with the last PDU in the RLC sender’s transmission buffer |
|
Last PDU in retransmission buffer (lastRetransmissionPDU-Poll) |
If this is configured, the poll should be sent with the last PDU in the RLC sender’s retransmission buffer |
|
Poll every N PDU (poll-PDU) |
This triggers the poll for every N PDU sent |
|
Poll every N SDU (poll-SDU) |
This triggers the poll for every N SDU sent |
|
Window-based polling |
This sets the polling bit when a certain percentage of the transmission window is sent |
|
Trigger for Status Report |
Description |
|
Polling bit |
The RLC reciever should send Status Report whenever it recieves AMD PDU with Poll bit = 1 except when it is within timerStatusProhibit |
|
Missing PDU indicator (missingPDU-Indicator) |
If this flag is set to be TRUE, RLC reciever should send Status Report whenever it finds any missing RLC sequence number except when it is within timerStatusProhibit. |
|
timer-based STATUS transfer (timerStatusPeriodic) |
If this parameter is configured, RLC sender send Status Report with a predefined interval except when it is within timerStatusProhibit |
|
MAC-hs reset |
This is trigger from MAC layer (not from RLC) which let RLC to send Status Report whenver MAC-hs resets. This is not influenced by timerStatusProhibit. |
Example 1 : in LTE - RLC Transmission from Network - IP throughput
This example comes from a downlink IP throughput test. The list below gives the RLC parameters of the DRB, and the table after it counts the AMD PDUs between polls. Use it to check which of the two poll triggers actually fires.
PollPDU = p128
PollByte = kB125
maxRetxThreshold = t32
t-PollRetransmit=ms35
t-Reordering=30ms
t-StatusProhibit = 30ms
|
Time (mm.ss.ms) |
Direction |
AMD PDU |
SN (Dec) |
# of PDUs |
Avg Size (Bytes) |
Poll Bit |
|
00.21.324-00.21.338 |
DL |
Data |
|
27 |
4586 |
0 |
|
00.21.338 |
DL |
Data |
|
1 |
4586 |
1 |
|
00.21.339-00.21.348 |
DL |
Data |
|
17 |
4586 |
0 |
|
00.21.349 |
UL |
Status(ACK) |
30 |
1 |
2 |
N/A |
|
00.21.349-00.21.353 |
DL |
Data |
|
9 |
4586 |
0 |
|
00.21.353 |
DL |
Data |
|
1 |
4586 |
1 |
|
00.21.354-00.21.368 |
DL |
Data |
|
27 |
4586 |
0 |
|
00.21.368 |
DL |
Data |
|
1 |
4586 |
1 |
|
00.21.369-00.21.381 |
DL |
Data |
|
27 |
4586 |
0 |
|
00.21.382 |
UL |
Status(ACK) |
90 |
1 |
2 |
N/A |
|
00.21.382 |
DL |
Data |
|
1 |
4586 |
0 |
|
00.21.382 |
DL |
Data |
|
1 |
4586 |
1 |
|
00.21.383-00.21.397 |
DL |
Data |
|
27 |
4586 |
0 |
|
00.21.397 |
DL |
Data |
|
1 |
4586 |
1 |
|
00.21.398-00.21.412 |
DL |
Data |
|
27 |
4586 |
0 |
|
00.21.412 |
DL |
Data |
|
1 |
4586 |
1 |
|
00.21.413-00.21.415 |
DL |
Data |
|
4 |
4586 |
0 |
|
00.21.415 |
UL |
Status(ACK) |
153 |
1 |
2 |
N/A |
|
00.21.415-00.21.426 |
DL |
Data |
|
23 |
4586 |
0 |
|
00.21.426 |
DL |
Data |
|
1 |
4586 |
1 |
|
00.21.426-00.21.441 |
DL |
Data |
|
27 |
4586 |
0 |
|
00.21.441 |
DL |
Data |
|
1 |
4586 |
1 |
|
00.21.443-00.21.446 |
DL |
Data |
|
8 |
4586 |
0 |
|
00.21.448 |
UL |
Status(ACK) |
216 |
1 |
2 |
N/A |
Look at how often the poll bit is set. It appears roughly once every 28 data PDUs. At an average of 4586 bytes per PDU, that is about 125 kBytes. So pollByte = kB125 sets the poll well before pollPDU = p128 would, and each STATUS PDU comes back within a few milliseconds of the poll.
Example 2 : in LTE - RLC Transmission from Network - LTE Registration
This example is an SRB during LTE registration, configured as the 36.508 table named below. Almost every DL PDU carries P=1, and the UE answers each poll with a STATUS PDU. The Header column lets you check every decode by hand.
Based on Table 4.6.3-19C: RLC-Config-SRB-AM-RECONFIG of 36.508
PollPDU = pInfinity (3GPP Default)
PollByte = kBInfinity (3GPP Default)
maxRetxThreshold = 3GPP Default
t-PollRetransmit=ms50
t-Reordering=t6
t-StatusProhibit = t0 (3GPP Default)
|
Time (mm.ss.ms) |
Direction |
AMD PDU |
SN (Dec) |
# of PDUs |
Avg Size (Bytes) |
Poll Bit |
Header |
|
00.13.297 |
DL |
DATA |
0 |
1 |
46 |
1 |
A0 00 |
|
00.13.304 |
UL |
Status(ACK) |
1 |
1 |
2 |
N/A |
00 04 |
|
00.13.416 |
DL |
DATA |
1 |
1 |
26 |
1 |
A0 01 |
|
00.13.423 |
UL |
Status(ACK) |
2 |
1 |
2 |
N/A |
00 08 |
|
00.13.461 |
DL |
DATA |
2 |
1 |
10 |
1 |
A0 02 |
|
00.13.468 |
UL |
Status(ACK) |
3 |
1 |
2 |
N/A |
00 0C |
|
00.13.522 |
DL |
DATA |
3 |
1 |
19 |
1 |
A0 03 |
|
00.13.529 |
UL |
Status(ACK) |
4 |
1 |
2 |
N/A |
00 10 |
|
00.13.587 |
DL |
DATA |
4 |
1 |
19 |
1 |
A0 04 |
|
00.13.594 |
UL |
Status(ACK) |
5 |
1 |
2 |
N/A |
00 14 |
|
00.13.617 |
DL |
DATA |
5 |
1 |
10 |
1 |
A0 05 |
|
00.13.624 |
UL |
Status(ACK) |
6 |
1 |
2 |
N/A |
00 18 |
|
00.13.883 |
DL |
DATA |
6 |
1 |
62 |
0 |
88 06 |
|
00.13.884 |
DL |
DATA |
7 |
1 |
62 |
0 |
98 07 |
|
00.13.885 |
DL |
DATA |
8 |
1 |
21 |
1 |
B0 08 |
|
00.13.892 |
UL |
Status(ACK) |
9 |
1 |
2 |
N/A |
00 18 |
pollPDU and pollByte are infinity here, so neither counter can trigger a poll. Every poll comes from the other trigger in 36.322 5.2.2.1, which fires when the transmission and retransmission buffers become empty. SN 6 to 8 show this clearly. Their FI values of 01, 11 and 10 mark one SDU split over three PDUs, and only the last one carries P=1.
One row of the table does not match its own header. The last STATUS row gives ACK_SN 9 but header 00 18, and 00 18 decodes to ACK_SN = 6. ACK_SN = 9 would be 00 24. The row is left as it was recorded.
Just for your reference, I put WCDMA RLC parameters in Radio Bearer Setup message as follows.
Decoded RRC message,
+-SRB-InformationSetup-r7 ::= SEQUENCE [1] | +-rb-Identity ::= INTEGER (1..32) [2] OPTIONAL:Exist | +-rlc-InfoChoice ::= CHOICE [rlc-Info] | | +-rlc-Info ::= SEQUENCE [1100] | | +-ul-RLC-Mode ::= CHOICE [ul-AM-RLC-Mode] OPTIONAL:Exist | | | +-ul-AM-RLC-Mode ::= SEQUENCE [1] | | | +-transmissionRLC-Discard ::= CHOICE [noDiscard] | | | | +-noDiscard ::= ENUMERATED [dat10] | | | +-transmissionWindowSize ::= ENUMERATED [tw128] | | | +-timerRST ::= ENUMERATED [tr550] | | | +-max-RST ::= ENUMERATED [rst1] | | | +-pollingInfo ::= SEQUENCE [010110] OPTIONAL:Exist | | | +-timerPollProhibit ::= ENUMERATED OPTIONAL:Omit | | | +-timerPoll ::= ENUMERATED [tp500] OPTIONAL:Exist | | | +-poll-PDU ::= ENUMERATED OPTIONAL:Omit | | | +-poll-SDU ::= ENUMERATED [sdu1] OPTIONAL:Exist | | | +-lastTransmissionPDU-Poll ::= BOOLEAN [TRUE] | | | +-lastRetransmissionPDU-Poll ::= BOOLEAN [TRUE] | | | +-pollWindow ::= ENUMERATED [pw50] OPTIONAL:Exist | | | +-timerPollPeriodic ::= ENUMERATED OPTIONAL:Omit | | +-dl-RLC-Mode ::= CHOICE [dl-AM-RLC-Mode] OPTIONAL:Exist | | | +-dl-AM-RLC-Mode ::= SEQUENCE | | | +-dl-RLC-PDU-size ::= CHOICE [fixedSize] | | | +-inSequenceDelivery ::= BOOLEAN [TRUE] | | | +-receivingWindowSize ::= ENUMERATED [rw128] | | | +-dl-RLC-StatusInfo ::= SEQUENCE [100] | | | +-timerStatusProhibit ::= ENUMERATED [tsp120] OPTIONAL:Exist | | | +-dummy ::= ENUMERATED OPTIONAL:Omit | | | +-missingPDU-Indicator ::= BOOLEAN [TRUE] | | | +-timerStatusPeriodic ::= ENUMERATED OPTIONAL:Omit
Example 3 : in LTE - RLC Bidirectional - From LTE Attach to YouTube
This example would the case that you might see most often in real life communication. This example shows all the RLC traffic both downlink and uplink from power on a UE to the start of YouTube download. This log is captured by Amarisoft OTS 100. Following is the RLC configuration for SRB, DRB set in RRC Connection Setup and RRC Connection Reconfiguration message. I put the decoded RLC headers shown on Amarisoft Web based log viewer, followed by corresponding Hex string. It will be a good practice if you pull out paper and pencil, deocde each hex string by hands and compare it with the decoded result shown on the log viewer.
Decoded RRC message,
srb-ToAddModList {
{
srb-Identity 1,
rlc-Config defaultValue: NULL,
logicalChannelConfig defaultValue: NULL
}
},
srb-ToAddModList {
{
srb-Identity 2,
rlc-Config defaultValue: NULL,
logicalChannelConfig defaultValue: NULL
}
},
drb-ToAddModList {
{
eps-BearerIdentity 5,
drb-Identity 1,
pdcp-Config {
discardTimer infinity,
rlc-AM {
statusReportRequired TRUE
},
headerCompression notUsed: NULL
},
rlc-Config am: {
ul-AM-RLC {
t-PollRetransmit ms80,
pollPDU p64,
pollByte kB125,
maxRetxThreshold t4
},
dl-AM-RLC {
t-Reordering ms80,
t-StatusProhibit ms60
}
},
logicalChannelIdentity 3,
logicalChannelConfig {
ul-SpecificParameters {
priority 13,
prioritisedBitRate infinity,
bucketSizeDuration ms100,
logicalChannelGroup 3
}
}
}
},
For SRB1 and SRB2 the capture shows rlc-Config defaultValue. In that case the UE applies the default values of 36.331 clause 9.2.1: t-PollRetransmit ms45, pollPDU infinity, pollByte infinity, maxRetxThreshold t4, t-Reordering ms35 and t-StatusProhibit ms0. The DRB gets explicit values instead, for example t-PollRetransmit ms80 and pollPDU p64.
Following is the screencapture of RLC traffic shown on Amarisoft Web Interface logging tool. (I removed a couple of columns between ENB and Info to make it fit to this page)


In this log, most SRB1 data PDUs carry P=1, and the peer answers with a STATUS PDU whose ACK_SN is one higher than the polled SN. Rows 7 and 8 are an example: SN=2 with P=1, then ACK_SN=3. A PDU with FI=01 followed by one with FI=10, as in rows 4 and 5, is one SDU split across two PDUs.
Following is the Hex string of each RLC traffic (PDU) shown above. Try decode these PDU on your own and compare it with the decoded result shown above if you want to get the detailed understanding of RLC PDU structure.
|
No |
RLC PDU |
|
1 |
88 00 00 20 30 00 80 23 80 84 17 3a a0 26 49 05 07 41 02 0b f6 00 f1 10 00 80 23 c1 00 45 67 05 |
|
2 |
b0 01 00 26 02 01 d0 11 27 20 80 80 21 10 01 00 00 10 81 06 00 00 00 00 83 06 00 00 00 00 00 0d |
|
3 |
00 08 |
|
4 |
88 00 00 08 00 18 3a a8 08 00 |
|
5 |
b0 01 00 00 00 |
|
6 |
00 08 |
|
7 |
a0 02 01 48 02 22 f6 54 b6 b1 c0 c0 ea c1 01 22 02 02 06 4a 8e d3 00 00 00 00 00 |
|
8 |
00 0c |
|
9 |
a0 02 01 08 01 20 3a 90 05 b2 a3 b1 d4 2e 09 ff e6 81 f3 71 fb 65 17 73 50 80 4e 0c a2 cc 5b cc |
|
10 |
00 0c |
|
11 |
a0 03 02 48 03 22 f4 2e 33 18 a0 e0 ea 62 16 c8 aa 81 38 32 8b 31 6b 14 f8 90 94 0f e0 12 a0 00 |
|
12 |
00 10 |
|
13 |
a0 03 02 08 00 89 bb ea 00 ec b8 00 3a e8 08 00 2f 83 86 02 03 86 08 00 00 00 00 |
|
14 |
00 10 |
|
15 |
a0 04 03 48 02 68 f3 8b f7 73 a0 00 eb c4 61 26 72 a0 20 a0 c0 04 80 5e a0 00 00 00 00 |
|
16 |
00 14 |
|
17 |
a0 04 03 30 00 10 84 90 80 b1 |
|
18 |
00 14 |
|
19 |
a0 05 04 28 00 06 04 bf 29 |
|
20 |
00 18 |
|
21 |
a0 05 04 38 00 00 3e a3 1a bb |
|
22 |
00 18 |
|
23 |
88 06 05 38 01 08 09 dc 99 80 05 0c 20 b0 c0 41 05 8b a8 ff f1 7f 1f fe 2b a3 ff c5 fc 7f f8 ab |
|
24 |
b0 07 fc 7f f8 bf 8f ff 17 f1 ff e2 fe 3f fc 5f c7 ff 00 26 00 00 c8 37 f8 00 00 00 1f f0 00 00 |
|
25 |
00 20 |
|
26 |
a0 06 05 20 06 02 a1 3f 39 fd 02 80 08 3a 10 17 00 30 00 07 88 80 00 08 01 22 90 0e 08 08 48 40 |
|
27 |
00 1c |
|
28 |
a0 08 06 10 00 d3 10 a9 14 |
|
29 |
00 24 |
|
30 |
a0 00 00 48 01 a4 e4 cc 6c a2 20 20 e8 60 00 6a 40 18 40 50 32 70 40 |
|
31 |
00 04 |
|
32 |
a0 07 06 08 01 91 3c b9 1a 8f 30 10 3b 0a 18 84 0e 0b b2 c4 f4 f5 fe 6b a4 85 9a 65 fd ff 2b 5a |
|
33 |
00 20 |
|
34 |
a0 00 80 00 45 00 00 45 2a a0 40 00 40 11 3d 4e c0 a8 02 02 08 08 08 08 1e 02 00 35 00 31 00 d2 |
|
35 |
00 04 |
|
36 |
a0 00 80 00 45 00 01 0a 88 5d 00 00 36 11 28 cc 08 08 08 08 c0 a8 02 02 00 35 1e 02 00 f6 7b da |
|
37 |
00 04 |
|
38 |
a0 01 80 01 45 00 00 3c 61 ac 40 00 40 06 bb 29 c0 a8 02 02 36 e6 24 56 9f a2 00 50 90 2d f7 5e |
|
39 |
00 08 |
|
40 |
a0 01 80 01 45 00 00 3c 00 00 40 00 35 06 27 d6 36 e6 24 56 c0 a8 02 02 00 50 9f a2 66 b7 2f 53 |
|
41 |
00 08 |
|
42 |
8c 02 03 60 80 02 45 00 00 34 61 ad 40 00 40 06 bb 30 c0 a8 02 02 36 e6 24 56 9f a2 00 50 90 2d |
|
43 |
b0 03 74 72 61 32 2e 62 69 6e 20 48 54 54 50 2f 31 2e 31 0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a |
|
44 |
00 10 |
|
45 |
a0 02 80 02 45 00 00 34 f2 c8 40 00 35 06 35 15 36 e6 24 56 c0 a8 02 02 00 50 9f a2 66 b7 2f 54 |
|
46 |
8c 03 5a 20 80 03 45 00 05 a0 f2 ca 40 00 35 06 2f a7 36 e6 24 56 c0 a8 02 02 00 50 9f a2 66 b7 |
How does RRC configure an RLC entity ?
Every RLC timer and polling parameter on this page gets its value from RRC. The UM and AM sections above show those values inside decoded messages, but a capture shows only the fields that one network used. The listing below is the full RLC-Config IE of 36.331, with the extensions added after Release 8.
Following is based on
RLC-Config ::= CHOICE { am SEQUENCE { ul-AM-RLC UL-AM-RLC, dl-AM-RLC DL-AM-RLC }, um-Bi-Directional SEQUENCE { ul-UM-RLC UL-UM-RLC, dl-UM-RLC DL-UM-RLC }, um-Uni-Directional-UL SEQUENCE { ul-UM-RLC UL-UM-RLC }, um-Uni-Directional-DL SEQUENCE { dl-UM-RLC DL-UM-RLC }, ... } RLC-Config-v1250 ::= SEQUENCE { ul-extended-RLC-LI-Field-r12 BOOLEAN, dl-extended-RLC-LI-Field-r12 BOOLEAN } RLC-Config-v1310 ::= SEQUENCE { ul-extended-RLC-AM-SN-r13 BOOLEAN, dl-extended-RLC-AM-SN-r13 BOOLEAN, pollPDU-v1310 PollPDU-v1310 OPTIONAL -- Need OR } RLC-Config-v1430 ::= CHOICE { release NULL, setup SEQUENCE { pollByte-r14 PollByte-r14 } } RLC-Config-v1510 ::= SEQUENCE { reestablishRLC-r15 ENUMERATED {true} } RLC-Config-v1530 ::= CHOICE { release NULL, setup SEQUENCE { rlc-OutOfOrderDelivery-r15 ENUMERATED {true} } } RLC-Config-v1700 ::= SEQUENCE { t-ReorderingExt-r17 SetupRelease {T-ReorderingExt-r17} } RLC-Config-r15 ::= SEQUENCE { mode-r15 CHOICE { am-r15 SEQUENCE { ul-AM-RLC-r15 UL-AM-RLC-r15, dl-AM-RLC-r15 DL-AM-RLC-r15 }, um-Bi-Directional-r15 SEQUENCE { ul-UM-RLC-r15 UL-UM-RLC, dl-UM-RLC-r15 DL-UM-RLC-r15 }, um-Uni-Directional-UL-r15 SEQUENCE { ul-UM-RLC-r15 UL-UM-RLC }, um-Uni-Directional-DL-r15 SEQUENCE { dl-UM-RLC-r15 DL-UM-RLC-r15 } }, reestablishRLC-r15 ENUMERATED {true} OPTIONAL, -- Need ON rlc-OutOfOrderDelivery-r15 ENUMERATED {true} OPTIONAL, -- Need ON ... } UL-AM-RLC ::= SEQUENCE { t-PollRetransmit T-PollRetransmit, pollPDU PollPDU, pollByte PollByte, maxRetxThreshold ENUMERATED { t1, t2, t3, t4, t6, t8, t16, t32} } UL-AM-RLC-r15 ::= SEQUENCE { t-PollRetransmit-r15 T-PollRetransmit, pollPDU-r15 PollPDU-r15, pollByte-r15 PollByte-r14, maxRetxThreshold-r15 ENUMERATED { t1, t2, t3, t4, t6, t8, t16, t32}, extended-RLC-LI-Field-r15 BOOLEAN } DL-AM-RLC ::= SEQUENCE { t-Reordering T-Reordering, t-StatusProhibit T-StatusProhibit } DL-AM-RLC-r15 ::= SEQUENCE { t-Reordering-r15 T-Reordering, t-StatusProhibit-r15 T-StatusProhibit, extended-RLC-LI-Field-r15 BOOLEAN } UL-UM-RLC ::= SEQUENCE { sn-FieldLength SN-FieldLength } DL-UM-RLC ::= SEQUENCE { sn-FieldLength SN-FieldLength, t-Reordering T-Reordering } DL-UM-RLC-r15 ::= SEQUENCE { sn-FieldLength-r15 SN-FieldLength-r15, t-Reordering-r15 T-Reordering } SN-FieldLength ::= ENUMERATED {size5, size10} SN-FieldLength-r15 ::= ENUMERATED {size5, size10, size16-r15} T-PollRetransmit ::= ENUMERATED { ms5, ms10, ms15, ms20, ms25, ms30, ms35, ms40, ms45, ms50, ms55, ms60, ms65, ms70, ms75, ms80, ms85, ms90, ms95, ms100, ms105, ms110, ms115, ms120, ms125, ms130, ms135, ms140, ms145, ms150, ms155, ms160, ms165, ms170, ms175, ms180, ms185, ms190, ms195, ms200, ms205, ms210, ms215, ms220, ms225, ms230, ms235, ms240, ms245, ms250, ms300, ms350, ms400, ms450, ms500, ms800-v1310, ms1000-v1310, ms2000-v1310, ms4000-v1310, spare5, spare4, spare3, spare2, spare1} PollPDU ::= ENUMERATED { p4, p8, p16, p32, p64, p128, p256, pInfinity} PollPDU-v1310 ::= ENUMERATED { p512, p1024, p2048, p4096, p6144, p8192, p12288, p16384} PollPDU-r15 ::= ENUMERATED { p4, p8, p16, p32, p64, p128, p256, p512, p1024, p2048-r15, p4096-r15, p6144-r15, p8192-r15, p12288-r15, p16384-r15, pInfinity} PollByte ::= ENUMERATED { kB25, kB50, kB75, kB100, kB125, kB250, kB375, kB500, kB750, kB1000, kB1250, kB1500, kB2000, kB3000, kBinfinity, spare1} PollByte-r14 ::= ENUMERATED { kB1, kB2, kB5, kB8, kB10, kB15, kB3500, kB4000, kB4500, kB5000, kB5500, kB6000, kB6500, kB7000, kB7500, kB8000, kB9000, kB10000, kB11000, kB12000, kB13000, kB14000, kB15000, kB16000, kB17000, kB18000, kB19000, kB20000, kB25000, kB30000, kB35000, kB40000} T-Reordering ::= ENUMERATED { ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35, ms40, ms45, ms50, ms55, ms60, ms65, ms70, ms75, ms80, ms85, ms90, ms95, ms100, ms110, ms120, ms130, ms140, ms150, ms160, ms170, ms180, ms190, ms200, ms1600-v1310} T-ReorderingExt-r17 ::= ENUMERATED {ms2200, ms3200} T-StatusProhibit ::= ENUMERATED { ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35, ms40, ms45, ms50, ms55, ms60, ms65, ms70, ms75, ms80, ms85, ms90, ms95, ms100, ms105, ms110, ms115, ms120, ms125, ms130, ms135, ms140, ms145, ms150, ms155, ms160, ms165, ms170, ms175, ms180, ms185, ms190, ms195, ms200, ms205, ms210, ms215, ms220, ms225, ms230, ms235, ms240, ms245, ms250, ms300, ms350, ms400, ms450, ms500, ms800-v1310, ms1000-v1310, ms1200-v1310, ms1600-v1310, ms2000-v1310, ms2400-v1310, spare2, spare1}
The base IE is a CHOICE of four modes. The am choice carries UL-AM-RLC and DL-AM-RLC. The um-Bi-Directional choice carries both UM halves, and the two uni-directional choices carry only one of them. TM has no entry, because a TM entity has nothing to configure.
The later fields do not sit inside RLC-Config itself. They are separate IEs, and DRB-ToAddMod carries them in its extension groups as rlc-Config-v1250, rlc-Config-v1310, rlc-Config-v1430, rlc-Config-v1510, rlc-Config-v1530 and rlc-Config-v1700. SRB-ToAddMod carries rlc-Config-v1530, rlc-Config-v1560 and rlc-Config-v1700. RLC-Config-r15 is a complete version of the IE, and RLC-BearerConfig-r15 uses it for a secondary RLC bearer, for example with PDCP duplication using CA.
The table below lists what each extension changes in 36.322. Most of them enlarge a field or a value range, so that RLC can handle higher data rates or longer delays.
Field | Release | What it changes |
ul/dl-extended-RLC-LI-Field-r12 | 12 | AM uses a 15 bit LI instead of 11 bits, so an SDU longer than 2047 bytes no longer has to sit at the end of the Data field |
ul/dl-extended-RLC-AM-SN-r13 | 13 | AM uses a 16 bit SN and a 16 bit SO instead of 10 and 15 bits, and AM_Window_Size grows from 512 to 32768 |
pollPDU-v1310 | 13 | pollPDU values from p512 to p16384; the UE then ignores pollPDU without suffix |
pollByte-r14 | 14 | pollByte values from kB1 to kB40000; the UE then ignores pollByte without suffix |
reestablishRLC-r15 | 15 | RLC re-establishment when a DRB changes from SN terminated split to MN terminated MCG RLC bearer in (NG)EN-DC, or on key refresh in NE-DC |
rlc-OutOfOrderDelivery-r15 | 15 | the receiver delivers each complete SDU to PDCP without waiting for reordering |
t-ReorderingExt-r17 | 17 | t-Reordering of 2200 or 3200 ms; the UE then ignores t-Reordering |
The timer lists also grew inside the base IE. For t-PollRetransmit and t-StatusProhibit, the values with a -v1310 suffix, such as ms800-v1310, are configured only for a UE that supports coverage enhancement. SRB1 and SRB2 often skip all of this with defaultValue. The UE then uses 36.331 clause 9.2.1: t-PollRetransmit ms45, pollPDU infinity, pollByte infinity, maxRetxThreshold t4, t-Reordering ms35 and t-StatusProhibit ms0.
One mismatch between the two specifications is worth knowing. SN-FieldLength-r15 in DL-UM-RLC-r15 lists size16-r15, but 36.322 v19.0.0 still defines only a 5 bit or a 10 bit SN for the UMD PDU.
RLC-Config is a CHOICE of AM and three UM variants : TM has no configuration.Extensions arrive as separate IEs : look for rlc-Config-v1250 to rlc-Config-v1700 in DRB-ToAddMod, not inside RLC-Config.16 bit SN and 15 bit LI are optional : the default AM header still uses a 10 bit SN and an 11 bit LI.defaultValue means clause 9.2.1 : t-PollRetransmit ms45, maxRetxThreshold t4, t-Reordering ms35 and t-StatusProhibit ms0 for SRB1 and SRB2.
RLC Data Structure
Like any data structure, you would not completely understand this structure until you really construct this structure or analyze the structure with real data either in programming or in manually. Of course my recommendation is to analyze manually.. I will put some of real RLC data example later, but for now let's just review the diagram from 3GPP specification and just try to be familiar with them.
TMD Structure
The first structure is as follows. It is data structure for TMD (TM mode data) structure. What kind of structure you see from the following diagram ?
< 36.322 Figure 6.2.1.2-1: TMD PDU >
It is Data only structure, not even with Header. Most of the data structure for any data communication has it's own header. IP packet has IP header. UDP packet has UDP header. TCP header has TCP header. ICMP packet has ICMP header, etc. But this packet does not have any header. As you know, the most important role of header is to carry the information as follows :
i) Who is the sender ? (sender address, sender id etc)
ii) Who is the reciepient (reciepient address, id etc)
iii) What is the size of the data ?
iv) etc..
But this data structure has none of these information. It means that the TMD packet does not add any additional (header) to the input data and does not split or combine the data coming into the RLC entity.
Then how the size of this TMD PDU is determined ? It is automatically set to be the same size as MAC PDU size.
What if the incoming data is bigger than the RLC PDU size ? It just take the initial part of data that can fit into its size and discard the rest of the data.
What if the incoming data is smaller than the RLC PDU size ? It just take the whole data and pass it to MAC layer and MAC layer add padding data at the end.
36.322 v19.0.0 does not describe a TM entity that cuts an SDU. Only one RLC SDU can be mapped to the Data field of a TMD PDU, and the transmitting TM entity submits the SDU without any modification. So the eNB has to size the grant for the whole SDU, and a TMD PDU is exactly as long as its SDU.
UMD Structure
Following is a data structure for UMD (UM mode data) structure. What are the meaning of Fl, E, SN ? You should refer to other sets of diagrams later. If you remember the diagram in previous section (Fig 4.2.1.2.1-1), RLC UM entity has capability of segmentation/concatenation. It means ... if the incoming data is greater than the RLC size, it segment the data into multiple chunks and passthem one by one. In this case, you have to put some tag (number) to each of the chunks.. otherwise the receiving side cannot combine them in proper sequence. This tag (number) is SN (Sequence Number). As you see in the following diagram, there are two different types of SN. One is 5 bits and the other one is 10 bits.
< 36.322 Figure 6.2.1.3-1: UMD PDU with 5 bit SN (No LI) >
< 36.322 Figure 6.2.1.3-2: UMD PDU with 10 bit SN (No LI) >
What if the a lot of small sized data packets are coming into the RLC entity ? The simplest way is to pack the small chunk as it is (as in TM mode), but it is waste of space.
Then what do we have to do in this case ? The simplest way is to put the multiple small chunk into a single RLC packet. In this case, you need special information for each of the small chunk within the RLC packet, except for the last one. LI (Length Indicator) is the length value for each of the small chunks within a RLC PDU, except for the last. For example, if you have 5 chunks in a single RLC packet, you would have four E fields and 4 LI fields since you don't need E and LI field for the last one (5th one in this case)
< 36.322 Figure 6.2.1.3-3: UMD PDU with 5 bit SN (Odd number of LIs, i.e. K = 1, 3, 5, …) >
< 36.322 Figure 6.2.1.3-4: UMD PDU with 5 bit SN (Even number of LIs, i.e. K = 2, 4, 6, …) >
< 36.322 Figure 6.2.1.3-5: UMD PDU with 10 bit SN (Odd number of LIs, i.e. K = 1, 3, 5, …) >
< 36.322 Figure 6.2.1.3-6: UMD PDU with 10 bit SN (Even number of LIs, i.e. K = 2, 4, 6, …) >
Followings are the descriptions for each field in the UMD PDU Header.
E Field : This field indicate whether this field is the end of the header or another extention follows or not.
< 36.322 Table 6.2.2.4-1: E field interpretation (for E field in the fixed part of the header) >
< 36.322 Table 6.2.2.4-2: E field interpretation (for E field in the extension part of the header) >

FI Field : This field indicate the relative location of the RLC PDU within a RLC SDU. For example, '01' indicate the PDU is the first segment of the SDU and '10' indicates the PDU is the last segment of the SDU, and '11' indicate the PDU is in between the first and last segment. In a SDU, there is only one '01' type PDU and only one '10' type PDU. There can be one or more '11' type PDU. If FI is 00, it means the RLC PDU is same as RLC SDU. When RLC recieves '01' type, the layer start buffering the PDU within RLC memory and only when it recieves '10' PDU, RLC reassembles all the recieved PDU and transfer it to PDCP.
< 36.322 Table 6.2.2.6-1: FI field interpretation >
How to Identify UMD PDU Type ?
In this section, you might have noticed that there are many different header types in UMD, but if you take a look at RRC configurations for RLC UM, there are not so many parameters to determined the header type. Actually there is only one parameter(sn-FieldLength) related to UMD header type. This is not enough to determined the exact UMD header type. For example, if we assume that sn-FieldLength is 5 bit, there are three possible UMD header type as shown below.
Case 1 : 36.322 Figure 6.2.1.3-1: UMD PDU with 5 bit SN (No LI)
Case 2 : 36.322 Figure 6.2.1.3-3: UMD PDU with 5 bit SN (Odd number of LIs, i.e. K = 1, 3, 5, …)
Case 3 : 36.322 Figure 6.2.1.3-4: UMD PDU with 5 bit SN (Even number of LIs, i.e. K = 2, 4, 6, …)
Then you may ask how the receiving side RLC can figure out which header. The answer lies in 'E' field. The 'E' field in the first Octet and the 'E' field in the following bytes (Oct >= 2). The 'E' field in the first octet determines the header should be 'Case 1' or 'Case 2,3' and the 'E' field in the following octets (more specifically K value) determines whether the header type is Case 2 or Case 3. If K is 'odd num, the Case 2 header is used. If K is even number, Case 3 header is used.
AMD Structure
The last type of RLC packet type is AMD (AM mode data) structure. Overall structure is very similar to UMD structure except that it has a couple of additional field D/C, RF, P.
< 36.322 Figure 6.2.1.4-1: AMD PDU (No LI) >
< 36.322 Figure 6.2.1.4-2: AMD PDU (Odd number of LIs, i.e. K = 1, 3, 5, …) >
< 36.322 Figure 6.2.1.4-3: AMD PDU (Even number of LIs, i.e. K = 2, 4, 6, …) >
The three figures above are the original Release 8 formats, with a 10 bit SN and an 11 bit LI. 36.322 v19.0.0 carries more AMD PDU figures, because RRC can configure two larger fields. With ul/dl-extended-RLC-AM-SN-r13 the SN grows to 16 bits, and the fixed part of the header grows from two bytes to three. With ul/dl-extended-RLC-LI-Field-r12 the LI grows to 15 bits, and then no padding follows an odd number of LIs. The default is still a 10 bit SN and an 11 bit LI.
We saw many of small fields in RLC header and now let's try understanding the meaning of each of these fields.
D/C Field : This field indicate whether the PDU is for RLC control or Data .
< 36.322 Table 6.2.2.9-1: D/C field interpretation >
RF Field : This field indicate tye type of the AMD PDU.
< 36.322 Table 6.2.2.10-1: RF field interpretation >
P Field : This field indicate the PDU requires a status report (RLC ACK or NACK) from the other party or not.
< 36.322 Table 6.2.2.11-1: P field interpretation >
FI Field : This field indicate the relative location of the RLC PDU within a RLC SDU. For example, '01' indicate the PDU is the first segment of the SDU and '10' indicates the PDU is the last segment of the SDU, and '11' indicate the PDU is in between the first and last segment. In a SDU, there is only one '01' type PDU and only one '10' type PDU. There can be one or more '11' type PDU. If FI is 00, it means the RLC PDU is same as RLC SDU. When RLC recieves '01' type, the layer start buffering the PDU within RLC memory and only when it recieves '10' PDU, RLC reassembles all the recieved PDU and transfer it to PDCP.
< 36.322 Table 6.2.2.6-1: FI field interpretation >
The LSF field below belongs to the AMD PDU segment, not to the AMD PDU. The transmitter builds a segment only when a retransmission no longer fits the grant, and it sets RF = 1 in the segment. The segment header adds LSF and a SO field to the AMD PDU header. SO gives the byte position of the segment inside the Data field of the original AMD PDU. It is 15 bits long with a 10 bit SN and 16 bits with a 16 bit SN, so the fixed part of the header is four or five bytes.
< 36.322 Table 6.2.2.8-1: LSF field interpretation >
E Field : This field indicate whether this field is the end of the header or another extention follows or not.
< 36.322 Table 6.2.2.4-1: E field interpretation (for E field in the fixed part of the header) >
< 36.322 Table 6.2.2.4-2: E field interpretation (for E field in the extension part of the header) >

Following is the structure of STATUS PDU and I recommend you to be familiar with this structure because this would be very useful for various troubleshoot case.
< Figure 6.2.1.6-1: STATUS PDU >
This is the format with a 10 bit SN. 36.322 v19.0.0 titles it Figure 6.2.1.6-1: STATUS PDU with 10 bit SN, and adds Figure 6.2.1.6-2 for a 16 bit SN with 16 bit SOstart and SOend. The payload always starts with one ACK_SN and one E1. Zero or more sets of NACK_SN, E1 and E2 follow, and each set can carry SOstart and SOend. One to seven padding bits at the end keep the PDU octet aligned.
CPT Field : This field applies when PDU type is Control PDU. It indicates whether the PDU is STATUS or not.
< 36.322 Table 6.2.2.13-1: CPT field interpretation >
E1 Field : This field applies when PDU type is Control PDU. It indicates whether a set of NACK_SN, E1 and E2 follows or not.
< 36.322 Table 6.2.2.15-1: E1 field interpretation >
< 36.322 Table 6.2.2.17-1: E2 field interpretation >
SOstart and SOend fields indicated the corresponding NACK_SN stands for 'detected as lost' which means a portion or the whole RLC PDU is lost. According to 36.322, section 6.2.2.18, 6.2.2.19 descrbes these fields as follows.
SOstart (15 bits) : The SOstart field (together with the SOend field) indicates the portion of the AMD PDU with SN = NACK_SN (the NACK_SN for which the SOstart is related to) that has been detected as lost at the receiving side of the AM RLC entity.
Specifically, the SOstart field indicates the position of the first byte of the portion of the AMD PDU in bytes within the Data field of the AMD PDU. The first byte in the Data field of the original AMD PDU is referred by the SOstart field value "000000000000000", i.e., numbering starts at zero
SOend (15 bits) : The SOend field (together with the SOstart field) indicates the portion of the AMD PDU with SN = NACK_SN (the NACK_SN for which the SOend is related to) that has been detected as lost at the receiving side of the AM RLC entity.
Specifically, the SOend field indicates the position of the last byte of the portion of the AMD PDU in bytes within the Data field of the AMD PDU. The first byte in the Data field of the original AMD PDU is referred by the SOend field value "000000000000000", i.e., numbering starts at zero. The special SOend value "111111111111111" is used to indicate that the missing portion of the AMD PDU includes all bytes to the last byte of the AMD PDU
RLC Decoding Tips
When you don't have automatic RLC decoder and you have to manually decode RLC header, you can get a lot of hints just by the first 4 bits of RLC PDU as listed below. Check this table with the examples.
|
Binary |
Hex |
Description |
|
0000 |
0 |
AMD Control PDU, Status PDU |
|
100x |
8 or 9 |
AMD Data PDU, Polling Bit = 0 |
|
101x |
A or B |
AMD Data PDU, Polling Bit = 1 |
|
110x |
C or D |
AMD PDU segment, Polling Bit = 0 |
|
111x |
E or F |
AMD PDU segment, Polling Bit = 1 |
The last two rows are the AMD PDU segments, with RF = 1. You will see them only in retransmissions that had to be re-segmented. These hints also work only on an AM logical channel. A UMD PDU has no D/C field, so with a 5 bit SN its first byte is FI, E and SN. With a 10 bit SN it starts with three R1 bits. For an AM control PDU the first four bits are always 0000, because CPT = 000 is the only value in use. The receiving entity discards a control PDU with CPT 001 to 111.
The first hex digit gives the PDU type : 0 is a STATUS PDU, 8 to B an AMD PDU and C to F an AMD PDU segment.The third bit is the poll bit : 8, 9, C and D mean P = 0, while A, B, E and F mean P = 1.UM needs the configured SN length : without D/C, the first byte of a UMD PDU cannot be read until you know sn-FieldLength.
Let's try the hints on two headers from Example 2. A0 00 starts with the digit A, which is 1010 in binary. So D/C = 1, RF = 0 and P = 1, which makes it an AMD PDU that asks for a STATUS report. 00 04 starts with 0, so it is a STATUS PDU, and its next ten bits give ACK_SN = 1. The Examples for RLC AMD PDU section below decodes both headers in full.
Examples for RLC AMD PDU
Followings are a couple of RLC PDU example. In RLC PDU case, especially AMD PDU case, you should anlayze several consecutive PDUs in both direction for you to get overal picture.
With these examples, you would learn and get familiar to how to utilize all the tables/diagrams shown above.
DL AMD : 88 06 06 20 06 03 41 39 40 5A D9 80 18 3A 10 17 00 30 00 07 88 80 00 08 01 A2 90 0E 08 08 48 40 3B 0B 73 93 4B A3 9B A8 28 0E 05 40 20 0A E8 08 01 80 71 1C 90 54 9C B2 03 43 A0 02 03 F8
Header decode of the captured PDU above,
88 06 = 10001000 00000110
D/C = 1 = Data PDU
RF = 0 = AMD PDU
P = 0 = Status PDU is not requested
FI = 01 = First byte of the Data field corresponds to the first byte of a RLC SDU,
Last byte of the Data field does not corresponds to the last byte of a RLC SDU
E = 0 = Data field follows from the octet following the LI field following this E field
SN = 0000000110
DL AMD : 98 07 00 00 01 90 1C 09 38 44 00 00 68 26 05 40 08 12 80 5F B0 07 88 84 00 08 00 00 00 00 08 98 07 88 80 00 01 18 2F A0 00 00 00 00 BF 02 CF 03 20 08 0B 53 E0 FA 81 BC 0F A8 E0 60 78 E6
Header decode of the captured PDU above,
98 07 = 10011000 00000111
D/C = 1 = Data PDU
RF = 0 = AMD PDU
P = 0 = Status PDU is not requested
FI = 11 = First byte of the Data field does not corresponds to the first byte of a RLC SDU,
Last byte of the Data field does not corresponds to the last byte of a RLC SDU
E = 0 = Data field follows from the octet following the LI field following this E field
SN = 0000000111
DL AMD : B0 08 3E 9D 52 D2 E8 00 FB 50 65 03 FF 04 07 E8 10 55 13 20 49
Header decode of the captured PDU above,
B0 08 = 10110000 00001000
D/C = 1 = Data PDU
RF = 0 = AMD PDU
P = 1 = Status PDU is requested
FI = 10 = First byte of the Data field does not corresponds to the first byte of a RLC SDU,
Last byte of the Data field corresponds to the last byte of a RLC SDU
E = 0 = Data field follows from the octet following the LI field following this E field
SN = 0000001000
DL AMD : 8C 00 DD CD DC 5D C0 80 00 6D 1B 72 6F 06 97 7E 70 DB 6C 8D C5 F5 88 B3 F3 5D 7F E4 44 B4 FF E9 3F 54 30 67 02 19 EA 57 A2 5A 33 B4 7D B5 6C A5 4B B5 ...
Header decode of the captured PDU above,
8C 00 DD CD DC 5D = 10001100 00000000 11011101 11001101 11011100 01011101
D/C = 1 = Data PDU
RF = 0 = AMD PDU
P = 0 = Status PDU is not requested
FI = 01 = First byte of the Data field corresponds to the first byte of a RLC SDU,
Last byte of the Data field does not corresponds to the last byte of a RLC SDU
E = 1 = A set of E field and LI field follows from the octet following the fixed part of the header
SN = 0000000000
E = 1
LI1 = 10111011100 (1500 Dec)
E = 1
LI2 = 10111011100 (1500 Dec)
RLC PDU = 8C 00 DD CD DC 5D C0 80 00 6D 1B 72 6F 06 97 7E 70 DB 6C 8D C5 F5 88 B3 F3 5D 7F E4 44 B4 FF E9 3F 54 30 67 02 19 EA 57 A2 5A 33 B4 7D B5 6C A5 4B B5...
DL AMD : 9C 01 D8 DD DC 5D C0 EB E2 5F BC 87 1E CA CD 1D F6 65 19 E6 3F B2 E8 F1 A8 87 C7 DC 1E 1A 01 54 91 F6 80 48 72 53 AC C3 43 6A 6B D6 9E DF 43 D6 A4 5C 03 ...
Header decode of the captured PDU above,
9C 01 D8 DD DC 5D = 10011100 00000001 11011000 11011101 11011100 01011101
D/C = 1 = Data PDU
RF = 0 = AMD PDU
P = 0 = Status PDU is not requested
FI = 11 = First byte of the Data field does not corresponds to the first byte of a RLC SDU,
Last byte of the Data field does not corresponds to the last byte of a RLC SDU
E = 1 = A set of E field and LI field follows from the octet following the fixed part of the header
SN = 0000000001
E = 1
LI1 = 10110001101 (1421 Dec)
E = 1
LI2 = 10111011100 (1500 Dec)
DL AMD : 9C 02 D3 ED DC 5D C0 E4 D4 DE 42 97 6B C5 3F DD 14 D8 31 CA F6 4F 16 D8 70 8D 4A 8B 0B 4C 07 CB D0 DC 0B BD 9A FD C3 24 07 3D 79 AA 02 0E E0 23 29 D0 ...
Header decode of the captured PDU above,
9C 02 D3 ED DC 5D = 10011100 00000010 11010011 11101101 11011100 01011101
D/C = 1 = Data PDU
RF = 0 = AMD PDU
P = 0 = Status PDU is not requested
FI = 11 = First byte of the Data field does not corresponds to the first byte of a RLC SDU,
Last byte of the Data field does not corresponds to the last byte of a RLC SDU
E = 1 = A set of E field and LI field follows from the octet following the fixed part of the header
SN = 0000000010
E = 1
LI1 = 1010011 1110 (1342 Dec)
E = 1
LI2 = 10111011100 (1500 Dec)
DL AMD : 94 12 84 ED DC 5D C0 BB 9E AE E2 26 8C 70 1D 50 FB 35 B2 B4 1A E1 96 52 5B BE 0A A1 D2 DF C1 FF 46 F4 00 54 06 AD CB 14 8F 56 7A DE 43 A6 D1 F9 C8 ...
Header decode of the captured PDU above,
94 12 84 ED DC 5D = 10010100 00010010 10000100 11101101 11011100 01011101
D/C = 1 = Data PDU
RF = 0 = AMD PDU
P = 0 = Status PDU is not requested
FI = 10 = First byte of the Data field does not corresponds to the first byte of a RLC SDU,
Last byte of the Data field corresponds to the last byte of a RLC SDU
E = 1 = A set of E field and LI field follows from the octet following the fixed part of the header
SN = 00 00010010
E = 1
LI1 = 00001001110 (78 Dec)
E = 1
LI2 = 10111011100 (1500 Dec)
DL AMD : BC 1B B6 4D DC 5D C0 C7 33 AF D4 1D FB CC 72 17 B0 35 91 F3 6F 37 38 66 EE 07 D2 8A B1 2C 15 73 80 57 22 CD 3D A5 D8 4A 4B 0A AF 31 C2 2B D6 BD
Header decode of the captured PDU above,
BC 1B B6 4D DC 5D = 10111100 00011011 10110110 01001101 11011100 01011101
D/C = 1 = Data PDU
RF = 0 = AMD PDU
P = 1 = Status PDU is requested
FI = 11 = First byte of the Data field does not corresponds to the first byte of a RLC SDU,
Last byte of the Data field does not corresponds to the last byte of a RLC SDU
E = 1 = A set of E field and LI field follows from the octet following the fixed part of the header
SN = 0000011011 (27 Dec)
E = 1
LI1 = 01101100100 (868 Dec)
E = 1
LI2 = 10111011100 (1500 Dec)
DL AMD : A0 00 00 08 01 20 3A 90 05 1E F0 63 69 B1 F1 86 1B 25 20 3C 78 DF C6 AB B8 82 F3 93 5A B5 A7 64 80 0D 1E 79 72 F3 93 5E 35 A8 00 00 00 00
Header decode of the captured PDU above,
A0 00 = 10100000 00000000
D/C = 1 = Data PDU
RF = 0 = AMD PDU
P = 1 = Status PDU is requested
FI = 00 = First byte of the Data field corresponds to the first byte of a RLC SDU,
Last byte of the Data field corresponds to the last byte of a RLC SDU
E = 0 = Data field follows from the octet following the LI field following this E field
SN = 0000000000
RLC PDU = A0 00 00 08 01 20 3A 90 05 1E F0 63 69 B1 F1 86 1B 25 20 3C 78 DF C6 AB B8 82 F3 93 5A B5 A7 64 80 0D 1E 79 72 F3 93 5E 35 A8 00 00 00 00
UL AMD : 00 04 = 00000000 00000100
Header decode of the captured PDU above,
D/C = 0 = Control PDU CPT = 000 = Status PDU ACN_SN = 0000000001 (This is ACK for DL RLC SN 0) E1 = 0
UL AMD : 00 78 = 00000000 01111000
Header decode of the captured PDU above,
D/C = 0 = Control PDU CPT = 000 = Status PDU ACN_SN = 0000011110 (This is ACK for DL RLC SN 29) E1 = 0
UL AMD : A0 01 01 48 01 60 EA 61 14 79 E5 CB CE 4D 6A D6 80 00 00 00 00
Header decode of the captured PDU above,
A0 00 = 10100000 00000001
D/C = 1 = Data PDU
RF = 0 = AMD PDU
P = 1 = Status PDU is requested
FI = 00 = First byte of the Data field corresponds to the first byte of a RLC SDU,
Last byte of the Data field corresponds to the last byte of a RLC SDU
E = 0 = Data field follows from the octet following the LI field following this E field
SN = 0000000001
RLC PDU = A0 01 01 48 01 60 EA 61 14 79 E5 CB CE 4D 6A D6 80 00 00 00 00
DL AMD : 00 08 = 00000000 00001000
Header decode of the captured PDU above,
D/C = 0 = Control PDU CPT = 000 = Status PDU ACN_SN = 0000000010 (This is ACK for UL RLC SN 1) E1 = 0 (It means that Octat 2 is the last Octat for this RLC PDU).
DL AMD : 00 22 00 40 0C 01 C0 20 = 00000000 00100010 00000000 01000000 00001100 00000001 11000000 00100000
Header decode of the captured PDU above,
D/C = 0 = Control PDU (1 bit) CPT = 000 = Status PDU (3 bits) ACN_SN = 0000001000 (10 bits, This is ACK for UL RLC SN 7) E1 = 1 (1 bit, It means that this is not the end of RLC PDU). NACK_SN = 0000000000 = 0 (10 bits) E1 = 1 (1 bit, It means that this is not the end of RLC PDU) E2 = 0 (1 bit, a set of SOstart and SOend does not follow for this NACK_SN) NACK_SN = 0000000001 = 1 (10 bits) E1 = 1 (1 bit, It means that this is not the end of RLC PDU) E2 = 0 (1 bit, a set of SOstart and SOend does not follow for this NACK_SN) NACK_SN = 0000000011 = 3 (10 bits) E1 = 1 (1 bit, It means that this is not the end of RLC PDU) E2 = 0 (1 bit, a set of SOstart and SOend does not follow for this NACK_SN) NACK_SN = 0000000100 = 4 (10 bits) E1 = 0 (1 bit, It means that this is the end of RLC PDU) E2 = 0 (1 bit, a set of SOstart and SOend does not follow for this NACK_SN)
Examples for RLC UMD PDU
UMD PDUs are harder to read by eye than AMD PDUs, because they carry no D/C, RF or P bits. These four PDUs use a 10 bit SN, so the first byte starts with three R1 bits. Watch the SN run from 225 to 228, and look at the LI and the padding bits in PDU 1 and PDU 4.
This example data are captured from a RLCs for IP throughput test (in this case, video streaming test)
DL UMD PDU 1: 1C E1 06 8F CC 48 23 E9 90 DA 18 D2 2B 1B A3 D9 5C 72 E8 D7 71 A9 51 A9 82 78 17 80 DC 9B 18 76 17 99 18 48 7F 77 22 B9 8E 79 DA A9 58 5A C8 6E 1C 93 F9 1D 64 C4 58 56 46 0C B5 A3 0C 5E B3 24 49 8F F0 51 FC D7 A0 F6 29 A3 51 73 C2 31 9E F8 4B 0F 07 34 B1 06 A8 E1 79 E0 E0 DD C7 C8 FC 23 52 08 D8 F4 48 ED 9A 70 10 EF DD 1C 80 54 45 00 02 50 0E 62 00 00 80 11 95 C9 01 01 C9 37 01 01 C9 38 04 E7 04 D2 02 3C 9B 62 47 00 44 11 E6 F0 B0 1C 80 33 A5 2C 12 C2 C8 35 16 92 61 68 12 07 0D 81 CC C7 29 C9 21 A1 B9 94 6C 25 22 E3 28 78 1A 6A E3 5A 50 1B 13 83 33 C6 57 11 4D 5B 19 55 08 31 26 75 FA 4B 42 FB 84 FF 2B 1B E2 22 B3 9C 67 07 20 AC 24 07 0D 89 6B 4D 07 24 57 BC 94 CF
Header decode of the captured PDU above,
1C E1 = 00011100 11100001
R1 = 0
R1 = 0
R1 = 0
FI = 11 = First byte of the Data field does not correspond to the first byte of a RLC SDU,
Last byte of the Data field does not correspond to the last byte of a RLC SDU
E = 1 = A set of E field and LI field follows from the octet following the fixed part of the header
SN = 0011100001 = 225
06 8F = 00000110 10001111
E = 0
LI = 0000110 1000 = 104
Padding = 1111
SDU 1:
SDU bytes carried in the captured PDU,
CC 48 23 E9 90 DA 18 D2 2B 1B A3 D9 5C 72 E8 D7 71 A9 51 A9 82 78 17 80 DC 9B 18 76 17 99 18 48 7F 77 22 B9 8E 79 DA A9 58 5A C8 6E 1C 93 F9 1D 64 C4 58 56 46 0C B5 A3 0C 5E B3 24 49 8F F0 51 FC D7 A0 F6 29 A3 51 73 C2 31 9E F8 4B 0F 07 34 B1 06 A8 E1 79 E0 E0 DD C7 C8 FC 23 52 08 D8 F4 48 ED 9A 70 10 EF DD 1C
SDU 2: (The part in color is IP address of the data going through this RLC. This IP is nothing to do with RLC itself, but it will be a good example that multiple IP packets are distributed among multiple RLC PDUs)
SDU bytes carried in the captured PDU,
80 54 45 00 02 50 0E 62 00 00 80 11 95 C9 01 01 C9 37 01 01 C9 38 04 E7 04 D2 02 3C 9B 62 47 00 44 11 E6 F0 B0 1C 80 33 A5 2C 12 C2 C8 35 16 92 61 68 12 07 0D 81 CC C7 29 C9 21 A1 B9 94 6C 25 22 E3 28 78 1A 6A E3 5A 50 1B 13 83 33 C6 57 11 4D 5B 19 55 08 31 26 75 FA 4B 42 FB 84 FF 2B 1B E2 22 B3 9C 67 07 20 AC 24 07 0D 89 6B 4D 07 24 57 BC 94 CF
NOTE : The first two bytes (80 54) is the PDCP header and the remaining part is IP packet. If you copy the whole SDU2 data from the third byte(i.e, 45 00 ..) and decode it with 3GPP decoder, you can see the contents of the IP packet.
DL UMD PDU 2 : 18 E2 05 D2 2D 55 82 D9 82 51 91 A9 B8 BE C0 42 23 87 1B B6 1B CA B1 B6 3A 09 0E B9 64 6C B0 72 BA 74 53 A4 9D 8D 23 5C 9B 18 23 78 87 55 02 F4 07 E4 48 27 F0 8D 4A 3A 7E 09 80 8B 29 13 1A B2 7E 3C 8C 2B 9F 7F 0C AD E0 38 7E ED 40 B1 E8 73 46 62 4F 12 C8 FB 17 FC 70 FC A2 CF 85 52 A6 C3 40 4A 92 79 42 DC FE B0 47 00 44 12 E4 2A 94 21 8B DF 37 69 2F 5E D9 8A 3F 65 E8 73 D4 9A 00 EE 49 D0 AC 8E 39 7E 23 F0 F9 43 F8 1B 1E FF 0A F4 5E 7C 8C B0 F2 B3 C3 80 29 E1 3A 9E 2E A0 38 DF 3C EE 1D DF 06 BE FD 82 37 62 13 A5 F1 40 F2 D5 17 6D 99 9E 5A BF D6 AB 1D 7B 96 31 1F 31 0A 1C 24 AA 35 3D 13 00 D5 B1 97 1A BC C4 7C 7A A3 C0 9E AB AC A3 75 1D 3B 2D D5 04 AA 3F 73 73 36 1F
Header decode of the captured PDU above,
18 E2 = 00011000 11100010
R1 = 0
R1 = 0
R1 = 0
FI = 11 = First byte of the Data field does not correspond to the first byte of a RLC SDU,
Last byte of the Data field does not correspond to the last byte of a RLC SDU
E = 0 = Data field follows from the octet following the fixed part of the header
SN = 0011100010 = 226
DL UMD PDU 3: 18 E3 4B 8B 6C 04 16 7B A4 DA 64 E7 D5 39 A3 2A 97 15 B0 E2 4E A5 3F 1E 38 50 2E 71 B7 18 F8 D8 F6 B1 E1 39 1C 44 80 F7 E0 F8 1D 21 2E 50 BA 80 84 A2 7F 52 BF 0F 57 3A FE 42 18 E8 2C 89 8C 75 FF 28 3A 98 02 4C 47 00 44 13 3C 11 81 25 A3 1A 5E 5B F7 1A E2 F0 57 F8 A7 D1 3A 4B 82 41 B0 E4 07 D0 A3 55 2C B7 F0 F4 C1 C5 28 90 7E 15 D7 82 CC 07 FE A0 17 0E 7C AD 49 2C 48 A0 1C 23 52 A5 71 A3 D7 5E 7E 3D 1B 8B E0 CE BC 86 8E DA FA 0B F0 B9 2F 6D 3A 0F FF 64 16 EB 53 B6 9D A9 10 4B 69 25 DF 93 30 B6 F1 A4 2E 36 CF 7C F2 92 7D E3 CB 48 AB 5E AC 4F A2 00 01 18 0D 2F 28 D0 F3 A6 04 2A 8B 6A 52 B7 A1 71 A1 C7 EF C0 B0 F2 A5 C9 16 18 30 71 6A FF 47 D2 C2 C0 0D 02 50 FB 2A 87
Header decode of the captured PDU above,
18 E3 = 00011000 11100011
R1 = 0
R1 = 0
R1 = 0
FI = 11 = First byte of the Data field does not correspond to the first byte of a RLC SDU,
Last byte of the Data field does not correspond to the last byte of a RLC SDU
E = 0 = Data field follows from the octet following the fixed part of the header
SN = 0011100011 = 227
DL UMD PDU 4: 1C E4 02 2F 92 F1 62 09 15 25 34 19 DC E4 3D 46 DE 9A 44 A9 2B 3F CF 44 1A 36 BA B9 89 D6 14 54 F0 B5 F0 60 7C 7F 80 55 45 00 02 50 0E 63 00 00 80 11 95 C8 01 01 C9 37 01 01 C9 38 04 E7 04 D2 02 3C 6C 19 47 00 44 14 29 50 78 3D EE C9 0C 23 9E CF A4 41 4E F1 E5 6B 81 72 B2 1A 57 CD FC 39 55 29 4F 84 CF 52 79 CC A5 03 5A 1A 34 E6 30 39 C2 3F B1 E3 BE 13 99 B8 50 63 4D 45 4E 69 F8 5B 9A 46 4B A6 23 9C 8E 12 99 CD 4C B0 73 49 78 33 C6 8C 6B C1 94 9C D2 20 F3 87 61 0B EC D1 E3 FD CC 0E D1 9D 2D 20 EE 60 34 6E F6 4E 5E 41 C1 3B 06 B9 72 20 32 B2 35 30 6B 63 E8 BC 3B 27 AB D6 F5 70 B2 0D 4F 09 34 06 69 96 59 1B 37 0D C3 5B D8 2C D4 6A FA 9F 3D 5E E3 5B AF AF F0 D8 43 0B
Header decode of the captured PDU above,
1C E4 = 00011100 11100100
R1 = 0
R1 = 0
R1 = 0
FI = 11 = First byte of the Data field does not correspond to the first byte of a RLC SDU,
Last byte of the Data field does not correspond to the last byte of a RLC SDU
E = 1 = A set of E field and LI field follows from the octet following the fixed part of the header
SN = 0011100100 = 228
02 2F = 00000010 00101111
E = 0
LI = 0000010 0010 = 34
Padding = 1111
SDU 1:
SDU bytes carried in the captured PDU,
92 F1 62 09 15 25 34 19 DC E4 3D 46 DE 9A 44 A9 2B 3F CF 44 1A 36 BA B9 89 D6 14 54 F0 B5 F0 60 7C 7F
SDU 2: (The part in color is IP address of the data going through this RLC. This IP is nothing to do with RLC itself, but it will be a good example that multiple IP packets are distributed among multiple RLC PDUs)
SDU bytes carried in the captured PDU,
80 55 45 00 02 50 0E 63 00 00 80 11 95 C8 01 01 C9 37 01 01 C9 38 04 E7 04 D2 02 3C 6C 19 47 00 44 14 29 50 78 3D EE C9 0C 23 9E CF A4 41 4E F1 E5 6B 81 72 B2 1A 57 CD FC 39 55 29 4F 84 CF 52 79 CC A5 03 5A 1A 34 E6 30 39 C2 3F B1 E3 BE 13 99 B8 50 63 4D 45 4E 69 F8 5B 9A 46 4B A6 23 9C 8E 12 99 CD 4C B0 73 49 78 33 C6 8C 6B C1 94 9C D2 20 F3 87 61 0B EC D1 E3 FD CC 0E D1 9D 2D 20 EE 60 34 6E F6 4E 5E 41 C1 3B 06 B9 72 20 32 B2 35 30 6B 63 E8 BC 3B 27 AB D6 F5 70 B2 0D 4F 09 34 06 69 96 59 1B 37 0D C3 5B D8 2C D4 6A FA 9F 3D 5E E3 5B AF AF F0 D8 43 0B
NOTE : The first two bytes (80 55) is the PDCP header and the remaining part is IP packet. If you copy the whole SDU2 data from the third byte(i.e, 45 00 ..) and decode it with 3GPP decoder, you can see the contents of the IP packet.
Examples from real life - Live Network
When you open a live log, a few checks catch most RLC problems. First, follow the SN of each bearer and look for gaps. Then match every PDU with P=1 to the STATUS PDU that answers it, and check that its ACK_SN moves past the polled SN. After that, look for NACK_SN entries and for the retransmissions they cause. These may come back as AMD PDU segments with RF=1. Finally, remember that a handover re-establishes RLC and resets all state variables, so the SNs start again from 0 on the target cell.
Refer to Live Network Examples in Fullstack. You may need to put some more effort to find out RLC layer log from this example, but you will see more diverse RLC PDU/SDU structure and see the relationship between RLC and other layers.
Variables, constants and timers for RLC
You may noticed that the overall data flow of RLC sounds relatively easy to understand. But understanding the RLC layer mechanism in such a detail that would help you with troubleshooting and RLC performance optimization would not be a simple task. For the level of understanding like this, you need to understand the details of 3GPP 36.322 section 7 (Variables, constants and timers) and 3GPP 36.322 section 5 (Procedures). I would suggest to study section 7 first and then the section 5.
|
Variable Name |
Category |
Description |
|
State Variable |
Acknowledgement state variable This state variable holds the value of the SN of the next AMD PDU for which a positive acknowledgment is to be received in-sequence, and it serves as the lower edge of the transmitting window. It is initially set to 0, and is updated whenever the AM RLC entity receives a positive acknowledgment for an AMD PDU with SN = VT(A). |
|
|
State Variable |
Maximum send state variable VT(MS) = VT(A) + AM_Window_Size it serves as the higher edge of the transmitting window |
|
|
State Variable |
Send state variable This state variable holds the value of the SN to be assigned for the next newly generated AMD PDU. It is initially set to 0, and is updated whenever the AM RLC entity delivers an AMD PDU with SN = VT(S) |
|
|
State Variable |
Receive state variable This state variable holds the value of the SN following the last in-sequence completely received AMD PDU it serves as the lower edge of the receiving window. It is initially set to 0, and is updated whenever the AM RLC entity receives an AMD PDU with SN = VR(R). |
|
|
State Variable |
Maximum acceptable receive state variable VR(MR)=VR(R) + AM_Window_Size it holds the value of the SN of the first AMD PDU that is beyond the receiving window and serves as the higher edge of the receiving window. |
|
|
State Variable |
t-Reordering state variable This state variable holds the value of the SN following the SN of the RLC data PDU which triggered t-Reordering |
|
|
State Variable |
Maximum STATUS transmit state variable This state variable holds the highest possible value of the SN which can be indicated by 'ACK_SN' when a STATUS PDU needs to be constructed. It is initially set to 0 |
|
|
State Variable |
Highest received state variable This state variable holds the value of the SN following the SN of the RLC data PDU with the highest SN among received RLC data PDUs. It is initially set to 0. |
|
|
State Variable |
This state variable holds the value of the SN to be assigned for the next newly generated UMD PDU. It is initially set to 0, and is updated whenever the UM RLC entity delivers an UMD PDU with SN = VT(US). |
|
|
State Variable |
UM receive state variable This state variable holds the value of the SN of the earliest UMD PDU that is still considered for reordering. It is initially set to 0 |
|
|
State Variable |
UM t-Reordering state variable This state variable holds the value of the SN following the SN of the UMD PDU which triggered t-Reordering |
|
|
State Variable |
UM highest received state variable This state variable holds the value of the SN following the SN of the UMD PDU with the highest SN among received UMD PDUs, and it serves as the higher edge of the reordering window. It is initially set to 0 |
|
|
State Variable |
Poll send state variable This state variable holds the value of VT(S)-1 upon the most recent transmission of a RLC data PDU with the poll bit set to '1'. It is initially set to 0. |
|
|
Counter |
This counter is initially set to 0. It counts the number of AMD PDUs sent since the most recent poll bit was transmitted |
|
|
Counter |
This counter is initially set to 0. It counts the number of data bytes sent since the most recent poll bit was transmitted |
|
|
Counter |
This counter counts the number of retransmissions of an AMD PDU. There is one RETX_COUNT counter per PDU that needs to be retransmitted. |
|
|
Constant |
AM_Window_Size = 512 |
|
|
Constant |
UM_Window_Size = 16 when SN size = 5 bits UM_Window_Size = 512 when SN size = 10 bits UM_Window_Size = 0 when UM RLC is for MTCH or MCCH |
|
|
Timer |
used by the transmitting side of an AM RLC entity in order to retransmit a poll |
|
|
Timer |
This timer is used by the receiving side of an AM RLC entity and receiving UM RLC entity in order to detect loss of RLC PDUs at lower layer. only one t-Reordering per RLC entity is running at a given time. |
|
|
Timer |
This timer is used by the receiving side of an AM RLC entity in order to prohibit transmission of a STATUS PDU |
|
|
Configurable parameters |
This parameter is used by the transmitting side of each AM RLC entity to limit the number of retransmissions of an AMD PDU |
|
|
Configurable parameters |
This parameter is used by the transmitting side of each AM RLC entity to trigger a poll for every pollPDU PDUs |
|
|
Configurable parameters |
This parameter is used by the transmitting side of each AM RLC entity to trigger a poll for every pollByte bytes |
|
|
Configurable parameters |
This parameter gives the UM SN field size in bits |
The table follows the Release 8 values, and two constants have grown since then. AM_Window_Size is 512 with a 10 bit SN and 32768 with the 16 bit SN of Release 13. The AM state variables then run from 0 to 65535 instead of 0 to 1023. UM_Window_Size is also 0 for SC-MCCH, SC-MTCH and sidelink STCH, not only for MCCH and MTCH. For an entity on STCH, VR(UR) and VR(UH) start at the SN of the first UMD PDU received rather than at 0.
Every comparison of SNs in 36.322 uses modulus arithmetic. At the AM transmitter the base is VT(A), and at the AM receiver it is VR(R). At the UM receiver the base is VR(UH) - UM_Window_Size. The base is subtracted from every value before the comparison, so a check such as VR(R) <= SN < VR(MR) still works when the SN wraps from 1023 back to 0.
Process of RLC UM Transmission
This section is about the RLC UM transmission procedure marked in yellow below. You can see the overall description from Overall Data Flow for UM RLC
< 36.322 Figure 4.2.1.2.1-1: Model of two unacknowledged mode peer entities >
The detailed procedure is described in 36.322 5.1.2.1 Transmit operations. (To understand this description, you have all of the variable description from Variables, constants and timers for RLC)
The process is simple. If I describe it in a psuedo code, it will be as follows.
i) VT(US) = SN (Sequence Number of the current PDU)
ii) VT(US) = VT(US) + 1
In 36.322 the assignment in step i runs the other way round. When the entity delivers a new UMD PDU to MAC, it sets the SN of that PDU to VT(US), and then increments VT(US) by one. VT(US) starts at 0 and wraps at 2sn-FieldLength, so at 32 with a 5 bit SN and at 1024 with a 10 bit SN.
UM has no retransmission and no feedback, but two more rules apply to the transmitter. When PDCP asks RLC to discard an SDU, the UM entity discards it only if no segment of it is in a UMD PDU yet. At RLC re-establishment, the transmitting UM entity discards all of its SDUs.
The UMD examples further down show this counter in a real log. The four DL UMD PDUs there carry SN 225, 226, 227 and 228, one after the other, so the transmitter incremented VT(US) once per PDU. They use a 10 bit SN, so the counter wraps to 0 after SN 1023.
SN = VT(US), then VT(US) + 1 : the SN counts UMD PDUs, not SDUs.The SN space is small : 32 values with a 5 bit SN and 1024 with 10 bits, so the SN wraps often on a busy bearer.PDCP discard works only before segmentation : once a segment of the SDU is in a UMD PDU, RLC keeps the SDU.
Process of RLC UM Reception
This section is about the RLC UM reception procedure marked in yellow below. You can see the overall description from Overall Data Flow for UM RLC
< 36.322 Figure 4.2.1.2.1-1: Model of two unacknowledged mode peer entities >
The reception process is described in "36.322 5.1.2.2 Receive operations" and at high level point of view the process goes as follows. Comparing to transmission process, you would immediately notice that recieiving process is much more complicated. The main reason of this complexity lies in the fact that you cannot guarantee that all the PDUs are coming in exact order (i.e, in-sequence). So we have to implement a specific algorithm to handle the case when these PDUs are coming out-of-sequence.
The receiving UM RLC entity shall maintain a reordering window according to state variable VR(UH) as follows:
- a SN falls within the reordering window if (VR(UH) – UM_Window_Size) <= SN < VR(UH);
- a SN falls outside of the reordering window otherwise.
When receiving an UMD PDU from lower layer, the receiving UM RLC entity shall:
- either discard the received UMD PDU or place it in the reception buffer (Refer to < Case 1 >);
If the received UMD PDU was placed in the reception buffer:
- update state variables, reassemble and deliver RLC SDUs to upper layer and start/stop t-Reordering as
needed (Refer to < Case 2 >);
When t-Reordering expires, the receiving UM RLC entity shall:
- update state variables, reassemble and deliver RLC SDUs to upper layer and start t-Reordering as needed (Refer to < Case 3 >).
Looking into this procedure in more detail, it can be split into following three sub process (cases).
Case 1 : Actions when an UMD PDU is received from lower layer
This process is described in 36.322 5.1.2.2.2 Actions when an UMD PDU is received from lower layer. I will summarise the process as follows. (NOTE : x = the sequence number of the received PDU)
if ( ( VR(UR) < x < VR(UH) ) AND (SN is overlapping with any one of previous PDUs) )
OR ((VR(UH) - UM_Window_Size) <= x < VR(UR) )
{
discard the received UMD PDU;
} else {
place the received UMD PDU in the reception buffer;
};
Case 2 : Actions when an UMD PDU is placed in the reception buffer
This process is described in 36.322 5.1.2.2.3 Actions when an UMD PDU is placed in the reception buffer. I will summarise the process as follows.
if ( SN is Not within the reordering window)
{
i) VR(UH) = SN + 1;
ii) reassemble RLC SDUs from any UMD PDUs with SN that falls outside of the reordering window, remove RLC headers when doing so and deliver the reassembled RLC SDUs to upper layer in ascending order of the RLC SN if not delivered before
if (VR(UR) falls outside of the reordering window) {
VR(UR) = (VR(UH) - UM_Window_Size);
}
}
if (the reception buffer contains an UMD PDU with SN = VR(UR) )
{
i) VR(UR) = (the SN of the first UMD PDU with SN which is greater than current VR(UR) ) that has not been received);
ii) reassemble RLC SDUs from any UMD PDUs with SN which is smaller than updated VR(UR), remove RLC headers when doing so and deliver the reassembled RLC SDUs to upper layer in ascending order of the RLC SN if not delivered before;
}
if(t-Reordering is running) {
if (VR(UX) <= VR(UR) ) OR (VR(UX) falls outside of the reordering window) AND (VR(UX) != VR(UH) ) {
stop and reset t-Reordering;
}
} else {
i) start t-Reordering;
}
}
Since Release 15, 36.322 adds one step at the start of this clause. If rlc-OutOfOrderDelivery is configured and all byte segments of the UMD PDU have arrived, the receiver reassembles that SDU and delivers it at once. It does not wait for the lower SNs in that case.
Case 3 : Actions when t-Reordering expires
t-Reordering is how the UM receiver stops waiting for a missing PDU. When the timer expires, the receiver treats the missing SNs below VR(UX) as lost. It delivers the SDUs it can reassemble, and it restarts the timer if a gap still remains. This follows 36.322 clause 5.1.2.2.4.
VR(UR) = the SN of the first UMD PDU with SN >= VR(UX) that has not been received;
Reassemble RLC SDUs from any UMD PDUs with SN < updated VR(UR), remove RLC headers when doing so
and deliver the reassembled RLC SDUs to upper layer in ascending order of the RLC SN if not delivered before;
start t-Reordering;
}
Process of RLC AM Transmission
The AM transmitter has more to do than the UM one. It numbers new PDUs, keeps them until the peer acknowledges them, retransmits what the peer reports as lost, and decides when to ask for a report. Let's go through 36.322 clauses 5.1.3.1, 5.2.1 and 5.2.2 in that order.
The transmitter keeps a transmitting window from VT(A) up to VT(MS), where VT(MS) = VT(A) + AM_Window_Size. It never sends a data PDU whose SN falls outside this window. When it delivers a new AMD PDU to MAC, it sets the SN to VT(S) and then increments VT(S) by one. When the peer positively acknowledges the PDU with SN = VT(A), VT(A) moves up to the lowest SN that is still unacknowledged. Once every PDU of an SDU is acknowledged, RLC tells PDCP that the SDU was delivered.
The transmitter also follows a fixed priority. RLC control PDUs go first, retransmissions go second, and new AMD PDUs go last. So a STATUS PDU for the other direction never waits behind a queue of data PDUs.
A negative acknowledgement arrives in a STATUS PDU, either for a whole AMD PDU or for a byte range given by SOstart and SOend. If the SN lies within VT(A) <= SN < VT(S), the transmitter considers that PDU or portion for retransmission. The first time, it sets RETX_COUNT for that PDU to 0. After that, it increments RETX_COUNT each time the PDU is considered again and is not already pending. When RETX_COUNT reaches maxRetxThreshold, RLC indicates this to upper layers.
If the retransmission fits the grant, the AMD PDU goes out unchanged except for the P field. Otherwise the transmitter re-segments it into AMD PDU segments, and the number of re-segmentations is not limited.
Polling decides when the peer should report. The transmitter sets P=1 in three situations. The first is when PDU_WITHOUT_POLL reaches pollPDU or BYTE_WITHOUT_POLL reaches pollByte. The second is when both the transmission buffer and the retransmission buffer become empty after this PDU. The third is when window stalling stops any new PDU. When it sends a poll, the transmitter resets both counters, sets POLL_SN to VT(S) - 1, and starts or restarts t-PollRetransmit.
t-PollRetransmit stops when a STATUS PDU acknowledges or negatively acknowledges POLL_SN. If it expires first, the transmitter sends a new poll. When both buffers are empty or the window has stalled, it first picks the PDU with SN = VT(S) - 1, or any unacknowledged PDU, for retransmission, so that there is a PDU to carry the poll.
VT(A) to VT(MS) is the transmitting window : nothing outside it is sent, so the transmitter stalls when the peer stops acknowledging.Control, then retransmission, then new data : this is the fixed priority of the AM transmitter.RETX_COUNT reaching maxRetxThreshold goes to RRC : in the UE, RRC treats it as radio link failure.Every poll restarts t-PollRetransmit : POLL_SN records the highest SN that the poll covers.
Process of RLC AM Reception
The AM receiver has two jobs. It reorders and reassembles the data as UM does, and it also reports to the peer what is missing. 36.322 clauses 5.1.3.2 and 5.2.3 describe both, using five state variables: VR(R), VR(MR), VR(X), VR(MS) and VR(H).
The receiving window runs from VR(R) up to VR(MR) = VR(R) + AM_Window_Size. A data PDU carries byte segments y to z of the AMD PDU with SN = x. The receiver discards it if x is outside the window, or if those bytes were received before. Otherwise it places the PDU in the reception buffer and drops only the duplicate bytes.
Placing a PDU in the buffer updates the state variables. If x >= VR(H), VR(H) becomes x + 1. When the PDU with SN = VR(MS) is complete, VR(MS) moves to the next SN that is not complete. When the PDU with SN = VR(R) is complete, VR(R) moves up the same way and VR(MR) follows it. The receiver then delivers the SDUs it can reassemble, in sequence. If rlc-OutOfOrderDelivery is configured, the receiver delivers each complete AMD PDU at once instead.
t-Reordering covers the gap between VR(R) and VR(H). If the timer is not running and VR(H) > VR(R), the receiver starts it and sets VR(X) to VR(H). It stops the timer when VR(X) = VR(R), or when VR(X) falls outside the window and is not equal to VR(MR). If the timer expires, VR(MS) moves to the first SN at or above VR(X) that is not complete. The timer restarts if VR(H) > VR(MS).
Two events trigger a STATUS report. The first is a PDU with P=1. The receiver triggers the report at once if that PDU is discarded, or if x < VR(MS) or x >= VR(MR). Otherwise it waits until one of these conditions becomes true, so that HARQ reordering has finished first. The second event is the expiry of t-Reordering. If t-StatusProhibit is running, the receiver sends a single STATUS PDU after the timer expires, however many triggers came in between. It starts t-StatusProhibit again each time it delivers a STATUS PDU to MAC.
To build the STATUS PDU, the receiver walks from VR(R) up to VR(MS). It lists each missing AMD PDU as a NACK_SN, and each missing byte range of a partly received PDU as a NACK_SN with SOstart and SOend. It stops when the PDU no longer fits the grant. Then it sets ACK_SN to the next SN not received that the STATUS PDU does not list as missing.
VR(R) is the lower edge, VR(H) the highest SN seen : t-Reordering waits for the gap between them.VR(MS) limits the STATUS PDU : ACK_SN never goes beyond it.A poll is answered after HARQ reordering : that is the reason for the x < VR(MS) or x >= VR(MR) condition.t-StatusProhibit merges reports : several triggers while it runs give one STATUS PDU.
Some issues with RLC Verification/Validation
I think one of the biggest issues with RLC test would be that most of the test equipt does not provide much flexibility in terms of RLC layer testing. Most of the equipment seems to think of RLC as just an intermediate blocks between PHY/MAC and RRC/NAS and think that just providing a normal RLC functionality as a big chunk with very limited user configuration would be good enough, and most of the customer of those equipment vendor does not put many strong requests for it. It may be OK and I haven't seen many cases where RLC layer is causing any serious issues, but sometimes this layer is really causing some problem and once the problem happens in this layer it tend to be really tricky to pin point out the root cause of the problem.
Some of the typical issues which may caused by RLC layer would be
i) When a bunch of RLC PDU/SDUs coming into RLC reciever with out-of sequence, the reciever fails to properly reorder it in correct sequence.
ii) When a bunch of RLC PDU/SDUs coming into RLC reciever with some missing sequence number, the receiver fails to detect the exact missing sequence number and send proper RLC status report to the other party.
iii) When a RLC sender send a RLC packet with Poll Bit Set, the reciever failed to reply with correct RLC status report or the status report within the specified time frame.
Probably this kind of problem would tend to occur in WCDMA low data rate configuration (e.g, R99) because there would be higher degree of fragmentation for a single C-plane or U-Plane user data packet. In this theory, LTE would have less problems since LTE can have very large data pipe that can carry a whole C-Plane/U-Plane packet with single transmission. But still there would be some possibility of RLC layer issues especially related to fragmentation and timing issues due to following reasons :
i) In real network (live network), it is not guaranteed that Network would allocate enough resource for the UE so that it can transmit a whole U-plane/C-plane packet without fragmentation.
ii) Even though the network would allocate the big enough resources for the UE, you cannot guarantee that it would allocate the resources before RLC timer get expired. (this would be less probable, but possible in theory).
Reference
[1] 3GPP TS 36.322 v19.0.0 - Evolved Universal Terrestrial Radio Access, E-UTRA, Radio Link Control, RLC, protocol specification
[2] 3GPP TS 36.331 v19.3.0 - RLC-Config, DRB-ToAddMod, SRB-ToAddMod and clause 9.2.1, default SRB configurations