1. 程式人生 > >Mesh Profile (3.5)低傳輸層

Mesh Profile (3.5)低傳輸層

建議 mes 完成 空間 其中 使用 oct 方正 組織

(翻譯自《MeshProfile v1.0》3.5 Lower Transport Layer)

綜述

低傳輸層利用來自高傳輸層的PDU組成自身的消息,並且將這些消息發送給對側的低傳輸層。這些高傳輸層PDU的大小可能適合一個單獨的地傳輸層PDU,也可能被分片為多個低傳輸層PDU。當接收到消息時,低傳輸層處理低傳輸層PDU,可能需要將多個PDUs重組為高傳輸層PDU,一旦重組完成便將他們遞交給高傳輸層。

低傳輸層PDU

低傳輸層PDU用於將高傳輸層PDU發送給其他節點。

低傳輸層PDU第一個octet的最高有效位是SEG字段。該字段用於表示該低傳輸層PDU是否是一個分片消息。

和網絡層PDU中CTL字段配合,有四種不同的情況。

CTL = 0, SEG = 0, 未分片的訪問消息

CTL = 0, SEG = 1, 分片的訪問消息

CTL = 1, SEG = 0, 未分片的控制消息

CTL = 1, SEG = 1, 分片的控制消息

未分片的訪問消息

未分片訪問消息用於傳輸一個大小適合一個單獨的網絡層PDU的高傳輸層訪問消息。

SEG字段應該被設置為0,1bit。

AKF字段表示應用秘鑰標誌,1bit。AID字段表示應用秘鑰標識符,6bit。這兩個字段由高傳輸層根據對訪問層數據加密使用應用秘鑰還是設備秘鑰來設置。

然後是高傳輸層PDU,大小為40~120bit,即最大15octets。由高傳輸層提供數據。

該消息並沒有SZMIC字段。這種情況高傳輸層的TransMCI應該是一個32bit的值。(存在疑問,NordicSDK在這裏做了某種賦值,需要確認)

分片的訪問消息

分片的訪問消息用於傳輸高傳輸層訪問PDU的一個分片。

SEG字段應該設置為1,1bit。

AKF字段表示應用秘鑰標誌,1bit。AID字段表示應用秘鑰標識符,6bit。根據訪問層數據的加密方式決定。

SZMIC字段用於表示TransMIC的大小,1bit。如果SZMIC字段為0,表示TransMIC是32bit,如果SZMIC為1,表示TransMIC為64bit。

SeqZero字段,13bits,用於表示SeqAuth的最低的13個bit。有高傳輸層設置。

SeqO字段,5bits,用於表示分片偏移序號。(從0開始)

SeqN字段,5bits,用於標誌最後一個分片的序號。

Seqment m,8~96bits,即1~12octets。用於填充高傳輸層PDU的分片。最多12octets是應為其他字段占去了4octets。

來自於同一個高傳輸層訪問PDU的每一個訪問消息的分片,應該具有相同的AKF,AID,SZMIC,SeqZero,SeqN。

未分片的控制消息

一個未分片的控制消息用於傳輸一個分片確認消息或者一個傳輸層控制消息。

SEG字段,應該設置為0,表示沒有分片,1bit

Opcode字段,7bit。0x00,表示一個分片確認消息;0x01~0x7F表示傳輸層控制消息的Opcode。

數據參數,0~88bit,即最大11octet。用於傳輸層控制消息的參數。

分片確認消息

分片確認消息用於低傳輸層確認由對側低傳輸層發來的分片消息。

SEG字段,1bit,運營官設置為0,表示沒有分片。

Opcode字段,7bit,設置為0x00。

OBO字段,1bit,設置為0表示接收到的消息直接尋址到該節點;設置為1表示該消息為朋友節點用於維護低功耗節點發出的確認,非直接尋址到該節點。

SeqZero字段,13bit,表示高傳輸層PDU的SeqZero。

RFU字段,2bit,待設置。

BlockAck,32bit,分片的塊確認。最低有效位,bit0,代表分片0;最高有效位,bit31,代表分片31。如果bit n 設置為1,則表示分片n被確認。如果bit n設置為0,則表示分片n沒有被確認。大於SeqN的位應該別忽略。

如果收到的分片的TTL被設置為0,建議將相應的分片確認消息在發送時將TTL設置為0。

分片的控制消息

分片的控制消息用於在傳輸層控制消息的尺寸不適合一個單獨的網絡PDU時將該消息分片發送出去。

SEG字段,1bit,設置為1。

Opcode字段,7bit,0x01~0x7F,表示傳輸層控制消息的命令碼。

RFU,1bit。

SeqZero,13bit,表示SeqAuth的最低13bit有效位。

SeqO,5bit,表示分片偏移序號。

SeqN,5bit,表示最後一個分片的序號。

Seqment m,8~64bit,即1~8octets、用於傳輸第m包高傳輸層控制PDU。

(由上面計算,分片控制消息最大12octets。)

分片和重組

傳輸大小超過15octets高傳輸層PDU時,低傳輸層需要分片和重組高傳輸層PDU。這些分片發送給對側時使用塊確認方案,這樣可以是低傳輸層發送的消息最小化。高傳輸層訪問PDU和高傳輸層控制PDU的分片過程是完全相同的。

註意:分片的尺寸對於高傳輸層控制PDU和高傳輸層訪問PDU是不同的。

技術分享圖片

上面這張圖闡釋了一個高傳輸層訪問PDU被發送的的情景。該PDU包含一個octet的命令碼,3個用於網絡秘鑰索引和應用秘鑰索引字段的octets,16個octets的應用秘鑰。這樣當使用應用秘鑰對其加密和認證後,高傳輸層PDU大小是24octets(包括4octets的TransMIC)。這個PDU會被低傳輸層分為兩個分片:分片0和分片1。每一個分片有一個用於區分分片序號的包頭,然後這兩個PDU被遞交給網絡層,並計算完成完整的網絡層PDU。然後網絡層將使用網絡層PDU序號對該PDU加密,以為了保證只有NID字段(和IV index)處於明文可見而混淆這些消息。因此上述的訪問層消息最終可以通過兩個網絡層PDU發送出去。

對於高傳輸層訪問PUD和高傳輸層控制PDU的分片過程是完全相同的。並且在下面的描述中,考慮這兩個PDU類型是完全相同的,除非明天的描述。

註意:對於高傳輸層訪問PDU和控制PDU的分片大小和尺寸是不同的。

分片

低傳輸層將高傳輸層PDU分片為一個或者多個低傳輸層PDU、低傳輸層在同一時間只能將一條單獨的,發送給同一個目的地址的高傳輸層PDU分片後的訪問消息或者分片的控制消息發送出去。在一條高傳輸層PDU被確認或者取消之前,低傳輸層只可以發送該PDU一次。(這裏需要關註協議棧中對於確認,取消和發送的關系的處理方式。)

如果一個高傳輸層PDU的大小適合一個單獨的使用未分片消息格式的低傳輸層PDU,那麽低傳輸層應該使用一個未分片消息發送這個高傳輸層PDU。

如果一個高傳輸層PDU的大小適合一個單獨的使用分片消息格式的低傳輸層PDU,那麽低傳輸層應該使用一個單獨的分片消息發送這個高傳輸層PDU。

否則,需要使用兩個或者多個分片的消息發送。

分片消息在低傳輸層完成確認,但是非分片消息並非如此。因此在發送高傳輸層PDU時,使用一個單獨的分片格式的消息效率要比使用一個非分片格式的消息更高效。(疑問,這裏有的選嗎,不是應該按照長度選擇嗎)

例如,如果一個用來確認的消息在傳輸層被發送,此時在傳輸層已經有多分片的消息被收到,而如果這個用於確認的消息發生了丟失,那麽全部的多分片消息必須再被全部發送一次。相反,如果一個應用的確認消息在一個單獨的分片格式的訪問消息中發送,那麽這個發送應該發生在低傳輸層,可以多次發送確認消息,因而避免了再次重傳多分片的消息。(這裏好混亂啊!!!總之是能用單獨的分片消息,就不要用非分片消息。)

