Documentation
¶
Overview ¶
Package dnp3 implements the DNP3 protocol (IEEE Std 1815-2012) for both master and outstation roles.
The stack is layered the way the standard is. Each layer below this package exposes a core that takes bytes and returns bytes — it performs no I/O, starts no goroutines, and reads no clock. Sessions and channels supply those concerns from the outside, which is what makes every parser fuzzable and every state machine testable against a virtual clock.
internal/link framing, CRC-16/DNP, primary and secondary state machines internal/transport FIR/FIN/SEQ segmentation and reassembly internal/app application headers, function codes, IIN, qualifiers objects group/variation codecs master, outstation session state machines built on the layers above channel TCP, TLS, UDP, serial and in-process pipe transports
This root package holds the value types the whole stack shares: measurements, quality flags, timestamps, commands and their status codes.
Index ¶
- Constants
- Variables
- func AnalogFitsIn16(v float64) bool
- func AnalogFitsIn32(v float64) bool
- func DNP3ToTime(ms uint64) time.Time
- func TimeToDNP3(t time.Time) uint64
- type Analog
- type AnalogOutput
- type AnalogOutputFloat32
- type AnalogOutputFloat64
- type AnalogOutputInt16
- type AnalogOutputInt32
- type AnalogOutputStatus
- type Binary
- type BinaryOutputStatus
- type Class
- type CommandStatus
- type ControlCode
- type ControlRelayOutputBlock
- type Counter
- type DoubleBit
- type DoubleBitBinary
- type Flags
- type FrozenCounter
- type Indexed
- type OctetString
- type PointType
- type RestartMode
- type Timestamp
- type TimestampQuality
Constants ¶
const MaxDNP3Time = int64(1)<<48 - 1
MaxDNP3Time is the largest instant a 48-bit DNP3 timestamp can express: 2^48 - 1 milliseconds after the UNIX epoch, which falls in the year 10889.
const MaxOctetStringLen = 255
MaxOctetStringLen is the largest octet string the encoding allows.
const Version = "0.1.0-dev"
Version is the library version, following semantic versioning.
Variables ¶
var ( // ErrMalformed means a received octet sequence did not conform to the // protocol and could not be recovered. ErrMalformed = errors.New("dnp3: malformed data") // ErrTimeout means a peer did not respond within the configured window. ErrTimeout = errors.New("dnp3: timeout") // ErrClosed means the session or channel has been shut down. ErrClosed = errors.New("dnp3: closed") // ErrNotSupported means the peer rejected a function code or object it // does not implement. ErrNotSupported = errors.New("dnp3: not supported by peer") // ErrBadConfig means a configuration value is outside the range the // protocol allows. ErrBadConfig = errors.New("dnp3: invalid configuration") // ErrTaskFailed means a master task exhausted its retries. ErrTaskFailed = errors.New("dnp3: task failed") // ErrNoConnection means the channel has no established connection. ErrNoConnection = errors.New("dnp3: no connection") )
Errors returned across the stack. Layer packages define their own detailed errors and wrap them in these, so callers can classify a failure without importing internal packages.
Functions ¶
func AnalogFitsIn16 ¶
AnalogFitsIn16 reports whether v can be encoded as a 16-bit analog without loss, which the outstation needs when a master requests a narrow variation.
func AnalogFitsIn32 ¶
AnalogFitsIn32 reports whether v can be encoded as a 32-bit analog without loss.
func DNP3ToTime ¶
DNP3ToTime converts a 48-bit DNP3 timestamp to a time.Time in UTC. Bits above the low 48 are ignored, matching what a conforming encoder can emit.
func TimeToDNP3 ¶
TimeToDNP3 converts t to DNP3's wire representation: milliseconds since the UNIX epoch, clamped to the 48 bits the encoding provides. Times before the epoch clamp to zero.
Types ¶
type Analog ¶
Analog is an analog input. The stack carries every analog variation — 16-bit, 32-bit, single and double precision — as a float64 and narrows only at the encoding boundary.
type AnalogOutput ¶
type AnalogOutput interface {
AnalogOutputInt16 | AnalogOutputInt32 | AnalogOutputFloat32 | AnalogOutputFloat64
}
AnalogOutput is any of the four analog output command variations.
type AnalogOutputFloat32 ¶
type AnalogOutputFloat32 struct {
Value float32
Status CommandStatus
}
AnalogOutputFloat32 is a group 41 variation 3 control.
type AnalogOutputFloat64 ¶
type AnalogOutputFloat64 struct {
Value float64
Status CommandStatus
}
AnalogOutputFloat64 is a group 41 variation 4 control.
type AnalogOutputInt16 ¶
type AnalogOutputInt16 struct {
Value int16
Status CommandStatus
}
AnalogOutputInt16 is a group 41 variation 2 control.
type AnalogOutputInt32 ¶
type AnalogOutputInt32 struct {
Value int32
Status CommandStatus
}
AnalogOutputInt32 is a group 41 variation 1 control.
type AnalogOutputStatus ¶
AnalogOutputStatus reports the present value of an analog control point.
type BinaryOutputStatus ¶
BinaryOutputStatus reports the present state of a control point.
type Class ¶
type Class uint8
Class is a bit mask over the DNP3 event classes plus class 0, the static data set. Masks are how polls are expressed: an integrity poll is Class0 | Class1 | Class2 | Class3.
const ( Class0 Class = 1 << iota // static data Class1 // event class 1, conventionally the most urgent Class2 Class3 // ClassNone assigns a point to no event class, suppressing its events. ClassNone Class = 0 // Class123 is every event class, excluding static data. Class123 = Class1 | Class2 | Class3 // ClassAll is an integrity poll: static data plus every event class. ClassAll = Class0 | Class123 )
Class mask bits.
type CommandStatus ¶
type CommandStatus uint8
CommandStatus is the outcome an outstation reports for a control operation.
const ( CommandSuccess CommandStatus = 0 CommandTimeout CommandStatus = 1 CommandNoSelect CommandStatus = 2 CommandFormatError CommandStatus = 3 CommandNotSupported CommandStatus = 4 CommandAlreadyActive CommandStatus = 5 CommandHardwareError CommandStatus = 6 CommandLocal CommandStatus = 7 CommandTooManyOps CommandStatus = 8 CommandNotAuthorized CommandStatus = 9 CommandAutomationInhibit CommandStatus = 10 CommandProcessingLimited CommandStatus = 11 CommandOutOfRange CommandStatus = 12 CommandDownstreamLocal CommandStatus = 13 CommandAlreadyComplete CommandStatus = 14 CommandBlocked CommandStatus = 15 CommandCanceled CommandStatus = 16 CommandBlockedOtherMstr CommandStatus = 17 CommandDownstreamFail CommandStatus = 18 CommandNonParticipating CommandStatus = 126 CommandUndefined CommandStatus = 127 )
Command status codes defined by the standard.
func (CommandStatus) OK ¶
func (s CommandStatus) OK() bool
OK reports whether the command succeeded.
func (CommandStatus) String ¶
func (s CommandStatus) String() string
type ControlCode ¶
type ControlCode uint8
ControlCode is the operation field of a Control Relay Output Block. It packs an operation type in the low four bits with three modifier flags above.
const ( ControlNUL ControlCode = 0x00 ControlPulseOn ControlCode = 0x01 ControlPulseOff ControlCode = 0x02 ControlLatchOn ControlCode = 0x03 ControlLatchOff ControlCode = 0x04 )
Control operation types, occupying the low nibble of a ControlCode.
const ( // ControlClose sets the close coil field. ControlClose ControlCode = 0x80 // ControlTrip sets the trip coil field. ControlTrip ControlCode = 0x40 )
Trip/close modifiers, which pair with an operation type to drive the two coils of a breaker.
func (ControlCode) Clear ¶
func (c ControlCode) Clear() bool
Clear reports whether the clear bit is set, which cancels a queued or running operation on the point.
func (ControlCode) IsClose ¶
func (c ControlCode) IsClose() bool
IsClose reports whether the close coil is selected.
func (ControlCode) IsTrip ¶
func (c ControlCode) IsTrip() bool
IsTrip reports whether the trip coil is selected.
func (ControlCode) OpType ¶
func (c ControlCode) OpType() ControlCode
OpType returns the operation type nibble.
func (ControlCode) String ¶
func (c ControlCode) String() string
type ControlRelayOutputBlock ¶
type ControlRelayOutputBlock struct {
Code ControlCode
// Count is how many times to execute the operation. Zero is legal and
// means "do nothing", which some masters use to probe a point.
Count uint8
// OnTime and OffTime are milliseconds, used by the pulse operations.
OnTime uint32
OffTime uint32
// Status is meaningful only on a response echo.
Status CommandStatus
}
ControlRelayOutputBlock is a group 12 variation 1 control: the command used to operate breakers, reclosers and other discrete outputs.
func (ControlRelayOutputBlock) String ¶
func (c ControlRelayOutputBlock) String() string
type DoubleBit ¶
type DoubleBit uint8
DoubleBit is the state of a double-bit binary input, which reports a two-contact device — typically a breaker with separate open and closed auxiliary contacts — and can therefore distinguish a device in transit or miswired from one that is definitely open or definitely closed.
const ( // DoubleBitIntermediate: both contacts read open. The device is moving. DoubleBitIntermediate DoubleBit = 0 // DoubleBitDeterminedOff: the device is open. DoubleBitDeterminedOff DoubleBit = 1 // DoubleBitDeterminedOn: the device is closed. DoubleBitDeterminedOn DoubleBit = 2 // DoubleBitIndeterminate: both contacts read closed, which is impossible. DoubleBitIndeterminate DoubleBit = 3 )
Double-bit states. The numeric values are the on-the-wire encoding.
type DoubleBitBinary ¶
DoubleBitBinary is a two-bit status input.
type Flags ¶
type Flags uint8
Flags is the quality octet that accompanies most measurements.
The low five bits mean the same thing for every measurement type. The upper three are type-specific: what is CHATTER_FILTER on a binary input is OVER_RANGE on an analog input and ROLLOVER on a counter. Because the interpretation depends on the point type, Flags stores the raw octet and leaves naming to the per-type accessors below.
const ( // Online means the point is being read from the field. A cleared Online // bit is the single most important quality signal in DNP3: the value // present alongside it is not trustworthy. Online Flags = 0x01 // Restart means the value has not been updated since the device restarted. Restart Flags = 0x02 // CommLost means communication with the source of the point has failed. CommLost Flags = 0x04 // RemoteForced means the value was forced by a downstream device. RemoteForced Flags = 0x08 // LocalForced means the value was forced by the outstation itself. LocalForced Flags = 0x10 )
Flag bits common to every measurement type.
const ( // ChatterFilter applies to binary and double-bit binary inputs: the point // is toggling faster than the outstation's filter allows. ChatterFilter Flags = 0x20 // Rollover applies to counters. Deprecated by the standard in favour of // letting the counter wrap, but still emitted by older devices. Rollover Flags = 0x20 // Discontinuity applies to counters: the value cannot be compared against // the previous reading. Discontinuity Flags = 0x40 // OverRange applies to analog inputs and outputs: the value exceeds the // range the point can represent. OverRange Flags = 0x20 // ReferenceErr applies to analog inputs and outputs: the reference used to // digitise the value is not accurate. ReferenceErr Flags = 0x40 // StateBit carries the value itself for binary points inside a flags // octet, as in group 1 variation 2. StateBit Flags = 0x80 )
Type-specific bits. Each is valid only for the measurement types named.
func (Flags) IsGood ¶
IsGood reports whether the value carrying these flags may be trusted: online, not restarting, not comm-lost, and not forced from either end.
func (Flags) String ¶
String renders the common bits by name. Type-specific bits are shown by position because their meaning depends on the point type; use Flags.StringFor when the type is known.
type FrozenCounter ¶
FrozenCounter is a counter value captured at a freeze command.
type OctetString ¶
type OctetString []byte
OctetString is a variable-length opaque value, group 110 and 111. The standard caps it at 255 octets.
type PointType ¶
type PointType uint8
PointType identifies a measurement type, which fixes the meaning of the upper three quality bits.
type RestartMode ¶
type RestartMode uint8
RestartMode selects between the two restart function codes.
const ( // ColdRestart reinitialises the outstation completely, as though power // had been cycled. ColdRestart RestartMode = iota // WarmRestart reinitialises only the communications process. WarmRestart )
Restart modes.
func (RestartMode) String ¶
func (m RestartMode) String() string
type Timestamp ¶
type Timestamp struct {
Time time.Time
Quality TimestampQuality
}
Timestamp pairs a time with how much that time can be trusted.
The two are kept together deliberately. A DNP3 measurement can carry a perfectly well-formed timestamp from an outstation whose clock has never been set, and a consumer that ignores the quality will happily file that event under 1970 or under whatever the drifted clock says.
func NoTime ¶
func NoTime() Timestamp
NoTime returns the timestamp used by measurements that carry no time.
func Unsynchronized ¶
Unsynchronized returns a timestamp for t whose source clock was not synced.
type TimestampQuality ¶
type TimestampQuality uint8
TimestampQuality describes how much a timestamp can be relied on.
const ( // TimestampInvalid means the measurement carried no time at all. The // Timestamp's Time field is the zero value. TimestampInvalid TimestampQuality = iota // TimestampUnsynchronized means the outstation reported a time while its // own clock was not synchronised to the master. TimestampUnsynchronized // TimestampSynchronized means the outstation's clock was synchronised when // the measurement was taken. TimestampSynchronized )
Timestamp qualities, in increasing order of trust.
func (TimestampQuality) String ¶
func (q TimestampQuality) String() string
Directories
¶
| Path | Synopsis |
|---|---|
|
Package channel provides the physical layer beneath a DNP3 session: the thing that produces a byte stream and reproduces it after a failure.
|
Package channel provides the physical layer beneath a DNP3 session: the thing that produces a byte stream and reproduces it after a failure. |
|
cmd
|
|
|
dnp3-decode
command
Command dnp3-decode renders DNP3 octets as a decoded protocol tree.
|
Command dnp3-decode renders DNP3 octets as a decoded protocol tree. |
|
dnp3-explorer
command
Command dnp3-explorer is a terminal browser for a DNP3 outstation.
|
Command dnp3-explorer is a terminal browser for a DNP3 outstation. |
|
dnp3-master
command
Command dnp3-master is a SCADA client: it polls outstations, records what they report, and issues controls.
|
Command dnp3-master is a SCADA client: it polls outstations, records what they report, and issues controls. |
|
dnp3-outstation
command
Command dnp3-outstation is a simulated DNP3 outstation: a substation RTU with plant behind it.
|
Command dnp3-outstation is a simulated DNP3 outstation: a substation RTU with plant behind it. |
|
Package decoder turns DNP3 octets into a structured trace.
|
Package decoder turns DNP3 octets into a structured trace. |
|
internal
|
|
|
app
Package app implements the DNP3 application layer framing: the fragment header, function codes, internal indications, and the object headers with their qualifier, range and prefix encodings.
|
Package app implements the DNP3 application layer framing: the fragment header, function codes, internal indications, and the object headers with their qualifier, range and prefix encodings. |
|
gen
command
Command gen reads objects/spec/dnp3_objects.yaml and emits the object codecs, the descriptor registry, and the size table the framing layer needs.
|
Command gen reads objects/spec/dnp3_objects.yaml and emits the object codecs, the descriptor registry, and the size table the framing layer needs. |
|
link
Package link implements the DNP3 data link layer: frame encoding and decoding, the CRC, and the primary and secondary station state machines.
|
Package link implements the DNP3 data link layer: frame encoding and decoding, the CRC, and the primary and secondary station state machines. |
|
stack
Package stack couples the link and transport layers to a byte stream.
|
Package stack couples the link and transport layers to a byte stream. |
|
transport
Package transport implements the DNP3 transport function: the single-octet layer that cuts application fragments into link-sized segments and puts them back together.
|
Package transport implements the DNP3 transport function: the single-octet layer that cuts application fragments into link-sized segments and puts them back together. |
|
Package master implements the DNP3 master role: the station that polls outstations, receives their events, and issues commands.
|
Package master implements the DNP3 master role: the station that polls outstations, receives their events, and issues commands. |
|
Package multidrop shares one channel between several DNP3 sessions.
|
Package multidrop shares one channel between several DNP3 sessions. |
|
Package objects implements the DNP3 object group and variation codecs.
|
Package objects implements the DNP3 object group and variation codecs. |
|
Package outstation implements the DNP3 outstation role: the device that holds measurements, answers a master's polls, and executes its commands.
|
Package outstation implements the DNP3 outstation role: the device that holds measurements, answers a master's polls, and executes its commands. |