議狀態(tài)機(jī)與定時器:LTE可靠傳輸?shù)牡讓舆壿? alt=)
簡介面向LTE無線接入網(wǎng)研發(fā)、協(xié)議棧實(shí)現(xiàn)與測試崗位工程師的學(xué)習(xí)資料聚焦TD-LTE數(shù)字蜂窩移動通信網(wǎng)Uu接口中的RLC協(xié)議。內(nèi)容依據(jù)中國通信標(biāo)準(zhǔn)化協(xié)會技術(shù)報告系統(tǒng)規(guī)定E-UTRA RLC子層結(jié)構(gòu)、RLC實(shí)體、上下層業(yè)務(wù)關(guān)系、功能劃分以及與對等層通信的協(xié)議數(shù)據(jù)元、格式和參數(shù)并說明未知或錯誤協(xié)議數(shù)據(jù)的處理方式同時覆蓋確認(rèn)模式等關(guān)鍵機(jī)制可幫助讀者理解RLC在數(shù)據(jù)傳輸與差錯校正中的職責(zé)邊界。資源包共1個doc文件約1.74MB為中文協(xié)議文本適合作為協(xié)議查閱與實(shí)現(xiàn)對照的案頭文檔。目前已有493人學(xué)習(xí)適合需要梳理Uu接口協(xié)議分層、準(zhǔn)備協(xié)議棧開發(fā)或測試用例設(shè)計(jì)的讀者參考使用。1. RLC 協(xié)議為什么 LTE 的“可靠傳輸”不靠重傳次數(shù)堆出來很多人第一次翻 LTE 協(xié)議棧會覺得 RLC 這一層“沒什么存在感”——上有 PDCP 做加密和頭壓縮下有 MAC 做調(diào)度和 HARQRLC 夾在中間好像只是把數(shù)據(jù)切一切、編個號。但真正在鏈路層調(diào)過參數(shù)的人會告訴你掉話、速率上不去、切換后業(yè)務(wù)卡頓最后追下去十有八九落在 RLC 的狀態(tài)變量和定時器上。RLC 協(xié)議真正解決的問題不是“重傳”而是在一個底層 HARQ 已經(jīng)會重傳、上層又要求按序交付的環(huán)境里如何用最少的反饋把“哪些收到了、哪些沒收到、什么時候該等、什么時候該放棄”講清楚。這份 TD-LTE Uu 接口技術(shù)要求第 7 部分把 TM、UM、AM 三種實(shí)體、發(fā)送/接收窗口、t_Reordering、t_PollRetransmit、t_StatusProhibit 這些機(jī)制一條條寫成了可實(shí)現(xiàn)的規(guī)范。搞懂它你才能明白為什么 LTE 的可靠傳輸不是靠“多傳幾遍”堆出來的而是靠窗口和定時器把不確定性收斂掉。2. 三種模式的分工TM、UM、AM 到底在取舍什么2.1 TM 實(shí)體為什么它連 RLC 頭都不給透明模式是三種模式里最“反直覺”的一個。按規(guī)范描述發(fā)送 TM RLC 實(shí)體從上層收到 RLC SDU 后不做分段、不做級聯(lián)也不在 TMD PDU 里加任何 RLC 頭直接往下層交。接收側(cè)同樣收到 TMD PDU 就原樣往上分發(fā)。這意味著 TM 實(shí)體根本不提供序列號也就沒有重排序、沒有重復(fù)檢測、沒有重傳。那它存在的意義是什么看它綁定的邏輯信道就明白了BCCH、DL/UL CCCH、PCCH。這些信道傳的是廣播信息、公共控制信息和尋呼信息特點(diǎn)是“一次性、面向小區(qū)內(nèi)所有終端、對時延敏感但對個別丟失不敏感”。如果給尋呼消息加一個 RLC 頭再編個 SN接收側(cè)還得維護(hù)窗口狀態(tài)純屬給終端增加無謂的狀態(tài)機(jī)負(fù)擔(dān)。TM 的設(shè)計(jì)動機(jī)就是當(dāng)上層業(yè)務(wù)本身不需要 RLC 級別的可靠性保證時把這一層的開銷壓到零。這里有個容易踩的細(xì)節(jié)TM 不分段意味著上層交下來的 SDU 必須能塞進(jìn)下層通知的傳輸機(jī)會里。實(shí)際實(shí)現(xiàn)中TM 實(shí)體通常只處理固定或受控大小的消息不會出現(xiàn)“SDU 太大塞不下”的情況。如果你在實(shí)現(xiàn)里給 TM 加了分段邏輯那已經(jīng)不是規(guī)范里的 TM 了。2.2 UM 實(shí)體單向可靠性的邊界在哪里UM 實(shí)體綁定在 DL/UL DTCH 上做分段、級聯(lián)、加 RLC 頭、編 SN接收側(cè)做重復(fù)檢測、重排序、丟失檢測但不請求重傳。這是它和 AM 最本質(zhì)的區(qū)別UM 承認(rèn)“有些 PDU 就是會丟”它只負(fù)責(zé)把收到的按序整理好、把等不到的東西在合理時間內(nèi)放過去而不是死等。規(guī)范里 UM 接收側(cè)維護(hù)一個以 VR(UH) 為基準(zhǔn)的重排序窗口窗口范圍是(VR(UH) – UM_Window_Size) SN VR(UH)。收到一個 UMD PDU 時先判斷它是否落在窗口內(nèi)、是否重復(fù)再決定丟棄還是放進(jìn)接收緩存。放進(jìn)去之后如果這個 SN 落在窗口外就推進(jìn) VR(UH)把窗口外能重組的 SDU 按 SN 升序往上交如果 VR(UR) 落在窗口外就把 VR(UR) 拉回VR(UH) – UM_Window_Size。這一套狀態(tài)推進(jìn)的邏輯核心目的只有一個不讓一個丟失的 PDU 把整個接收緩存無限期卡住。t_Reordering 就是那個“后悔藥”。當(dāng) VR(UH) VR(UR)說明有空洞啟動定時器超時后直接把 VR(UR) 推到 VR(UX)的第一個未收到 SN把空洞之前能交的都交上去。這樣即使中間丟了一個包后續(xù)數(shù)據(jù)也不會被永久阻塞。UM 的取舍很清晰用“可能丟一點(diǎn)”換“不會因?yàn)橐粋€包卡死整條鏈路”適合語音、流媒體這類對時延敏感、對少量丟包可容忍的業(yè)務(wù)。2.3 AM 實(shí)體ARQ 和 HARQ 為什么要疊兩層AM 實(shí)體是三種模式里狀態(tài)最復(fù)雜的發(fā)送部分和接收部分各自維護(hù)窗口和一組狀態(tài)變量。發(fā)送側(cè)窗口由 VT(A) 和 VT(MS) 界定VT(A) SN VT(MS)內(nèi)的 PDU 才允許下發(fā)接收側(cè)窗口由 VR(R) 和 VR(MR) 界定。AM 同時支持分段、級聯(lián)、重分段、ARQ 重傳、輪詢和狀態(tài)報告。一個常見疑問是MAC 層已經(jīng)有 HARQ 了為什么 RLC 還要做 ARQ因?yàn)閮烧呓鉀Q的問題不在一個時間尺度上。HARQ 是快速反饋、基于傳輸塊的重傳次數(shù)有限失敗后就把“這個塊沒救回來”的事實(shí)往上報RLC ARQ 是慢速反饋、基于 PDU 序列號的它負(fù)責(zé)把 HARQ 漏掉的那些洞補(bǔ)上。規(guī)范里 AM 發(fā)送部分明確寫了“傳輸 RLC 控制 PDU 優(yōu)先于數(shù)據(jù) PDU重傳數(shù)據(jù) PDU 優(yōu)先于新數(shù)據(jù) PDU”這個優(yōu)先級順序就是為 ARQ 服務(wù)的狀態(tài)報告先走欠的賬先還新數(shù)據(jù)往后排。AM 的重分段能力也值得單獨(dú)說。當(dāng)一個待重傳的 AMD PDU 塞不進(jìn)當(dāng)前傳輸機(jī)會時發(fā)送部分可以把它重新分段成多個 AMD PDU 段而且規(guī)范明確寫了“重分段的分段數(shù)量沒有限制”。這給了實(shí)現(xiàn)很大的靈活性底層給的授權(quán)忽大忽小RLC 不用死等一個剛好合適的傳輸機(jī)會而是把大 PDU 拆小分批送。代價是接收側(cè)要按“字節(jié)段序號”來管理重復(fù)檢測比 UM 的整 PDU 粒度復(fù)雜得多。3. 狀態(tài)變量與窗口RLC 的“賬本”是怎么記的3.1 UM 接收側(cè)的四個變量和一次收包決策UM 接收側(cè)的核心狀態(tài)變量是 VR(UR)、VR(UH)、VR(UX)。VR(UR) 是“下一個期望按序收到的 SN”VR(UH) 是“已收到的最高 SN 加一”VR(UX) 是 t_Reordering 啟動時記下的快照。收到 SN x 的 UMD PDU 時決策順序大致如下收到 SN x 的 UMD PDU 若 VR(UR) x VR(UH) 且 x 之前已收到 - 丟棄重復(fù) 若 (VR(UH) - UM_Window_Size) x VR(UR) - 丟棄窗口外舊包 否則 - 放入接收緩存 放入緩存后 若 x 落在重排序窗口之外 VR(UH) x 1 重組并向上分發(fā)窗口外可交付的 SDU 若 VR(UR) 落在窗口之外 VR(UR) VR(UH) - UM_Window_Size 若緩存中存在 SN VR(UR) 的 PDU VR(UR) 推進(jìn)到下一個未收到的 SN 重組并分發(fā) SN 新 VR(UR) 的 SDU 若 t_Reordering 在運(yùn)行且滿足停止條件 停止并重置 t_Reordering 若 t_Reordering 未運(yùn)行且 VR(UH) VR(UR) 啟動 t_ReorderingVR(UX) VR(UH)這段偽代碼對應(yīng)規(guī)范 5.1.2.2.2 和 5.1.2.2.3 兩節(jié)。幾個參數(shù)的含義需要說清楚UM_Window_Size決定了接收側(cè)最多能容忍多大的亂序范圍窗口越大抗亂序能力越強(qiáng)但接收緩存和狀態(tài)維護(hù)成本越高VR(UX)的作用是給 t_Reordering 超時后的推進(jìn)設(shè)一個下界避免超時后把還沒等到的包直接跳過太多。t_Reordering 超時時VR(UR) 被推到“SN VR(UX) 的第一個未收到 PDU”然后如果還有空洞就重啟定時器。這套邏輯的本質(zhì)是用定時器把“等”這件事量化等多久由 VR(UX) 和窗口共同決定而不是無限等。3.2 AM 發(fā)送窗口VT(A)、VT(S)、VT(MS) 三者的關(guān)系A(chǔ)M 發(fā)送側(cè)的狀態(tài)變量更多但核心就三個VT(A) 是“最早未被肯定應(yīng)答的 SN”VT(S) 是“下一個新 PDU 要用的 SN”VT(MS) 是“發(fā)送窗口上界”滿足VT(MS) VT(A) AM_Window_Size。發(fā)送窗口的有效范圍是VT(A) SN VT(MS)任何 SN 落在窗口外的數(shù)據(jù) PDU 都不允許下發(fā)。這個窗口機(jī)制解決的是“發(fā)送方不能無限往前跑”的問題。如果沒有窗口發(fā)送方可以一直發(fā)新數(shù)據(jù)接收方的緩存和狀態(tài)變量會無限增長而且一旦某個早期 PDU 丟了后面所有 PDU 都得在接收側(cè)等著重排序壓力全壓在接收端。窗口把“在途未確認(rèn)數(shù)據(jù)”的數(shù)量限制住讓收發(fā)雙方的狀態(tài)空間有界。收到肯定應(yīng)答時如果應(yīng)答的 SN 等于 VT(A)發(fā)送部分就把 VT(A) 推進(jìn)到“VT(A) 到 VT(S) 范圍內(nèi)最小的未被肯定應(yīng)答的 SN”。這里有個容易忽略的點(diǎn)規(guī)范說的是“最小的未被肯定應(yīng)答的 SN”不是簡單地 VT(A)1。因?yàn)?STATUS PDU 可能一次性確認(rèn)多個 PDU也可能有空洞VT(A) 必須跳到第一個真正沒被確認(rèn)的位置。如果某個 RLC SDU 的所有相關(guān) AMD PDU 都被確認(rèn)了還要向上層發(fā)“發(fā)送成功指示”——這就是 AM 模式對 PDCP 的交付保證。3.3 AM 接收窗口與字節(jié)段粒度AM 接收側(cè)的窗口由 VR(R) 和 VR(MR) 界定VR(R) SN VR(MR)為窗口內(nèi)。和 UM 不同的是AM 的重復(fù)檢測粒度是字節(jié)段一個 AMD PDU 可能被重分段成多個段接收側(cè)要記錄每個 SN 下哪些字節(jié)段已經(jīng)收到。規(guī)范 5.1.3.2.2 寫得很明確收到包含 SNx 的 AMD PDU 字節(jié)段 y 到 z 的 PDU 時如果 x 在窗口外或 y 到 z 之前已收到丟棄否則放入緩存并把其中重復(fù)的字節(jié)段丟掉。這個設(shè)計(jì)直接來自 AM 的重分段能力。如果只按整 PDU 做重復(fù)檢測重分段后的段就沒法正確合并。字節(jié)段粒度讓接收側(cè)可以“拼圖”同一個 SN 下不同段可能從不同傳輸機(jī)會到達(dá)只要所有字節(jié)段湊齊這個 AMD PDU 就算完整收到。VR(MS) 就是用來跟蹤“哪些 SN 還沒湊齊所有字節(jié)段”的t_Reordering 超時后 VR(MS) 被更新為“SN VR(X) 的第一個未湊齊的 PDU”觸發(fā)狀態(tài)報告把缺口告訴發(fā)送方。4. ARQ 與輪詢STATUS 報告什么時候發(fā)、發(fā)給誰4.1 輪詢的觸發(fā)條件不是想發(fā)就發(fā)AM 發(fā)送部分通過 P 域poll 位觸發(fā)對等實(shí)體回 STATUS 報告。規(guī)范給了幾類觸發(fā)條件PDU_WITHOUT_POLL pollPDU、BYTE_WITHOUT_POLL pollByte、發(fā)送后發(fā)送緩存和重傳緩存都空、或者沒有新數(shù)據(jù)能發(fā)窗口延遲。這幾個條件覆蓋了不同場景前兩個是“發(fā)夠了就問問”后兩個是“沒得發(fā)了趕緊確認(rèn)一下好推進(jìn)窗口”。輪詢不是免費(fèi)的。每發(fā)一個帶 P 域的 PDU就要啟動或重啟 t_PollRetransmit如果對等實(shí)體沒回 STATUS定時器超時后要重傳并再次輪詢。所以 pollPDU 和 pollByte 設(shè)得太小STATUS 報告會過于頻繁反向鏈路開銷上去設(shè)得太大窗口推進(jìn)慢吞吐受影響。這是典型的參數(shù)調(diào)優(yōu)取舍沒有放之四海皆準(zhǔn)的值。4.2 STATUS 報告的觸發(fā)與禁止接收側(cè)觸發(fā) STATUS 報告的來源有三類收到 P 域?yàn)?1 的 PDU、t_Reordering 超時檢測到接收失敗、以及規(guī)范里提到的其他觸發(fā)。但觸發(fā)不等于立刻發(fā)還要過 t_StatusProhibit 這一關(guān)如果 t_StatusProhibit 沒在運(yùn)行就在下一個傳輸機(jī)會構(gòu)造并下發(fā) STATUS PDU如果在運(yùn)行就等它超時后的第一個傳輸機(jī)會再發(fā)而且期間多次觸發(fā)也只發(fā)一個。這個“狀態(tài)禁止定時器”的設(shè)計(jì)動機(jī)是防止 STATUS 風(fēng)暴。設(shè)想接收側(cè)連續(xù)收到多個帶 P 域的 PDU如果每個都立刻回一個 STATUS反向鏈路會被狀態(tài)報告淹沒而且這些報告內(nèi)容高度重疊。t_StatusProhibit 把反饋合并、限頻用一點(diǎn)反饋延遲換反向鏈路效率。規(guī)范里還特別注了一句P 域?yàn)?1 的 PDU 如果 x VR(MS) 或 x VR(MR)觸發(fā) STATUS否則延遲觸發(fā)直到條件滿足——這是為了保證狀態(tài)報告在 HARQ 重排序之后發(fā)避免基于亂序到達(dá)的中間狀態(tài)做出錯誤判斷。4.3 重傳計(jì)數(shù)與 maxRetxThresholdAM 發(fā)送部分對每個 AMD PDU 維護(hù) RETX_COUNT。首次重傳時置 0之后每次“該 PDU 或它的部分不再等待重傳”時加一。當(dāng) RETX_COUNT 達(dá)到 maxRetxThreshold向上層指示“已達(dá)到最大重傳”。這個機(jī)制是 RLC 的“止損線”ARQ 不能無限重傳否則一個永遠(yuǎn)收不到的 PDU 會把整個承載卡死。達(dá)到閾值后往上報告由上層決定是重建、釋放還是別的處理。這里有個實(shí)現(xiàn)上的坑RETX_COUNT 的加一條件是“不再等待重傳”而不是“每次重傳就加一”。因?yàn)橐粋€ PDU 可能被重分段成多個段分多次發(fā)送規(guī)范用“不再等待重傳”這個狀態(tài)來界定一次完整的重傳嘗試避免分段導(dǎo)致計(jì)數(shù)虛高。5. 避坑與排查RLC 實(shí)現(xiàn)里最容易翻車的幾件事5.1 現(xiàn)象切換后業(yè)務(wù)卡住STATUS 報告一直不發(fā)原因通常是 t_StatusProhibit 配置過大或者狀態(tài)報告觸發(fā)條件判斷有誤。切換過程中接收側(cè)可能積壓了多個觸發(fā)事件如果 t_StatusProhibit 沒超時這些觸發(fā)會被合并延遲。排查時先看接收側(cè)是否在 t_StatusProhibit 運(yùn)行期間持續(xù)觸發(fā)但從未下發(fā) STATUS PDU再看 VR(MS) 是否長時間不更新。解決方式是核對 t_StatusProhibit 的配置值和觸發(fā)邏輯確認(rèn)“延遲觸發(fā)直到 x VR(MS) 或 x VR(MR)”這個條件沒有被實(shí)現(xiàn)成永久等待。5.2 現(xiàn)象UM 業(yè)務(wù)偶發(fā)大面積亂序交付原因多半是 t_Reordering 超時處理里 VR(UR) 推進(jìn)邏輯寫錯。規(guī)范要求超時后 VR(UR) 更新為“SN VR(UX) 的第一個未收到 PDU 的 SN”如果實(shí)現(xiàn)里誤寫成“VR(UX) 本身”或“VR(UH)”就會把還沒等到的包直接跳過造成上層看到空洞。排查時抓接收側(cè)狀態(tài)變量日志對比超時前后 VR(UR)、VR(UX)、VR(UH) 的變化是否符合規(guī)范 5.1.2.2.4 節(jié)。解決是按規(guī)范逐條核對狀態(tài)推進(jìn)順序特別注意“先更新 VR(UR)再重組分發(fā)再判斷是否重啟定時器”這個次序。5.3 現(xiàn)象AM 重傳次數(shù)異常增長RETX_COUNT 很快打滿常見原因是重分段后 RETX_COUNT 的加一條件判斷錯誤。如果實(shí)現(xiàn)里每發(fā)一個分段就加一一個 PDU 被拆成多段重傳幾次就會虛高到閾值。規(guī)范說的是“該 PDU 或它的部分不再等待重傳”時才加一。排查時看 RETX_COUNT 的增長是否和“完整重傳嘗試次數(shù)”一致而不是和“分段發(fā)送次數(shù)”一致。解決是把計(jì)數(shù)點(diǎn)放在“一次重傳嘗試結(jié)束”的位置而不是每次下發(fā)分段時。5.4 現(xiàn)象窗口延遲導(dǎo)致吞吐上不去發(fā)送側(cè) VT(MS) 長時間不推進(jìn)新數(shù)據(jù)發(fā)不出去表現(xiàn)為“有數(shù)據(jù)但發(fā)不了”。根因可能是 STATUS 報告丟失或輪詢沒觸發(fā)。檢查 pollPDU、pollByte 是否設(shè)得過大導(dǎo)致長時間不輪詢以及 t_PollRetransmit 超時后是否正確重傳并重新輪詢。另一個可能是接收側(cè) VR(MS) 更新邏輯有誤導(dǎo)致狀態(tài)報告里漏報缺口。排查時同時看發(fā)送側(cè) VT(A)/VT(S)/VT(MS) 和接收側(cè) VR(R)/VR(MS) 的日志確認(rèn)缺口是否被正確報告和確認(rèn)。5.5 現(xiàn)象TM 承載上出現(xiàn)“SDU 太大塞不下”TM 不分段如果上層交下來的 SDU 超過下層傳輸機(jī)會能承載的大小實(shí)現(xiàn)里沒有合法處理路徑。這通常不是 RLC 本身的問題而是上層對 TM 承載的使用方式不對或者傳輸機(jī)會通知的大小計(jì)算有誤。排查時確認(rèn)該承載是否真的應(yīng)該用 TM以及下層通知的 RLC PDU 總大小是否包含了必要的開銷。解決要么調(diào)整上層數(shù)據(jù)大小要么重新評估該業(yè)務(wù)是否適合 TM。6. 設(shè)計(jì)取舍RLC 為什么把復(fù)雜度放在狀態(tài)機(jī)上回頭看這份規(guī)范RLC 最值得琢磨的地方不是某個具體過程而是它把“可靠性”拆成了幾層不同時間尺度的機(jī)制HARQ 管快速重傳RLC ARQ 管慢速補(bǔ)洞t_Reordering 管亂序容忍t_StatusProhibit 管反饋限頻窗口管狀態(tài)有界。每一層都在做一個取舍——用多少狀態(tài)、多少延遲、多少反饋開銷換多少可靠性。一個有意思的對比是 UM 和 AM 的接收側(cè)。UM 只有 VR(UR)、VR(UH)、VR(UX) 三個變量重復(fù)檢測是整 PDU 粒度AM 多了 VR(R)、VR(MR)、VR(MS)、VR(H)、VR(X)重復(fù)檢測細(xì)到字節(jié)段。這個復(fù)雜度差異不是隨意的而是由“是否支持重傳和重分段”決定的一旦允許重傳和重分段接收側(cè)就必須能表達(dá)“這個 SN 下哪些字節(jié)收到了、哪些沒收到”狀態(tài)空間自然膨脹。規(guī)范沒有試圖用一套統(tǒng)一的狀態(tài)機(jī)覆蓋三種模式而是讓 TM 極簡、UM 中等、AM 完整各取所需。另一個取舍是定時器的角色。t_Reordering、t_PollRetransmit、t_StatusProhibit 三個定時器分別對應(yīng)“等亂序”“等狀態(tài)”“限反饋”它們都不是為了“保證正確”而存在而是為了“在不確定的情況下做出可接受的決策”。協(xié)議不能假設(shè)底層永遠(yuǎn)不丟包、不能假設(shè)對等實(shí)體永遠(yuǎn)及時回復(fù)所以用定時器把“等多久”變成一個可配置、可驗(yàn)證的量。這也解釋了為什么 RLC 的參數(shù)調(diào)優(yōu)這么依賴場景定時器值本質(zhì)上是把業(yè)務(wù)特征時延容忍度、丟包率、往返時間編碼進(jìn)協(xié)議行為里。我自己的習(xí)慣是每次碰到 RLC 相關(guān)的異常先把收發(fā)兩側(cè)的狀態(tài)變量按時間軸拉出來對照規(guī)范里狀態(tài)推進(jìn)的條件逐條核對而不是先去調(diào)定時器參數(shù)。因?yàn)榇蠖鄶?shù)“玄學(xué)”問題最后都能在某個狀態(tài)變量的推進(jìn)條件里找到根因——定時器只是把問題暴露出來的那個觸發(fā)器。希望這份規(guī)范里的狀態(tài)機(jī)和過程描述能幫你在下次排查鏈路層問題時少走一點(diǎn)彎路。本文還有配套的精品資源點(diǎn)擊獲取