Skip to content

Commit

Permalink
minimised system parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
pascaldekloe committed Aug 9, 2024
1 parent 6af3d02 commit a50f216
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 54 deletions.
38 changes: 19 additions & 19 deletions cmd/iecat/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,45 +130,43 @@ func mustPacketStream() packetStream {
CmdLog.Fatal("width of information-object address is neither 1 nor 2 nor 3 octets")

case *cOTAddrFlag == 1 && *comAddrFlag == 1 && *objAddrFlag == 1:
return system[info.OrigAddr0, info.ComAddr8, info.ObjAddr8]{}
return setup[info.OrigAddr0, info.ComAddr8, info.ObjAddr8]{}
case *cOTAddrFlag == 1 && *comAddrFlag == 1 && *objAddrFlag == 2:
return system[info.OrigAddr0, info.ComAddr8, info.ObjAddr16]{}
return setup[info.OrigAddr0, info.ComAddr8, info.ObjAddr16]{}
case *cOTAddrFlag == 1 && *comAddrFlag == 1 && *objAddrFlag == 3:
return system[info.OrigAddr0, info.ComAddr8, info.ObjAddr24]{}
return setup[info.OrigAddr0, info.ComAddr8, info.ObjAddr24]{}

case *cOTAddrFlag == 1 && *comAddrFlag == 2 && *objAddrFlag == 1:
return system[info.OrigAddr0, info.ComAddr16, info.ObjAddr8]{}
return setup[info.OrigAddr0, info.ComAddr16, info.ObjAddr8]{}
case *cOTAddrFlag == 1 && *comAddrFlag == 2 && *objAddrFlag == 2:
return system[info.OrigAddr0, info.ComAddr16, info.ObjAddr16]{}
return setup[info.OrigAddr0, info.ComAddr16, info.ObjAddr16]{}
case *cOTAddrFlag == 1 && *comAddrFlag == 2 && *objAddrFlag == 3:
return system[info.OrigAddr0, info.ComAddr16, info.ObjAddr24]{}
return setup[info.OrigAddr0, info.ComAddr16, info.ObjAddr24]{}

case *cOTAddrFlag == 2 && *comAddrFlag == 1 && *objAddrFlag == 1:
return system[info.OrigAddr8, info.ComAddr8, info.ObjAddr8]{}
return setup[info.OrigAddr8, info.ComAddr8, info.ObjAddr8]{}
case *cOTAddrFlag == 2 && *comAddrFlag == 1 && *objAddrFlag == 2:
return system[info.OrigAddr8, info.ComAddr8, info.ObjAddr16]{}
return setup[info.OrigAddr8, info.ComAddr8, info.ObjAddr16]{}
case *cOTAddrFlag == 2 && *comAddrFlag == 1 && *objAddrFlag == 3:
return system[info.OrigAddr8, info.ComAddr8, info.ObjAddr24]{}
return setup[info.OrigAddr8, info.ComAddr8, info.ObjAddr24]{}

case *cOTAddrFlag == 2 && *comAddrFlag == 2 && *objAddrFlag == 1:
return system[info.OrigAddr8, info.ComAddr16, info.ObjAddr8]{}
return setup[info.OrigAddr8, info.ComAddr16, info.ObjAddr8]{}
case *cOTAddrFlag == 2 && *comAddrFlag == 2 && *objAddrFlag == 2:
return system[info.OrigAddr8, info.ComAddr16, info.ObjAddr16]{}
return setup[info.OrigAddr8, info.ComAddr16, info.ObjAddr16]{}
case *cOTAddrFlag == 2 && *comAddrFlag == 2 && *objAddrFlag == 3:
return system[info.OrigAddr8, info.ComAddr16, info.ObjAddr24]{}
return setup[info.OrigAddr8, info.ComAddr16, info.ObjAddr24]{}
}

panic("unreachable")
}

// System has a network setup.
type system[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr] struct {
info.Params[Orig, Com, Obj]
}
type setup[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr] struct { }

