羅 捷,潘江峰,耿修堂
(西北機電工程研究所,陜西 咸陽 712099)
隨著信息技術的迅猛發展,武器裝備的信息化程度亟待提高。在某武器系統信息化工程中,指揮控制指令的下達、空情信息的傳達、武器終端的狀態上報等信息的傳遞,由一個共同遵循的協議進行約定。協議中詳細規定了所交換的報文及其相關信息。如何能夠快速、準確地對報文進行編解碼,是實現該協議重點需要解決的問題。
針對該協議定義,筆者設計了一種編解碼模塊的實現方案,并在某項目上成功進行了應用。
設計的編解碼模塊應滿足如下要求:
1)滿足協議對實時性的要求。
2)向高層提供編碼和解碼2個接口函數。
3)出現異常情況時,能自動提供異常信息。
4)具有校驗功能。
實現協議報文的編解碼主要有兩方面的工作,一是進行協議轉換,二是編解碼程序的設計實現,其實現過程如圖1所示。
1.2.1 協議轉換
協議是在一種抽象層次上來表示數據結構信息,在實際應用中,需要將協議描述的數據結構翻譯轉換成具體語言(如C、C++等)的數據結構表示形式[1]。需要對協議描述進行分析、總結,提煉出統一的C語言數據結構,將其作為與高層的數據接口。
1.2.2 編解碼程序的設計實現
編碼的過程是將高層提供的待編碼的報文信息(轉換后的C語言數據結構),經過編碼函數處理后,轉換成二進制碼流提供給高層。
解碼的過程是將高層提供的待解碼的二進制碼流,經過解碼函數處理后,解析成報文信息(C語言數據結構)提供給高層。
在對編解碼模塊進行設計時,需要著重考慮軟件的可維護性和健壯性等[2-5]。
該協議詳細定義了所交換的報文的結構、報文中每個字段的含義及字段長度、校驗方式等。
報文由報頭、報文類型字、信息字段、報文校驗字組成。報頭由一些地址信息和控制類信息組成。報文類型字決定了報文的類型,從而確定了本報文所包含的信息字段及其排列順序。報文校驗字采用累加校驗和的方式。
從協議描述到C語言數據結構的轉換需要經過字段類型的轉換、報文結構的轉換、數據接口的轉換3個步驟。
縱觀整個協議,各個字段的字長從1 ~32 bit不等,有的帶有符號位,有的沒有符號位。在將協議描述轉換成C語言數據結構時,轉換規則見表1。
表1 類型轉換規則
每個報文都有一個報頭,其結構是固定的,所以將報頭定義為一個C語言的結構體類型。
typedef struct
{
報頭字段1
報頭字段2
……
} HEAD; //報頭
對于一個指定的報文,其包含的信息字段及其排列順序是固定的,所以將每一個報文的信息字段定義為一個C語言的結構體類型,這樣定義了多個C語言結構體類型與每個報文的信息字段對應。
typedef struct
{
報文1的信息字段1
報文1的信息字段2
……
} BWXX1; //報文1的信息字段
typedef struct
{
報文2的信息字段1
報文2的信息字段2
……
} BWXX2; //報文2的信息字段
……
每個報文的報頭和報文類型字的結構是固定的。
報文的校驗功能在編解碼模塊中實現,只需把校驗的結果反饋給高層即可。
從結構上看,各個報文的不同之處在報文的信息字段部分,故將各個報文信息字段定義為一個C語言的共用體類型,從而實現向高層提供一個統一的數據接口,定義示意如下。
typedef struct
{
struct HEAD head; //報頭
unsigned char type; //報文類型字
union
{
struct BWXX1 bw1;
struct BWXX2 bw2;
……
}bwxx;//報文信息
}MESSAGE;
編解碼模塊從功能上可以分為核心模塊、校驗模塊、異常處理模塊、比特流處理模塊。編解碼模塊的結構如圖2所示。
核心模塊負責實現對報文的編解碼功能,并向高層提供編碼和解碼2個接口。
每一個C語言結構體類型都有一個對應的編碼函數,負責對結構中的所有成員進行編碼。在實現對報文的編碼時,先打包報頭、報文類型字,再根據報文類型字判斷是哪條報文,繼而調用該報文信息字段的編碼函數。
每一個C語言結構體類型都有一個對應的解碼函數,負責對結構中的所有成員進行解碼。在實現對報文的解碼時,先解包報頭、報文類型字,再根據報文類型字判斷是哪條報文,繼而調用該報文信息字段的解碼函數。
協議采用校驗和的方式進行校驗,即編碼后的數據流按字節累加,其結果的低8位作為校驗和,放在報文的最后一個字節。為了簡化高層的處理,將校驗功能放到編解碼模塊里來實現。編碼時,需要按照規定在編碼后的比特流后添加校驗和。解碼時,需要根據校驗和進行判斷,以確定是否正確接收到了報文。
在編解碼過程中還要對難以預料的一些問題進行異常處理,比如數據越界、不支持的報文類型字、待解包的字符串過短解不出正確的數據、由校驗和判斷出傳輸中出現錯誤等等,并將發現的問題向高層報告。
協議中的數據類型從1~32 bit不等,而且出現的順序是隨機的,沒有規律可循,如何能夠實現從字節中的任何位置開始打包、解包任何長度(32 bit內)的數據,同時保證具有良好的擴展性是重點需要解決的問題,這也是編解碼模塊實現的難點。
對于編碼過程,采用以下3個層次進行處理:
3.4.1 基礎編碼函數
基礎編碼函數是將1~8 bit數據打包到比特流中,需要全面考慮待打包數據從當前字節的第幾個比特開始打包、當前字節是否放得下、是否需要跨字節等情況,從而使得基礎編碼函數能夠適用于所有可能的情況。這是進行編碼的基礎,它的正確性、健壯性決定了編碼模塊的正確性、健壯性。
3.4.2 擴展編碼函數
擴展編碼函數是將9 ~32 bit數據打包到比特流中,這里采用了一個巧妙的方法將問題進行轉化。首先,對待編碼數據進行分解,分解成n+8、n+8+8、n+8+8+8位,其中1≤n≤8,n代表待編碼數據最高字節占有的比特數;其次,針對待編碼數據的每個字節調用一次基礎編碼函數,從高字節到低字節依次進行編碼。這樣復雜的編碼問題轉換成了簡單的加法問題。
3.4.3 帶符號位的數據的編碼函數
對于帶符號位的數據來說,區分正負數分別對待。對于正數,直接調用相關的基礎編碼函數、擴展編碼函數即可。對于負數,先調用基礎編碼函數將符號位進行打包,再根據負數的存儲形式取其數據位[6],之后再調用相關的基礎編碼函數、擴展編碼函數。
與編碼過程類似,解碼過程也是采用基礎解碼函數、擴展解碼函數、帶符號位的數據的解碼函數3個層次進行處理。
筆者所設計并實現的編解碼模塊具有良好的框架,使得具有較高的可維護性。當因協議需要而增加新報文或者當因協議修改而需要修改某報文的信息字段時,只需要對相關結構定義、報文信息字段的編解碼函數等進行修改即可。本編解碼模塊具有良好的健壯性。對基本編碼解碼函數的遍歷測試,保證了對比特流處理的正確性;對各種可能出現的異常情況進行異常處理,保證了本編解碼模塊的健壯性。本編解碼模塊能夠滿足實時性的要求。經測試,完成一條報文的編碼解碼需要的時間是幾個毫秒,完全滿足系統實時性的需要。
目前該編解碼模塊已經在某系統的多個設備中進行了應用,并取得了較好的效果。
參考文獻(References)
[1] 李小文,冉靖.LTE協議棧中ASN.1模塊的設計與實現[J].計算機工程,2011,37(8):252-255.
LI Xiao-wen, Ran Jing. Design and realization of ASN.1 module in LTE protocol stack[J].Computer Engineering,2011,37(8):252-255. (in Chinese)
[2] 何國偉,王瑋.軟件可靠性[M].北京:國防工業出版社,1998:218-348.
HE Guo-wei, WANG Wei. Software reliability[M]. Bejing:National Defense Industry Press,1998:218-348. (in Chinese)
[3] 鄧良松,劉海巖,陸麗娜.軟件工程[M].2版.西安:西安電子科技大學出版社,2004:83-93.
DENG Liang-song, LIU Hai-yan, LU Li-na. Software engineering[M].2nd ed. Xi’an: Xi’an Electronic and Science University Press,2004:83-93. (in Chinese)
[4] 普雷斯曼 R S.軟件工程[M].郭肇德,鄭少仁,譯.北京:國防工業出版社,1988:248-269.
Prysmian R S.Software engineering[M].GUO Zhao-de,ZHENG Shao-ren,translated. Bejing:National Defense Industry Press,1988:248-269. (in Chinese)
[5] 鄭人杰,殷仁昆.實用軟件工程[M].北京:清華大學出版社,1991:202-220.
ZHENG Ren-jie, YIN Ren-kun. Practical software engineering[M]. Beijing: Tsinghua University Press,1991:202-220. (in Chinese)
[6] 譚浩強.C程序設計[M].3版.北京:清華大學出版社,2005:40-41.
TAN Hao-qiang. C programming design[M].3rd ed. Beijing: Tsinghua University Press,2005:40-41. (in Chinese)