每一個高傳輸層訪問PDU的分片應該為12octets,除了最後一個分片。

每一個高傳輸層控制PDU的分片應該為8octets,除了最後一個分片。

例如,當使用一個32bit的TransMIC時,如果高傳輸層訪問PDU長度有42octets,那麽0~11octets為分片0;12~23octets為分片1;24~35octets為分片2;剩余的6個octets,36~41octets為分片3。

如果高傳輸層控制PDU長度42octets,那麽0~7octets為分片0,8~15octets為分片1;16~23octets為分片2;24~31為分片3;32~39為分片4;剩下的2octets,40~42為分片5。

高傳輸層PDU的每一個分片通過SeqO字段區分。各個分片通過用於加密和認證高傳輸層訪問PDU的SeqAuth值連接組織在一起(表示為同一個高傳輸層PDU的分片)。一個高傳輸層訪問PDU的每一個低傳輸層分片具有相同的IV index作為SeqAuth。

與訪問PDU類似,控制PDU也使用SeqO區分,使用SeqAuth值完成連接組織(表示為同一個高傳輸層PDU的分片)。

SeqAuth有IV index和第一個分片的序列號(SEQ)組成,56bit。其中從最高有效位開始是IV index,從最低有效位開始是序列號。SeqAuth中只有最低的13個bit(被稱作SeqZero)被包括在分片消息和分片確認消息中。當重組一個完整的訪問消息時,SeqAuth可以通過IV index,SeqZero和SEQ計算出來,由最大的SeqAuth決定(這裏SeqZero最大為8191,即0x1FFF,並且使用相同的IV index)。

例如,如果收到一個消息的SEQ是0x647262,IV index是0x58437AF2,

當SeqZero是0x1849時,SeqAuth是 0x58437AF2 645 849;

當SeqZero是0x1263時,SeqAuth是 0x58437AF2 645 263;

(如何計算SeqAuth呢)

由於SeqZero大小的限制,不可以發送一個SEQ比8192大的分片消息。如果一個分片消息沒有在時間內被確認,那麽高傳輸層PDU的發送應該被取消。

消息的每一個分片都包括了分片偏移序列號和最後分片號這兩個信息。

例如,在上面的42octets的高傳輸層控制PDU中,分片為0,1,2,3,4,5 最後分片號是5。分片偏移號和最後分片號都包括在分片消息中,可以讓接收方計算出高傳輸層PDU的大小尺寸。

重組

重組動作在接收設備上執行。

對於低功耗節點,它的確認消息將由朋友節點處理,低功耗節點不需要發送分片的確認消息。

當接收到一個分片消息時,會檢查SeqAuth,以確定該高傳輸層PDU是否之前已經被接收到。如果分片消息沒有被接收到,那麽接收設備需要按照SegN(最後一個分片序號)的描述開辟額外的內存,來保存該高傳輸層PDU的分片,並維持對接收到的分片的追蹤,並且認為該消息已經被接收。

如果節點不是低功耗節點,並且消息的目的地址是一個單播地址,如果該節點不能在此時收到高傳輸層PDU(比如節點忙碌或則資源受限),那麽該節點需要向源節點發送塊確認值為0x0000000的信號。

如果分片消息正在接收處理的過程中,那麽分片偏移序號(SegO)將確定在這個分片消息中哪一個高傳輸層PDU的etet需要替換之前為本條消息開辟的內存空間。然後,接收方會更新快確認值,來記錄鎖發送消息的成功分發。

一旦對於一個給定的SeqZero的高傳輸層PDU被完全接收,那麽高傳輸層將檢查高傳輸層PDU。

分片行為

(需要重新翻譯)

一旦高傳輸層消息被分片,低傳輸層將發送消息中的每一個分片。

如果消息的目的地址是一個單播地址,那麽低傳輸層期望收到來自源節電或者朋友節點的確認消息。

如果消息的目的地址是一個虛擬地址或者組地址,那麽不會接收到確認消息。

