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 23a545c417f482c338e0d4661294866d9ca4e95a Author: Sebastian Rühl <[email protected]> AuthorDate: Wed Aug 21 22:33:53 2024 +0200 feat(plc4go/bacnet): RouterAvailableToNetwork --- plc4go/internal/bacnetip/comp.go | 1 + plc4go/internal/bacnetip/npdu.go | 71 ++++++++++++++++++++-- plc4go/internal/bacnetip/tests/state_machine.go | 13 +++- .../bacnetip/tests/test_npdu/test_codec_test.go | 60 ++++++++++++++++++ 4 files changed, 140 insertions(+), 5 deletions(-) diff --git a/plc4go/internal/bacnetip/comp.go b/plc4go/internal/bacnetip/comp.go index 05ad939480..98a9174baa 100644 --- a/plc4go/internal/bacnetip/comp.go +++ b/plc4go/internal/bacnetip/comp.go @@ -129,6 +129,7 @@ const ( KWRmtnRejectionReason = KnownKey("rmtnRejectionReason") KWRmtnDNET = KnownKey("rmtnDNET") KWRbtnNetworkList = KnownKey("rbtnNetworkList") + KWRatnNetworkList = KnownKey("ratnNetworkList") ) type MessageBridge struct { diff --git a/plc4go/internal/bacnetip/npdu.go b/plc4go/internal/bacnetip/npdu.go index 0736ce1ca6..330bd196cf 100644 --- a/plc4go/internal/bacnetip/npdu.go +++ b/plc4go/internal/bacnetip/npdu.go @@ -654,14 +654,77 @@ func (r *RouterBusyToNetwork) String() string { type RouterAvailableToNetwork struct { *_NPDU + + ratnNetworkList []uint16 + + readWriteModel.NLMRouterAvailableToNetwork } -func NewRouterAvailableToNetwork() (*RouterAvailableToNetwork, error) { - panic("implement me") +func NewRouterAvailableToNetwork(opts ...func(*RouterAvailableToNetwork)) (*RouterAvailableToNetwork, error) { + i := &RouterAvailableToNetwork{} + for _, opt := range opts { + opt(i) + } + i.NLMRouterAvailableToNetwork = readWriteModel.NewNLMRouterAvailableToNetwork(i.ratnNetworkList, 0) + npdu, err := NewNPDU(i.NLMRouterAvailableToNetwork, nil) + if err != nil { + return nil, errors.Wrap(err, "error creating NPDU") + } + i._NPDU = npdu.(*_NPDU) + return i, nil } -type RoutingTableEntry struct { - *_NPDU +func WithRouterAvailableToNetworkDnet(networkList []uint16) func(*RouterAvailableToNetwork) { + return func(n *RouterAvailableToNetwork) { + n.ratnNetworkList = networkList + } +} + +func (r *RouterAvailableToNetwork) GetRatnNetworkList() []uint16 { + return r.ratnNetworkList +} + +func (r *RouterAvailableToNetwork) Encode(npdu Arg) error { + switch npdu := npdu.(type) { + case NPDU: + if err := npdu.Update(r); err != nil { + return errors.Wrap(err, "error updating _NPCI") + } + for _, net := range r.GetRatnNetworkList() { + npdu.PutShort(int16(net)) + } + npdu.setNPDU(r.npdu) + npdu.setNLM(r.nlm) + npdu.setAPDU(r.apdu) + return nil + default: + return errors.Errorf("invalid NPDU type %T", npdu) + } +} + +func (r *RouterAvailableToNetwork) Decode(npdu Arg) error { + switch npdu := npdu.(type) { + case NPDU: + if err := r.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.NLMRouterAvailableToNetwork: + r.setNLM(nlm) + r.NLMRouterAvailableToNetwork = nlm + r.ratnNetworkList = nlm.GetDestinationNetworkAddresses() + } + } + return nil + default: + return errors.Errorf("invalid NPDU type %T", npdu) + } +} + +func (r *RouterAvailableToNetwork) String() string { + return fmt.Sprintf("RouterAvailableToNetwork{%s, ratnNetworkList: %v}", r._NPDU, r.ratnNetworkList) } func NewRoutingTableEntry() (*RoutingTableEntry, error) { diff --git a/plc4go/internal/bacnetip/tests/state_machine.go b/plc4go/internal/bacnetip/tests/state_machine.go index 06de94058c..b51f893a69 100644 --- a/plc4go/internal/bacnetip/tests/state_machine.go +++ b/plc4go/internal/bacnetip/tests/state_machine.go @@ -178,7 +178,7 @@ func MatchPdu(localLog zerolog.Logger, pdu bacnetip.PDU, pduType any, pduAttrs m if !ok { return false } - return iamrtn.GetIcbrtnPerformanceIndex() == attrValue + return iamrtn.GetIcbrtnNetwork() == attrValue case bacnetip.KWIcbrtnPerformanceIndex: iamrtn, ok := pdu.(*bacnetip.ICouldBeRouterToNetwork) if !ok { @@ -208,6 +208,17 @@ func MatchPdu(localLog zerolog.Logger, pdu bacnetip.PDU, pduType any, pduAttrs m return false } return slices.Equal(net, uint16s) + case bacnetip.KWRatnNetworkList: + ratn, ok := pdu.(*bacnetip.RouterAvailableToNetwork) + if !ok { + return false + } + net := ratn.GetRatnNetworkList() + uint16s, ok := attrValue.([]uint16) + if !ok { + return false + } + return slices.Equal(net, uint16s) 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 6922d78912..a13b8794d6 100644 --- a/plc4go/internal/bacnetip/tests/test_npdu/test_codec_test.go +++ b/plc4go/internal/bacnetip/tests/test_npdu/test_codec_test.go @@ -71,6 +71,14 @@ func RouterBusyToNetwork(netList ...uint16) *bacnetip.RouterBusyToNetwork { return network } +func RouterAvailableToNetwork(netList ...uint16) *bacnetip.RouterAvailableToNetwork { + network, err := bacnetip.NewRouterAvailableToNetwork(bacnetip.WithRouterAvailableToNetworkDnet(netList)) + if err != nil { + panic(err) + } + return network +} + type TestNPDUCodecSuite struct { suite.Suite @@ -314,6 +322,58 @@ func (suite *TestNPDUCodecSuite) TestRouterBusyToNetworkNetworks() { // Test the err = suite.Confirmation(bacnetip.NewArgs(&bacnetip.RouterBusyToNetwork{}), bacnetip.NewKWArgs(bacnetip.KWRbtnNetworkList, networkList)) } +func (suite *TestNPDUCodecSuite) TestRouterAvailableToNetworkEmpty() { // Test the Result encoding and decoding. + // Request successful + networkList := []uint16{} + pduBytes, err := bacnetip.Xtob( + "01.80" + // version, network layer message + "05", // message type, no networks + ) + 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(RouterAvailableToNetwork(networkList...)), 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.RouterAvailableToNetwork{}), bacnetip.NewKWArgs(bacnetip.KWRatnNetworkList, networkList)) +} + +func (suite *TestNPDUCodecSuite) TestRouterAvailableToNetworkNetworks() { // Test the Result encoding and decoding. + // Request successful + networkList := []uint16{1, 2, 3} + pduBytes, err := bacnetip.Xtob( + "01.80" + // version, network layer message + "05 0001 0002 0003", // message type and network list + ) + 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(RouterAvailableToNetwork(networkList...)), 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.RouterAvailableToNetwork{}), bacnetip.NewKWArgs(bacnetip.KWRatnNetworkList, networkList)) +} + func TestNPDUCodec(t *testing.T) { suite.Run(t, new(TestNPDUCodecSuite)) }
