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
The following commit(s) were added to refs/heads/develop by this push:
new 8680bfc939 feat(plc4go/bacnet): RejectMessageToNetwork
8680bfc939 is described below
commit 8680bfc9395788c893a23f386947d51766eccaa5
Author: Sebastian Rühl <[email protected]>
AuthorDate: Wed Aug 21 18:45:30 2024 +0200
feat(plc4go/bacnet): RejectMessageToNetwork
---
plc4go/internal/bacnetip/CommunicationsModule.go | 1 +
plc4go/internal/bacnetip/comp.go | 2 +
plc4go/internal/bacnetip/npdu.go | 88 +++++++++++++++++++++-
plc4go/internal/bacnetip/tests/state_machine.go | 14 +++-
.../bacnetip/tests/test_bvll/test_simple_test.go | 24 +-----
.../bacnetip/tests/test_npdu/test_codec_test.go | 33 ++++++++
6 files changed, 136 insertions(+), 26 deletions(-)
diff --git a/plc4go/internal/bacnetip/CommunicationsModule.go
b/plc4go/internal/bacnetip/CommunicationsModule.go
index 99912ba3f4..7e51a9a0ae 100644
--- a/plc4go/internal/bacnetip/CommunicationsModule.go
+++ b/plc4go/internal/bacnetip/CommunicationsModule.go
@@ -71,6 +71,7 @@ func new__PCI(pduUserData spi.Message, pduSource *Address,
pduDestination *Addre
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/comp.go b/plc4go/internal/bacnetip/comp.go
index 855ded48e3..174e569a71 100644
--- a/plc4go/internal/bacnetip/comp.go
+++ b/plc4go/internal/bacnetip/comp.go
@@ -126,6 +126,8 @@ const (
KWIartnNetworkList = KnownKey("iartnNetworkList")
KWIcbrtnNetwork = KnownKey("icbrtnNetwork")
KWIcbrtnPerformanceIndex = KnownKey("icbrtnPerformanceIndex")
+ KWRmtnRejectionReason = KnownKey("rmtnRejectionReason")
+ KWRmtnDNET = KnownKey("rmtnDNET")
)
type MessageBridge struct {
diff --git a/plc4go/internal/bacnetip/npdu.go b/plc4go/internal/bacnetip/npdu.go
index 1ae53d0c38..5fa6939442 100644
--- a/plc4go/internal/bacnetip/npdu.go
+++ b/plc4go/internal/bacnetip/npdu.go
@@ -442,7 +442,7 @@ func
WithICouldBeRouterToNetworkPerformanceIndex(icbrtnPerformanceIndex uint8) f
}
}
-func (n *ICouldBeRouterToNetwork) GeticbrtnNetwork() uint16 {
+func (n *ICouldBeRouterToNetwork) GetIcbrtnNetwork() uint16 {
return n.icbrtnNetwork
}
@@ -495,10 +495,87 @@ func (n *ICouldBeRouterToNetwork) String() string {
type RejectMessageToNetwork struct {
*_NPDU
+
+ rmtnRejectionReason readWriteModel.NLMRejectMessageToNetworkRejectReason
+ rmtnDNET uint16
+
+ readWriteModel.NLMRejectMessageToNetwork
}
-func NewRejectMessageToNetwork() (*RejectMessageToNetwork, error) {
- panic("implement me")
+func NewRejectMessageToNetwork(opts ...func(*RejectMessageToNetwork))
(*RejectMessageToNetwork, error) {
+ i := &RejectMessageToNetwork{}
+ for _, opt := range opts {
+ opt(i)
+ }
+ i.NLMRejectMessageToNetwork =
readWriteModel.NewNLMRejectMessageToNetwork(i.rmtnRejectionReason, i.rmtnDNET,
0)
+ npdu, err := NewNPDU(i.NLMRejectMessageToNetwork, nil)
+ if err != nil {
+ return nil, errors.Wrap(err, "error creating NPDU")
+ }
+ i._NPDU = npdu.(*_NPDU)
+ return i, nil
+}
+
+func WithRejectMessageToNetworkRejectionReason(reason
readWriteModel.NLMRejectMessageToNetworkRejectReason)
func(*RejectMessageToNetwork) {
+ return func(n *RejectMessageToNetwork) {
+ n.rmtnRejectionReason = reason
+ }
+}
+func WithRejectMessageToNetworkDnet(dnet uint16) func(*RejectMessageToNetwork)
{
+ return func(n *RejectMessageToNetwork) {
+ n.rmtnDNET = dnet
+ }
+}
+
+func (n *RejectMessageToNetwork) GetRmtnRejectionReason()
readWriteModel.NLMRejectMessageToNetworkRejectReason {
+ return n.rmtnRejectionReason
+}
+
+func (n *RejectMessageToNetwork) GetRmtnDNET() uint16 {
+ return n.rmtnDNET
+}
+
+func (n *RejectMessageToNetwork) 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.Put(byte(n.rmtnRejectionReason))
+ npdu.PutShort(int16(n.rmtnDNET))
+ 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 *RejectMessageToNetwork) 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.NLMRejectMessageToNetworkExactly:
+ n.setNLM(nlm)
+ n.NLMRejectMessageToNetwork = nlm
+ n.rmtnRejectionReason = nlm.GetRejectReason()
+ n.rmtnDNET = nlm.GetDestinationNetworkAddress()
+ }
+ }
+ return nil
+ default:
+ return errors.Errorf("invalid NPDU type %T", npdu)
+ }
+}
+
+func (n *RejectMessageToNetwork) String() string {
+ return fmt.Sprintf("RejectMessageToNetwork{%s, rmtnRejectionReason: %s,
rmtnDNET: %v}", n._NPDU, n.rmtnRejectionReason, n.rmtnDNET)
}
type RouterBusyToNetwork struct {
@@ -587,7 +664,10 @@ func init() {
v, _ := NewICouldBeRouterToNetwork()
return v
},
- // 0x03: NewRejectRouterToNetwork, // TODO: not present upstream
+ 0x03: func() interface{ Decode(Arg) error } {
+ v, _ := NewRejectMessageToNetwork() // TODO: should be
NewRejectMessageToNetwork
+ return v
+ },
0x04: func() interface{ Decode(Arg) error } {
v, _ := NewRouterBusyToNetwork()
return v
diff --git a/plc4go/internal/bacnetip/tests/state_machine.go
b/plc4go/internal/bacnetip/tests/state_machine.go
index b0915769ca..5b46866411 100644
--- a/plc4go/internal/bacnetip/tests/state_machine.go
+++ b/plc4go/internal/bacnetip/tests/state_machine.go
@@ -178,13 +178,25 @@ func MatchPdu(localLog zerolog.Logger, pdu bacnetip.PDU,
pduType any, pduAttrs m
if !ok {
return false
}
- return iamrtn.GetDestinationNetworkAddress() ==
attrValue
+ return iamrtn.GetIcbrtnPerformanceIndex() == attrValue
case bacnetip.KWIcbrtnPerformanceIndex:
iamrtn, ok := pdu.(*bacnetip.ICouldBeRouterToNetwork)
if !ok {
return false
}
return iamrtn.GetPerformanceIndex() == attrValue
+ case bacnetip.KWRmtnRejectionReason:
+ iamrtn, ok := pdu.(*bacnetip.RejectMessageToNetwork)
+ if !ok {
+ return false
+ }
+ return iamrtn.GetRmtnRejectionReason() == attrValue
+ case bacnetip.KWRmtnDNET:
+ iamrtn, ok := pdu.(*bacnetip.RejectMessageToNetwork)
+ if !ok {
+ return false
+ }
+ return iamrtn.GetDestinationNetworkAddress() ==
attrValue
default:
panic("implement " + attrName)
}
diff --git a/plc4go/internal/bacnetip/tests/test_bvll/test_simple_test.go
b/plc4go/internal/bacnetip/tests/test_bvll/test_simple_test.go
index 41b06a9daa..8eb2d38b4e 100644
--- a/plc4go/internal/bacnetip/tests/test_bvll/test_simple_test.go
+++ b/plc4go/internal/bacnetip/tests/test_bvll/test_simple_test.go
@@ -126,35 +126,17 @@ func TestSimple(t *testing.T) {
//make a PDU from node 1 to node 2
pduData, err := bacnetip.Xtob("dead.beef")
require.NoError(t, err)
- apdu := model.NewAPDUUnknown(0, pduData, 0)
- control := model.NewNPDUControl(false, true, true, false,
model.NPDUNetworkPriority_CRITICAL_EQUIPMENT_MESSAGE)
- sourceAddr := tnet.td.address
- destAddr := tnet.iut.address
- npdu := model.NewNPDU(0,
- control,
- destAddr.AddrNet,
- destAddr.AddrLen,
- destAddr.AddrAddress,
- sourceAddr.AddrNet,
- sourceAddr.AddrLen,
- sourceAddr.AddrAddress,
- nil,
- nil,
- apdu,
- 0)
- t.Logf("pdu: \n%v", npdu)
+ pdu := bacnetip.NewPDU(&bacnetip.MessageBridge{Bytes: pduData},
bacnetip.WithPDUSource(tnet.td.address),
bacnetip.WithPDUDestination(tnet.iut.address))
+ t.Logf("pdu: \n%v", pdu)
// test device sends it, iut gets it
- pdu := bacnetip.NewPDU(npdu)
- pdu.SetPDUSource(tnet.td.address)
- pdu.SetPDUDestination(tnet.iut.address)
tnet.td.GetStartState().Send(pdu, nil).Success("")
tnet.iut.GetStartState().Receive(bacnetip.NewArgs(bacnetip.NewPDU(nil)),
bacnetip.NewKWArgs(
bacnetip.KWPPDUSource, tnet.td.address,
)).Success("")
// sniffer sees message on the wire
-
tnet.sniffer.GetStartState().Receive(bacnetip.NewArgs(bacnetip.NewPDU(npdu)),
bacnetip.NewKWArgs(
+
tnet.sniffer.GetStartState().Receive(bacnetip.NewArgs(bacnetip.NewPDU(nil)),
bacnetip.NewKWArgs(
bacnetip.KWPPDUSource, tnet.td.address.AddrTuple,
bacnetip.KWPDUDestination, tnet.iut.address.AddrTuple,
bacnetip.KWPDUData, pduData,
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 d175dee519..1dca7c188e 100644
--- a/plc4go/internal/bacnetip/tests/test_npdu/test_codec_test.go
+++ b/plc4go/internal/bacnetip/tests/test_npdu/test_codec_test.go
@@ -55,6 +55,14 @@ func ICouldBeRouterToNetwork(net uint16, perf uint8)
*bacnetip.ICouldBeRouterToN
return network
}
+func RejectMessageToNetwork(reason uint8, dnet uint16)
*bacnetip.RejectMessageToNetwork {
+ network, err :=
bacnetip.NewRejectMessageToNetwork(bacnetip.WithRejectMessageToNetworkRejectionReason(readWriteModel.NLMRejectMessageToNetworkRejectReason(reason)),
bacnetip.WithRejectMessageToNetworkDnet(dnet))
+ if err != nil {
+ panic(err)
+ }
+ return network
+}
+
type TestNPDUCodecSuite struct {
suite.Suite
@@ -221,6 +229,31 @@ func (suite *TestNPDUCodecSuite)
TestICouldBeRouterToNetworks() { // Test the Re
err =
suite.Confirmation(bacnetip.NewArgs(&bacnetip.ICouldBeRouterToNetwork{}),
bacnetip.NewKWArgs(bacnetip.KWIcbrtnNetwork, uint16(1),
bacnetip.KWIcbrtnPerformanceIndex, uint8(2)))
}
+func (suite *TestNPDUCodecSuite) TestRejectMessageToNetworks() { // Test the
Result encoding and decoding.
+ // Request successful
+ pduBytes, err := bacnetip.Xtob(
+ "01.80" + // version, network layer message
+ "03 01 0002", // message type, reason, performance
+ )
+ 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(RejectMessageToNetwork(1, 2)),
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.RejectMessageToNetwork{}),
bacnetip.NewKWArgs(bacnetip.KWRmtnRejectionReason,
readWriteModel.NLMRejectMessageToNetworkRejectReason(1), bacnetip.KWRmtnDNET,
uint16(2)))
+}
+
func TestNPDUCodec(t *testing.T) {
suite.Run(t, new(TestNPDUCodecSuite))
}