如果分片包被發送給一個組地址或者虛擬地址,那麽低傳輸層需要發送全部的分片包。建議發送全部的分片包多次,並在每次重復中引入智能隨機延時。(Nordic如何處理該延時呢?)

當低傳輸層PDU發送給單播地址時需要主要一下必要的應用方式

當低傳輸層PDU被發送,一個分片的傳輸定時器應該開始計時,在一定時間範圍內,分片的確認消息應該被收到。這個時間最小應該設置為 200 + 50 * TTL ms。

一個有效的分片確認消息需要滿足

  • 分片確認消息的OBO字段設置為0
  • DST字段設置為元素的單播地址
  • SeqZero字段設置為分片消息的SeqZero字段
  • SRC字段設置為分片消息的目的地址

如果一個分片確認消息的OBO字段設置為1, 並且DST字段設置為元素的單播地址,並且SeqZero字段設置為分片消息的SeqZero字段,那麽這個分片確認消息是一個有效的分片確認消息。

對於一個給定的SeqAuth,只有從第一個SRC地址接收到的分片確認消息可以被認作有效的分片確認消息。

???OBO字段的含義於朋友關系

如果一個有效的分片確認消息被接收,低傳輸層需要重置分片傳輸定時器並且重傳全部沒有確認的低傳輸層PDU。

如果一個確認了全部低傳輸層消息的分片確認消息被接收,那麽表明高傳輸層PDU是完整的。

如果一個將BlockAck字段設置為0x00000000的分片確認消息被接收,那麽高傳輸層PDU應該立即取消,並且更高的層次應該接到這個取消通知。

如果分片傳輸定時器超時,並且沒有有效的確認被接收,那麽低傳輸層應該重發全部沒有被確認的低傳輸層PDU。

每一個低傳輸層PDU至少要被發送兩次,除非確認更早的到達。如果在全部確認消息到達前,低傳輸層停止發送低傳輸層PDU,那麽高傳輸層PDU將被取消。

重組行為

(需要重新翻譯)

不適用於低功耗特性。

低傳輸層對於每一個源設備的SeqAuth有一個序列認證值和一個塊確認值。

如果低傳輸層收到一個SeqAuth比序列認證值小的分片消息,需要忽略這個分片消息。

如果低傳輸層收到一個新的消息,應該保存來自分片包的SeqAuth值作為新的序列認證值。

註意:序列認證值邏輯上包含了 IV index 信息,因此如果一個低傳輸層PDU通過使用一個較早的IV index被接收,那麽這個PDU應該有一個比序列認證值更小的SeqAuth。

如果一個低傳輸層接收到一個多分片消息中的一個分片包,但是不能在此時接收這個多分片消息。這是因為當前接收方正處於忙碌或者資源用盡的情況。

如果一個 消息的目的地址是一個單播地址,低傳輸層應該回應一哥BlockAck字段設置為0x00000000的確認包。

低傳輸層收到一個SeqAuth比序列確認值大的多分片消息中的一個分片時,應該開啟一個未完成定時器。這個定時器定義了低傳輸層等待最大時間數。這個未完成的定時器最小應該別設置為10s。

低傳輸層收到一個SeqAuth比序列確認值大的,並且目的地址是一個單播地址的多分片消息中的一個分片時,應該開啟一個確認定時器。這個定時器定義了低傳輸層發送一個分片確認消息後的時間次數。這個確認定時器應該最小設置為 150 + 50 * TTL ms。

註意:NT

如果一個低傳輸層在未完成定時器結束後收到了無論任何分片消息,未完成定時器應該重新打開。

低傳輸層應該標記每一個接收到一個塊確認值的分片包,這個塊確認值能夠在之後傳回發送的源節點。

當全部分片信息的分片被接收時,低傳輸層應該發送一個BlockAck字段設置為塊確認值的分片確認消息

低功耗特性的重組行為

低傳輸層行為

發送一個低傳輸層PDU

接收一個低傳輸層PDU

朋友隊列

Mesh Profile (3.5)低傳輸層