Skip to content

Commit

Permalink
feat(plc4go/bacnetip): ReadBroadcastDistributionTableAck
Browse files Browse the repository at this point in the history
  • Loading branch information
sruehl committed Aug 22, 2024
1 parent 6e237f2 commit c5d0cbd
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 14 deletions.
94 changes: 84 additions & 10 deletions plc4go/internal/bacnetip/bvll.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ func NewWriteBroadcastDistributionTable(opts ...func(*WriteBroadcastDistribution
return b, nil
}

func WithWriteBroadcastDistributionTable(bdt ...*Address) func(*WriteBroadcastDistributionTable) {
func WithWriteBroadcastDistributionTableBDT(bdt ...*Address) func(*WriteBroadcastDistributionTable) {
return func(b *WriteBroadcastDistributionTable) {
b.bvlciBDT = bdt
}
Expand Down Expand Up @@ -417,27 +417,101 @@ func (w *ReadBroadcastDistributionTable) String() string {
return fmt.Sprintf("ReadBroadcastDistributionTable{%v}", w._BVLPDU)
}

// TODO: finish
type ReadBroadcastDistributionTableAck struct {
*_BVLPDU
bvlciBDT []*Address
}

var _ BVLPDU = (*ReadBroadcastDistributionTableAck)(nil)

func NewReadBroadcastDistributionTableAck() (BVLPDU, error) {
func NewReadBroadcastDistributionTableAck(opts ...func(*ReadBroadcastDistributionTableAck)) (*ReadBroadcastDistributionTableAck, error) {
b := &ReadBroadcastDistributionTableAck{}
b._BVLPDU = NewBVLPDU(nil).(*_BVLPDU)
for _, opt := range opts {
opt(b)
}
b._BVLPDU = NewBVLPDU(readWriteModel.NewBVLCReadBroadcastDistributionTableAck(b.produceBroadcastDistributionTable(), 0)).(*_BVLPDU)
return b, nil
}

func (b *ReadBroadcastDistributionTableAck) Encode(pdu Arg) error {
// TODO: finish
return nil
func WithReadBroadcastDistributionTableAckBDT(bdt ...*Address) func(*ReadBroadcastDistributionTableAck) {
return func(b *ReadBroadcastDistributionTableAck) {
b.bvlciBDT = bdt
}
}

func (b *ReadBroadcastDistributionTableAck) Decode(pdu Arg) error {
// TODO: finish
return nil
func (w *ReadBroadcastDistributionTableAck) GetBvlciBDT() []*Address {
return w.bvlciBDT
}

func (w *ReadBroadcastDistributionTableAck) produceBroadcastDistributionTable() (entries []readWriteModel.BVLCBroadcastDistributionTableEntry) {
for _, address := range w.bvlciBDT {
addr := address.AddrAddress[:4]
port := uint16(47808)
if address.AddrPort != nil {
port = *address.AddrPort
}
mask := make([]byte, 4)
if address.AddrMask != nil {
binary.BigEndian.PutUint32(mask, *address.AddrMask)
}
entries = append(entries, readWriteModel.NewBVLCBroadcastDistributionTableEntry(addr, port, mask))
}
return
}

func (w *ReadBroadcastDistributionTableAck) produceBvlciBDT(entries []readWriteModel.BVLCBroadcastDistributionTableEntry) (bvlciBDT []*Address) {
for _, entry := range entries {
addr := entry.GetIp()
port := entry.GetPort()
var portArray = make([]byte, 2)
binary.BigEndian.PutUint16(portArray, port)
address, _ := NewAddress(zerolog.Nop(), append(addr, portArray...))
mask := binary.BigEndian.Uint32(entry.GetBroadcastDistributionMap())
address.AddrMask = &mask
bvlciBDT = append(bvlciBDT, address)
}
return
}

func (w *ReadBroadcastDistributionTableAck) Encode(bvlpdu Arg) error {
switch bvlpdu := bvlpdu.(type) {
case BVLPDU:
if err := bvlpdu.Update(w); err != nil {
return errors.Wrap(err, "error updating BVLPDU")
}
for _, bdte := range w.bvlciBDT {
bvlpdu.PutData(bdte.AddrAddress...)
bvlpdu.PutLong(*bdte.AddrMask)
}
bvlpdu.setBVLC(w.bvlc)
return nil
default:
return errors.Errorf("invalid BVLPDU type %T", bvlpdu)
}
}

func (w *ReadBroadcastDistributionTableAck) Decode(bvlpdu Arg) error {
switch bvlpdu := bvlpdu.(type) {
case BVLPDU:
if err := w.Update(bvlpdu); err != nil {
return errors.Wrap(err, "error updating BVLPDU")
}
switch pduUserData := bvlpdu.GetPDUUserData().(type) {
case readWriteModel.BVLCReadBroadcastDistributionTableAckExactly:
switch bvlc := pduUserData.(type) {
case readWriteModel.BVLCReadBroadcastDistributionTableAck:
w.setBVLC(bvlc)
w.bvlciBDT = w.produceBvlciBDT(bvlc.GetTable())
}
}
return nil
default:
return errors.Errorf("invalid BVLPDU type %T", bvlpdu)
}
}

func (w *ReadBroadcastDistributionTableAck) String() string {
return fmt.Sprintf("ReadBroadcastDistributionTableAck{%v, bvlciBDT: %v}", w._BVLPDU, w.bvlciBDT)
}

// TODO: finish
Expand Down
10 changes: 7 additions & 3 deletions plc4go/internal/bacnetip/tests/state_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,15 @@ func MatchPdu(localLog zerolog.Logger, pdu bacnetip.PDU, pduType any, pduAttrs m
}
return r.GetBvlciResultCode() == attrValue
case bacnetip.KWBvlciBDT:
wbdt, ok := pdu.(*bacnetip.WriteBroadcastDistributionTable)
if !ok {
var iwbdt []*bacnetip.Address
switch pdu := pdu.(type) {
case *bacnetip.WriteBroadcastDistributionTable:
iwbdt = pdu.GetBvlciBDT()
case *bacnetip.ReadBroadcastDistributionTableAck:
iwbdt = pdu.GetBvlciBDT()
default:
return false
}
iwbdt := wbdt.GetBvlciBDT()
owbdt, ok := attrValue.([]*bacnetip.Address)
if !ok {
return false
Expand Down
54 changes: 53 additions & 1 deletion plc4go/internal/bacnetip/tests/test_bvll/test_codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func Result(i uint16) *bacnetip.Result {
}

func WriteBroadcastDistributionTable(bdt ...*bacnetip.Address) *bacnetip.WriteBroadcastDistributionTable {
writeBroadcastDistributionTable, err := bacnetip.NewWriteBroadcastDistributionTable(bacnetip.WithWriteBroadcastDistributionTable(bdt...))
writeBroadcastDistributionTable, err := bacnetip.NewWriteBroadcastDistributionTable(bacnetip.WithWriteBroadcastDistributionTableBDT(bdt...))
if err != nil {
panic(err)
}
Expand All @@ -55,6 +55,14 @@ func ReadBroadcastDistributionTable() *bacnetip.ReadBroadcastDistributionTable {
return readBroadcastDistributionTable
}

func ReadBroadcastDistributionTableAck(bdt ...*bacnetip.Address) *bacnetip.ReadBroadcastDistributionTableAck {
readBroadcastDistributionTable, err := bacnetip.NewReadBroadcastDistributionTableAck(bacnetip.WithReadBroadcastDistributionTableAckBDT(bdt...))
if err != nil {
panic(err)
}
return readBroadcastDistributionTable
}

type TestAnnexJCodecSuite struct {
suite.Suite

Expand Down Expand Up @@ -227,6 +235,50 @@ func (suite *TestAnnexJCodecSuite) TestReadBroadcastDistributionTable() {
err = suite.Confirmation(bacnetip.NewArgs((*bacnetip.ReadBroadcastDistributionTable)(nil)), bacnetip.NoKWArgs)
}

func (suite *TestAnnexJCodecSuite) TestReadBroadcastDistributionTableAck() {
// Read an empty TableAck
pduBytes, err := bacnetip.Xtob("81.03.0004")
suite.Require().NoError(err)
{ // Parse with plc4x parser to validate
parse, err := readWriteModel.BVLCParse(testutils.TestContext(suite.T()), pduBytes)
suite.Assert().NoError(err)
if parse != nil {
suite.T().Log("\n" + parse.String())
}
}

err = suite.Request(bacnetip.NewArgs(ReadBroadcastDistributionTableAck()), 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.ReadBroadcastDistributionTableAck)(nil)), bacnetip.NewKWArgs(bacnetip.KWBvlciBDT, []*bacnetip.Address{}))

// Read TableAck with an element
addr, _ := bacnetip.NewAddress(zerolog.Nop(), "192.168.0.254/24")
pduBytes, err = bacnetip.Xtob("81.03.000e" + //bvlci
"c0.a8.00.fe.ba.c0 ff.ff.ff.00") // address and mask
suite.Require().NoError(err)
{ // Parse with plc4x parser to validate
parse, err := readWriteModel.BVLCParse(testutils.TestContext(suite.T()), pduBytes)
suite.Assert().NoError(err)
if parse != nil {
suite.T().Log("\n" + parse.String())
}
}

err = suite.Request(bacnetip.NewArgs(ReadBroadcastDistributionTableAck(addr)), 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.ReadBroadcastDistributionTableAck)(nil)), bacnetip.NewKWArgs(bacnetip.KWBvlciBDT, []*bacnetip.Address{addr}))
}

func TestAnnexJCodec(t *testing.T) {
suite.Run(t, new(TestAnnexJCodecSuite))
}

0 comments on commit c5d0cbd

Please sign in to comment.