報(bào)文結(jié)構(gòu)
報(bào)文是構(gòu)成鏈路層的基石。報(bào)文就是攜帶著標(biāo)簽的數(shù)據(jù)殉摔,有一個(gè)設(shè)備發(fā)送州胳,其他設(shè)備接收。
比特序列
- 數(shù)據(jù)按照字節(jié)傳輸時(shí)逸月,總是從最低位開始傳輸?shù)乃ㄗ玻?x01是1000000
- 多個(gè)字節(jié)組成的數(shù)據(jù)總是從低字節(jié)開始傳輸,例如0x0103發(fā)送序列是11001000
前導(dǎo)
前導(dǎo)序列是一個(gè)01010101或者10101010的8bit交替序列碗硬。如果接入地址的第一位是0瓤湘,前導(dǎo)序列則是01010101瓢颅,否則是10101010,這樣的設(shè)計(jì)是為了保證報(bào)文的前9位都是交替的岭粤。
這個(gè)前導(dǎo)序列的作用主要是為了做 數(shù)據(jù)接收的訓(xùn)練惜索,比如頻率同步,符號時(shí)間評估剃浇,AGC訓(xùn)練巾兆。通過這段數(shù)據(jù)的訓(xùn)練使得接收器調(diào)整到合適的狀態(tài)對接下來的數(shù)據(jù)進(jìn)行接收。
Access Address
接入地址是一個(gè)32位的地址虎囚,包含兩種類型:
- 廣播接入地址(廣播數(shù)據(jù)角塑,掃描或者發(fā)起連接)
- 數(shù)據(jù)接入地址(兩個(gè)設(shè)備建立連接之后)
考慮到無線通信存在的噪音干擾和其他鏈路的干擾,就涉及了接入地址用來排除噪音和其他干擾數(shù)據(jù)包淘讥。
例如廣播介入地址是一個(gè)固定值10001110100010011011111011010110b (0x8E89BED6) 圃伶,當(dāng)接受到廣播后驗(yàn)證接入地址正確后才認(rèn)為他是個(gè)廣播報(bào)文而不是噪音。
而對于數(shù)據(jù)報(bào)文的介入地址則是隨機(jī)地址蒲列,不同的連接有不同的值窒朋,這是為了進(jìn)行專線交流用的。
從BLE空口包中的Link Layer 可以看到每個(gè)報(bào)文都有一個(gè)Access Address蝗岖,Adv_pkt有一個(gè)固定Access Address侥猩,而intiator發(fā)con_req時(shí)會包含一個(gè)Con_Access_Addr,連接之后的data pkt都是用的這個(gè)新的Access Addr了抵赢; 每次重新斷開建立連接欺劳,Access Address會不一樣,都會重新隨機(jī)生成铅鲤。
如下圖划提,廣播包使用固定的0x8E89BED6
如下圖,連接請求包使用協(xié)商通知新的地址邢享,此處為0x5b71c59b
如下圖鹏往,連接過程中使用的地址則為connect_ind中協(xié)商
其實(shí)關(guān)于Access Address是還有一些要求的,如不能有連續(xù)的6個(gè)1 bit位或6個(gè)連續(xù)的0 bit位驼仪,因此這樣算下來掸犬,滿足作為Access Address的4byte的組合中有231個(gè)是可用的
報(bào)頭
報(bào)頭雖然只有8bit,但是包含了不少的信息绪爸,而且他的內(nèi)容因是廣播報(bào)文還是數(shù)據(jù)報(bào)文差異很大湾碎。我們將依次來分析他們的結(jié)構(gòu)和內(nèi)容。
廣播報(bào)文的Header
廣播報(bào)文類型包括7種:
- ADV_IND —— 通用廣播指示
- ADV_DIRECT_IND —— 定向連接指示
- ADV_NONCONN_IND —— 不可連接指示
- ADV_SCAN_IND —— 可掃描指示
- SCAN_REQ —— 主動(dòng)掃描請求
- SCAN_RSP —— 主動(dòng)掃描響應(yīng)
- CONNECT_REQ —— 連接請求
其中根據(jù)其作用域奠货,還可以將他們分為三類介褥,ADV_* 屬于廣播數(shù)據(jù)單元,
SCAN_* 屬于掃描數(shù)據(jù)單元,CONNECT_* 屬于發(fā)起數(shù)據(jù)單元柔滔。
發(fā)送地址類型和接收地址類型都是BLE地址類型溢陪,只有兩種,公有地址和隨機(jī)地址睛廊,因而用一個(gè)bit就可以進(jìn)行區(qū)分形真。公有地址是需要向IEEE申請和購買的類似于公網(wǎng)ip,但是隨機(jī)地址則不需要超全。
數(shù)據(jù)報(bào)文的Header
邏輯鏈路標(biāo)識符咆霜,主要是用來判斷數(shù)據(jù)報(bào)文的類型:
- 鏈路控制報(bào)文(11)—— 鏈路層用來進(jìn)行管理連接的控制報(bào)文,這種類型的報(bào)文直接交給鏈路層來進(jìn)行處理嘶朱。
- 上層報(bào)文的開始(10)—— 表明該報(bào)文是屬于host蛾坯,需要交給host才能進(jìn)行解讀和處理,因?yàn)閔ost最多能夠發(fā)送27個(gè)字節(jié)的數(shù)據(jù)疏遏,但是無法一次性放入單個(gè)鏈路層數(shù)據(jù)報(bào)文脉课,因此需要將它截成幾段進(jìn)行傳輸,該標(biāo)志位用于標(biāo)識host報(bào)文的初識包财异。
- 上層報(bào)文的延續(xù)(01)—— 標(biāo)識host數(shù)據(jù)包的后續(xù)包倘零。
以一個(gè)L2CAP數(shù)據(jù)包為例,可以分為以下結(jié)構(gòu):
這樣帶來兩種后果:第一是鏈路層并不知道一個(gè)上層數(shù)據(jù)包究竟有多少個(gè)鏈路層報(bào)文組成戳寸,連續(xù)的數(shù)量不確定视事;第二是總是可以發(fā)送長度為零的延續(xù)包,這些長度為零的空包可以用來進(jìn)行消息的確認(rèn)庆揩。
** 序列號SN **建立連接后的第一個(gè)數(shù)據(jù)包序號為零;每次發(fā)送新的數(shù)據(jù)包時(shí)跌穗,其序列號與上一個(gè)數(shù)據(jù)包的序列號不同订晌;
也就是說,如果序列號與上一個(gè)數(shù)據(jù)包的序列號相同則為重傳報(bào)文蚌吸,如果不同則是新的報(bào)文锈拨。
** 期待序列號NESN **期待序列號,就是告訴對方自己期待的序列號羹唠。這其實(shí)起到一個(gè)數(shù)據(jù)包確認(rèn)的作用奕枢,如果確認(rèn)數(shù)據(jù)包的期待序列號和發(fā)送的序列號相同,則說明對方期待我們重傳剛剛的數(shù)據(jù)包佩微,如果是不同的缝彬,則是希望我們發(fā)送新的數(shù)據(jù)報(bào)文。
** 更多數(shù)據(jù) **更多數(shù)據(jù)位是用來告之對方哺眯,我方是否還有下一個(gè)數(shù)據(jù)包要發(fā)送谷浅,如果該位設(shè)置為1,則表明仍有數(shù)據(jù)要傳送,對方則選擇保持連接一疯;設(shè)為0撼玄,則表明沒有更多數(shù)據(jù)要進(jìn)行發(fā)送,對方則會斷開連接墩邀,節(jié)省能量掌猛。
一圖以概之
- SN和NESN除了可以用來確認(rèn)數(shù)據(jù),保證數(shù)據(jù)的準(zhǔn)確送達(dá)眉睹。
- NESN除了確認(rèn)數(shù)據(jù)荔茬,還可以用來進(jìn)行流控制,當(dāng)我方緩存區(qū)緊張時(shí)辣往,可以不發(fā)送NESN給對方兔院,使對方重發(fā)來等待我方釋放足夠的緩存區(qū)在進(jìn)行確認(rèn)處理。
- 當(dāng)報(bào)文CRC校驗(yàn)失敗時(shí)站削,認(rèn)為報(bào)文傳輸失敗坊萝,要求重傳。
- 在同一連接里许起,出現(xiàn)兩次數(shù)據(jù)包接受出錯(cuò)十偶,則停止該連接,進(jìn)行重新連接發(fā)送數(shù)據(jù)园细,這說明該信道很大的可能被干擾導(dǎo)致質(zhì)量較差惦积,需要重新連接更換信道。
長度
長度這個(gè)數(shù)據(jù)段很簡單猛频,表示數(shù)據(jù)段的實(shí)際數(shù)據(jù)的長度狮崩。
對于廣播報(bào)文,該段是由6個(gè)bit組成鹿寻,剩余兩個(gè)bit留作未來使用睦柴;
對于數(shù)據(jù)報(bào)文,該段是由5個(gè)bit成毡熏,剩余三個(gè)bit留作未來使用坦敌;
他們長度需要bit不相同的原因是,廣播數(shù)據(jù)報(bào)文多了6個(gè)字節(jié)的設(shè)備地址需要攜帶痢法,因?yàn)樾枰?bit來標(biāo)識長度狱窘;
數(shù)據(jù)(凈荷)
最大傳輸?shù)臄?shù)據(jù)是31個(gè)字節(jié),但是如果數(shù)據(jù)被加密财搁,需要留出4個(gè)自己進(jìn)行數(shù)據(jù)完整性校驗(yàn)
循環(huán)冗余校驗(yàn)碼
24bit的循環(huán)校驗(yàn)碼蘸炸,可以校驗(yàn)所有基數(shù)位以及所有2,4位錯(cuò)誤尖奔,顯然其并不能校驗(yàn)所有位錯(cuò)誤幻馁,但是出于低功耗考慮洗鸵,這是一個(gè)妥協(xié)的產(chǎn)物。