![【LMP】規(guī)范精講[3]: 一條鏈路的一生——建鏈、經(jīng)營(yíng)與散場(chǎng)](http://pic.xiahunao.cn/yaotu/【LMP】規(guī)范精講[3]: 一條鏈路的一生——建鏈、經(jīng)營(yíng)與散場(chǎng))
建鏈那 90 毫秒里發(fā)生了什么功率為什么像鋸齒一樣升降斷連時(shí) 6×Tpoll 到底在等誰(shuí)這篇把連接控制掰開(kāi)揉碎講清楚。前面兩篇把 LMP 的信令骨架PDU 格式、事務(wù)與碰撞規(guī)則、特性交換過(guò)了一遍。那些是語(yǔ)法今天這篇講的是語(yǔ)義——連接控制LMP 里條目最多的一個(gè)大家族從建鏈握手到斷連收尾一條 ACL 鏈路要經(jīng)歷的所有管理動(dòng)作都在這里面。目錄一、開(kāi)張90 毫秒的參數(shù)全家桶1.1 page 結(jié)束之后誰(shuí)先開(kāi)口1.2 建鏈后的參數(shù)下發(fā)二、經(jīng)營(yíng)運(yùn)行態(tài)的八個(gè)子系統(tǒng)2.1 功率控制三條腿走路的閉環(huán)2.2 AFH跳頻地圖的動(dòng)態(tài)改道2.3 信道分類情報(bào)上拋機(jī)制2.4 監(jiān)督超時(shí)鏈路的死亡判決書(shū)2.5 CQDDR看路況換車型2.6 QoS輪詢節(jié)奏的兩副面孔2.7 多時(shí)隙包保守起步的授權(quán)制2.8 EDR 包型表?yè)Q調(diào)制先封路2.9 封裝 PDU大件物流的拆裝規(guī)則2.10 Ping帶防偽的心跳2.11 時(shí)鐘調(diào)整微調(diào)表針的兩種手法2.12 SAM錯(cuò)峰營(yíng)業(yè)的時(shí)隙地圖三、打烊兩種告別方式3.1 Detach 的全套規(guī)矩3.2 空口現(xiàn)場(chǎng)三次告別四、換老板不關(guān)店角色切換五、代碼時(shí)間5.1 解析 AFH 信道地圖5.2 Detach 計(jì)時(shí)狀態(tài)機(jī)六、收個(gè)尾七、測(cè)驗(yàn)我拿一份手頭的空口抓包做伴讀素材是一條真實(shí)鏈路的完整生命周期從 17:03:50 建鏈到 17:05:40 結(jié)束中間還夾了一次掉線重連和一次角色切換。先上全景圖把這篇文章的骨架立起來(lái)一條鏈路的一生可以切成三段開(kāi)張建鏈與參數(shù)初始化、經(jīng)營(yíng)運(yùn)行態(tài)的各種閉環(huán)控制、打烊斷連。外加一個(gè)特殊事件換老板角色切換。下面按這個(gè)順序展開(kāi)。一、開(kāi)張90毫秒的參數(shù)全家桶1.1 page 結(jié)束之后誰(shuí)先開(kāi)口Baseband 的 page 過(guò)程建立的是物理層同步——兩邊對(duì)上了跳頻序列和時(shí)鐘。但 LM 層的建鏈?zhǔn)橇硪换厥?。?guī)范在連接控制一開(kāi)篇就畫(huà)了那張經(jīng)典流程圖注意 page 框下面那行字允許立刻發(fā)起的 LMP 過(guò)程只有五個(gè)clock offset request、version、supported features、name request、detach。為什么偏偏是這五個(gè)看性質(zhì)就明白了——clock offset 是物理層剛同步完順手就能量出來(lái)的值version 和 features 是靜態(tài)只讀信息name 是緩存過(guò)的老數(shù)據(jù)detach 則是給對(duì)端隨時(shí)保留的退出通道。全是輕量、無(wú)副作用、不需要 Host 參與的東西。而真正涉及上層的連接要等一條專門的 PDUWhen the paging device wishes to create a connection involving layers above LM, it sends an LMP_HOST_CONNECTION_REQ PDU. When the other side receives this message, the Host is informed about the incoming connection.這句話的關(guān)鍵在第二句。LM 層的鏈路通了不代表對(duì)端的 Host 知道這件事——HOST_CONNECTION_REQ 的本質(zhì)作用是把對(duì)端的 Host 從床上叫起來(lái)。對(duì)端 Host 有權(quán)說(shuō)不回一條 LMP_NOT_ACCEPTED發(fā)起方就要立刻走斷連流程。協(xié)議設(shè)計(jì)里這種 Host 否決權(quán)的例子不多這里是第一個(gè)。抓包里的現(xiàn)場(chǎng)是這樣的17:03:50.437Host Connection 被 Accepted36 毫秒后17:03:50.473雙方完成 SETUP_COMPLETE。這兩條 PDU 夾著配對(duì)認(rèn)證的整個(gè)流程——本例里中間穿插了 SSP 配對(duì)、鑒權(quán)、加密啟動(dòng)全部在 2 秒內(nèi)完成。SETUP_COMPLETE 的語(yǔ)義值得逐字看When a device is not going to initiate any more security procedures during connection establishment it sends an LMP_SETUP_COMPLETE PDU. When both devices have sent LMP_SETUP_COMPLETE PDUs the traffic can be transferred on the BR/EDR ACL logical transport.兩個(gè)要點(diǎn)一是它只聲明安全流程結(jié)束不是所有初始化結(jié)束二是必須雙向都發(fā)業(yè)務(wù)數(shù)據(jù)才放行。這是個(gè)兩階段收口——單方面的開(kāi)門不算開(kāi)門。1.2 建鏈后的參數(shù)下發(fā)SETUP_COMPLETE 之后立刻就是一頓密集的參數(shù)下發(fā)??纯湛趶?17:03:50.434 到 17:03:50.511約 80 毫秒內(nèi)發(fā)生了功率直接拉到最大、AFH 地圖下發(fā)、信道分類上報(bào)開(kāi)關(guān)打開(kāi)、Max Slot 協(xié)商到 5 時(shí)隙、EDR 包型表啟用 2/3Mbps、CQDDR 自適應(yīng)速率開(kāi)啟、時(shí)鐘偏移讀取、監(jiān)督超時(shí)設(shè)為 5 秒。這張截圖值得逐行讀因?yàn)樗褪钦恼碌哪夸涱A(yù)告功率控制第一個(gè)動(dòng)作是 Increase to maximum power——新鏈路信號(hào)未知先按最壞情況打滿再靠閉環(huán)往下調(diào)。寧濫勿缺先通再優(yōu)。SET_AFH 緊跟著下發(fā)裁剪地圖本例 20 個(gè)信道——跳頻改道這件事從建鏈第一毫秒就開(kāi)始了。Channel Classification Request 打開(kāi)了從設(shè)備的上報(bào)通道——地圖不是拍腦袋定的是靠持續(xù)情報(bào)喂出來(lái)的。Max Slot Request 雙方各發(fā)一次都要求 5 時(shí)隙——大包傳輸?shù)氖跈?quán)過(guò)程。Packet Type Table 協(xié)商到 2/3Mbps——EDR 調(diào)制解調(diào)模式的選擇。Auto Rate 和 Preferred Rate 一發(fā)一收——CQDDR 速率自適應(yīng)的握手。Clock Offset Transaction——把對(duì)端時(shí)鐘偏移讀出來(lái)存著下次 page 能快幾百毫秒。Supervision Timeout 5 秒——給這條鏈路預(yù)設(shè)了死亡判決時(shí)限。每一條后面都對(duì)應(yīng)一節(jié)下面進(jìn)入經(jīng)營(yíng)篇逐個(gè)展開(kāi)。二、經(jīng)營(yíng)運(yùn)行態(tài)的八個(gè)子系統(tǒng)2.1 功率控制三條腿走路的閉環(huán)藍(lán)牙的功率控制容易被人小看以為是簡(jiǎn)單的升降。實(shí)際上規(guī)范里寫(xiě)了一套相當(dāng)細(xì)的規(guī)則。先看兩套機(jī)制的分界。legacy 功率控制用 LMP_INCR_POWER_REQ / LMP_DECR_POWER_REQenhanced 用 LMP_POWER_CONTROL_REQ / LMP_POWER_CONTROL_RES。切換規(guī)則只有一條After the Link Manager supported features responses have been processed, if both devices support enhanced power control then only enhanced power control shall be used. Otherwise, if either device supports only the legacy power control mechanism then only legacy power control shall be used.木桶效應(yīng)——任一方不支持 enhanced整條鏈路就退回 legacy。而且切換點(diǎn)是特性交換完成那一刻之前甚至可以先用 legacy 發(fā)一條應(yīng)急調(diào)整。抓包里 17:03:50.434 那條 Increase to maximum power 就是 enhanced 功控的 all the way to max在特性交換剛完成時(shí)就發(fā)出去了。enhanced 功控的三種請(qǐng)求檔位one step up、one step down、all the way to max。應(yīng)答方要在新的功率檔上發(fā)送 LMP_POWER_CONTROL_RES——這一條是閉環(huán)的精髓應(yīng)答報(bào)文本身就是新功率的第一塊試金石發(fā)起方收到它的 RSSI 直接就是下一輪決策的輸入。還有一個(gè)反直覺(jué)的單向鎖定規(guī)則If the receiver of the LMP_POWER_CONTROL_REQ PDU has indicated that the output power levels for all of the supported modulation modes are at maximum the requesting device shall only request an increase again after having requested a decrease at least once.已經(jīng)到頂了還反復(fù)請(qǐng)求升功率不行必須先請(qǐng)求一次降功率解鎖。這是防抖設(shè)計(jì)——避免兩個(gè)決策魯棒的實(shí)現(xiàn)在極端場(chǎng)景下互相拉扯。SPEC 對(duì)功率檔位本身還有一組約束屬于射頻側(cè)的底層配套相鄰檔位步長(zhǎng)最小 2dB 最大 8dB最低檔應(yīng)低于 -30dBm所有包類型的頭部功率差不能超過(guò) 10dBClass 1 設(shè)備最大 100mW / 20dBm必須能把功率降回 4dBm 以下——不發(fā)功控消息的鏈路發(fā)射功率不得超過(guò) Class 2 上限。這些數(shù)字在音頻耳機(jī)這種 Class 2 設(shè)備上感知不強(qiáng)但在車載、工業(yè)這些 Class 1 場(chǎng)景里就是硬指標(biāo)。看穩(wěn)態(tài)下的真實(shí)波形17:04:49 降一步、17:04:50 升一步、17:04:52 升到頂應(yīng)答 Max power、17:04:56 連降兩步——典型的搜索-保持-再搜索循環(huán)。注意 17:04:49.597 那條降功率請(qǐng)求標(biāo)著 No Response From Peripheral大約 1 秒后鏈路直接改發(fā)升功率請(qǐng)求并成功??湛谏弦粭l LMP 請(qǐng)求丟了不代表鏈路有問(wèn)題——基帶重傳和上層超時(shí)各管各的功率控制這種高頻小事務(wù)有自己的容錯(cuò)節(jié)奏。上面是規(guī)范里的 legacy 功控序列圖Sequence 3 和 4 是兩條邊界應(yīng)答MAX_POWER 和 MIN_POWER。到頂了、到底了都要明說(shuō)。2.2 AFH跳頻地圖的動(dòng)態(tài)改道AFH 解決兩個(gè)問(wèn)題自己的鏈路被 ISM 頻段里其他東西干擾時(shí)繞開(kāi)壞信道同時(shí)自己也少去干擾別人。規(guī)范一句話交代了使用范圍AFH shall only be used during Connection state——page、inquiry 階段一律全 79 信道跳因?yàn)槟菚r(shí)雙方還沒(méi)有協(xié)商的信道。核心 PDU 是 LMP_SET_AFH三個(gè)參數(shù)The LMP_SET_AFH PDU contains three parameters: AFH_Instant, AFH_Mode, and AFH_Channel_Map. The parameter, AFH_Instant, specifies the instant at which the hopset switch shall become effective. This is specified as a Bluetooth Clock value of the Centrals clock, that is available to both devices. The AFH instant is chosen by the Central and shall be an even value at least 6×Tpoll or 96 slots (whichever is greater) in the future. The AFH_Instant shall be within 12 hours of the current clock value.Instant 機(jī)制是整個(gè) LMP 的一個(gè)通用設(shè)計(jì)模式所有涉及時(shí)序切換的操作AFH、時(shí)鐘調(diào)整、角色切換、Sniff 進(jìn)入退出都不用隱式生效而是約定一個(gè)未來(lái)的時(shí)鐘刻度雙方到點(diǎn)同時(shí)切。這個(gè)刻度用 Central 的時(shí)鐘表示——因?yàn)樗钦麄€(gè) piconet 唯一的公共時(shí)間基準(zhǔn)。為什么至少 6×Tpoll 或 96 slots給基帶確認(rèn)和調(diào)度留時(shí)間。SET_AFH 發(fā)出后要等兩層確認(rèn)Baseband ACK 確認(rèn)從設(shè)備收到了instant 過(guò)了確認(rèn)從設(shè)備切過(guò)去了。Central 在收到 ACK 且 instant 未到之前不許發(fā)新的 SET_AFH。上限 12 小時(shí)則是防整數(shù)溢出式的荒謬值。還有一條容易忽略的規(guī)矩使能/更新 AFH 前Central 要先暫停 ACL-U 邏輯鏈路上的業(yè)務(wù)——先封路再改道。收到 Baseband ACK 后恢復(fù)傳輸??湛诤苡幸馑肌1纠绦诺罃?shù)穩(wěn)定在 20但地圖編碼幾乎每次都在變——0x1A67C5C、0x1A68E60、0x1A69C3E……這說(shuō)明什么20 個(gè)信道的集合沒(méi)大變但具體選哪 20 個(gè)一直在微調(diào)。每次從設(shè)備上報(bào)信道分類Central 都重新評(píng)估地圖哪怕結(jié)論只是換掉一兩個(gè)邊緣信道。跳頻改道不是一次性的大動(dòng)作而是持續(xù)的小步快跑。另一個(gè)值得注意的細(xì)節(jié)嗅探窗口約 17:04:05 到 17:04:33內(nèi)Central 照常三次微調(diào)地圖但從設(shè)備的分類上報(bào)整整靜默了 28 秒退出嗅探后 73 毫秒立即恢復(fù)。規(guī)范只要求 Hold 模式下從設(shè)備不執(zhí)行分類上報(bào)功率都停了量了也白量嗅探下的靜默是實(shí)現(xiàn)自己的節(jié)能策略——嗅探窗口外收音機(jī)根本不開(kāi)自然沒(méi)法量信道。2.3 信道分類情報(bào)上拋機(jī)制上一節(jié)說(shuō)了 Central 會(huì)根據(jù)上報(bào)改地圖這一節(jié)說(shuō)上報(bào)本身。從設(shè)備把 79 個(gè)信道按相鄰兩個(gè)一組分成 40 對(duì)每對(duì)報(bào)告 good、bad 或 unknown 三種狀態(tài)。對(duì)內(nèi)兩信道狀態(tài)不一致時(shí)有明確的吸收規(guī)則good unknown 報(bào) goodbad unknown 報(bào) badgood bad 的處理由實(shí)現(xiàn)自定。為什么要成對(duì)省空口開(kāi)銷——40 對(duì)每組兩比特比逐信道報(bào)告緊湊。上報(bào)的節(jié)奏由三個(gè)參數(shù)控制都裝在 LMP_CHANNEL_CLASSIFICATION_REQ 里AFH_reporting_mode開(kāi)關(guān)、AFH_min_interval最小上報(bào)間隔、AFH_max_interval最大上報(bào)間隔。這是標(biāo)準(zhǔn)的令牌桶式限速——太頻繁浪費(fèi)空口太稀疏地圖過(guò)期兩端給夾住。本例里從設(shè)備實(shí)際上報(bào)間隔約 1~3 秒屬于相當(dāng)積極的檔位。地圖更新間隔約 2~7 秒比上報(bào)周期長(zhǎng)——Central 不是每份情報(bào)都采納攢幾次再改道避免地圖抖動(dòng)。有個(gè)架構(gòu)性的認(rèn)識(shí)值得強(qiáng)調(diào)上報(bào)的是從設(shè)備的局部視角裁決權(quán)在 Central。每臺(tái)從設(shè)備只知道自己收發(fā)時(shí)經(jīng)歷的信道質(zhì)量多個(gè)從設(shè)備的情報(bào)在 Central 匯總成一張對(duì)全 piconet 生效的地圖。這是中心化決策——好處是一致性壞處是 Central 的地圖算法成了單點(diǎn)做不好全 piconet 陪葬。2.4 監(jiān)督超時(shí)鏈路的死亡判決書(shū)每個(gè)物理鏈路上都有一個(gè)監(jiān)督計(jì)時(shí)器規(guī)格Part B 3.1說(shuō)得直白Upon reception of a valid packet header with one of the Peripherals addresses on the physical link, the timer shall be reset. If at any time in Connection state, the timer reaches the supervisionTO value, the connection shall be considered disconnected.只要收到一個(gè)帶著自己 LT_ADDR 的有效包頭計(jì)時(shí)器就歸零。注意是包頭就行——哪怕載荷全錯(cuò)至少證明對(duì)端還活著、還在按跳頻序列發(fā)包。計(jì)時(shí)器到點(diǎn)鏈路宣告死亡無(wú)論誰(shuí)在什么狀態(tài)。為什么需要這個(gè)看似粗暴的機(jī)制SPEC Part B 原文給了答案Since this can happen without any prior warning, it is important to monitor the link on both the Central and the Peripheral side to avoid possible collisions when the logical transport address is reassigned to another Peripheral.關(guān)鍵詞是 LT_ADDR 復(fù)用。3 比特的 LT_ADDR 只有 7 個(gè)有效值piconet 里設(shè)備一多就得回收復(fù)用。如果舊鏈路沒(méi)死透、新鏈路已經(jīng)開(kāi)始用同一個(gè)地址兩個(gè)從設(shè)備會(huì)對(duì)同一個(gè)包頭做出響應(yīng)——空口直接亂套。監(jiān)督超時(shí)就是給地址復(fù)用兜底的死亡證明到了時(shí)限沒(méi)收到包就視為物理層已斷地址可以放心交給下一家。LMP 層的 LMP_SUPERVISION_TIMEOUT 是單向下發(fā)的通知從設(shè)備無(wú)權(quán)拒絕??湛谙掳l(fā) 8000 slots 5 秒。有意思的是主機(jī)側(cè)的細(xì)節(jié)看 HCI 證據(jù)主機(jī) 寫(xiě)了一次 Write Link Supervision Timeout (5s)緊接著 又寫(xiě)一次第二次收到 Command Disallowed。為什么因?yàn)榈谝淮我呀?jīng)生效了控制器拒絕重復(fù)配置。而重連后的 出現(xiàn)了 HCI Link Supervision Timeout Changed 事件——控制器先于主機(jī)指令改了超時(shí)值角色切換后新 Central 重發(fā)了全家桶見(jiàn)第四節(jié)主機(jī)隨后補(bǔ)寫(xiě)確認(rèn)。同一個(gè) 5 秒值三條消息三種觸發(fā)路徑控制器的自主性和主機(jī)的期望在這里碰了一下。監(jiān)督超時(shí)的值怎么選太小——正常嗅探間隔里沒(méi)包就誤判死亡太大——真斷鏈了要干等才知道。本例 5 秒對(duì) 500ms 嗅探間隔的鏈路是 10 倍冗余留足了重傳和調(diào)度抖動(dòng)的余量。2.5 CQDDR看路況換車型信道質(zhì)量驅(qū)動(dòng)的數(shù)據(jù)速率變化機(jī)制輕巧設(shè)備 A 發(fā)一條 LMP_AUTO_RATE 說(shuō)我開(kāi)通了此業(yè)務(wù)之后設(shè)備 B 隨時(shí)可以用 LMP_PREFERRED_RATE 建議 A 用什么檔位的包——是否帶 2/3 FEC、幾個(gè)時(shí)隙、BR 還是 EDR 速率。注意用詞是建議may request / preferredA 可以不聽(tīng)但有一個(gè)硬約束Device A shall not send a packet that is larger than max slots even if the preferred size is greater than this value.CQDDR 只能建議換車型不能突破道路限寬——限寬由下一節(jié)的 Max Slots 說(shuō)了算。本例建鏈時(shí) AUTO_RATE 和 PREFERRED_RATEBRFEC、EDR3Mbps5時(shí)隙包都出現(xiàn)了說(shuō)明這條鏈路全程開(kāi)著速率自適應(yīng)。Data_Rate 參數(shù)的設(shè)計(jì)有個(gè)小巧思一個(gè)字節(jié)里同時(shí)裝了 BR 和 EDR 兩套速率建議BR 模式看 bit 0~2、EDR 模式看 bit 3~6且規(guī)范明確要求支持 EDR 的設(shè)備兩套建議必須同時(shí)有效。為什么因?yàn)殒溌冯S時(shí)可能在 BR 和 EDR 包型之間切配合下一節(jié)的 ptt 協(xié)商如果建議值只有一個(gè)當(dāng)前模式的檔位模式一換建議就失效了還得重發(fā)一次 PREFERRED_RATE。兩套并存等于把換擋建議做成模式無(wú)關(guān)的靜態(tài)配置。2.6 QoS輪詢節(jié)奏的兩副面孔Tpoll 的定義值得背下來(lái)Central 對(duì)某個(gè)特定從設(shè)備兩次 ACL 發(fā)送之間的最大時(shí)間間隔。它是 piconet 調(diào)度的節(jié)拍器——每個(gè)從設(shè)備的 Tpoll 就是它分到的帶寬和時(shí)延預(yù)算。QoS 有兩副面孔規(guī)格里寫(xiě)得清楚The Central notifies the Peripheral of the new poll interval and NBC by sending the LMP_QUALITY_OF_SERVICE PDU. The Peripheral cannot reject the notification.通知LMP_QUALITY_OF_SERVICE不可拒絕——Central 是調(diào)度者它說(shuō)了算。請(qǐng)求LMP_QUALITY_OF_SERVICE_REQ可以談——雙向都能發(fā)起Central 可以接也可以拒。NBC 是廣播包重復(fù)次數(shù)只有 Central 發(fā)給從設(shè)備時(shí)才有意義從設(shè)備發(fā)的請(qǐng)求里這個(gè)字段直接被無(wú)視。Tpoll 的承諾在 Active 和 Sniff 模式下都要兌現(xiàn)但例外清單很長(zhǎng)page/page scan/inquiry 撞車、本 piconet 或其他 piconet 的關(guān)鍵 LMP 序列、基帶關(guān)鍵序列page 響應(yīng)、建鏈后第一個(gè) POLL 之前、角色切換。翻譯一下——Tpoll 是盡力而為的軟承諾調(diào)度沖突時(shí)優(yōu)先保命不保點(diǎn)。2.7 多時(shí)隙包保守起步的授權(quán)制ACL 包可以占 1、3、5 個(gè)時(shí)隙。占的時(shí)隙多一次拉的數(shù)據(jù)多但代價(jià)是對(duì)端要陪聽(tīng)更久、piconet 里其他從設(shè)備被壓得更狠。所以這是個(gè)需要授權(quán)的東西。兩條 PDU 分兩種語(yǔ)義LMP_MAX_SLOT 是我允許你用幾時(shí)隙LMP_MAX_SLOT_REQ 是我請(qǐng)求用幾時(shí)隙。一條給權(quán)限一條要權(quán)限。關(guān)鍵規(guī)則After a new connection (as a result of page or page scan), or after a role switch, the value shall be 1 slot.每次新建鏈路或角色切換后默認(rèn)值強(qiáng)制回 1 時(shí)隙。為什么這么保守角色切換意味著 piconet 參數(shù)全變跳頻序列跟著新 Central 的地址和時(shí)鐘重算誰(shuí)也不知道切換后空口質(zhì)量如何——先用最小包探路確認(rèn)沒(méi)問(wèn)題再逐步放開(kāi)。本例建鏈時(shí)雙方各發(fā)一條 MAX_SLOT_REQ5 slots都被接受注意是雙方——A 想發(fā)大包要 B 同意B 想發(fā)大包也要 A 同意權(quán)限是對(duì)等的。HCI 側(cè)能看到對(duì)應(yīng)事件HCI Max Slots Change (Slots5)在空口協(xié)商完成后幾毫秒內(nèi)上報(bào)主機(jī)。2.8 EDR 包型表?yè)Q調(diào)制先封路EDR 用 pttpacket type table選擇 ACL 鏈路上允許的包和調(diào)制模式。協(xié)商協(xié)議本身簡(jiǎn)單一條 LMP_PACKET_TYPE_TABLE_REQ應(yīng)答 ACCEPTED_EXT 或 NOT_ACCEPTED_EXT但流程有三板斧Before changing the packet type table, the initiator shall finalize the transmission of the current ACL packet with ACL-U information and shall stop ACL-U transmissions. It shall then send the LMP_PACKET_TYPE_TABLE_REQ PDU.先把手頭帶業(yè)務(wù)數(shù)據(jù)的 ACL 包發(fā)完、停發(fā)業(yè)務(wù)、再發(fā)協(xié)商——和 AFH 一樣的先封路再改道。接受方也一樣確認(rèn)收完、停發(fā)、切換表、應(yīng)答收到應(yīng)答的 Baseband ACK 后才恢復(fù)傳輸。任何時(shí)刻空口上都不存在用不同調(diào)制解調(diào)的半切換狀態(tài)。還有一個(gè)細(xì)節(jié)改 ACL 的 ptt 不影響同 LT_ADDR 上 SCO 鏈路的包型。語(yǔ)音鏈路的包型在 eSCO 建鏈時(shí)就鎖死了不跟著數(shù)據(jù)鏈路的調(diào)制變。2.9 封裝 PDU大件物流的拆裝規(guī)則有些事務(wù)配對(duì)的公鑰就是典型載荷超過(guò) 16 字節(jié)而單個(gè) LMP 消息裝不下。封裝機(jī)制來(lái)了一個(gè)封裝 PDU 1 個(gè) header N 個(gè) payload 分片每片 16 字節(jié)最后一片可以零填充。最有意思的是這份豁免清單——封裝傳輸進(jìn)行中以下九種 PDU 可以隨時(shí)插進(jìn)來(lái)而不算事務(wù)碰撞信道分類、功率升降請(qǐng)求、MAX/MIN POWER、DETACH、MAX_SLOT、PREFERRED_RATE、SET_AFH。想想為什么是這九個(gè)功率控制和信道分類是高頻心跳斷連是緊急出口MAX_SLOT 和速率建議是輕量配置——全是短平快、跟被封裝的大事務(wù)沒(méi)有任何狀態(tài)耦合的 PDU。碰撞規(guī)則里規(guī)定的是不同事務(wù)不能并發(fā)這九個(gè)天生就是無(wú)狀態(tài)的散兵游勇放行它們既不破壞封裝事務(wù)的原子性又保住了鏈路管理的實(shí)時(shí)性。2.10 Ping帶防偽的心跳Ping 是安全連接配套的特性雙方都要支持 Ping feature。表面看是心跳檢測(cè)——LMP_PING_REQ / LMP_PING_RES 一問(wèn)一答。但規(guī)范里那段 Note 才是重點(diǎn)Since the LMP_PING_RES PDU contains a MIC and will update the packet counter, the sender of the LMP_PING_REQ PDU can verify that packets with earlier packet counter values have not been deliberately suppressed by an attacker.MIC 是消息完整性校驗(yàn)包計(jì)數(shù)器每發(fā)一個(gè)帶 MIC 的包就加一。攻擊者如果想吞掉之前某些包比如吞掉一條降權(quán)限的指令計(jì)數(shù)器就會(huì)出現(xiàn)空洞——ping 一下對(duì)端必須回帶 MIC 的包計(jì)數(shù)器必須連續(xù)。這不是簡(jiǎn)單的心跳是帶防重放、防抑制的活體檢測(cè)。觸發(fā)時(shí)機(jī)也講究Host 設(shè)了一個(gè) authenticated payload timeout超過(guò)這個(gè)時(shí)限沒(méi)收到任何帶 MIC 的包LM 就該主動(dòng) ping——而且是趕在超時(shí)前提前 ping給對(duì)端留出響應(yīng)時(shí)間。2.11 時(shí)鐘調(diào)整微調(diào)表針的兩種手法piconet 時(shí)鐘就是 Central 的表但有時(shí)候 Central 要把表調(diào)一下——典型場(chǎng)景是對(duì)齊外部時(shí)間基準(zhǔn)比如音頻廣播系統(tǒng)里的多 piconet 同步。兩種手法粗調(diào)Coarse Clock Adjustment一步到位拖拽Clock Dragging溫水煮青蛙。這個(gè) Instant 的約束比 AFH 松AFH 要 6×Tpoll 或 96 slots因?yàn)闀r(shí)鐘調(diào)整不改跳頻序列只是改表——不需要給跳頻內(nèi)核留切換時(shí)間。Spec Part B 里那張經(jīng)典的正調(diào)整圖Figure 8.14值得展開(kāi)講clk_adj_instant 設(shè)在 12 號(hào)槽clk_adj_slots6clk_adj_us400μs。表針往前撥 6×6254004150μs。新時(shí)鐘域的第一個(gè)槽從 18 號(hào)開(kāi)始但 400μs 的 offset 意味著這個(gè)槽已經(jīng)過(guò)去了 400μs——只剩 225μs 的尾巴這個(gè)殘缺的槽不可用。傳輸不能從槽中間開(kāi)始所以新時(shí)鐘域的第一個(gè)完整可用槽要等到 20 號(hào)Central 發(fā)送槽。負(fù)調(diào)整則相反第一個(gè)槽要在 instant 之后 400μs 才開(kāi)始之前那 400μs 是上一個(gè)槽的延續(xù)同樣不可用。兩種方向都會(huì)浪費(fèi)一個(gè)槽——調(diào)表是有成本的這也是為什么有 Clock Dragging 作為溫和替代每次只挪 1μs 級(jí)別靠著 clk_adj_dragTO1 秒超時(shí)的分段機(jī)制慢慢拖到位不產(chǎn)生不可用槽。從設(shè)備也可以請(qǐng)求調(diào)表LMP_CLK_ADJ_REQ而且有個(gè)很優(yōu)雅的參數(shù)設(shè)計(jì)——Clk_Adj_Period。原文例子Clk_Adj_Slots18、Clk_Adj_Period48意味著 18、66、114、162、210 個(gè)槽的調(diào)整對(duì)從設(shè)備等效Central 可以在這組值里挑一個(gè)跟其他從設(shè)備需求沖突最小的。多目標(biāo)優(yōu)化問(wèn)題用一組周期解來(lái)松弛這個(gè)設(shè)計(jì)我很喜歡。還有一個(gè)錯(cuò)誤碼專門為拒絕但幫忙的場(chǎng)景準(zhǔn)備0x40Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock Dragging——粗調(diào)我拒絕了但我會(huì)用拖拽幫你調(diào)到位。拒絕里帶著承諾。最后是并行限制這是 instant 類操作的通用紅線任何帶著 instant 或時(shí)序控制標(biāo)志的事務(wù)角色切換、AFH、SCO、eSCO、嗅探、嗅探子評(píng)級(jí)、Hold、加密暫停恢復(fù)進(jìn)行中不許發(fā)起時(shí)鐘調(diào)整時(shí)鐘調(diào)整 instant 未到、拖拽超時(shí)未過(guò)、恢復(fù)模式未出也不許發(fā)起那些事務(wù)。否則報(bào) Different Transaction Collision (0x2A)。所有改時(shí)序的操作必須嚴(yán)格串行——兩件事同時(shí)改表表就亂了。2.12 SAM錯(cuò)峰營(yíng)業(yè)的時(shí)隙地圖SAMSlot Availability Mask是給共存場(chǎng)景準(zhǔn)備的——設(shè)備里有 LTE、WiFi 等其他無(wú)線時(shí)某些時(shí)隙得讓出去。機(jī)制是把時(shí)隙按周期分成可用/不可用兩類雙方按地圖錯(cuò)峰收發(fā)。三步曲設(shè)計(jì)得很干凈LMP_SAM_SET_TYPE0先定義 type0 子圖一種特殊的外部不可用時(shí)隙模式必須先定義后引用——在 DEFINE_MAP 里用了沒(méi)定義過(guò)的 type0直接報(bào) 0x41 錯(cuò)誤。LMP_SAM_DEFINE_MAP定義完整地圖子圖數(shù)量 NSAM_SM、子圖長(zhǎng)度 TSAM_SM∈[2,56] 偶數(shù)、每子圖 2 比特類型。NSAM_SM0 表示刪除地圖。SAM_Index 不能是 0xFF保留給禁用也不能是當(dāng)前選中的圖。同一 SAM_Index 重復(fù)定義時(shí)新參數(shù)直接覆蓋舊的。地圖里可以引用 type0 子圖但前提是 SET_TYPE0 已經(jīng)跑過(guò)——沒(méi)定義就引用報(bào) 0x41。LMP_SAM_SWITCH切換到某張圖或用 0xFF 禁用 SAM。DSAM 是錨點(diǎn)偏移SAM_Instant 是激活時(shí)刻——instant 機(jī)制第三次出現(xiàn)了。而且這條有個(gè)狠細(xì)節(jié)The new SAM slot map may be activated at SAM_Instant even if the Baseband acknowledgment is not received——不等確認(rèn)到點(diǎn)就切。跳頻序列是雙方各自的本地計(jì)算切錯(cuò)了頂多對(duì)不上跳SAM 地圖如果兩邊不同步一邊以為讓出去了一邊還在發(fā)狀態(tài)直接分裂。所以寧可單方面到點(diǎn)硬切也要保證 instant 的確定性。SET_TYPE0 里的 Update_Mode 參數(shù)有三個(gè)值語(yǔ)義分層清晰0 表示作廢所有引用了 type0 子圖的現(xiàn)有地圖對(duì)應(yīng)索引在重新定義前不可用1 表示新 type0 子圖立即生效2 表示下一個(gè)子間隔開(kāi)始生效。如果當(dāng)前激活的地圖里有 type0 子圖Update_Mode 不許設(shè) 0否則收到 0x1E 拒絕——不給你作廢正在使用的地圖。SAM_SWITCH 里則有兩個(gè)防御性設(shè)計(jì)SAM_Instant 用 28 位 Central 時(shí)鐘的 bit 27:1 表示Timing_Control_Flags 專門對(duì)付時(shí)鐘回繞問(wèn)題——藍(lán)牙時(shí)鐘約 23.3 小時(shí)回繞一次instant 如果落在回繞點(diǎn)附近不提前約定初始化規(guī)則就會(huì)出現(xiàn)今天和明天兩個(gè)候選刻度的歧義。與兩個(gè)模式的關(guān)系規(guī)則角色切換瞬間強(qiáng)制禁用SAM兩邊都要失敗則恢復(fù)切換前參數(shù)。角色切換本身 piconet 時(shí)鐘都換了SAM 錨點(diǎn)全部失效重新配置。嗅探優(yōu)先于 SAM如果嗅探節(jié)奏無(wú)法跟 SAM 對(duì)齊理想情況是嗅探錨點(diǎn)落在可用槽、嗅探周期是 TSAM 整數(shù)倍嗅探配置說(shuō)了算——哪怕要在 SAM 標(biāo)記不可用的槽上收發(fā)。退出嗅探后 SAM 地圖恢復(fù)效力。這個(gè)優(yōu)先級(jí)安排透露了價(jià)值排序電源管理嗅探的確定性 共存禮貌SAM。共存是錦上添花鏈路?;钍堑拙€。三、打烊兩種告別方式鏈路的死亡有兩種好聚好散的 Detach無(wú)聲無(wú)息的監(jiān)督超時(shí)。前者是協(xié)議告別后者是法定死亡。3.1 Detach 的全套規(guī)矩Detach 的 PDU 只有一個(gè) Error_Code 參數(shù)但斷鏈握手的規(guī)定是整個(gè) Connection control 里最細(xì)的段落之一值得整段引用The initiating LM shall pause traffic on the ACL-U logical link. The initiating LM then queues the LMP_DETACH for transmission and it shall start a timer for 6×Tpoll slots where Tpoll is the poll interval for the connection. If the initiating LM receives the Baseband acknowledgment before the timer expires it starts a timer for 3×Tpoll slots. When this timer expires, and if the initiating LM is the Central, the LT_ADDR(s) may be re-used immediately. If the initial timer expires then the initiating LM drops the link and starts a timer for Tlinksupervisiontimeout slots after which the LT_ADDR(s) may be re-used if the initiating LM is the Central.拆解一下發(fā)起方的流程先停業(yè)務(wù)ACL-U 暫?!质窍确饴?。發(fā) DETACH起 6×Tpoll 計(jì)時(shí)器等 Baseband ACK。收到 ACK → 再等 3×Tpoll → Central 可以立刻復(fù)用 LT_ADDR。沒(méi)收到 ACK → 直接掉鏈等監(jiān)督超時(shí)那么久 → 才能復(fù)用 LT_ADDR。接收方對(duì)稱收到 DETACH 后 Central 等 6×Tpoll、從設(shè)備等 3×Tpoll然后拆鏈。如果 DETACH 永遠(yuǎn)沒(méi)送到空口太差監(jiān)督超時(shí)兜底判死。為什么發(fā)起方和接收方的等待時(shí)間不對(duì)稱3 vs 6想一下各自在等什么。發(fā)起方收到 ACK 后還等 3×Tpoll是給接收方留出完成它那 3×Tpoll 等待的時(shí)間——保證我這邊復(fù)用地址發(fā)新包時(shí)對(duì)面的舊狀態(tài)已經(jīng)清干凈了。接收方收到 DETACH 就證明發(fā)起方至少發(fā)出來(lái)了但發(fā)起方可能還沒(méi)收到 ACK——所以接收方多等一倍6×Tpoll覆蓋發(fā)起方 6×Tpoll 的 ACK 等待窗口。每個(gè)等待時(shí)間都精確對(duì)應(yīng)另一邊的某個(gè)階段像兩把互相咬合的齒輪。中間還有一段 Hold/Sniff 的特殊規(guī)則If the connection is in Hold mode, the initiating LM shall wait for Hold mode to end before initiating the procedure defined above. If the connection is in Sniff mode, the initiating LM shall perform the procedure to exit Sniff mode before initiating the procedure defined above. If the procedure to exit Sniff mode does not complete within the LMP response timeout (30 seconds) the procedure defined above shall be initiated anyway.Hold 里的從設(shè)備收音機(jī)是關(guān)的發(fā)了也白發(fā)——等 Hold 結(jié)束再發(fā)。嗅探里的從設(shè)備只在嗅探窗口醒來(lái)——先退嗅探再發(fā) Detach。但退嗅探本身要通信極端情況下通信不了怎么辦30 秒硬上限到點(diǎn)強(qiáng)行發(fā)。斷連是最高優(yōu)先級(jí)的意圖任何中間狀態(tài)都不能無(wú)限期阻塞它。最后一條冷知識(shí)鏈路上有 SCO/eSCO 時(shí)收 DETACH 會(huì)隱式拆除所有同步鏈路發(fā)起方不用挨個(gè)發(fā)拆除指令。斷 ACL 等于斷全部——同步語(yǔ)音鏈路寄生在 ACL 的物理鏈路上皮之不存毛將焉附。3.2 空口現(xiàn)場(chǎng)三次告別抓包里 110 秒內(nèi)出現(xiàn)了三次 Detach原因碼全是 Remote User Terminated Connection對(duì)端用戶主動(dòng)斷開(kāi)第一次比本次建鏈還早 0.3 秒——上一條短命探測(cè)鏈路的收尾。上一條鏈路剛斷新鏈路緊跟著就建了空口上兩代鏈路的揮手幾乎首尾相接。第二次由耳機(jī)側(cè)發(fā)起結(jié)束了 68 秒的穩(wěn)態(tài)運(yùn)行。注意斷開(kāi)前 1 秒地圖更新還在照常進(jìn)行——鏈路完全健康斷連是上層的決定不是射頻的鍋。這類證據(jù)在排查斷連問(wèn)題時(shí)特別有價(jià)值把斷連前最后幾條 PDU 拉出來(lái)看如果地圖、功率、上報(bào)一切正?;究梢耘懦锢韺訂?wèn)題。第三次結(jié)束重連后的鏈路。三次告別三種上下文同一套協(xié)議流程。四、換老板不關(guān)店角色切換角色切換嚴(yán)格說(shuō)不在連接控制的條目里它在獨(dú)立的小節(jié)但從抓包看它和連接控制的耦合太深——切換瞬間 AFH 地圖、Max Slot、監(jiān)督超時(shí)全部要重談不講它這篇就不完整。為什么需要角色切換Spec Part B 給了兩個(gè)場(chǎng)景尋呼方天生是 Central要加入現(xiàn)有 piconet 就得讓位piconet 里的從設(shè)備想另立山頭當(dāng) Central也得切。本例抓包里的場(chǎng)景更日?!鷻C(jī)發(fā)起重連尋呼方是耳機(jī)于是耳機(jī)先當(dāng)了臨時(shí) Central然后把位置還給手機(jī)。流程上是兩層切換的疊加TDD 切換收發(fā)時(shí)隙對(duì)調(diào) piconet 切換整個(gè)微網(wǎng)的參數(shù)換到新 Central 的地址和時(shí)鐘上。Part B 的描述非常精彩To begin the role switch, A and B shall perform a TDD switch using the former hopping scheme (still using the Bluetooth Device Address and clock of device B), so there is no piconet switch yet.先在舊跳頻序列上對(duì)調(diào)收發(fā)時(shí)序——此時(shí)微網(wǎng)還是舊微網(wǎng)只是角色先換。然后新 Central A 用舊微網(wǎng)參數(shù)發(fā) FHS 包里面裝著新微網(wǎng)的地址、時(shí)鐘、給 B 的新 LT_ADDRB 回 ID 包確認(rèn)確認(rèn)之后雙方才一起切到新微網(wǎng)參數(shù)上。中間還掛著一個(gè) newconnectionTO 計(jì)時(shí)器超時(shí)了就全部回滾——舊角色、舊參數(shù)、舊狀態(tài)當(dāng)無(wú)事發(fā)生。FHS 里的時(shí)鐘信息只有 1.25ms 分辨率不夠?qū)R槽邊界所以切換前 A 要先發(fā)一條 LMP_SLOT_OFFSET——舊微網(wǎng) Central 槽起點(diǎn)和新微網(wǎng) Central 槽起點(diǎn)之間的微秒級(jí)偏移0~1249μs、1μs 分辨率。1μs 精度的對(duì)齊信息提前打好包切換后 B 用它定位相關(guān)窗口??湛诶镞@個(gè)場(chǎng)景的時(shí)間線堪稱教科書(shū)17:05:13.328耳機(jī)臨時(shí) Central下發(fā) SET_AFHCh79——全 79 信道耳機(jī)當(dāng) Central 的這十幾毫秒里地圖是全開(kāi)的。耳機(jī)對(duì)環(huán)境信道的掌握有限畢竟一直當(dāng)從設(shè)備干脆全圖跑等手機(jī)接手后再裁剪。17:05:13.597LMP Role Switch356μs 的 slot offset切換完成。17:05:13.920 起手機(jī)新 Central立刻重發(fā)全家桶——SET_AFH 裁回 20 信道、分類上報(bào)開(kāi)關(guān)重開(kāi)、Max Slot 重設(shè)、監(jiān)督超時(shí)重設(shè) 5 秒。對(duì)照 HCI 日志還能看到一個(gè)細(xì)節(jié)重連后主機(jī)用的連接句柄是 0x0003——這是此前那條舊鏈路用過(guò)的句柄控制器復(fù)用了它。角色切換加句柄復(fù)用資源回收利用得干干凈凈。還有一條前面提過(guò)的規(guī)則在這里兌現(xiàn)SAM 在角色切換瞬間強(qiáng)制禁用SAM 和角色切換不能同時(shí)掛起。所有涉及時(shí)序的操作在切換面前讓路。五、代碼時(shí)間5.1 解析 AFH 信道地圖SET_AFH 的地圖是 10 字節(jié) 80 比特79 個(gè)信道每信道 1 比特最高位保留。寫(xiě)個(gè)解析器把地圖轉(zhuǎn)成信道列表順便算信道數(shù)def parse_afh_channel_map(map_bytes: bytes) - list[int]: LMP_SET_AFH 信道地圖 - 可用信道列表。 地圖 10 字節(jié) 80 比特bit(n) 對(duì)應(yīng)信道 nn0..78 比特為 1 表示信道可用。最高位bit79保留忽略。 if len(map_bytes) ! 10: raise ValueError(AFH map 應(yīng)為 10 字節(jié)) channels [] value int.from_bytes(map_bytes, big) for ch in range(79): # 信道 0~78 if value (79 - ch) 1: # 從 MSB 起數(shù) channels.append(ch) return channels # 空口抓包里的一條真實(shí)地圖16 進(jìn)制縮短形式還原成 10 字節(jié) # Ch20 表示裁剪后剩 20 個(gè)信道 sample bytes.fromhex(0007A0000000000000) # 示意前幾信道全開(kāi) chans parse_afh_channel_map(sample) print(f可用信道 {len(chans)} 個(gè): {chans}) # 抓包里另一條Ch79 全圖角色切換期間臨時(shí) Central 下發(fā) full bytes.fromhex(FFFFFFFFFFFFFE0000) # 79 個(gè) 1 保留位 assert len(parse_afh_channel_map(full)) 79配合抓包數(shù)據(jù)可以做一致性校驗(yàn)——每條 SET_AFH 的地圖解析出來(lái)的信道數(shù)應(yīng)該和 PDU 里帶的信道計(jì)數(shù)字段一致不一致就是抓包工具或解析器的 bug。5.2 Detach 計(jì)時(shí)狀態(tài)機(jī)把 3.1 節(jié)的文字規(guī)則翻譯成狀態(tài)機(jī)C 風(fēng)格偽碼/* Detach 發(fā)起方狀態(tài)機(jī)簡(jiǎn)化版 */ typedef enum { ST_PAUSE_ACL, /* 停 ACL-U排隊(duì) DETACH */ ST_WAIT_BB_ACK, /* 等 Baseband ACK6*Tpoll */ ST_LINGER, /* ACK 后逗留3*Tpoll期滿可復(fù)用地址 */ ST_DROP_WAIT, /* 無(wú) ACK 掉鏈等監(jiān)督超時(shí) */ ST_DONE } detach_state_t; void detach_fsm_tick(link_t *lk) { switch (lk-detach_state) { case ST_PAUSE_ACL: acl_u_pause(lk); lmp_send_detach(lk, lk-reason); timer_start(lk-t, TPOLL_SLOTS(lk) * 6); lk-detach_state ST_WAIT_BB_ACK; break; case ST_WAIT_BB_ACK: if (lk-bb_acked) { /* 收到 BB ACK */ timer_start(lk-t, TPOLL_SLOTS(lk) * 3); lk-detach_state ST_LINGER; } else if (timer_expired(lk-t)) { /* 6*Tpoll 無(wú) ACK */ link_drop(lk); /* 直接掉鏈 */ timer_start(lk-t, lk-supervision_timeout); lk-detach_state ST_DROP_WAIT; } break; case ST_LINGER: if (timer_expired(lk-t)) { if (is_central(lk)) lt_addr_pool_recycle(lk-lt_addr); /* 立即復(fù)用 */ lk-detach_state ST_DONE; } break; case ST_DROP_WAIT: if (timer_expired(lk-t)) { if (is_central(lk)) lt_addr_pool_recycle(lk-lt_addr); /* 超時(shí)后復(fù)用 */ lk-detach_state ST_DONE; } break; default: break; } }注意 ST_LINGER 和 ST_DROP_WAIT 兩個(gè)出口對(duì) LT_ADDR 復(fù)用時(shí)機(jī)的區(qū)別——一個(gè)立即、一個(gè)等滿監(jiān)督超時(shí)。實(shí)現(xiàn)里把這個(gè)順序?qū)懛淳蜁?huì)出現(xiàn)前面說(shuō)的地址復(fù)用碰撞。六、收個(gè)尾把整篇的內(nèi)容壓回一張圖其實(shí)就是開(kāi)頭那張全景圖的三列。寫(xiě)完這篇最大的感受是 LMP 連接控制里有幾個(gè)反復(fù)出現(xiàn)的設(shè)計(jì)母題-Instant 機(jī)制——AFH、時(shí)鐘調(diào)整、SAM、嗅探、角色切換所有改時(shí)序的操作都用未來(lái)時(shí)鐘刻度約定生效點(diǎn)雙方到點(diǎn)同切不存在半切換狀態(tài)。-先封路再改道——SET_AFH、包型表切換、Detach動(dòng)參數(shù)前一律先停業(yè)務(wù)確認(rèn)后恢復(fù)。-保守起步——新鏈路 Max Slot 歸 1、功率先拉滿再往下調(diào)、臨時(shí) Central 發(fā)全圖。未知環(huán)境下先按最壞情況兜底再逐步優(yōu)化。-串行紅線——所有帶 instant 的事務(wù)嚴(yán)格互斥碰撞報(bào) 0x2A。時(shí)序狀態(tài)只有一個(gè)改它的操作必須排隊(duì)。理解了這幾個(gè)母題再看 Connection control 的任何一個(gè)小節(jié)都是熟面孔。協(xié)議條文背后是有哲學(xué)的。七、測(cè)驗(yàn)Q1LMP_DETACH 發(fā)送后Central 什么時(shí)候可以復(fù)用該從設(shè)備的 LT_ADDR如果一直收不到 Baseband ACK 呢答分兩條路徑。正常路徑發(fā)起方停 ACL-U 業(yè)務(wù)后發(fā)送 DETACH在 6×Tpoll 內(nèi)收到 Baseband ACK再等 3×Tpoll這段逗留是給接收方完成它自己的等待流程留的時(shí)間期滿后 Central 可立即復(fù)用 LT_ADDR。異常路徑6×Tpoll 內(nèi)沒(méi)收到 ACK發(fā)起方直接放棄鏈路但要再等一個(gè) link supervision timeout 的時(shí)長(zhǎng)才能復(fù)用地址——因?yàn)閷?duì)端可能根本沒(méi)收到 DETACH它的舊鏈路狀態(tài)要靠監(jiān)督超時(shí)來(lái)判死提前復(fù)用地址會(huì)讓新從設(shè)備和還活著的舊狀態(tài)對(duì)同一個(gè) LT_ADDR 的包頭同時(shí)響應(yīng)。接收方側(cè)對(duì)稱收到 DETACH 后 Central 等 6×Tpoll、從設(shè)備等 3×Tpoll 再拆鏈。核心思想LT_ADDR 復(fù)用必須以對(duì)端舊狀態(tài)的確定性消亡為前提。Q2為什么 LMP_SET_AFH 的 AFH_Instant 要求至少是 6×Tpoll 或 96 slots 之后的未來(lái)時(shí)刻取大者而且要在 12 小時(shí)之內(nèi)答下界是為了留足協(xié)商傳播時(shí)間。SET_AFH 要經(jīng)歷兩個(gè)階段——Baseband ACK 確認(rèn)從設(shè)備收到指令、instant 到達(dá)確認(rèn)雙方同時(shí)切換。instant 太近從設(shè)備可能還沒(méi)來(lái)得及處理上一條指令尤其鏈路在嗅探或高負(fù)載時(shí)Tpoll 本身就大造成兩邊跳頻序列不同步、鏈路直接斷。所以取 6×Tpoll 和 96 slots 的較大值覆蓋最壞調(diào)度延遲。上界 12 小時(shí)是防止 instant 無(wú)限遠(yuǎn)掛起——一個(gè)永遠(yuǎn)不到的 instant 會(huì)讓鏈路卡在待切換狀態(tài)同時(shí)任何其他帶 instant 的操作都被 0x2A 碰撞錯(cuò)誤阻塞。另外 Central 收到上一條 SET_AFH 的 ACK 且 instant 過(guò)去之前不允許發(fā)新的 SET_AFH保證同一時(shí)刻只有一個(gè)待生效地圖。Q3legacy 功率控制和 enhanced 功率控制能否在同一條鏈路上混用切換時(shí)機(jī)是什么enhanced 模式下為什么規(guī)定應(yīng)答方要在新的功率檔上發(fā)送 LMP_POWER_CONTROL_RES答不能混用。特性交換響應(yīng)處理完畢后若雙方都支持 enhanced 則只用 enhanced任一方只支持 legacy 則整條鏈路退回 legacy——木桶效應(yīng)向下兼容。切換時(shí)機(jī)點(diǎn)之前的過(guò)渡窗口里允許用 legacy 發(fā)應(yīng)急調(diào)整。應(yīng)答方在新功率檔上發(fā) RES 的原因功率控制是閉環(huán)發(fā)起方依據(jù)接收信號(hào)質(zhì)量決策RES 本身就是新功率下的第一份數(shù)據(jù)樣本發(fā)起方收到它的 RSSI 直接驗(yàn)證調(diào)整效果并作為下一輪決策輸入——應(yīng)答報(bào)文兼作校準(zhǔn)信號(hào)閉環(huán)一步到位。另外 enhanced 功控還有單向鎖定規(guī)則應(yīng)答方報(bào)告所有調(diào)制模式都到最大或最小功率后發(fā)起方必須先請(qǐng)求一次反方向調(diào)整才能再次請(qǐng)求同方向——防止兩個(gè)實(shí)現(xiàn)在邊界值上互相拉扯。