Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

uwni/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

AltStyle によって変換されたページ (->オリジナル) /