Hardware Protocol Specification: DNP3 (Distributed Network Protocol), serial data link layer¶
Version: DNP3-2013
Physical Layer: 9600 bps, 8N1.0
Framing: binary
Integrity Algorithm: crc16_dnp
📄 AsyncAPI Artifacts: Download AsyncAPI 2.6.0 YAML | View Interactive AsyncAPI HTML Docs
Description¶
SCADA/utility protocol. Its data-link CRC is exactly this schema's existing crc-16-dnp preset -- unused since it was first added several rounds ago. Its real structural novelty: data is chunked into 16-byte blocks, EACH with its own trailing CRC, not one check for the whole frame.
Command Catalog & Message Signatures¶
Category: GENERAL¶
DataLinkFrame (Command ID: 0x00) - control/destination/source are the LENGTH-counted header; userData is the application payload. userData is actually split into 16-byte blocks, each followed by its OWN separate CRC-16/DNP (the final block may be shorter) -- now recorded via framing.dataBlockChecking, though variableLength:remainder here still computes userData's byte count by simple subtraction against the frame's declared length, which INCLUDES the interleaved per-block check bytes; the true logical (non-check) data length is smaller and only recoverable by actually walking the blocks, not by this schema's arithmetic alone -- see dataBlockChecking's own description.¶
| Parameter | Type | Unit | Range / Constraints | Options |
|---|---|---|---|---|
control |
uint8 |
- | - | - |
destination |
uint16 |
- | - | - |
source |
uint16 |
- | - | - |
userData |
bytes |
- | - | - |
Formal AsyncAPI 2.6.0 Specification¶
asyncapi: 2.6.0
info:
title: DNP3 (Distributed Network Protocol), serial data link layer
version: DNP3-2013
description: 'SCADA/utility protocol. Its data-link CRC is exactly this schema''s
existing crc-16-dnp preset -- unused since it was first added several rounds ago.
Its real structural novelty: data is chunked into 16-byte blocks, EACH with its
own trailing CRC, not one check for the whole frame.'
servers:
serial_link:
url: serial://tty/9600
protocol: serial
description: Physical UART Transport (9600 bps, 8N1.0)
bindings:
serial:
baudRate: 9600
dataBits: 8
parity: none
stopBits: 1.0
framingType: binary
integrity: crc16_dnp
channels:
omniuart/cmd/DataLinkFrame:
publish:
summary: 'Send command DataLinkFrame (ID: 0x00)'
description: control/destination/source are the LENGTH-counted header; userData
is the application payload. userData is actually split into 16-byte blocks,
each followed by its OWN separate CRC-16/DNP (the final block may be shorter)
-- now recorded via framing.dataBlockChecking, though variableLength:remainder
here still computes userData's byte count by simple subtraction against the
frame's declared length, which INCLUDES the interleaved per-block check bytes;
the true logical (non-check) data length is smaller and only recoverable by
actually walking the blocks, not by this schema's arithmetic alone -- see
dataBlockChecking's own description.
message:
name: DataLinkFrame_Message
title: DataLinkFrame Command
payload:
$ref: '#/components/schemas/DataLinkFrame_Request'
components:
messages: {}
schemas:
DataLinkFrame_Request:
type: object
properties:
command_id:
type: integer
const: 0
description: Opcode ID for DataLinkFrame
control:
type: integer
destination:
type: integer
source:
type: integer
userData:
type: string
contentEncoding: base64
description: control/destination/source are the LENGTH-counted header; userData
is the application payload. userData is actually split into 16-byte blocks,
each followed by its OWN separate CRC-16/DNP (the final block may be shorter)
-- now recorded via framing.dataBlockChecking, though variableLength:remainder
here still computes userData's byte count by simple subtraction against the
frame's declared length, which INCLUDES the interleaved per-block check bytes;
the true logical (non-check) data length is smaller and only recoverable by
actually walking the blocks, not by this schema's arithmetic alone -- see
dataBlockChecking's own description.