You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2022/04/25 10:59:07 UTC

[plc4x] branch develop updated: feat(bacnet): refined BDT and FDT support

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 5c895a3004 feat(bacnet): refined BDT and FDT support
5c895a3004 is described below

commit 5c895a30046a96558a7dcefabab082ab303a7bf5
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Mon Apr 25 12:59:00 2022 +0200

    feat(bacnet): refined BDT and FDT support
---
 .../plc4go/bacnetip/readwrite/ParserHelper.go      |   6 +-
 .../plc4go/bacnetip/readwrite/XmlParserHelper.go   |   6 +-
 ...y.go => BVLCBroadcastDistributionTableEntry.go} |  52 ++---
 .../model/BVLCDeleteForeignDeviceTableEntry.go     |  92 ++++++--
 .../readwrite/model/BVLCForeignDeviceTableEntry.go | 240 +++++++++++++++++++++
 .../model/BVLCReadBroadcastDistributionTableAck.go |  70 ++++--
 .../model/BVLCReadForeignDeviceTableAck.go         |  70 ++++--
 .../model/BVLCWriteBroadcastDistributionTable.go   |  12 +-
 .../resources/protocols/bacnetip/bacnetip.mspec    |  23 +-
 9 files changed, 459 insertions(+), 112 deletions(-)

diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/ParserHelper.go b/plc4go/internal/plc4go/bacnetip/readwrite/ParserHelper.go
index c4da8997c2..7011aaa8cf 100644
--- a/plc4go/internal/plc4go/bacnetip/readwrite/ParserHelper.go
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/ParserHelper.go
@@ -49,6 +49,8 @@ func (m BacnetipParserHelper) Parse(typeName string, arguments []string, io util
 		return model.BACnetReadAccessPropertyErrorParse(io)
 	case "BACnetTagPayloadReal":
 		return model.BACnetTagPayloadRealParse(io)
+	case "BVLCForeignDeviceTableEntry":
+		return model.BVLCForeignDeviceTableEntryParse(io)
 	case "NLM":
 		apduLength, err := utils.StrToUint16(arguments[0])
 		if err != nil {
@@ -138,6 +140,8 @@ func (m BacnetipParserHelper) Parse(typeName string, arguments []string, io util
 		return model.BVLCParse(io)
 	case "BACnetTagPayloadObjectIdentifier":
 		return model.BACnetTagPayloadObjectIdentifierParse(io)
+	case "BVLCBroadcastDistributionTableEntry":
+		return model.BVLCBroadcastDistributionTableEntryParse(io)
 	case "BACnetPropertyWriteDefinition":
 		objectType := model.BACnetObjectTypeByName(arguments[0])
 		return model.BACnetPropertyWriteDefinitionParse(io, objectType)
@@ -256,8 +260,6 @@ func (m BacnetipParserHelper) Parse(typeName string, arguments []string, io util
 		return model.NPDUParse(io, npduLength)
 	case "BACnetPropertyReference":
 		return model.BACnetPropertyReferenceParse(io)
-	case "BVLCWriteBroadcastDistributionTableEntry":
-		return model.BVLCWriteBroadcastDistributionTableEntryParse(io)
 	}
 	return nil, errors.Errorf("Unsupported type %s", typeName)
 }
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/XmlParserHelper.go b/plc4go/internal/plc4go/bacnetip/readwrite/XmlParserHelper.go
index d500bbb87a..7e8c5b3364 100644
--- a/plc4go/internal/plc4go/bacnetip/readwrite/XmlParserHelper.go
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/XmlParserHelper.go
@@ -61,6 +61,8 @@ func (m BacnetipXmlParserHelper) Parse(typeName string, xmlString string, parser
 		return model.BACnetReadAccessPropertyErrorParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
 	case "BACnetTagPayloadReal":
 		return model.BACnetTagPayloadRealParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
+	case "BVLCForeignDeviceTableEntry":
+		return model.BVLCForeignDeviceTableEntryParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
 	case "NLM":
 		parsedUint0, err := strconv.ParseUint(parserArguments[0], 10, 16)
 		if err != nil {
@@ -161,6 +163,8 @@ func (m BacnetipXmlParserHelper) Parse(typeName string, xmlString string, parser
 		return model.BVLCParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
 	case "BACnetTagPayloadObjectIdentifier":
 		return model.BACnetTagPayloadObjectIdentifierParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
+	case "BVLCBroadcastDistributionTableEntry":
+		return model.BVLCBroadcastDistributionTableEntryParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
 	case "BACnetPropertyWriteDefinition":
 		objectType := model.BACnetObjectTypeByName(parserArguments[0])
 		return model.BACnetPropertyWriteDefinitionParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)), objectType)
@@ -295,8 +299,6 @@ func (m BacnetipXmlParserHelper) Parse(typeName string, xmlString string, parser
 		return model.NPDUParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)), npduLength)
 	case "BACnetPropertyReference":
 		return model.BACnetPropertyReferenceParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
