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 6eaf6faa15307f3b910a143acaa030670fedf15b
Author: Sebastian Rühl <[email protected]>
AuthorDate: Wed Aug 21 17:34:41 2024 +0200

    fix(plc4go/bacnet): IAmRouterToNetwork
---
 plc4go/internal/bacnetip/CommunicationsModule.go   |  4 ++
 plc4go/internal/bacnetip/PDU.go                    | 24 ++++++-
 plc4go/internal/bacnetip/comp.go                   |  3 +-
 plc4go/internal/bacnetip/npdu.go                   | 73 ++++++++++++++++++-
 plc4go/internal/bacnetip/tests/state_machine.go    | 11 +++
 .../bacnetip/tests/test_npdu/test_codec_test.go    | 81 ++++++++++++++++++----
 .../test_utilities/test_state_machine_test.go      |  5 ++
 7 files changed, 180 insertions(+), 21 deletions(-)

diff --git a/plc4go/internal/bacnetip/CommunicationsModule.go 
b/plc4go/internal/bacnetip/CommunicationsModule.go
index e2c39c7abe..99912ba3f4 100644
--- a/plc4go/internal/bacnetip/CommunicationsModule.go
+++ b/plc4go/internal/bacnetip/CommunicationsModule.go
@@ -47,6 +47,7 @@ func init() {
 
 type IPCI interface {
        fmt.Stringer
+       SetPDUUserData(spi.Message)
        GetPDUUserData() spi.Message
        GetPDUSource() *Address
        SetPDUSource(source *Address)
@@ -67,6 +68,9 @@ func new__PCI(pduUserData spi.Message, pduSource *Address, 
pduDestination *Addre
        return &__PCI{pduUserData, pduSource, pduDestination}
 }
 
+func (p *__PCI) SetPDUUserData(pduUserData spi.Message) {
+       p.pduUserData = pduUserData
+}
 func (p *__PCI) GetPDUUserData() spi.Message {
        return p.pduUserData
 }
diff --git a/plc4go/internal/bacnetip/PDU.go b/plc4go/internal/bacnetip/PDU.go
index 169a7da129..206c1abc73 100644
--- a/plc4go/internal/bacnetip/PDU.go
+++ b/plc4go/internal/bacnetip/PDU.go
@@ -638,9 +638,29 @@ func (a *Address) Equals(other any) bool {
                if a == other {
                        return true
                }
-               return a.String() == other.String()
+               thisString := a.String()
+               otherString := other.String()
+               equals := thisString == otherString
+               if !equals {
+                       a.log.Debug().Str("thisString", 
thisString).Str("otherString", otherString).Msg("Mismatch")
+               }
+               return equals
        case Address:
-               return a.String() == other.String()
+               thisString := a.String()
+               otherString := other.String()
+               equals := thisString == otherString
+               if !equals {
+                       a.log.Debug().Str("thisString", 
thisString).Str("otherString", otherString).Msg("Mismatch")
+               }
+               return equals
+       case *AddressTuple[string, uint16]:
+               thisString := a.AddrTuple.String()
+               otherString := other.String()
+               equals := thisString == otherString
+               if !equals {
+                       a.log.Debug().Str("thisString", 
thisString).Str("otherString", otherString).Msg("Mismatch")
+               }
+               return equals
        default:
                return false
        }
diff --git a/plc4go/internal/bacnetip/comp.go b/plc4go/internal/bacnetip/comp.go
index 8440fc9f5c..5978a94dd5 100644
--- a/plc4go/internal/bacnetip/comp.go
+++ b/plc4go/internal/bacnetip/comp.go
@@ -122,7 +122,8 @@ const (
        ////
        // NPDU related keys
 
-       KWWirtnNetwork = KnownKey("wirtnNetwork")
+       KWWirtnNetwork     = KnownKey("wirtnNetwork")
+       KWIartnNetworkList = KnownKey("iartnNetworkList")
 )
 
 type MessageBridge struct {
diff --git a/plc4go/internal/bacnetip/npdu.go b/plc4go/internal/bacnetip/npdu.go
index 9b568091b7..e7d5f5842b 100644
--- a/plc4go/internal/bacnetip/npdu.go
+++ b/plc4go/internal/bacnetip/npdu.go
@@ -208,7 +208,7 @@ func (n *_NPDU) Encode(pdu Arg) error {
        if err != nil {
                return errors.Wrap(err, "error building NPDU")
        }
-       pdu.(PDUData).PutData(n.GetPduData()...) // TODO: better validate that 
arg is really PDUData... use switch similar to Update
+       n.SetPDUUserData(n.npdu)
        return nil
 }
 
@@ -335,10 +335,77 @@ func (n *WhoIsRouterToNetwork) String() string {
 
 type IAmRouterToNetwork struct {
        *_NPDU
+
+       iartnNetworkList []uint16
+
+       readWriteModel.NLMIAmRouterToNetwork
 }
 
-func NewIAmRouterToNetwork() (*IAmRouterToNetwork, error) {
-       panic("implement me")
+func NewIAmRouterToNetwork(opts ...func(*IAmRouterToNetwork)) 
(*IAmRouterToNetwork, error) {
+       w := &IAmRouterToNetwork{}
+       for _, opt := range opts {
+               opt(w)
+       }
+       w.NLMIAmRouterToNetwork = 
readWriteModel.NewNLMIAmRouterToNetwork(w.iartnNetworkList, 0)
+       npdu, err := NewNPDU(w.NLMIAmRouterToNetwork, nil)
+       if err != nil {
+               return nil, errors.Wrap(err, "error creating NPDU")
+       }
+       w._NPDU = npdu.(*_NPDU)
+       return w, nil
+}
+
+func WithIAmRouterToNetworkNetworkList(iartnNetworkList ...uint16) 
func(*IAmRouterToNetwork) {
+       return func(n *IAmRouterToNetwork) {
+               n.iartnNetworkList = iartnNetworkList
+       }
+}
+
+func (n *IAmRouterToNetwork) GetIartnNetworkList() []uint16 {
+       return n.iartnNetworkList
+}
+
+func (n *IAmRouterToNetwork) Encode(npdu Arg) error {
+       switch npdu := npdu.(type) {
+       case NPDU:
+               if err := npdu.Update(n); err != nil {
+                       return errors.Wrap(err, "error updating _NPCI")
+               }
+               for _, net := range n.iartnNetworkList {
+                       npdu.PutShort(int16(net))
+               }
+               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 *IAmRouterToNetwork) 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.NLMIAmRouterToNetworkExactly:
+                               n.setNLM(nlm)
+                               n.NLMIAmRouterToNetwork = nlm
+                               n.iartnNetworkList = 
nlm.GetDestinationNetworkAddresses()
+                       }
+               }
+               return nil
+       default:
+               return errors.Errorf("invalid NPDU type %T", npdu)
+       }
+}
+
+func (n *IAmRouterToNetwork) String() string {
+       return fmt.Sprintf("IAmRouterToNetwork{%s, iartnNetworkList: %v}", 
n._NPDU, n.iartnNetworkList)
 }
 
 type ICouldBeRouterToNetwork struct {
diff --git a/plc4go/internal/bacnetip/tests/state_machine.go 
b/plc4go/internal/bacnetip/tests/state_machine.go
index b3e96c8360..37fa005ee8 100644
--- a/plc4go/internal/bacnetip/tests/state_machine.go
+++ b/plc4go/internal/bacnetip/tests/state_machine.go
@@ -162,6 +162,17 @@ func MatchPdu(localLog zerolog.Logger, pdu bacnetip.PDU, 
pduType any, pduAttrs m
                                return false
                        }
                        return *net == attrValue
+               case bacnetip.KWIartnNetworkList:
+                       iamrtn, ok := pdu.(*bacnetip.IAmRouterToNetwork)
+                       if !ok {
+                               return false
+                       }
+                       net := iamrtn.GetIartnNetworkList()
+                       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 d0ab4d9005..7967781e36 100644
--- a/plc4go/internal/bacnetip/tests/test_npdu/test_codec_test.go
+++ b/plc4go/internal/bacnetip/tests/test_npdu/test_codec_test.go
@@ -31,20 +31,20 @@ import (
        "github.com/stretchr/testify/suite"
 )
 
-func WhoIsRouterToNetwork(args ...any) *bacnetip.WhoIsRouterToNetwork {
-       if len(args) == 1 {
-               var net uint16
-               net = uint16(args[0].(int))
-               network, err := 
bacnetip.NewWhoIsRouterToNetwork(bacnetip.WithWhoIsRouterToNetworkNet(net))
-               if err != nil {
-                       panic(err)
-               }
-               return network
-       } else {
-               network, err := bacnetip.NewWhoIsRouterToNetwork()
+func WhoIsRouterToNetwork(net uint16) *bacnetip.WhoIsRouterToNetwork {
+       network, err := 
bacnetip.NewWhoIsRouterToNetwork(bacnetip.WithWhoIsRouterToNetworkNet(net))
+       if err != nil {
+               panic(err)
+       }
+       return network
+}
+
+func IAmRouterToNetwork(netList ...uint16) *bacnetip.IAmRouterToNetwork {
+       network, err := 
bacnetip.NewIAmRouterToNetwork(bacnetip.WithIAmRouterToNetworkNetworkList(netList...))
+       if err != nil {
                panic(err)
-               return network
        }
+       return network
 }
 
 type TestNPDUCodecSuite struct {
@@ -115,15 +115,14 @@ func (suite *TestNPDUCodecSuite) 
TestWhoIsRouterToNetwork() { // Test the Result
        // Request successful
        pduBytes, err := bacnetip.Xtob(
                "01.80" + // version, network layer message
-                       "00 0001" + // message type and network
-                       "00 01", // whois
+                       "00 0001", // message type and network
        )
        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(parse.String())
+                       suite.T().Log("\n" + parse.String())
                }
        }
 
@@ -137,6 +136,58 @@ func (suite *TestNPDUCodecSuite) 
TestWhoIsRouterToNetwork() { // Test the Result
        err = 
suite.Confirmation(bacnetip.NewArgs(&bacnetip.WhoIsRouterToNetwork{}), 
bacnetip.NewKWArgs(bacnetip.KWWirtnNetwork, uint16(1)))
 }
 
+func (suite *TestNPDUCodecSuite) TestIAMRouterToNetworkEmpty() { // Test the 
Result encoding and decoding.
+       // Request successful
+       networkList := []uint16{}
+       pduBytes, err := bacnetip.Xtob(
+               "01.80" + // version, network layer message
+                       "01", // message type, no network
+       )
+       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(IAmRouterToNetwork(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.IAmRouterToNetwork{}), 
bacnetip.NewKWArgs(bacnetip.KWIartnNetworkList, networkList))
+}
+
+func (suite *TestNPDUCodecSuite) TestIAMRouterToNetworks() { // Test the 
Result encoding and decoding.
+       // Request successful
+       networkList := []uint16{1, 2, 3}
+       pduBytes, err := bacnetip.Xtob(
+               "01.80" + // version, network layer message
+                       "01 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(parse.String())
+               }
+       }
+
+       err = 
suite.Request(bacnetip.NewArgs(IAmRouterToNetwork(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.IAmRouterToNetwork{}), 
bacnetip.NewKWArgs(bacnetip.KWIartnNetworkList, networkList))
+}
+
 func TestNPDUCodec(t *testing.T) {
        suite.Run(t, new(TestNPDUCodecSuite))
 }
diff --git 
a/plc4go/internal/bacnetip/tests/test_utilities/test_state_machine_test.go 
b/plc4go/internal/bacnetip/tests/test_utilities/test_state_machine_test.go
index 81cf636cea..01304cf902 100644
--- a/plc4go/internal/bacnetip/tests/test_utilities/test_state_machine_test.go
+++ b/plc4go/internal/bacnetip/tests/test_utilities/test_state_machine_test.go
@@ -71,6 +71,11 @@ func (t TPDU) GetMessage() spi.Message {
        panic("implement me")
 }
 
+func (t TPDU) SetPDUUserData(message spi.Message) {
+       //TODO implement me
+       panic("implement me")
+}
+
 func (t TPDU) GetPDUSource() *bacnetip.Address {
        panic("implement me")
 }

Reply via email to