// StreamInbound implements the packetStream interface.
func (sys system[Orig, Com, Obj]) streamInbound(client *session.Station) {
mon := part5.NewLogger(sys.Params, os.Stdout)
func (_ setup[Orig, Com, Obj]) streamInbound(client *session.Station) {
var sys info.System[Orig, Com, Obj]
mon := part5.NewLogger(sys, os.Stdout)

u := sys.NewDataUnit() // reusable
var n uint64
Expand Down Expand Up @@ -205,7 +203,9 @@ func (sys system[Orig, Com, Obj]) streamInbound(client *session.Station) {
}

// StreamOutbound implements the packetStream interface.
func (sys system[Orig, Com, Obj]) streamOutbound(client *session.Station) {
func (_ setup[Orig, Com, Obj]) streamOutbound(client *session.Station) {
var sys info.System[Orig, Com, Obj]

client.Target <- session.Up

if *inroFlag != "<none>" {
Expand Down
4 changes: 2 additions & 2 deletions exchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import (

// Exchange supplies communication with another station.
type Exchange[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr] struct {
info.Params[Orig, Com, Obj]
info.System[Orig, Com, Obj]

Orig Orig // originator address, if any
Com Com // common adress
}

// NewDataUnit returns a new ASDU without payload; .Info is empty.
func (x Exchange[Orig, Com, Obj]) NewDataUnit(t info.TypeID, e info.Enc, c info.Cause) info.DataUnit[Orig, Com, Obj] {
u := x.Params.NewDataUnit()
u := x.System.NewDataUnit()
u.Type = t
u.Enc = e
u.Cause = c
Expand Down
23 changes: 12 additions & 11 deletions info/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@ import (
"strings"
)

// Params define the system-specific parameters. Specifically, the generics set
// the address width, which can be zero [none] for the originator.
type Params[Orig OrigAddr, Com ComAddr, Obj ObjAddr] struct{}
// System defines the system-specific parameters with generics. The parameters
// are the 3 address widths, specifically. Note that the originating address is
// commonly hidden as a cause-of-transmission size.
type System[Orig OrigAddr, Com ComAddr, Obj ObjAddr] struct{}

// ErrComAddrZero denies the zero value as an address. Use is explicitly
// prohibited in subsection 7.2.4.
var errComAddrZero = errors.New("part5: common address <0> is not used")

type (
// ComAddr can be instantiated with ComAddrN of Params.
// ComAddr can be instantiated with ComAddrN of System.
// The “common address” addresses stations. Zero is not used.
// All information objects/addresses reside in a common address.
// See companion standard 101, subclause 7.2.4.
Expand All @@ -52,7 +53,7 @@ type (

// ComAddrN returns either a numeric match, or false when n overflows the
// address width of Com.
func (p Params[Orig, Com, Obj]) ComAddrN(n uint) (Com, bool) {
func (_ System[Orig, Com, Obj]) ComAddrN(n uint) (Com, bool) {
var addr Com
for i := 0; i < len(addr); i++ {
addr[i] = uint8(n)
Expand All @@ -62,8 +63,8 @@ func (p Params[Orig, Com, Obj]) ComAddrN(n uint) (Com, bool) {
}

// MustComAddrN is like ComAddrN, yet it panics on overflow.
func (p Params[Orig, Com, Obj]) MustComAddrN(n uint) Com {
addr, ok := p.ComAddrN(n)
func (_ System[Orig, Com, Obj]) MustComAddrN(n uint) Com {
addr, ok := System[Orig, Com, Obj]{}.ComAddrN(n)
if !ok {
panic("overflow of common address")
}
Expand Down Expand Up @@ -97,7 +98,7 @@ func (addr ComAddr16) LowOctet() uint8 { return addr[0] }
func (addr ComAddr16) HighOctet() uint8 { return addr[1] }

type (
// ObjAddr can be instantiated with ObjAddrN of Params.
// ObjAddr can be instantiated with ObjAddrN of System.
//
// “The information object address is used as a destination address in
// control direction and a source address in the monitor direction.”
Expand All @@ -118,7 +119,7 @@ type (

// ObjAddrN returns either a numeric match, or false when n overflows the
// address width of Obj.
func (p Params[Orig, Com, Obj]) ObjAddrN(n uint) (Obj, bool) {
func (_ System[Orig, Com, Obj]) ObjAddrN(n uint) (Obj, bool) {
var addr Obj
for i := 0; i < len(addr); i++ {
addr[i] = uint8(n)
Expand All @@ -128,8 +129,8 @@ func (p Params[Orig, Com, Obj]) ObjAddrN(n uint) (Obj, bool) {
}

// MustObjAddrN is like ObjAddrN, yet it panics on overflow.
func (p Params[Orig, Com, Obj]) MustObjAddrN(n uint) Obj {
addr, ok := p.ObjAddrN(n)
func (_ System[Orig, Com, Obj]) MustObjAddrN(n uint) Obj {
addr, ok := System[Orig, Com, Obj]{}.ObjAddrN(n)
if !ok {
panic("overflow of information-object")
}
Expand Down
14 changes: 7 additions & 7 deletions info/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (e Enc) AddrSeq() bool { return e&0x80 != 0 }
var ErrAddrSeq = errors.New("part5: address sequence [VQL SQ] overflows the addres space for information objects")

type (
// OrigAddr can be instantiated with OrigAddrN from Params.
// OrigAddr can be instantiated with OrigAddrN from System.
// The originator address defaults to zero.
// Value 1..255 addresses a specific part of the system.
OrigAddr interface {
Expand All @@ -40,7 +40,7 @@ type (

// OrigAddrN returns either a numeric match, or false when n overflows the
// address width of Orig. Note that any non-zero value for OrigAddr0 gets false.
func (p Params[Orig, Com, Obj]) OrigAddrN(n uint) (Orig, bool) {
func (_ System[Orig, Com, Obj]) OrigAddrN(n uint) (Orig, bool) {
var addr Orig
for i := 0; i < len(addr); i++ {
addr[i] = uint8(n)
Expand All @@ -50,8 +50,8 @@ func (p Params[Orig, Com, Obj]) OrigAddrN(n uint) (Orig, bool) {
}

// MustOrigAddrN is like OrigAddrN, yet it panics on overflow.
func (p Params[Orig, Com, Obj]) MustOrigAddrN(n uint) Orig {
addr, ok := p.OrigAddrN(n)
func (_ System[Orig, Com, Obj]) MustOrigAddrN(n uint) Orig {
addr, ok := System[Orig, Com, Obj]{}.OrigAddrN(n)
if !ok {
panic("overflow of originator address")
}
Expand All @@ -68,8 +68,8 @@ func (addr OrigAddr8) N() uint { return uint(addr[0]) }
// Service Data Unit. Information objects are encoded conform the TypeID and
// and Enc values. Encoding is likely to contain one or more Object addresses.
type DataUnit[Orig OrigAddr, Com ComAddr, Obj ObjAddr] struct {
// configuration inherited from generics
Params[Orig, Com, Obj]
// configuration inheritance with generics
System[Orig, Com, Obj]

Type TypeID // payload class
Enc // payload structure
Expand All @@ -84,7 +84,7 @@ type DataUnit[Orig OrigAddr, Com ComAddr, Obj ObjAddr] struct {
}

// NewDataUnit returns a new ASDU.
func (p Params[Orig, Com, Obj]) NewDataUnit() DataUnit[Orig, Com, Obj] {
func (_ System[Orig, Com, Obj]) NewDataUnit() DataUnit[Orig, Com, Obj] {
var u DataUnit[Orig, Com, Obj]
u.Info = u.bootstrap[:0]
return u
Expand Down
2 changes: 1 addition & 1 deletion info/packet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

// Wide tests multi-byte addressing.
var Wide Params[OrigAddr8, ComAddr16, ObjAddr16]
var Wide System[OrigAddr8, ComAddr16, ObjAddr16]

var goldenDataUnits = []struct {
unit DataUnit[OrigAddr8, ComAddr16, ObjAddr16]
Expand Down
22 changes: 11 additions & 11 deletions monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ func MonitorDataUnit[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](mon
}
for _, b := range u.Info[len(addr):] {
mon.SinglePt(u, addr, info.SinglePtQual(b))
addr, _ = u.Params.ObjAddrN(addr.N() + 1)
addr, _ = u.System.ObjAddrN(addr.N() + 1)
}
} else {
if len(u.Info) != u.Enc.Count()*(len(addr)+1) {
Expand Down Expand Up @@ -564,7 +564,7 @@ func MonitorDataUnit[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](mon
),
info.Qual(u.Info[i+4]),
)
addr, _ = u.Params.ObjAddrN(addr.N() + 1)
addr, _ = u.System.ObjAddrN(addr.N() + 1)
}
} else {
if len(u.Info) != u.Enc.Count()*(len(addr)+5) {
Expand All @@ -591,7 +591,7 @@ func MonitorDataUnit[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](mon
}
for _, b := range u.Info[len(addr):] {
mon.DoublePt(u, addr, info.DoublePtQual(b))
addr, _ = u.Params.ObjAddrN(addr.N() + 1)
addr, _ = u.System.ObjAddrN(addr.N() + 1)
}
} else {
if len(u.Info) != u.Enc.Count()*(len(addr)+1) {
Expand Down Expand Up @@ -643,7 +643,7 @@ func MonitorDataUnit[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](mon
}
for i := len(addr); i+2 <= len(u.Info); i += 2 {
mon.Step(u, addr, info.StepQual(u.Info[i:i+2]))
addr, _ = u.Params.ObjAddrN(addr.N() + 1)
addr, _ = u.System.ObjAddrN(addr.N() + 1)
}
} else {
if len(u.Info) != u.Enc.Count()*(len(addr)+2) {
Expand Down Expand Up @@ -695,7 +695,7 @@ func MonitorDataUnit[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](mon
}
for i := len(addr); i+5 <= len(u.Info); i += 5 {
mon.Bits(u, addr, info.BitsQual(u.Info[i:i+5]))
addr, _ = u.Params.ObjAddrN(addr.N() + 1)
addr, _ = u.System.ObjAddrN(addr.N() + 1)
}
} else {
if len(u.Info) != u.Enc.Count()*(len(addr)+5) {
Expand Down Expand Up @@ -747,7 +747,7 @@ func MonitorDataUnit[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](mon
}
for i := len(addr); i+1 < len(u.Info); i += 2 {
mon.NormUnqual(u, addr, info.Norm(u.Info[i:i+2]))
addr, _ = u.Params.ObjAddrN(addr.N() + 1)
addr, _ = u.System.ObjAddrN(addr.N() + 1)
}
} else {
if len(u.Info) != u.Enc.Count()*(len(addr)+2) {
Expand All @@ -769,7 +769,7 @@ func MonitorDataUnit[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](mon
}
for i := len(addr); i+3 <= len(u.Info); i += 3 {
mon.Norm(u, addr, info.NormQual(u.Info[i:i+3]))
addr, _ = u.Params.ObjAddrN(addr.N() + 1)
addr, _ = u.System.ObjAddrN(addr.N() + 1)
}
} else {
if len(u.Info) != u.Enc.Count()*(len(addr)+3) {
Expand Down Expand Up @@ -828,7 +828,7 @@ func MonitorDataUnit[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](mon
),
info.Qual(u.Info[i+2]),
)
addr, _ = u.Params.ObjAddrN(addr.N() + 1)
addr, _ = u.System.ObjAddrN(addr.N() + 1)
}
} else {
if len(u.Info) != u.Enc.Count()*(len(addr)+3) {
Expand Down Expand Up @@ -903,7 +903,7 @@ func MonitorDataUnit[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](mon
),
info.Qual(u.Info[i+4]),
)
addr, _ = u.Params.ObjAddrN(addr.N() + 1)
addr, _ = u.System.ObjAddrN(addr.N() + 1)
}
} else {
if len(u.Info) != u.Enc.Count()*(len(addr)+5) {
Expand Down Expand Up @@ -970,7 +970,7 @@ func MonitorDataUnit[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](mon
}
for i := len(addr); i+5 <= len(u.Info); i += 5 {
mon.Totals(u, addr, info.Counter(u.Info[i:i+5]))
addr, _ = u.Params.ObjAddrN(addr.N() + 1)
addr, _ = u.System.ObjAddrN(addr.N() + 1)
}
} else {
if len(u.Info) != u.Enc.Count()*(len(addr)+5) {
Expand Down Expand Up @@ -1117,7 +1117,7 @@ func addrSeqStart[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](u *inf

// overflow check
lastN := addr.N() + uint(u.Enc.Count()) - 1
if _, ok := u.Params.ObjAddrN(lastN); !ok {
if _, ok := u.System.ObjAddrN(lastN); !ok {
return addr, info.ErrAddrSeq
}
return addr, nil
Expand Down
2 changes: 1 addition & 1 deletion monitor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

// Be resillient against malicious and faulty ASDU.
func FuzzMonitorWideASDU(f *testing.F) {
var sys info.Params[info.OrigAddr8, info.ComAddr16, info.ObjAddr24]
var sys info.System[info.OrigAddr8, info.ComAddr16, info.ObjAddr24]

f.Fuzz(func(t *testing.T, asdu []byte) {
var buf bytes.Buffer
Expand Down
4 changes: 2 additions & 2 deletions tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type MonitorDelegate[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr] str
}

// NewMonitorDelegate returns a new delegate with each sub-interface nil.
func NewMonitorDelegate[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](_ info.Params[Orig, Com, Obj]) *MonitorDelegate[Orig, Com, Obj] {
func NewMonitorDelegate[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](_ info.System[Orig, Com, Obj]) *MonitorDelegate[Orig, Com, Obj] {
return NewMonitorDelegateDefault[Orig, Com, Obj](nil)
}

Expand Down Expand Up @@ -254,7 +254,7 @@ type logger[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr] struct {

// NewLogger returns a Monitor which writes on each invocation as a text line in
// a human readable formon.
func NewLogger[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](_ info.Params[Orig, Com, Obj], w io.Writer) Monitor[Orig, Com, Obj] {
func NewLogger[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr](_ info.System[Orig, Com, Obj], w io.Writer) Monitor[Orig, Com, Obj] {
return logger[Orig, Com, Obj]{w}
}

Expand Down

0 comments on commit a50f216

Please sign in to comment.