diff --git a/cmd/iecat/main.go b/cmd/iecat/main.go index 7bdb9ab..0cc7997 100644 --- a/cmd/iecat/main.go +++ b/cmd/iecat/main.go @@ -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 @@ -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 != "" { diff --git a/exchange.go b/exchange.go index 67129a9..9f3ca08 100644 --- a/exchange.go +++ b/exchange.go @@ -9,7 +9,7 @@ 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 @@ -17,7 +17,7 @@ type Exchange[Orig info.OrigAddr, Com info.ComAddr, Obj info.ObjAddr] struct { // 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 diff --git a/info/info.go b/info/info.go index 9c3ec8d..991325c 100644 --- a/info/info.go +++ b/info/info.go @@ -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. @@ -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) @@ -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") } @@ -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.” @@ -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) @@ -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") } diff --git a/info/packet.go b/info/packet.go index 6560c80..ddb3dba 100644 --- a/info/packet.go +++ b/info/packet.go @@ -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 { @@ -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) @@ -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") } @@ -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 @@ -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 diff --git a/info/packet_test.go b/info/packet_test.go index fd814ca..c621fd4 100644 --- a/info/packet_test.go +++ b/info/packet_test.go @@ -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] diff --git a/monitor.go b/monitor.go index f6b8c82..5261f40 100644 --- a/monitor.go +++ b/monitor.go @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -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 diff --git a/monitor_test.go b/monitor_test.go index 5559cc9..0a7ba89 100644 --- a/monitor_test.go +++ b/monitor_test.go @@ -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 diff --git a/tool.go b/tool.go index 823b14a..f58e2f0 100644 --- a/tool.go +++ b/tool.go @@ -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) } @@ -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} }