-	case "BVLCWriteBroadcastDistributionTableEntry":
-		return model.BVLCWriteBroadcastDistributionTableEntryParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
 	}
 	return nil, errors.Errorf("Unsupported type %s", typeName)
 }
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCWriteBroadcastDistributionTableEntry.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCBroadcastDistributionTableEntry.go
similarity index 69%
rename from plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCWriteBroadcastDistributionTableEntry.go
rename to plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCBroadcastDistributionTableEntry.go
index 7eff557d3e..b54928d83a 100644
--- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCWriteBroadcastDistributionTableEntry.go
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCBroadcastDistributionTableEntry.go
@@ -26,15 +26,15 @@ import (
 
 // Code generated by code-generation. DO NOT EDIT.
 
-// BVLCWriteBroadcastDistributionTableEntry is the data-structure of this message
-type BVLCWriteBroadcastDistributionTableEntry struct {
+// BVLCBroadcastDistributionTableEntry is the data-structure of this message
+type BVLCBroadcastDistributionTableEntry struct {
 	Ip                       []uint8
 	Port                     uint16
 	BroadcastDistributionMap []uint8
 }
 
-// IBVLCWriteBroadcastDistributionTableEntry is the corresponding interface of BVLCWriteBroadcastDistributionTableEntry
-type IBVLCWriteBroadcastDistributionTableEntry interface {
+// IBVLCBroadcastDistributionTableEntry is the corresponding interface of BVLCBroadcastDistributionTableEntry
+type IBVLCBroadcastDistributionTableEntry interface {
 	// GetIp returns Ip (property field)
 	GetIp() []uint8
 	// GetPort returns Port (property field)
@@ -54,15 +54,15 @@ type IBVLCWriteBroadcastDistributionTableEntry interface {
 /////////////////////// Accessors for property fields.
 ///////////////////////
 
-func (m *BVLCWriteBroadcastDistributionTableEntry) GetIp() []uint8 {
+func (m *BVLCBroadcastDistributionTableEntry) GetIp() []uint8 {
 	return m.Ip
 }
 
-func (m *BVLCWriteBroadcastDistributionTableEntry) GetPort() uint16 {
+func (m *BVLCBroadcastDistributionTableEntry) GetPort() uint16 {
 	return m.Port
 }
 
-func (m *BVLCWriteBroadcastDistributionTableEntry) GetBroadcastDistributionMap() []uint8 {
+func (m *BVLCBroadcastDistributionTableEntry) GetBroadcastDistributionMap() []uint8 {
 	return m.BroadcastDistributionMap
 }
 
@@ -71,30 +71,30 @@ func (m *BVLCWriteBroadcastDistributionTableEntry) GetBroadcastDistributionMap()
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
-// NewBVLCWriteBroadcastDistributionTableEntry factory function for BVLCWriteBroadcastDistributionTableEntry
-func NewBVLCWriteBroadcastDistributionTableEntry(ip []uint8, port uint16, broadcastDistributionMap []uint8) *BVLCWriteBroadcastDistributionTableEntry {
-	return &BVLCWriteBroadcastDistributionTableEntry{Ip: ip, Port: port, BroadcastDistributionMap: broadcastDistributionMap}
+// NewBVLCBroadcastDistributionTableEntry factory function for BVLCBroadcastDistributionTableEntry
+func NewBVLCBroadcastDistributionTableEntry(ip []uint8, port uint16, broadcastDistributionMap []uint8) *BVLCBroadcastDistributionTableEntry {
+	return &BVLCBroadcastDistributionTableEntry{Ip: ip, Port: port, BroadcastDistributionMap: broadcastDistributionMap}
 }
 
-func CastBVLCWriteBroadcastDistributionTableEntry(structType interface{}) *BVLCWriteBroadcastDistributionTableEntry {
-	if casted, ok := structType.(BVLCWriteBroadcastDistributionTableEntry); ok {
+func CastBVLCBroadcastDistributionTableEntry(structType interface{}) *BVLCBroadcastDistributionTableEntry {
+	if casted, ok := structType.(BVLCBroadcastDistributionTableEntry); ok {
 		return &casted
 	}
-	if casted, ok := structType.(*BVLCWriteBroadcastDistributionTableEntry); ok {
+	if casted, ok := structType.(*BVLCBroadcastDistributionTableEntry); ok {
 		return casted
 	}
 	return nil
 }
 
-func (m *BVLCWriteBroadcastDistributionTableEntry) GetTypeName() string {
-	return "BVLCWriteBroadcastDistributionTableEntry"
+func (m *BVLCBroadcastDistributionTableEntry) GetTypeName() string {
+	return "BVLCBroadcastDistributionTableEntry"
 }
 
-func (m *BVLCWriteBroadcastDistributionTableEntry) GetLengthInBits() uint16 {
+func (m *BVLCBroadcastDistributionTableEntry) GetLengthInBits() uint16 {
 	return m.GetLengthInBitsConditional(false)
 }
 
-func (m *BVLCWriteBroadcastDistributionTableEntry) GetLengthInBitsConditional(lastItem bool) uint16 {
+func (m *BVLCBroadcastDistributionTableEntry) GetLengthInBitsConditional(lastItem bool) uint16 {
 	lengthInBits := uint16(0)
 
 	// Array field
@@ -113,12 +113,12 @@ func (m *BVLCWriteBroadcastDistributionTableEntry) GetLengthInBitsConditional(la
 	return lengthInBits
 }
 
-func (m *BVLCWriteBroadcastDistributionTableEntry) GetLengthInBytes() uint16 {
+func (m *BVLCBroadcastDistributionTableEntry) GetLengthInBytes() uint16 {
 	return m.GetLengthInBits() / 8
 }
 
-func BVLCWriteBroadcastDistributionTableEntryParse(readBuffer utils.ReadBuffer) (*BVLCWriteBroadcastDistributionTableEntry, error) {
-	if pullErr := readBuffer.PullContext("BVLCWriteBroadcastDistributionTableEntry"); pullErr != nil {
+func BVLCBroadcastDistributionTableEntryParse(readBuffer utils.ReadBuffer) (*BVLCBroadcastDistributionTableEntry, error) {
+	if pullErr := readBuffer.PullContext("BVLCBroadcastDistributionTableEntry"); pullErr != nil {
 		return nil, pullErr
 	}
 	currentPos := readBuffer.GetPos()
@@ -169,16 +169,16 @@ func BVLCWriteBroadcastDistributionTableEntryParse(readBuffer utils.ReadBuffer)
 		return nil, closeErr
 	}
 
-	if closeErr := readBuffer.CloseContext("BVLCWriteBroadcastDistributionTableEntry"); closeErr != nil {
+	if closeErr := readBuffer.CloseContext("BVLCBroadcastDistributionTableEntry"); closeErr != nil {
 		return nil, closeErr
 	}
 
 	// Create the instance
-	return NewBVLCWriteBroadcastDistributionTableEntry(ip, port, broadcastDistributionMap), nil
+	return NewBVLCBroadcastDistributionTableEntry(ip, port, broadcastDistributionMap), nil
 }
 
-func (m *BVLCWriteBroadcastDistributionTableEntry) Serialize(writeBuffer utils.WriteBuffer) error {
-	if pushErr := writeBuffer.PushContext("BVLCWriteBroadcastDistributionTableEntry"); pushErr != nil {
+func (m *BVLCBroadcastDistributionTableEntry) Serialize(writeBuffer utils.WriteBuffer) error {
+	if pushErr := writeBuffer.PushContext("BVLCBroadcastDistributionTableEntry"); pushErr != nil {
 		return pushErr
 	}
 
@@ -221,13 +221,13 @@ func (m *BVLCWriteBroadcastDistributionTableEntry) Serialize(writeBuffer utils.W
 		}
 	}
 
-	if popErr := writeBuffer.PopContext("BVLCWriteBroadcastDistributionTableEntry"); popErr != nil {
+	if popErr := writeBuffer.PopContext("BVLCBroadcastDistributionTableEntry"); popErr != nil {
 		return popErr
 	}
 	return nil
 }
 
-func (m *BVLCWriteBroadcastDistributionTableEntry) String() string {
+func (m *BVLCBroadcastDistributionTableEntry) String() string {
 	if m == nil {
 		return "<nil>"
 	}
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDeleteForeignDeviceTableEntry.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDeleteForeignDeviceTableEntry.go
index b4c15e2074..8261ef4794 100644
--- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDeleteForeignDeviceTableEntry.go
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCDeleteForeignDeviceTableEntry.go
@@ -29,14 +29,17 @@ import (
 // BVLCDeleteForeignDeviceTableEntry is the data-structure of this message
 type BVLCDeleteForeignDeviceTableEntry struct {
 	*BVLC
-	FdtEntry []byte
+	Ip   []uint8
+	Port uint16
 }
 
 // IBVLCDeleteForeignDeviceTableEntry is the corresponding interface of BVLCDeleteForeignDeviceTableEntry
 type IBVLCDeleteForeignDeviceTableEntry interface {
 	IBVLC
-	// GetFdtEntry returns FdtEntry (property field)
-	GetFdtEntry() []byte
+	// GetIp returns Ip (property field)
+	GetIp() []uint8
+	// GetPort returns Port (property field)
+	GetPort() uint16
 	// GetLengthInBytes returns the length in bytes
 	GetLengthInBytes() uint16
 	// GetLengthInBits returns the length in bits
@@ -70,8 +73,12 @@ func (m *BVLCDeleteForeignDeviceTableEntry) GetParent() *BVLC {
 /////////////////////// Accessors for property fields.
 ///////////////////////
 
-func (m *BVLCDeleteForeignDeviceTableEntry) GetFdtEntry() []byte {
-	return m.FdtEntry
+func (m *BVLCDeleteForeignDeviceTableEntry) GetIp() []uint8 {
+	return m.Ip
+}
+
+func (m *BVLCDeleteForeignDeviceTableEntry) GetPort() uint16 {
+	return m.Port
 }
 
 ///////////////////////
@@ -80,10 +87,11 @@ func (m *BVLCDeleteForeignDeviceTableEntry) GetFdtEntry() []byte {
 ///////////////////////////////////////////////////////////
 
 // NewBVLCDeleteForeignDeviceTableEntry factory function for BVLCDeleteForeignDeviceTableEntry
-func NewBVLCDeleteForeignDeviceTableEntry(fdtEntry []byte) *BVLCDeleteForeignDeviceTableEntry {
+func NewBVLCDeleteForeignDeviceTableEntry(ip []uint8, port uint16) *BVLCDeleteForeignDeviceTableEntry {
 	_result := &BVLCDeleteForeignDeviceTableEntry{
-		FdtEntry: fdtEntry,
-		BVLC:     NewBVLC(),
+		Ip:   ip,
+		Port: port,
+		BVLC: NewBVLC(),
 	}
 	_result.Child = _result
 	return _result
@@ -117,10 +125,13 @@ func (m *BVLCDeleteForeignDeviceTableEntry) GetLengthInBitsConditional(lastItem
 	lengthInBits := uint16(m.GetParentLengthInBits())
 
 	// Array field
-	if len(m.FdtEntry) > 0 {
-		lengthInBits += 8 * uint16(len(m.FdtEntry))
+	if len(m.Ip) > 0 {
+		lengthInBits += 8 * uint16(len(m.Ip))
 	}
 
+	// Simple field (port)
+	lengthInBits += 16
+
 	return lengthInBits
 }
 
@@ -134,12 +145,32 @@ func BVLCDeleteForeignDeviceTableEntryParse(readBuffer utils.ReadBuffer) (*BVLCD
 	}
 	currentPos := readBuffer.GetPos()
 	_ = currentPos
-	// Byte Array field (fdtEntry)
-	numberOfBytesfdtEntry := int(uint16(6))
-	fdtEntry, _readArrayErr := readBuffer.ReadByteArray("fdtEntry", numberOfBytesfdtEntry)
-	if _readArrayErr != nil {
-		return nil, errors.Wrap(_readArrayErr, "Error parsing 'fdtEntry' field")
+
+	// Array field (ip)
+	if pullErr := readBuffer.PullContext("ip", utils.WithRenderAsList(true)); pullErr != nil {
+		return nil, pullErr
+	}
+	// Count array
+	ip := make([]uint8, uint16(4))
+	{
+		for curItem := uint16(0); curItem < uint16(uint16(4)); curItem++ {
+			_item, _err := readBuffer.ReadUint8("", 8)
+			if _err != nil {
+				return nil, errors.Wrap(_err, "Error parsing 'ip' field")
+			}
+			ip[curItem] = _item
+		}
 	}
+	if closeErr := readBuffer.CloseContext("ip", utils.WithRenderAsList(true)); closeErr != nil {
+		return nil, closeErr
+	}
+
+	// Simple Field (port)
+	_port, _portErr := readBuffer.ReadUint16("port", 16)
+	if _portErr != nil {
+		return nil, errors.Wrap(_portErr, "Error parsing 'port' field")
+	}
+	port := _port
 
 	if closeErr := readBuffer.CloseContext("BVLCDeleteForeignDeviceTableEntry"); closeErr != nil {
 		return nil, closeErr
@@ -147,8 +178,9 @@ func BVLCDeleteForeignDeviceTableEntryParse(readBuffer utils.ReadBuffer) (*BVLCD
 
 	// Create a partially initialized instance
 	_child := &BVLCDeleteForeignDeviceTableEntry{
-		FdtEntry: fdtEntry,
-		BVLC:     &BVLC{},
+		Ip:   ip,
+		Port: port,
+		BVLC: &BVLC{},
 	}
 	_child.BVLC.Child = _child
 	return _child, nil
@@ -160,13 +192,27 @@ func (m *BVLCDeleteForeignDeviceTableEntry) Serialize(writeBuffer utils.WriteBuf
 			return pushErr
 		}
 
-		// Array Field (fdtEntry)
-		if m.FdtEntry != nil {
-			// Byte Array field (fdtEntry)
-			_writeArrayErr := writeBuffer.WriteByteArray("fdtEntry", m.FdtEntry)
-			if _writeArrayErr != nil {
-				return errors.Wrap(_writeArrayErr, "Error serializing 'fdtEntry' field")
+		// Array Field (ip)
+		if m.Ip != nil {
+			if pushErr := writeBuffer.PushContext("ip", utils.WithRenderAsList(true)); pushErr != nil {
+				return pushErr
 			}
+			for _, _element := range m.Ip {
+				_elementErr := writeBuffer.WriteUint8("", 8, _element)
+				if _elementErr != nil {
+					return errors.Wrap(_elementErr, "Error serializing 'ip' field")
+				}
+			}
+			if popErr := writeBuffer.PopContext("ip", utils.WithRenderAsList(true)); popErr != nil {
+				return popErr
+			}
+		}
+
+		// Simple Field (port)
+		port := uint16(m.Port)
+		_portErr := writeBuffer.WriteUint16("port", 16, (port))
+		if _portErr != nil {
+			return errors.Wrap(_portErr, "Error serializing 'port' field")
 		}
 
 		if popErr := writeBuffer.PopContext("BVLCDeleteForeignDeviceTableEntry"); popErr != nil {
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCForeignDeviceTableEntry.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCForeignDeviceTableEntry.go
new file mode 100644
index 0000000000..f737e0dd4f
--- /dev/null
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCForeignDeviceTableEntry.go
@@ -0,0 +1,240 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package model
+
+import (
+	"github.com/apache/plc4x/plc4go/internal/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// BVLCForeignDeviceTableEntry is the data-structure of this message
+type BVLCForeignDeviceTableEntry struct {
+	Ip                         []uint8
+	Port                       uint16
+	Ttl                        uint16
+	SecondRemainingBeforePurge uint16
+}
+
+// IBVLCForeignDeviceTableEntry is the corresponding interface of BVLCForeignDeviceTableEntry
+type IBVLCForeignDeviceTableEntry interface {
+	// GetIp returns Ip (property field)
+	GetIp() []uint8
+	// GetPort returns Port (property field)
+	GetPort() uint16
+	// GetTtl returns Ttl (property field)
+	GetTtl() uint16
+	// GetSecondRemainingBeforePurge returns SecondRemainingBeforePurge (property field)
+	GetSecondRemainingBeforePurge() uint16
+	// GetLengthInBytes returns the length in bytes
+	GetLengthInBytes() uint16
+	// GetLengthInBits returns the length in bits
+	GetLengthInBits() uint16
+	// Serialize serializes this type
+	Serialize(writeBuffer utils.WriteBuffer) error
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *BVLCForeignDeviceTableEntry) GetIp() []uint8 {
+	return m.Ip
+}
+
+func (m *BVLCForeignDeviceTableEntry) GetPort() uint16 {
+	return m.Port
+}
+
+func (m *BVLCForeignDeviceTableEntry) GetTtl() uint16 {
+	return m.Ttl
+}
+
+func (m *BVLCForeignDeviceTableEntry) GetSecondRemainingBeforePurge() uint16 {
+	return m.SecondRemainingBeforePurge
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewBVLCForeignDeviceTableEntry factory function for BVLCForeignDeviceTableEntry
+func NewBVLCForeignDeviceTableEntry(ip []uint8, port uint16, ttl uint16, secondRemainingBeforePurge uint16) *BVLCForeignDeviceTableEntry {
+	return &BVLCForeignDeviceTableEntry{Ip: ip, Port: port, Ttl: ttl, SecondRemainingBeforePurge: secondRemainingBeforePurge}
+}
+
+func CastBVLCForeignDeviceTableEntry(structType interface{}) *BVLCForeignDeviceTableEntry {
+	if casted, ok := structType.(BVLCForeignDeviceTableEntry); ok {
+		return &casted
+	}
+	if casted, ok := structType.(*BVLCForeignDeviceTableEntry); ok {
+		return casted
+	}
+	return nil
+}
+
+func (m *BVLCForeignDeviceTableEntry) GetTypeName() string {
+	return "BVLCForeignDeviceTableEntry"
+}
+
+func (m *BVLCForeignDeviceTableEntry) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *BVLCForeignDeviceTableEntry) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(0)
+
+	// Array field
+	if len(m.Ip) > 0 {
+		lengthInBits += 8 * uint16(len(m.Ip))
+	}
+
+	// Simple field (port)
+	lengthInBits += 16
+
+	// Simple field (ttl)
+	lengthInBits += 16
+
+	// Simple field (secondRemainingBeforePurge)
+	lengthInBits += 16
+
+	return lengthInBits
+}
+
+func (m *BVLCForeignDeviceTableEntry) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func BVLCForeignDeviceTableEntryParse(readBuffer utils.ReadBuffer) (*BVLCForeignDeviceTableEntry, error) {
+	if pullErr := readBuffer.PullContext("BVLCForeignDeviceTableEntry"); pullErr != nil {
+		return nil, pullErr
+	}
+	currentPos := readBuffer.GetPos()
+	_ = currentPos
+
+	// Array field (ip)
+	if pullErr := readBuffer.PullContext("ip", utils.WithRenderAsList(true)); pullErr != nil {
+		return nil, pullErr
+	}
+	// Count array
+	ip := make([]uint8, uint16(4))
+	{
+		for curItem := uint16(0); curItem < uint16(uint16(4)); curItem++ {
+			_item, _err := readBuffer.ReadUint8("", 8)
+			if _err != nil {
+				return nil, errors.Wrap(_err, "Error parsing 'ip' field")
+			}
+			ip[curItem] = _item
+		}
+	}
+	if closeErr := readBuffer.CloseContext("ip", utils.WithRenderAsList(true)); closeErr != nil {
+		return nil, closeErr
+	}
+
+	// Simple Field (port)
+	_port, _portErr := readBuffer.ReadUint16("port", 16)
+	if _portErr != nil {
+		return nil, errors.Wrap(_portErr, "Error parsing 'port' field")
+	}
+	port := _port
+
+	// Simple Field (ttl)
+	_ttl, _ttlErr := readBuffer.ReadUint16("ttl", 16)
+	if _ttlErr != nil {
+		return nil, errors.Wrap(_ttlErr, "Error parsing 'ttl' field")
+	}
+	ttl := _ttl
+
+	// Simple Field (secondRemainingBeforePurge)
+	_secondRemainingBeforePurge, _secondRemainingBeforePurgeErr := readBuffer.ReadUint16("secondRemainingBeforePurge", 16)
+	if _secondRemainingBeforePurgeErr != nil {
+		return nil, errors.Wrap(_secondRemainingBeforePurgeErr, "Error parsing 'secondRemainingBeforePurge' field")
+	}
+	secondRemainingBeforePurge := _secondRemainingBeforePurge
+
+	if closeErr := readBuffer.CloseContext("BVLCForeignDeviceTableEntry"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	// Create the instance
+	return NewBVLCForeignDeviceTableEntry(ip, port, ttl, secondRemainingBeforePurge), nil
+}
+
+func (m *BVLCForeignDeviceTableEntry) Serialize(writeBuffer utils.WriteBuffer) error {
+	if pushErr := writeBuffer.PushContext("BVLCForeignDeviceTableEntry"); pushErr != nil {
+		return pushErr
+	}
+
+	// Array Field (ip)
+	if m.Ip != nil {
+		if pushErr := writeBuffer.PushContext("ip", utils.WithRenderAsList(true)); pushErr != nil {
+			return pushErr
+		}
+		for _, _element := range m.Ip {
+			_elementErr := writeBuffer.WriteUint8("", 8, _element)
+			if _elementErr != nil {
+				return errors.Wrap(_elementErr, "Error serializing 'ip' field")
+			}
+		}
+		if popErr := writeBuffer.PopContext("ip", utils.WithRenderAsList(true)); popErr != nil {
+			return popErr
+		}
+	}
+
+	// Simple Field (port)
+	port := uint16(m.Port)
+	_portErr := writeBuffer.WriteUint16("port", 16, (port))
+	if _portErr != nil {
+		return errors.Wrap(_portErr, "Error serializing 'port' field")
+	}
+
+	// Simple Field (ttl)
+	ttl := uint16(m.Ttl)
+	_ttlErr := writeBuffer.WriteUint16("ttl", 16, (ttl))
+	if _ttlErr != nil {
+		return errors.Wrap(_ttlErr, "Error serializing 'ttl' field")
+	}
+
+	// Simple Field (secondRemainingBeforePurge)
+	secondRemainingBeforePurge := uint16(m.SecondRemainingBeforePurge)
+	_secondRemainingBeforePurgeErr := writeBuffer.WriteUint16("secondRemainingBeforePurge", 16, (secondRemainingBeforePurge))
+	if _secondRemainingBeforePurgeErr != nil {
+		return errors.Wrap(_secondRemainingBeforePurgeErr, "Error serializing 'secondRemainingBeforePurge' field")
+	}
+
+	if popErr := writeBuffer.PopContext("BVLCForeignDeviceTableEntry"); popErr != nil {
+		return popErr
+	}
+	return nil
+}
+
+func (m *BVLCForeignDeviceTableEntry) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	buffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := m.Serialize(buffer); err != nil {
+		return err.Error()
+	}
+	return buffer.GetBox().String()
+}
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTableAck.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTableAck.go
index abc0aad10a..edc4b0bbf8 100644
--- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTableAck.go
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadBroadcastDistributionTableAck.go
@@ -29,7 +29,7 @@ import (
 // BVLCReadBroadcastDistributionTableAck is the data-structure of this message
 type BVLCReadBroadcastDistributionTableAck struct {
 	*BVLC
-	BdtEntries []byte
+	Table []*BVLCBroadcastDistributionTableEntry
 
 	// Arguments.
 	BvlcPayloadLength uint16
@@ -38,8 +38,8 @@ type BVLCReadBroadcastDistributionTableAck struct {
 // IBVLCReadBroadcastDistributionTableAck is the corresponding interface of BVLCReadBroadcastDistributionTableAck
 type IBVLCReadBroadcastDistributionTableAck interface {
 	IBVLC
-	// GetBdtEntries returns BdtEntries (property field)
-	GetBdtEntries() []byte
+	// GetTable returns Table (property field)
+	GetTable() []*BVLCBroadcastDistributionTableEntry
 	// GetLengthInBytes returns the length in bytes
 	GetLengthInBytes() uint16
 	// GetLengthInBits returns the length in bits
@@ -73,8 +73,8 @@ func (m *BVLCReadBroadcastDistributionTableAck) GetParent() *BVLC {
 /////////////////////// Accessors for property fields.
 ///////////////////////
 
-func (m *BVLCReadBroadcastDistributionTableAck) GetBdtEntries() []byte {
-	return m.BdtEntries
+func (m *BVLCReadBroadcastDistributionTableAck) GetTable() []*BVLCBroadcastDistributionTableEntry {
+	return m.Table
 }
 
 ///////////////////////
@@ -83,10 +83,10 @@ func (m *BVLCReadBroadcastDistributionTableAck) GetBdtEntries() []byte {
 ///////////////////////////////////////////////////////////
 
 // NewBVLCReadBroadcastDistributionTableAck factory function for BVLCReadBroadcastDistributionTableAck
-func NewBVLCReadBroadcastDistributionTableAck(bdtEntries []byte, bvlcPayloadLength uint16) *BVLCReadBroadcastDistributionTableAck {
+func NewBVLCReadBroadcastDistributionTableAck(table []*BVLCBroadcastDistributionTableEntry, bvlcPayloadLength uint16) *BVLCReadBroadcastDistributionTableAck {
 	_result := &BVLCReadBroadcastDistributionTableAck{
-		BdtEntries: bdtEntries,
-		BVLC:       NewBVLC(),
+		Table: table,
+		BVLC:  NewBVLC(),
 	}
 	_result.Child = _result
 	return _result
@@ -120,8 +120,10 @@ func (m *BVLCReadBroadcastDistributionTableAck) GetLengthInBitsConditional(lastI
 	lengthInBits := uint16(m.GetParentLengthInBits())
 
 	// Array field
-	if len(m.BdtEntries) > 0 {
-		lengthInBits += 8 * uint16(len(m.BdtEntries))
+	if len(m.Table) > 0 {
+		for _, element := range m.Table {
+			lengthInBits += element.GetLengthInBits()
+		}
 	}
 
 	return lengthInBits
@@ -137,11 +139,26 @@ func BVLCReadBroadcastDistributionTableAckParse(readBuffer utils.ReadBuffer, bvl
 	}
 	currentPos := readBuffer.GetPos()
 	_ = currentPos
-	// Byte Array field (bdtEntries)
-	numberOfBytesbdtEntries := int(bvlcPayloadLength)
-	bdtEntries, _readArrayErr := readBuffer.ReadByteArray("bdtEntries", numberOfBytesbdtEntries)
-	if _readArrayErr != nil {
-		return nil, errors.Wrap(_readArrayErr, "Error parsing 'bdtEntries' field")
+
+	// Array field (table)
+	if pullErr := readBuffer.PullContext("table", utils.WithRenderAsList(true)); pullErr != nil {
+		return nil, pullErr
+	}
+	// Length array
+	table := make([]*BVLCBroadcastDistributionTableEntry, 0)
+	{
+		_tableLength := bvlcPayloadLength
+		_tableEndPos := readBuffer.GetPos() + uint16(_tableLength)
+		for readBuffer.GetPos() < _tableEndPos {
+			_item, _err := BVLCBroadcastDistributionTableEntryParse(readBuffer)
+			if _err != nil {
+				return nil, errors.Wrap(_err, "Error parsing 'table' field")
+			}
+			table = append(table, _item)
+		}
+	}
+	if closeErr := readBuffer.CloseContext("table", utils.WithRenderAsList(true)); closeErr != nil {
+		return nil, closeErr
 	}
 
 	if closeErr := readBuffer.CloseContext("BVLCReadBroadcastDistributionTableAck"); closeErr != nil {
@@ -150,8 +167,8 @@ func BVLCReadBroadcastDistributionTableAckParse(readBuffer utils.ReadBuffer, bvl
 
 	// Create a partially initialized instance
 	_child := &BVLCReadBroadcastDistributionTableAck{
-		BdtEntries: bdtEntries,
-		BVLC:       &BVLC{},
+		Table: table,
+		BVLC:  &BVLC{},
 	}
 	_child.BVLC.Child = _child
 	return _child, nil
@@ -163,12 +180,19 @@ func (m *BVLCReadBroadcastDistributionTableAck) Serialize(writeBuffer utils.Writ
 			return pushErr
 		}
 
-		// Array Field (bdtEntries)
-		if m.BdtEntries != nil {
-			// Byte Array field (bdtEntries)
-			_writeArrayErr := writeBuffer.WriteByteArray("bdtEntries", m.BdtEntries)
-			if _writeArrayErr != nil {
-				return errors.Wrap(_writeArrayErr, "Error serializing 'bdtEntries' field")
+		// Array Field (table)
+		if m.Table != nil {
+			if pushErr := writeBuffer.PushContext("table", utils.WithRenderAsList(true)); pushErr != nil {
+				return pushErr
+			}
+			for _, _element := range m.Table {
+				_elementErr := _element.Serialize(writeBuffer)
+				if _elementErr != nil {
+					return errors.Wrap(_elementErr, "Error serializing 'table' field")
+				}
+			}
+			if popErr := writeBuffer.PopContext("table", utils.WithRenderAsList(true)); popErr != nil {
+				return popErr
 			}
 		}
 
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTableAck.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTableAck.go
index 97229b5d9c..8722d60f3c 100644
--- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTableAck.go
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCReadForeignDeviceTableAck.go
@@ -29,7 +29,7 @@ import (
 // BVLCReadForeignDeviceTableAck is the data-structure of this message
 type BVLCReadForeignDeviceTableAck struct {
 	*BVLC
-	FdtEntries []byte
+	Table []*BVLCForeignDeviceTableEntry
 
 	// Arguments.
 	BvlcPayloadLength uint16
@@ -38,8 +38,8 @@ type BVLCReadForeignDeviceTableAck struct {
 // IBVLCReadForeignDeviceTableAck is the corresponding interface of BVLCReadForeignDeviceTableAck
 type IBVLCReadForeignDeviceTableAck interface {
 	IBVLC
-	// GetFdtEntries returns FdtEntries (property field)
-	GetFdtEntries() []byte
+	// GetTable returns Table (property field)
+	GetTable() []*BVLCForeignDeviceTableEntry
 	// GetLengthInBytes returns the length in bytes
 	GetLengthInBytes() uint16
 	// GetLengthInBits returns the length in bits
@@ -73,8 +73,8 @@ func (m *BVLCReadForeignDeviceTableAck) GetParent() *BVLC {
 /////////////////////// Accessors for property fields.
 ///////////////////////
 
-func (m *BVLCReadForeignDeviceTableAck) GetFdtEntries() []byte {
-	return m.FdtEntries
+func (m *BVLCReadForeignDeviceTableAck) GetTable() []*BVLCForeignDeviceTableEntry {
+	return m.Table
 }
 
 ///////////////////////
@@ -83,10 +83,10 @@ func (m *BVLCReadForeignDeviceTableAck) GetFdtEntries() []byte {
 ///////////////////////////////////////////////////////////
 
 // NewBVLCReadForeignDeviceTableAck factory function for BVLCReadForeignDeviceTableAck
-func NewBVLCReadForeignDeviceTableAck(fdtEntries []byte, bvlcPayloadLength uint16) *BVLCReadForeignDeviceTableAck {
+func NewBVLCReadForeignDeviceTableAck(table []*BVLCForeignDeviceTableEntry, bvlcPayloadLength uint16) *BVLCReadForeignDeviceTableAck {
 	_result := &BVLCReadForeignDeviceTableAck{
-		FdtEntries: fdtEntries,
-		BVLC:       NewBVLC(),
+		Table: table,
+		BVLC:  NewBVLC(),
 	}
 	_result.Child = _result
 	return _result
@@ -120,8 +120,10 @@ func (m *BVLCReadForeignDeviceTableAck) GetLengthInBitsConditional(lastItem bool
 	lengthInBits := uint16(m.GetParentLengthInBits())
 
 	// Array field
-	if len(m.FdtEntries) > 0 {
-		lengthInBits += 8 * uint16(len(m.FdtEntries))
+	if len(m.Table) > 0 {
+		for _, element := range m.Table {
+			lengthInBits += element.GetLengthInBits()
+		}
 	}
 
 	return lengthInBits
@@ -137,11 +139,26 @@ func BVLCReadForeignDeviceTableAckParse(readBuffer utils.ReadBuffer, bvlcPayload
 	}
 	currentPos := readBuffer.GetPos()
 	_ = currentPos
-	// Byte Array field (fdtEntries)
-	numberOfBytesfdtEntries := int(bvlcPayloadLength)
-	fdtEntries, _readArrayErr := readBuffer.ReadByteArray("fdtEntries", numberOfBytesfdtEntries)
-	if _readArrayErr != nil {
-		return nil, errors.Wrap(_readArrayErr, "Error parsing 'fdtEntries' field")
+
+	// Array field (table)
+	if pullErr := readBuffer.PullContext("table", utils.WithRenderAsList(true)); pullErr != nil {
+		return nil, pullErr
+	}
+	// Length array
+	table := make([]*BVLCForeignDeviceTableEntry, 0)
+	{
+		_tableLength := bvlcPayloadLength
+		_tableEndPos := readBuffer.GetPos() + uint16(_tableLength)
+		for readBuffer.GetPos() < _tableEndPos {
+			_item, _err := BVLCForeignDeviceTableEntryParse(readBuffer)
+			if _err != nil {
+				return nil, errors.Wrap(_err, "Error parsing 'table' field")
+			}
+			table = append(table, _item)
+		}
+	}
+	if closeErr := readBuffer.CloseContext("table", utils.WithRenderAsList(true)); closeErr != nil {
+		return nil, closeErr
 	}
 
 	if closeErr := readBuffer.CloseContext("BVLCReadForeignDeviceTableAck"); closeErr != nil {
@@ -150,8 +167,8 @@ func BVLCReadForeignDeviceTableAckParse(readBuffer utils.ReadBuffer, bvlcPayload
 
 	// Create a partially initialized instance
 	_child := &BVLCReadForeignDeviceTableAck{
-		FdtEntries: fdtEntries,
-		BVLC:       &BVLC{},
+		Table: table,
+		BVLC:  &BVLC{},
 	}
 	_child.BVLC.Child = _child
 	return _child, nil
@@ -163,12 +180,19 @@ func (m *BVLCReadForeignDeviceTableAck) Serialize(writeBuffer utils.WriteBuffer)
 			return pushErr
 		}
 
-		// Array Field (fdtEntries)
-		if m.FdtEntries != nil {
-			// Byte Array field (fdtEntries)
-			_writeArrayErr := writeBuffer.WriteByteArray("fdtEntries", m.FdtEntries)
-			if _writeArrayErr != nil {
-				return errors.Wrap(_writeArrayErr, "Error serializing 'fdtEntries' field")
+		// Array Field (table)
+		if m.Table != nil {
+			if pushErr := writeBuffer.PushContext("table", utils.WithRenderAsList(true)); pushErr != nil {
+				return pushErr
+			}
+			for _, _element := range m.Table {
+				_elementErr := _element.Serialize(writeBuffer)
+				if _elementErr != nil {
+					return errors.Wrap(_elementErr, "Error serializing 'table' field")
+				}
+			}
+			if popErr := writeBuffer.PopContext("table", utils.WithRenderAsList(true)); popErr != nil {
+				return popErr
 			}
 		}
 
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCWriteBroadcastDistributionTable.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCWriteBroadcastDistributionTable.go
index 8673352acb..563ecf8420 100644
--- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCWriteBroadcastDistributionTable.go
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BVLCWriteBroadcastDistributionTable.go
@@ -29,7 +29,7 @@ import (
 // BVLCWriteBroadcastDistributionTable is the data-structure of this message
 type BVLCWriteBroadcastDistributionTable struct {
 	*BVLC
-	Table []*BVLCWriteBroadcastDistributionTableEntry
+	Table []*BVLCBroadcastDistributionTableEntry
 
 	// Arguments.
 	BvlcPayloadLength uint16
@@ -39,7 +39,7 @@ type BVLCWriteBroadcastDistributionTable struct {
 type IBVLCWriteBroadcastDistributionTable interface {
 	IBVLC
 	// GetTable returns Table (property field)
-	GetTable() []*BVLCWriteBroadcastDistributionTableEntry
+	GetTable() []*BVLCBroadcastDistributionTableEntry
 	// GetLengthInBytes returns the length in bytes
 	GetLengthInBytes() uint16
 	// GetLengthInBits returns the length in bits
@@ -73,7 +73,7 @@ func (m *BVLCWriteBroadcastDistributionTable) GetParent() *BVLC {
 /////////////////////// Accessors for property fields.
 ///////////////////////
 
-func (m *BVLCWriteBroadcastDistributionTable) GetTable() []*BVLCWriteBroadcastDistributionTableEntry {
+func (m *BVLCWriteBroadcastDistributionTable) GetTable() []*BVLCBroadcastDistributionTableEntry {
 	return m.Table
 }
 
@@ -83,7 +83,7 @@ func (m *BVLCWriteBroadcastDistributionTable) GetTable() []*BVLCWriteBroadcastDi
 ///////////////////////////////////////////////////////////
 
 // NewBVLCWriteBroadcastDistributionTable factory function for BVLCWriteBroadcastDistributionTable
-func NewBVLCWriteBroadcastDistributionTable(table []*BVLCWriteBroadcastDistributionTableEntry, bvlcPayloadLength uint16) *BVLCWriteBroadcastDistributionTable {
+func NewBVLCWriteBroadcastDistributionTable(table []*BVLCBroadcastDistributionTableEntry, bvlcPayloadLength uint16) *BVLCWriteBroadcastDistributionTable {
 	_result := &BVLCWriteBroadcastDistributionTable{
 		Table: table,
 		BVLC:  NewBVLC(),
@@ -145,12 +145,12 @@ func BVLCWriteBroadcastDistributionTableParse(readBuffer utils.ReadBuffer, bvlcP
 		return nil, pullErr
 	}
 	// Length array
-	table := make([]*BVLCWriteBroadcastDistributionTableEntry, 0)
+	table := make([]*BVLCBroadcastDistributionTableEntry, 0)
 	{
 		_tableLength := bvlcPayloadLength
 		_tableEndPos := readBuffer.GetPos() + uint16(_tableLength)
 		for readBuffer.GetPos() < _tableEndPos {
-			_item, _err := BVLCWriteBroadcastDistributionTableEntryParse(readBuffer)
+			_item, _err := BVLCBroadcastDistributionTableEntryParse(readBuffer)
 			if _err != nil {
 				return nil, errors.Wrap(_err, "Error parsing 'table' field")
 			}
diff --git a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
index 307fd3780c..4249dcc91f 100644
--- a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
+++ b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
@@ -28,14 +28,15 @@
                             code                                ]
         ]
         ['0x01' BVLCWriteBroadcastDistributionTable(uint 16 bvlcPayloadLength)
-            [array  BVLCWriteBroadcastDistributionTableEntry
+            [array BVLCBroadcastDistributionTableEntry
                             table
                             length 'bvlcPayloadLength'          ]
         ]
         ['0x02' BVLCReadBroadcastDistributionTable
         ]
         ['0x03' BVLCReadBroadcastDistributionTableAck(uint 16 bvlcPayloadLength)
-            [array byte     bdtEntries
+            [array BVLCBroadcastDistributionTableEntry
+                            table
                             length 'bvlcPayloadLength'          ]
         ]
         ['0x04' BVLCForwardedNPDU(uint 16 bvlcPayloadLength)
@@ -50,12 +51,13 @@
         ['0x06' BVLCReadForeignDeviceTable
         ]
         ['0x07' BVLCReadForeignDeviceTableAck(uint 16 bvlcPayloadLength)
-            [array byte     fdtEntries
-                             length 'bvlcPayloadLength'          ]
+            [array BVLCForeignDeviceTableEntry
+                            table
+                            length 'bvlcPayloadLength'          ]
         ]
         ['0x08' BVLCDeleteForeignDeviceTableEntry
-            [array byte     fdtEntry
-                            count   '6']
+            [array  uint 8      ip                          count '4'       ]
+            [simple uint 16     port                                        ]
         ]
         ['0x09' BVLCDistributeBroadcastToNetwork(uint 16 bvlcPayloadLength)
             [simple NPDU('bvlcPayloadLength')
@@ -76,12 +78,19 @@
     ]
 ]
 
-[type BVLCWriteBroadcastDistributionTableEntry
+[type BVLCBroadcastDistributionTableEntry
     [array  uint 8      ip                          count '4'       ]
     [simple uint 16     port                                        ]
     [array  uint 8      broadcastDistributionMap    count '4'       ]
 ]
 
+[type BVLCForeignDeviceTableEntry
+    [array  uint 8      ip                          count '4'       ]
+    [simple uint 16     port                                        ]
+    [simple uint 16     ttl                                         ]
+    [simple uint 16     secondRemainingBeforePurge                  ]
+]
+
 [type NPDU(uint 16 npduLength)
     [simple     uint 8      protocolVersionNumber                                                                   ]
     [simple     NPDUControl control                                                                                 ]