Skip to content

rinmyo/ctcsbt-rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ctcsbt-rs

a codec for CTCS Balise Telegram.

解碼之思路

一個報文中存可能存在多個用戶信息包,而若能成功的爲所有用戶信息包分片,則解碼之最小單位是用戶信息包.

而分片的核心在於找到每個 Packet 的起點,這裏從用戶信息包的定義中,我們可以發現一個有用的變量:L_PACKET 。這個變量標記了該信息包的位置, 通常來說該變量是處於某個 Packet 的 (10, 23] 位.

因爲長報文也不過千位, 實在沒有並行化之必要. 所以解碼器採用線性解碼. 即從前往後以此解碼多個用戶信息包

因此我們需要一個數組, 以保存每個 Packet 之類型與長度. 該數組的目的同時還有充當緩存之用, 即避免重複解析 NID_PACKET 和 L_PACKET 兩個變量.

let l = [(21, 50), (7, 50), (141, 50), (21, 60)];

我們還需要一個指針 start_ptr = 0,其值爲數組 l 的前 $n$ 項和, 即表示第 $n+1$ 個 Packet 的起點.

流程: 讀入用戶信息包區的前 8 位從而獲得第一個 Packet 的類型. 通過 macro 預設好的長度確定其 L_PACKET 的值,即長度, 同時也等於下一個 Packet 的起點. 記入數組 l. 讀入下一個 Packet 的 NID 再找到 L_PACKET 以確定下一個 Packet 的長度記入 l... 如此循環

校驗:因爲沒有校驗碼, 我們只得通過信息結束 11111111 來判斷是否有信息錯誤. 而且我們需要一個快速的方法來校驗其合法性. 而且校驗應該在解碼之前,但要想辦法不做重複的工作.

如果一個報文是合法的, 那麼在其最後一個數據包結束之後就應該是幀結束標記. 當我們爲所有 Packet 分片之後, 從 l 之和處起連續 8 bits 就應該是 11111111. 當然我們不需要計算這個加法. 前文提到的 start_ptr 就是累加器.

這個校驗應該在正式解碼之前完成. 如果校驗失敗,那麼說明輸入非法. 直接 panic!

關於宏: 本案中宏的作用十分巨大. 爲每一個 Packet 的變量增加 meta 信息, 同時使用 Derive 宏實現上述算法.

對於如何解析變量含義的問題. 需要從 i18n 中讀入

Packet 44 的處理

在 CTCS 中, Packet 44 中寄生着 CTCS 用戶信息包. 因此 Packet 44 不能用宏來實現. 需要手動實現以正確解析其中的 CTCS 包.

Crates

src: encoder & decoder 的接口 ctcsbt-cli: clap 封裝 ctcsbt-macro: 過程宏, ctcsbt-packets: 用戶信息包定義

About

a codec for CTCS balise telegram in Rust.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages