This is an automated email from the ASF dual-hosted git repository. sruehl pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 345c5c7c797dc891dff79a250515470d374dca64 Author: Sebastian Rühl <[email protected]> AuthorDate: Wed Aug 21 22:37:43 2024 +0200 feat(plc4go/bacnet): EstablishConnectionToNetwork --- plc4go/internal/bacnetip/comp.go | 2 + plc4go/internal/bacnetip/npdu.go | 81 +++++++++++++++++++++- plc4go/internal/bacnetip/tests/state_machine.go | 12 ++++ .../bacnetip/tests/test_npdu/test_codec_test.go | 33 +++++++++ 4 files changed, 126 insertions(+), 2 deletions(-) diff --git a/plc4go/internal/bacnetip/comp.go b/plc4go/internal/bacnetip/comp.go index 3c28148b0c..8a7913983e 100644 --- a/plc4go/internal/bacnetip/comp.go +++ b/plc4go/internal/bacnetip/comp.go @@ -132,6 +132,8 @@ const ( KWRatnNetworkList = KnownKey("ratnNetworkList") KWIrtTable = KnownKey("irtTable") KWIrtaTable = KnownKey("irtaTable") + KWEctnDNET = KnownKey("ectnDNET") + KWEctnTerminationTime = KnownKey("ectnTerminationTime") ) type MessageBridge struct { diff --git a/plc4go/internal/bacnetip/npdu.go b/plc4go/internal/bacnetip/npdu.go index de6791f359..a890ca955c 100644 --- a/plc4go/internal/bacnetip/npdu.go +++ b/plc4go/internal/bacnetip/npdu.go @@ -982,10 +982,87 @@ func (r *InitializeRoutingTableAck) String() string { type EstablishConnectionToNetwork struct { *_NPDU + ectnDNET uint16 + ectnTerminationTime uint8 + + readWriteModel.NLMEstablishConnectionToNetwork } -func NewEstablishConnectionToNetwork() (*EstablishConnectionToNetwork, error) { - panic("implement me") +func NewEstablishConnectionToNetwork(opts ...func(*EstablishConnectionToNetwork)) (*EstablishConnectionToNetwork, error) { + i := &EstablishConnectionToNetwork{} + for _, opt := range opts { + opt(i) + } + i.NLMEstablishConnectionToNetwork = readWriteModel.NewNLMEstablishConnectionToNetwork(i.ectnDNET, i.ectnTerminationTime, 0) + npdu, err := NewNPDU(i.NLMEstablishConnectionToNetwork, nil) + if err != nil { + return nil, errors.Wrap(err, "error creating NPDU") + } + i._NPDU = npdu.(*_NPDU) + return i, nil +} + +func WithEstablishConnectionToNetworkDNET(dnet uint16) func(*EstablishConnectionToNetwork) { + return func(n *EstablishConnectionToNetwork) { + n.ectnDNET = dnet + } +} + +func WithEstablishConnectionToNetworkTerminationTime(terminationTime uint8) func(*EstablishConnectionToNetwork) { + return func(n *EstablishConnectionToNetwork) { + n.ectnTerminationTime = terminationTime + } +} + +func (n *EstablishConnectionToNetwork) GetEctnDNET() uint16 { + return n.ectnDNET +} + +func (n *EstablishConnectionToNetwork) GetEctnTerminationTime() uint8 { + return n.ectnTerminationTime +} + +func (n *EstablishConnectionToNetwork) Encode(npdu Arg) error { + switch npdu := npdu.(type) { + case NPDU: + if err := npdu.Update(n); err != nil { + return errors.Wrap(err, "error updating _NPCI") + } + npdu.PutShort(int16(n.ectnDNET)) + npdu.Put(n.ectnTerminationTime) + npdu.setNPDU(n.npdu) + npdu.setNLM(n.nlm) + npdu.setAPDU(n.apdu) + return nil + default: + return errors.Errorf("invalid NPDU type %T", npdu) + } +} + +func (n *EstablishConnectionToNetwork) Decode(npdu Arg) error { + switch npdu := npdu.(type) { + case NPDU: + if err := n.Update(npdu); err != nil { + return errors.Wrap(err, "error updating _NPCI") + } + switch pduUserData := npdu.GetPDUUserData().(type) { + case readWriteModel.NPDUExactly: + switch nlm := pduUserData.GetNlm().(type) { + case readWriteModel.NLMEstablishConnectionToNetworkExactly: + n.setNLM(nlm) + n.NLMEstablishConnectionToNetwork = nlm + n.ectnDNET = nlm.GetDestinationNetworkAddress() + n.ectnTerminationTime = nlm.GetTerminationTime() + } + } + return nil + default: + return errors.Errorf("invalid NPDU type %T", npdu) + } +} + +func (n *EstablishConnectionToNetwork) String() string { + return fmt.Sprintf("EstablishConnectionToNetwork{%s, ectnDNET: %v, ectnTerminationTime: %v}", n._NPDU, n.ectnDNET, n.ectnTerminationTime) } type DisconnectConnectionToNetwork struct { diff --git a/plc4go/internal/bacnetip/tests/state_machine.go b/plc4go/internal/bacnetip/tests/state_machine.go index 0d957e1765..4131f6d5c3 100644 --- a/plc4go/internal/bacnetip/tests/state_machine.go +++ b/plc4go/internal/bacnetip/tests/state_machine.go @@ -245,6 +245,18 @@ func MatchPdu(localLog zerolog.Logger, pdu bacnetip.PDU, pduType any, pduAttrs m return slices.EqualFunc(irts, oirts, func(entry *bacnetip.RoutingTableEntry, entry2 *bacnetip.RoutingTableEntry) bool { return entry.Equals(entry2) }) + case bacnetip.KWEctnDNET: + ectn, ok := pdu.(*bacnetip.EstablishConnectionToNetwork) + if !ok { + return false + } + return ectn.GetEctnDNET() == attrValue + case bacnetip.KWEctnTerminationTime: + ectn, ok := pdu.(*bacnetip.EstablishConnectionToNetwork) + if !ok { + return false + } + return ectn.GetEctnTerminationTime() == attrValue default: panic("implement " + attrName) } diff --git a/plc4go/internal/bacnetip/tests/test_npdu/test_codec_test.go b/plc4go/internal/bacnetip/tests/test_npdu/test_codec_test.go index b53bcb9d48..e186843789 100644 --- a/plc4go/internal/bacnetip/tests/test_npdu/test_codec_test.go +++ b/plc4go/internal/bacnetip/tests/test_npdu/test_codec_test.go @@ -103,6 +103,14 @@ func InitializeRoutingTableAck(irtaTable ...*bacnetip.RoutingTableEntry) *bacnet return network } +func EstablishConnectionToNetwork(dnet uint16, terminationTime uint8) *bacnetip.EstablishConnectionToNetwork { + network, err := bacnetip.NewEstablishConnectionToNetwork(bacnetip.WithEstablishConnectionToNetworkDNET(dnet), bacnetip.WithEstablishConnectionToNetworkTerminationTime(terminationTime)) + if err != nil { + panic(err) + } + return network +} + type TestNPDUCodecSuite struct { suite.Suite @@ -551,6 +559,31 @@ func (suite *TestNPDUCodecSuite) TestInitializeRoutingTableAck02() { // Test the err = suite.Confirmation(bacnetip.NewArgs(&bacnetip.InitializeRoutingTableAck{}), bacnetip.NewKWArgs(bacnetip.KWIrtaTable, rtEntries)) } +func (suite *TestNPDUCodecSuite) TestEstablishConnectionToNetworks() { // Test the Result encoding and decoding. + // Request successful + pduBytes, err := bacnetip.Xtob( + "01.80" + // version, network layer message + "08 0005 06", // message type, network, terminationTime + ) + suite.Require().NoError(err) + { // Parse with plc4x parser to validate + parse, err := readWriteModel.NPDUParse(testutils.TestContext(suite.T()), pduBytes, uint16(len(pduBytes))) + suite.Assert().NoError(err) + if parse != nil { + suite.T().Log("\n" + parse.String()) + } + } + + err = suite.Request(bacnetip.NewArgs(EstablishConnectionToNetwork(5, 6)), bacnetip.NoKWArgs) + suite.Assert().NoError(err) + err = suite.Indication(bacnetip.NoArgs, bacnetip.NewKWArgs(bacnetip.KWPDUData, pduBytes)) + suite.Assert().NoError(err) + + err = suite.Response(bacnetip.NewArgs(bacnetip.NewPDU(&bacnetip.MessageBridge{Bytes: pduBytes})), bacnetip.NoKWArgs) + suite.Assert().NoError(err) + err = suite.Confirmation(bacnetip.NewArgs(&bacnetip.EstablishConnectionToNetwork{}), bacnetip.NewKWArgs(bacnetip.KWEctnDNET, uint16(5), bacnetip.KWEctnTerminationTime, uint8(6))) +} + func TestNPDUCodec(t *testing.T) { suite.Run(t, new(TestNPDUCodecSuite)) }
