在認識 Application Layer 前,建議讀者先瞭解 DNP3 的資料傳遞流程。
可以參考此篇:認識 DNP3 通訊協定 - 概述
在 DNP3 中,點(Point)
用於識別物理或邏輯實體。
Point 與特定的測量訊號或計算的模擬量有關:
輸入訊號
輸出訊號
此外,Point 除了值還會具有其他的 屬性(Attribute)
。
Point Type(點類型)
是對於具有相關特徵、相似功能以及與物理硬體或邏輯空間相關的 Point 進行分類的方法。
每個 Point Type 都是獨立的陣列,透過索引來識別每個 Point。
以 Analog Input 為例:
- 單一個 Analog Input 就算是一個 Point。
- 除了測量值以外,還可以具有名稱、比例因子、事件偵測的死區值和其他 Attribute。
- Analog Input 屬於 Analog Input Point Type。
DNP3 將 索引(Index)
用於識別 Point Type 陣列中的 Point,其最低值為 0。
以下圖為例:
- 這是一個具有可傳輸五種 Point Type 的 DNP3 Outstation。
- Analog Input Point Type 有五個 Analog Input Point。
- 透過Index 編號 0 ~ 4 來識別這五個 Point。
群組(Group)
用於分類訊息中的資料類型。
每個 Group 編號共享同一種 Point Type 以及資料產生或建立的方法,也可用於指定報告時間值、檔案傳輸以及設備資訊等所需的資料類型。
以 Analog Input 為例:
- Group 30 用於報告 Analog Input 當前值。
- Group 31 用於報告 Analog Input 凍結值。
- Group 32 用於報告 Analog Input 當前值變更的 Event。
- Group 33 用於報告 Analog Input 凍結值變更的 Event。
設備並非支援所有 Group,而是依照供應商的系統設計而定。
DNP3 為許多資料類型提供了多種資料格式的選擇,這些資料格式稱為 變體(Variation)
。
每個 Group 編號都有一組獨立的 Variation。
以 Group 30 為例:
- Variation 1 為帶有標誌 32-bit 的整數值
- Variation 2 為帶有標誌 16-bit 的整數值
- Variation 3 為無標誌 32-bit 的整數值
- Variation 4 為無標誌 16-bit 的整數值
- Variation 5 為帶有標誌 32-bit 的浮點數值
- Variation 6 為帶有標誌 16-bit 的浮點數值
標誌(Flag)
用於表示當前的設備在線狀況、設備是否已重啟或值已超出測量範圍等補充內容或是條件。
Object 通用 Flag(值為 Bool)
DNP3 物件(DNP3 Object)
由 Point 或其他結構的資料,進行編碼後所取得。
DNP3 Object 會根據其 Group 編號和 Variation 編號進行格式化以便資料透過訊息傳輸。
訊息中可以包含多個 Object,每個 Object 代表 Point 的當前值或是向 Point 發送的命令。
靜態(Static)
表示 Point 的當前值。
DNP3 允許透過 Request 來取得全部或部分 Static 的資料。
事件(Event)
與有意義的事情發生有關。
有些 DNP3 Object 會稱其為 Event Object,這只是 Event 的表示方法,並非在 Outstation 中儲存的實際數據。
只有在 Event 資訊傳遞到 Master(在 DNP3 Object 中),
並且 Outstation 有接收到來自 Master 回傳 "確認收到 Event" 的 確認(Confirmation)
後,
Event 才會從 Outstation 的 事件緩衝區(Event Buffer)
中刪除。
以 Analog Input 為例:
- 狀態的變化。
- 當前值的變化超過死區值。
- 特定時間所取得的數據快照。
- 等等…
DNP3 並沒有定義 Event Buffer 的數量、結構、資料組織以及內容,而是依照供應商的系統設計而定。
DNP3 透過 類別(Class)
來將 Static 跟 Event 進行分類:
大多數資料類型的 Point 可以分配到其中一種 Class。
如果某個 Point 是被分配到 Class 0,
當 Master 向 Outstation 作 Class 0 輪詢(Poll)
時,必須回傳該 Point 的當前值(Event 不會被記錄或回傳)。
如果某個 Point 是被分配到 Class 1、Class 2 或 Class 3,
那麼 Outstation 則必須記錄該 Point 所發生的 Event,並在 Class 0 Poll 時回覆其當前值。
如果某個 Point 完全沒有被分配到任何 Class,
那麼 Outstation 則不會記錄該 Point 所發生的 Event,也不會在 Class 0 Poll 時回覆其當前值。
不過,當 Master 對該 Point 實施 Static Poll,Outstation 仍然必須回傳該 Point 的當前值。
不同的 Poll 對上不同的 Class,其運作如下表:
無分配 | Class 0 | Class 1 | Class 2 | Class 3 | |
---|---|---|---|---|---|
Static Poll | ✓ | ✓ | ✓ | ✓ | ✓ |
Class 0 Poll | ✓ | ✓ | ✓ | ✓ | |
Class 1 Poll | ✓ | ||||
Class 2 Poll | ✓ | ||||
Class 3 Poll | ✓ |
Application Layer 的 片段(Fragment)
包含在 Request 或 Response 的訊息中,結構如下表:
Application Header | First Object Header | DNP3 Object | … | Last Object Header | DNP3 Object |
---|
每個 Fragment 都以包含控制資訊的 應用標頭(Application Header)
開始,無論它們出現在單一還是多個 Fragment 訊息中。
然而,通常單獨的 Application Header 不足以傳遞完整的訊息。
因此在 Application Header 後面會加上一或多組的 物件標頭(Object Header)
及 DNP3 Object 來形成完整訊息所需的附加資訊。
由 應用控制(Application Control)
跟 功能碼(Function Code)
組成。
不過 Response 的 Application Header 多了 內部指示(Internal Indication, IIN)
。
Application Request Header 的結構如下表:
Application Control | Function Code |
---|---|
1 octet | 1 octet |
Application Response Header 的結構如下表:
Application Control | Function Code | IIN |
---|---|---|
1 octet | 1 octet | 2 octets |
Application Control 的訊息大小為 1 個 Octet。
提供建構跟重組多個 Fragment 訊息所需的參數,並且指示接收方的 Application Layer 是否必須回覆 Confirmation 及協助檢測重複的訊息。
Application Control 由 FIR、FIN、CON、UNS 跟 SEQ 五種參數組成,其結構如下:
FIR - 1 bit
FIN - 1 bit
CON - 1 bit
UNS - 1 bit
SEQ - 4 bits
用於驗證 Fragment 是否以正確的順序接收,並檢查是否重複。
值的範圍為 0 ~ 15,並以 1 為單位遞增。值為 15 後,下一個值為 0。
Response 跟 Unsolicited Response 的 SEQ 值,兩者獨立互不相關。
Function Code 的訊息大小為 1 個 Octet。
用於識別 Fragment 訊息的目的。
Function Code 的種類較多,因此將簡易說明放到這篇:DNP3 - Function Code
IIN 的訊息大小為 2 個 Octet。
透過特定位元來表示 Outstation 內的某些狀態或是錯誤,其結構如下:
DNP3 透過代碼的方式來指定特定位元:IIN x.y。
關於 Internal Indication 的簡易說明如下表:
代碼 | 名稱 | 簡要說明 |
---|---|---|
IIN 1.0 | ALL_STATIONS | 收到廣播訊息 |
IIN 1.1 | CLASS_1_EVENTS | Outstation 有未報告的 Class 1 Event |
IIN 1.2 | CLASS_2_EVENTS | Outstation 有未報告的 Class 2 Event |
IIN 1.3 | CLASS_3_EVENTS | Outstation 有未報告的 Class 3 Event |
IIN 1.4 | NEED_TIME | 需要時間同步 |
IIN 1.5 | LOCAL_CONTROL | Outstation 的一或多個 Point 處於本地控制模式 |
IIN 1.6 | DEVICE_TROUBLE | Outstation 存在 "異常" 或 "設備特定的情況" |
IIN 1.7 | DEVICE_RESTART | Outstation 重啟 |
IIN 2.0 | NO_FUNC_CODE_SUPPORT | Outstation 不支援該 Function Code。 |
IIN 2.1 | OBJECT_UNKNOWN | Outstation 不支援該 Object 的 Request 操作 |
IIN 2.2 | PARAMETER_ERROR | 偵測到參數錯誤 |
IIN 2.3 | EVENT_BUFFER_OVERFLOW | Outstation 的 Event Buffer 出現溢位的情況 |
IIN 2.4 | ALREADY_EXECUTING | 【可選】Request 的操作已執行 |
IIN 2.5 | CONFIG_CORRUPT | 【可選】Outstation 偵測到損壞的設置 |
IIN 2.6 | RESERVED_2 | 【值常駐為 0】保留 |
IIN 2.7 | RESERVED_1 | 【值常駐為 0】保留 |
以發生 Outstation 不支援該 Object 的 Request 操作的狀態為例:
- 該狀態的 IIN 代碼為 IIN2.1
- 因此在 IIN 的第二個 Octet 中,第二個 bit 的值會為 1
由 物件類型符(Object Type Field)
、限定符(Qualifier Field)
以及 範圍符(Range Field)
組成。
Object Header 的結構如下表:
Object Type Field | Qualifier Field | Range Field |
---|---|---|
2 octet | 1 octet | N octets(取決於 Qualifier Field) |
以一個想要從 Outstation 讀取十個 Analog Input 的 Master 為例:
- Master 會使用 Function Code 0x01(READ)來制定 Request 訊息。
- 而 Object Header 會指定:
- 想要的 Analog Input Point Type 資料。
- Outstation 傳送資料時,應該使用的整數或浮點格式。
- 那十個 Analog Input Point 的 Index。
- Request 中不會包含 DNP3 Object,只會有一或多個 Object Header。
因為 Master 不傳送值,只傳送讓 Outstation 知道 Master 需要的值或是資料格式。- 接著,Outstation 會使用 RESPONSE(0x81)的 Function Code 來制定 Response 訊息。
其中包含了與 Request 相同或相似的 Object Header,並在後面接著 DNP3 Object。
後面接著的所有 DNP3 Object,每個都包含來自單個 Index 的單一 Analog 值。
Object Type Field 的訊息大小為 2 個 Octet,Group 跟 Variation 各占一個 Octet。
關於 Group 跟 Variation 的說明請看本篇章節:關鍵術語 - Group 跟 關鍵術語 - Variation
Qualifier Field 的訊息大小為 1 個 Octet,而 Range Field 則取決於 Qualifier Field 的內容。
Qualifier Field 由 Res、Object Prefix Code 跟 Range Specifier Code 三種參數組成,其結構如下:
Res - 1 bit
保留,且值常駐為 0。
Object Prefix Code - 3 bits
前綴(Prefix)
可以用來表示 Object 的 Index 編號或 Object 的大小。
它會出現在 Object Header 後的每個 DNP3 Object 前面,位置如下:
而 Object Prefix Code 則是用於指定 Prefix 的內容,其代碼說明如下表:
值 | 說明 | Prefix 的大小 |
---|---|---|
0x00 | 不使用 Prefix | |
0x01 | 以 Index 作為 Prefix | 1 octet |
0x02 | 以 Index 作為 Prefix | 2 octets |
0x03 | 以 Index 作為 Prefix | 4 octets |
0x04 | 以 Object Size 作為 Prefix | 1 octet |
0x05 | 以 Object Size 作為 Prefix | 2 octets |
0x06 | 以 Object Size 作為 Prefix | 4 octets |
0x07 | 保留 |
以 Master 想要讀取一連串 Index 為 "非連續排列" 的 Analog Input Point 為例:
- Master 會將 Object Prefix Code 設置為 0x01、0x02 或 0x03。
- 並發送以 Index 為 Prefix 的 0 octet 的空 Object。
- 該 Request 的 Fragment 將會如下:
若讀取的是 Index 為 "連續排列" 的情況下,
接下來要介紹的 Range Specifier Code 就可以指定起始跟截止的 Index 範圍,
並且不需要加入 Prefix(Object Prefix Code 設置為 0x00)。
Range Specifier Code - 4 bits
Range Specifier Code 指定是否使用 Range Field,並定義 Range Field 的內容及大小。
其代碼說明如下表:
值 | 說明 | Range Field 的大小 |
---|---|---|
0x00 | 1 octet 的起始 Index 跟截止 Index | 2 octets |
0x01 | 2 octets 的起始 Index 跟截止 Index | 4 octets |
0x02 | 4 octets 的起始 Index 跟截止 Index | 8 octets |
0x03 | 1 octet 的起始虛擬地址跟截止虛擬地址 | 2 octets |
0x04 | 2 octets 的起始虛擬地址跟截止虛擬地址 | 4 octets |
0x05 | 4 octets 的起始虛擬地址跟截止虛擬地址 | 8 octets |
0x06 | 不使用 Range Field | 0 octet |
0x07 | 1 octet 的 Objects 數量 | 1 octet |
0x08 | 2 octets 的 Objects 數量 | 2 octets |
0x09 | 4 octets 的 Objects 數量 | 4 octets |
0x0A | 保留 | |
0x0B | 1 octet 的 Objects 數量(可變長度的格式) | 1 octet |
0x0C | 保留 | |
0x0D | 保留 | |
0x0E | 保留 | |
0x0F | 保留 |
Range Field 的訊息大小以及內容取決於 Qualifier Field 的 Range Specifier Code。
自發性回應(Unsolicited Response)
是當重要的事件發生時,在 Master 沒有發起 Request 情況下由 Outstation 發送訊息。
此功能是否啟用,是依照供應商的系統設計而定。