---
# System prepended metadata

title: 認識 DNP3 通訊協定 - 概述
tags: [Protocol, DNP3]

---

# 認識 DNP3 通訊協定 - 概述

因為關於 DNP3 的中文相關詳細資料真的很少，
所以在這裡紀錄 DNP3 的學習內容。

會分成四篇文章講解：

1. [概述](https://hackmd.io/@tm3u/dnp3-overview)
2. [應用層](https://hackmd.io/@tm3u/dnp3-application_layer)
3. [傳輸功能](https://hackmd.io/@tm3u/dnp3-transport_function)
4. [資料連結層](https://hackmd.io/@tm3u/dnp3-data_link_layer)

## 協定介紹

DNP3（Distributed Network Protocol 3）分布式網路協定。

是一種使用於自動化組件之間的通訊協定，目的是為了統一 SCADA 的通訊方式，
讓 SCADA 可以使用 DNP3　與主站、遠程終端單元（RTU）、智能電子設備（IED）等進行通訊，
主要應用於電力系統與自來水公司等公用事業。

DNP3　具有一定的可靠性，可以用來對抗惡劣環境中產生的電磁干擾與元件老化等信號失真現象，
在協議中大量使用了 CRC 校驗碼來保證數據的準確性，
適用於要求高度安全、中等速率和中等資料量的數據通訊領域。

## 通訊架構

國際標準化組織（ISO）定義了一種名為 OSI 七層模型的通訊架構，DNP3 基於該架構進行簡化，其稱為 `增強型效能架構（EPA）`。

EPA 僅有三個層級，其分別為：
`應用層（Application Layer）`、`資料連結層（Data Link Layer）` 跟 `物理媒介（Physical Media）` 。

其中，Application Layer 為了能夠與 Data Link Layer 互相傳遞資料，
需要將來自彼此的資料進行分割或重組，
因此在 Application Layer 中包含了 `傳輸功能（Transport Function）` 來進行中繼的資料處理。

因此 Transport Function 有時也被稱為 "偽層級"。

## 資料傳遞流程

DNP3 的運作分成兩個部份，分別為：`主站（Master）` 跟 `分站（Outstation）`。

![image](https://hackmd.io/_uploads/B1gbqFa6a.png)

上圖左側 Master 中的 `使用者層（User Layer）` 透過 Application Layer，
向 Outstation 發送 `請求（Request）` 來發起資料傳輸。

該 Request 包含了 1 個 `功能碼（Function Code）` 跟 0 ~ n 個 `DNP3 物件（DNP3 Object）`。

接著 Application Layer 會將 Request 傳遞到 Transport Function，
將其分割成符合傳輸長度的單元後傳遞給 Data Link Layer。

Data Link Layer 會加入 `目標位址（Destination）`、`來源位址（Source）` 跟 `循環冗餘校驗（CRC）`，
並透過 Physical Media 傳遞到 Outstation。

上圖右側 Outstation 中的 Data Link Layer 會從 Physical Media 接收 `八位元組（Octet）`，並檢查資料在傳輸過程中產生的錯誤。

如果檢查無誤，會從中去除原先 Data Link Layer 加入的 Destination、Source 以及 CRC，剩下的傳遞給 Application Layer。

傳遞給 Application Layer 的途中如有必要，Transport Function 會先將多筆資料重新組裝成一個完整的 Request。

隨後 Application Layer 提取 Request 中的 Function Code 跟 DNP3 Objects，
並且向 User Layer 呈現出 Master 想要的資料。

接著 Outstation 的 Application Layer 會根據 Master 的 Request 發起 `回應（Response）`。

Outstation 取得 Master 想要的數據資料（I/O 狀態或系統資訊等等...）後，會對其進行分類並傳遞給 Application Layer。

該 Application Layer 會建立成一筆 DNP3 Objects 格式化的資料，
並通過 Transport Function 傳遞給 Data Link Layer。

當 Master 收到 Response 後，通過各個層級進行錯誤檢查以及重新組裝的程序，從而還原回一組完整的 Application Layer 資料。

隨後從該資料中提取出 DNP3 Objects 呈現給 User Layer，讓 Master 的使用者可以進行儲存或是進一步的操作。

Master 發送完一筆 Request 後必須接收到 Outstation 的 Response 或是觸發 `逾時（Timeout）`，才會接續發送另一筆 Request。

而系統內可能會發生多筆同時交涉，例如：兩個 Master 同時向一個 Outstation 發出 Request。

因此，DNP3 允許 Outstation 在符合特定的條件後，自動將該筆資料傳送給 Master。這樣的功能稱為 `自發性回應（Unsolicited Response）`。

## 訊息分割

為了要符合每個層級的封包大小，Application Layer 訊息必須被分割成更小單元，
並在每一層添加 `標頭（Header）`，結構如下圖：

![image](https://hackmd.io/_uploads/HkOBwRyRa.png)

* Application Layer - `片段（Fragment）`

  * 允許設定接收的記憶體要求的上限。
  * Request 必須符合在一個 Fragment。
  * Response 可能超過一個 Fragment。

* Transport Function - `分段（Segment）`

  * Segment 會將 Fragment 分割成符合 Data Link Layer 的 Frame。
  * 每一個 Segment 包含了一個 `傳輸標頭（Transport Header）`。
  * 每一個 Fragment 只有第一個 Segment 才有 `應用標頭（Application Header）`。
  * 每個 Segment 最多只能有 250 個 Octets（包含 Transport Header）。
  
* Data Link Layer - `框架（Frame）`

  * 一個 Frame 最多只能有 292 個 Octet（包含 `連結標頭（Link Header）`）。
  * Frame 是為了檢查錯誤而設計。
