add_bearer:
//choose mode-->insert entity-->configure and add to array
configure:
//check timers-->configure timers-->configure timers/status_prohibit_timer
write_sdu:
//check size-->check if block on write to queue-->write-->in case of fail, the try_write returns back the sdu;
总结:write_sdu的作用:
可以写就写,不能写就返回?
read_pdu:
//Tx STATUS if requested-->build_status_pdu
//if tx_window is full and retx_queue empty-->retransmit random PDU
// RETX if required--->build_retx_pdu()
build_status_pdu:
//get_status_pdu
//reset_status-->run()
//debug_state-->rlc_am_write_status_pdu
get_status_pdu:
// start with lower edge of the rx window--->status->ack_sn = vr_r!
//We don't use segment NACKs - just NACK the full PDU
// only update ACK_SN if this SN has been received
// make sure we don't exceed grant size---->if (status->N_nack >= 1 && status->N_nack < RLC_AM_WINDOW_SIZE)--->status->N_nack
// make sure we don't have the current ACK_SN in the NACK list-->rlc_am_is_valid_status_pdu
retransmit_random_pdu:
//randomly select PDU in tx window for retransmission(rand)-->retx_queue.push_b
ack
build_retx_pdu:
// Check there is at least 1 element before calling front()-->front()应该就是取队首元素;
//Sanity check - drop any retx SNs not present in tx_window(tx_window.end() == tx_window.find(retx.sn)-->retx-queuepop-front()???为什么发送窗口首位的单元不能重传?
// Is resegmentation needed?--->required_buffer_size-->build_segment
// Update & write header
// Set poll bit
//rlc_am_write_data_pdu_header
//max_retx_attempted
//debug_state
required_buffer_size:
//Construct new header---->rlc_am_packed_length(&new_header)
//Need to rebuild the li table & update fi based on so_start and so_en
build_segment:
//Construct new header--->rlc_am_packed_length(&new_header)
//Make sure we can fit at least one N_li element if old header contained at least one-->if (old_header.N_li > 0)
//pdu_space = nof_bytes - head_len
//Need to rebuild the li table & update fi based on so_start and so_end--->if (retx.so_start == 0 && rlc_am_start_aligned(old_header.fi))
//Accomodate some extra space for for LIs if old header contained segments too
//only increment N_li if more SDU (segments) are being added
//Update retx_queue--->Write header and pdu
build_data_pdu:
// do not build any more PDU if window is already full
// Check for SDU segment
// if (tx_sdu != NULL--->First byte does not correspond to first byte of SDU
// Pull SDUs from queue--> load new SDUs--while(loop)--->
//head_len = rlc_am_packed_length(&header); --->// fixed part+Extension part--- integer rounding up
// Make sure, at least one SDU (segment) has been added until this point
// Set Poll bit
// Set SN
// Place PDU in tx_window, write header and TX----将相关数据记录在tx_window中
// Write header to pointer & move pointer Segment part+ Extension part + Pad if N_li is odd
debug_state();
return total_len;
总结:build_data_pdu做了些什么事:
检测整个窗口的状态--->检查是否有残留的SDU残留-->加入新的sdu-->头文件的设置--->发送窗口的设置-->合并头文件和SDU,生成pdu
总结:read_pdu做了些什么事情:
首先检测是否满足触发status的条件,满足则触发build_status_pdu:
*build_status_pdu调用get_status_pdu确认哪些SN收到了还是没收到,生成status report;
*如果重传队列为空并且发送窗口满,调用retransmit_random_pdu随机重传一个PDU;//没有插入轮询P?
*如果重传队列不为空:发送重传队列中的pdu,调用build_retx_pdu生成重传pdu
*检查是否需要对重传队列进行重分割;
*调用build segment 进行重分割;
*如果都没有问题,那就调用build_data_pdu生成新的pdu;
更新num_tx_bytes;
write_pdu:
//if (rlc_am_is_control_pdu(payload))--->handle_control_pdu
//rlc_am_read_data_pdu_header
//handle_data_pdu_segment/handle_data_pdu
handle_control_pdu:
//rlc_am_read_status_pdu--->E1,E2,CPT...
//stop poll_retx_timer--->reset?
// flush retx queue to avoid unordered SNs, we expect the Rx to request lost PDUs again
// Handle ACKs and NACKs
// sanity check--->print error but try to send original PDU again--->// check for special SO_end value
// if (!nack)--->// ACKed SNs get marked and removed from tx_window if possible
rlc_am_read_data_pdu_header:
// Fixed part---->Extension part---->Account for padding if N_li is odd
handle_data_pdu_segment:
// Check inside rx window
// Check if we already have a segment from the same PDU
// Add segment to PDU list and check for complete--->add_segment_and_check--->Check for first segment--> Check for complete---> We have all segments of the PDU - reconstruct and handle--->Reconstruct fi\Li field-->Copy data--->handle_data_pdu
handle_data_pdu:
//sanity check for segments not exceeding PDU length-->Len and inside of window?
// Write to rx window-->check available space for payload-->Update vr_h-->vr_ms
// Check poll bit
// Reassemble and deliver SDUs--> reassemble_rx_sdus
// Update reordering variables and timers
reassemble_rx_sdus:
// reassemble_rx_sdus-->while(vr_r!=end(0) Handle any SDU segments-->sanity check to avoid zero-size SDUs-->进行了几次长度判断(都是哪些方面)-->调用pdcp->write_pdu()
//ptr msg should point to the length of sdu recieved already;
//Handle last segment-->// Move the rx_window-->also erase any segments of this SN
总结:write_pdu作用:
*判断是不是控制pdu,如果是,调用handle_control_pdu进行处理;
*对状态报告进行解读;rlc_am_rad_status_pdu
**如果状态报告中包含有NACk的包,则清空重传窗口;???每次都这样吗?
*如果是数据pdu,
*调用rlc_am_read_data_pdu_header读取header数据;
*如果是pdu segment-->pdu
*调用reasemble_rx_sdus重组sdu;
*给出了此pdu中有多少的个sdu segment;
*用len指示当前的分段的长度
*用rx_sdu标识接收端缓冲区大小;
*接收窗口好像直接把数据给rx_sdu缓冲区了,到底是怎么重组回来的呢?
*如果sdu的大小大于单个PDU的时候如何处理?一个sdu放在三个pdu的情况怎么办?
==========================TM============================================
总结:TM模式较为简单粗暴:
*write_sdu和AM模式相差不大;能写就写,写不下丢掉;
*read_pdu中,直接读取走sdu;
*write_pdu中,拷贝走了数据,判断是哪种承载,然后交付;
==========================UM============================================
总结:UM模式涉及到pdu的组装与拆分:
*build_data_pdu
*检测是否sdu segment 残留-->有,压入pdu,并设置fi为非从头开始-->压入其它sdu-->检查是否整个sdu压完或者pdu是否还有空间-->设置标头
*handle_data_pdu
*read_data_pdu_header,对相关的值进行判断,是否为正常的sdu,没什么好说的;
*写入接收窗口,
*分离pdu标头,
*如果sn不在接收窗口内,跟新窗口上限值
*reassemble_rx_sdus:
*先置位ur;
*开始处理pdu,
*丢弃有遗漏的sdu,其它的正常压入接收窗口;
* 处理最后一个segment,更新接收窗口;
*然后开始处理UR往上;
*if (not pdu_belongs_to_rx_sdu())
*Handle any SDU segments
*丢弃存在遗漏的sdu;
*跟新接收窗口指针;
*检查sdu剩余空间;
*在sdu缓冲区中设置了一个ur指针,指示提交的最大ur值,
*和接收窗口的指针值相比较,
*符合条件就继续传送这个sn的pdu;
*不符合的话更新接收缓冲区的sn值,开始传一个新的sn的值
*提交或者丢弃
*处理最后一个segment;
本文概述了UM模式中PDU处理流程,重点在于build_data_pdu的SDU组装,包括检查残留SDU、添加到PDU、设置头信息和处理接收窗口。read_pdu则涉及状态报告处理、随机重传和数据PDU的重组与交付。
3143

被折叠的 条评论
为什么被折叠?



