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/11/07 11:33:34 UTC

[plc4x] 02/02: feat(protocol/bacnet): add missing NLM types

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 955efbea0cf0653b88bbfd8d4765c1c144866eaa
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Mon Nov 7 12:33:10 2022 +0100

    feat(protocol/bacnet): add missing NLM types
---
 .../protocols/bacnetip/readwrite/ParserHelper.go   |  11 +
 .../bacnetip/readwrite/XmlParserHelper.go          |  12 +
 plc4go/protocols/bacnetip/readwrite/model/NLM.go   | 109 ++--
 .../readwrite/model/NLMChallengeRequest.go         | 259 +++++++++
 .../model/NLMDisconnectConnectionToNetwork.go      |  14 +-
 .../model/NLMEstablishConnectionToNetwork.go       |  14 +-
 .../readwrite/model/NLMIAmRouterToNetwork.go       |  16 +-
 .../readwrite/model/NLMICouldBeRouterToNetwork.go  |  14 +-
 .../readwrite/model/NLMInitalizeRoutingTable.go    |  14 +-
 .../readwrite/model/NLMInitalizeRoutingTableAck.go |  14 +-
 .../bacnetip/readwrite/model/NLMNetworkNumberIs.go | 272 ++++++++++
 .../readwrite/model/NLMRejectRouterToNetwork.go    |  14 +-
 .../readwrite/model/NLMRequestKeyUpdate.go         | 363 +++++++++++++
 .../readwrite/model/NLMRequestMasterKey.go         | 233 ++++++++
 .../bacnetip/readwrite/model/NLMReserved.go        | 207 +++++++
 .../readwrite/model/NLMRouterAvailableToNetwork.go |  16 +-
 .../readwrite/model/NLMRouterBusyToNetwork.go      |  16 +-
 .../bacnetip/readwrite/model/NLMSecurityPayload.go | 233 ++++++++
 .../readwrite/model/NLMSecurityResponse.go         | 296 ++++++++++
 .../bacnetip/readwrite/model/NLMSetMasterKey.go    | 218 ++++++++
 .../readwrite/model/NLMUpdateKeyDistributionKey.go | 244 +++++++++
 .../bacnetip/readwrite/model/NLMUpdateKeyUpdate.go | 598 +++++++++++++++++++++
 .../model/NLMUpdateKeyUpdateControlFlags.go        | 347 ++++++++++++
 .../readwrite/model/NLMUpdateKeyUpdateKeyEntry.go  | 222 ++++++++
 .../readwrite/model/NLMVendorProprietaryMessage.go | 244 +++++++++
 .../readwrite/model/NLMWhatIsNetworkNumber.go      | 171 ++++++
 .../readwrite/model/NLMWhoIsRouterToNetwork.go     |  16 +-
 .../readwrite/model/SecurityResponseCode.go        | 334 ++++++++++++
 .../readwrite/model/SecurityResponseCodeTagged.go  | 239 ++++++++
 .../protocols/bacnetip/bacnet-private-enums.mspec  |  30 ++
 .../resources/protocols/bacnetip/bacnetip.mspec    | 128 ++++-
 31 files changed, 4758 insertions(+), 160 deletions(-)

diff --git a/plc4go/protocols/bacnetip/readwrite/ParserHelper.go b/plc4go/protocols/bacnetip/readwrite/ParserHelper.go
index 17cdd13903..759d1cc039 100644
--- a/plc4go/protocols/bacnetip/readwrite/ParserHelper.go
+++ b/plc4go/protocols/bacnetip/readwrite/ParserHelper.go
@@ -48,6 +48,8 @@ func (m BacnetipParserHelper) Parse(typeName string, arguments []string, io util
 		return model.BACnetLiftGroupModeTaggedParseWithBuffer(io, tagNumber, tagClass)
 	case "BACnetValueSource":
 		return model.BACnetValueSourceParseWithBuffer(io)
+	case "NLMUpdateKeyUpdateKeyEntry":
+		return model.NLMUpdateKeyUpdateKeyEntryParseWithBuffer(io)
 	case "BACnetOpeningTag":
 		tagNumberArgument, err := utils.StrToUint8(arguments[0])
 		if err != nil {
@@ -64,6 +66,13 @@ func (m BacnetipParserHelper) Parse(typeName string, arguments []string, io util
 		return model.BACnetPriorityArrayParseWithBuffer(io, objectTypeArgument, tagNumber, arrayIndexArgument)
 	case "BACnetNameValue":
 		return model.BACnetNameValueParseWithBuffer(io)
+	case "SecurityResponseCodeTagged":
+		tagNumber, err := utils.StrToUint8(arguments[0])
+		if err != nil {
+			return nil, errors.Wrap(err, "Error parsing")
+		}
+		tagClass, _ := model.TagClassByName(arguments[1])
+		return model.SecurityResponseCodeTaggedParseWithBuffer(io, tagNumber, tagClass)
 	case "BACnetPropertyReferenceEnclosed":
 		tagNumber, err := utils.StrToUint8(arguments[0])
 		if err != nil {
@@ -796,6 +805,8 @@ func (m BacnetipParserHelper) Parse(typeName string, arguments []string, io util
 		}
 		tagClass, _ := model.TagClassByName(arguments[1])
 		return model.BACnetLightingTransitionTaggedParseWithBuffer(io, tagNumber, tagClass)
+	case "NLMUpdateKeyUpdateControlFlags":
+		return model.NLMUpdateKeyUpdateControlFlagsParseWithBuffer(io)
 	case "BACnetAssignedLandingCalls":
 		return model.BACnetAssignedLandingCallsParseWithBuffer(io)
 	case "BACnetNotifyTypeTagged":
diff --git a/plc4go/protocols/bacnetip/readwrite/XmlParserHelper.go b/plc4go/protocols/bacnetip/readwrite/XmlParserHelper.go
index c6247990a1..9a748421af 100644
--- a/plc4go/protocols/bacnetip/readwrite/XmlParserHelper.go
+++ b/plc4go/protocols/bacnetip/readwrite/XmlParserHelper.go
@@ -60,6 +60,8 @@ func (m BacnetipXmlParserHelper) Parse(typeName string, xmlString string, parser
 		return model.BACnetLiftGroupModeTaggedParseWithBuffer(utils.NewXmlReadBuffer(strings.NewReader(xmlString)), tagNumber, tagClass)
 	case "BACnetValueSource":
 		return model.BACnetValueSourceParseWithBuffer(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
+	case "NLMUpdateKeyUpdateKeyEntry":
+		return model.NLMUpdateKeyUpdateKeyEntryParseWithBuffer(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
 	case "BACnetOpeningTag":
 		parsedUint0, err := strconv.ParseUint(parserArguments[0], 10, 8)
 		if err != nil {
@@ -79,6 +81,14 @@ func (m BacnetipXmlParserHelper) Parse(typeName string, xmlString string, parser
 		return model.BACnetPriorityArrayParseWithBuffer(utils.NewXmlReadBuffer(strings.NewReader(xmlString)), objectTypeArgument, tagNumber, arrayIndexArgument)
 	case "BACnetNameValue":
 		return model.BACnetNameValueParseWithBuffer(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
+	case "SecurityResponseCodeTagged":
+		parsedUint0, err := strconv.ParseUint(parserArguments[0], 10, 8)
+		if err != nil {
+			return nil, err
+		}
+		tagNumber := uint8(parsedUint0)
+		tagClass, _ := model.TagClassByName(parserArguments[1])
+		return model.SecurityResponseCodeTaggedParseWithBuffer(utils.NewXmlReadBuffer(strings.NewReader(xmlString)), tagNumber, tagClass)
 	case "BACnetPropertyReferenceEnclosed":
 		parsedUint0, err := strconv.ParseUint(parserArguments[0], 10, 8)
 		if err != nil {
@@ -908,6 +918,8 @@ func (m BacnetipXmlParserHelper) Parse(typeName string, xmlString string, parser
 		tagNumber := uint8(parsedUint0)
 		tagClass, _ := model.TagClassByName(parserArguments[1])
 		return model.BACnetLightingTransitionTaggedParseWithBuffer(utils.NewXmlReadBuffer(strings.NewReader(xmlString)), tagNumber, tagClass)
+	case "NLMUpdateKeyUpdateControlFlags":
+		return model.NLMUpdateKeyUpdateControlFlagsParseWithBuffer(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
 	case "BACnetAssignedLandingCalls":
 		return model.BACnetAssignedLandingCallsParseWithBuffer(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
 	case "BACnetNotifyTypeTagged":
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLM.go b/plc4go/protocols/bacnetip/readwrite/model/NLM.go
index 7097d90c6f..f029045a53 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/NLM.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLM.go
@@ -33,8 +33,8 @@ type NLM interface {
 	utils.Serializable
 	// GetMessageType returns MessageType (discriminator field)
 	GetMessageType() uint8
-	// GetVendorId returns VendorId (property field)
-	GetVendorId() *BACnetVendorId
+	// GetIsVendorProprietaryMessage returns IsVendorProprietaryMessage (virtual field)
+	GetIsVendorProprietaryMessage() bool
 }
 
 // NLMExactly can be used when we want exactly this type and not a type which fulfills NLM.
@@ -47,7 +47,6 @@ type NLMExactly interface {
 // _NLM is the data-structure of this message
 type _NLM struct {
 	_NLMChildRequirements
-	VendorId *BACnetVendorId
 
 	// Arguments.
 	ApduLength uint16
@@ -67,7 +66,7 @@ type NLMParent interface {
 
 type NLMChild interface {
 	utils.Serializable
-	InitializeParent(parent NLM, vendorId *BACnetVendorId)
+	InitializeParent(parent NLM)
 	GetParent() *NLM
 
 	GetTypeName() string
@@ -76,11 +75,11 @@ type NLMChild interface {
 
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
-/////////////////////// Accessors for property fields.
+/////////////////////// Accessors for virtual fields.
 ///////////////////////
 
-func (m *_NLM) GetVendorId() *BACnetVendorId {
-	return m.VendorId
+func (m *_NLM) GetIsVendorProprietaryMessage() bool {
+	return bool(bool((m.GetMessageType()) >= (128)))
 }
 
 ///////////////////////
@@ -89,8 +88,8 @@ func (m *_NLM) GetVendorId() *BACnetVendorId {
 ///////////////////////////////////////////////////////////
 
 // NewNLM factory function for _NLM
-func NewNLM(vendorId *BACnetVendorId, apduLength uint16) *_NLM {
-	return &_NLM{VendorId: vendorId, ApduLength: apduLength}
+func NewNLM(apduLength uint16) *_NLM {
+	return &_NLM{ApduLength: apduLength}
 }
 
 // Deprecated: use the interface for direct cast
@@ -113,10 +112,7 @@ func (m *_NLM) GetParentLengthInBits() uint16 {
 	// Discriminator Field (messageType)
 	lengthInBits += 8
 
-	// Optional Field (vendorId)
-	if m.VendorId != nil {
-		lengthInBits += 16
-	}
+	// A virtual field doesn't have any in- or output.
 
 	return lengthInBits
 }
@@ -144,26 +140,15 @@ func NLMParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLM, er
 		return nil, errors.Wrap(_messageTypeErr, "Error parsing 'messageType' field of NLM")
 	}
 
-	// Optional Field (vendorId) (Can be skipped, if a given expression evaluates to false)
-	var vendorId *BACnetVendorId = nil
-	if bool((bool((messageType) >= (128)))) && bool((bool((messageType) <= (255)))) {
-		if pullErr := readBuffer.PullContext("vendorId"); pullErr != nil {
-			return nil, errors.Wrap(pullErr, "Error pulling for vendorId")
-		}
-		_val, _err := BACnetVendorIdParseWithBuffer(readBuffer)
-		if _err != nil {
-			return nil, errors.Wrap(_err, "Error parsing 'vendorId' field of NLM")
-		}
-		vendorId = &_val
-		if closeErr := readBuffer.CloseContext("vendorId"); closeErr != nil {
-			return nil, errors.Wrap(closeErr, "Error closing for vendorId")
-		}
-	}
+	// Virtual field
+	_isVendorProprietaryMessage := bool((messageType) >= (128))
+	isVendorProprietaryMessage := bool(_isVendorProprietaryMessage)
+	_ = isVendorProprietaryMessage
 
 	// Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
 	type NLMChildSerializeRequirement interface {
 		NLM
-		InitializeParent(NLM, *BACnetVendorId)
+		InitializeParent(NLM)
 		GetParent() NLM
 	}
 	var _childTemp interface{}
@@ -171,27 +156,51 @@ func NLMParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLM, er
 	var typeSwitchError error
 	switch {
 	case messageType == 0x00: // NLMWhoIsRouterToNetwork
-		_childTemp, typeSwitchError = NLMWhoIsRouterToNetworkParseWithBuffer(readBuffer, apduLength, messageType)
+		_childTemp, typeSwitchError = NLMWhoIsRouterToNetworkParseWithBuffer(readBuffer, apduLength)
 	case messageType == 0x01: // NLMIAmRouterToNetwork
-		_childTemp, typeSwitchError = NLMIAmRouterToNetworkParseWithBuffer(readBuffer, apduLength, messageType)
+		_childTemp, typeSwitchError = NLMIAmRouterToNetworkParseWithBuffer(readBuffer, apduLength)
 	case messageType == 0x02: // NLMICouldBeRouterToNetwork
-		_childTemp, typeSwitchError = NLMICouldBeRouterToNetworkParseWithBuffer(readBuffer, apduLength, messageType)
+		_childTemp, typeSwitchError = NLMICouldBeRouterToNetworkParseWithBuffer(readBuffer, apduLength)
 	case messageType == 0x03: // NLMRejectRouterToNetwork
-		_childTemp, typeSwitchError = NLMRejectRouterToNetworkParseWithBuffer(readBuffer, apduLength, messageType)
+		_childTemp, typeSwitchError = NLMRejectRouterToNetworkParseWithBuffer(readBuffer, apduLength)
 	case messageType == 0x04: // NLMRouterBusyToNetwork
-		_childTemp, typeSwitchError = NLMRouterBusyToNetworkParseWithBuffer(readBuffer, apduLength, messageType)
+		_childTemp, typeSwitchError = NLMRouterBusyToNetworkParseWithBuffer(readBuffer, apduLength)
 	case messageType == 0x05: // NLMRouterAvailableToNetwork
-		_childTemp, typeSwitchError = NLMRouterAvailableToNetworkParseWithBuffer(readBuffer, apduLength, messageType)
+		_childTemp, typeSwitchError = NLMRouterAvailableToNetworkParseWithBuffer(readBuffer, apduLength)
 	case messageType == 0x06: // NLMInitalizeRoutingTable
-		_childTemp, typeSwitchError = NLMInitalizeRoutingTableParseWithBuffer(readBuffer, apduLength, messageType)
+		_childTemp, typeSwitchError = NLMInitalizeRoutingTableParseWithBuffer(readBuffer, apduLength)
 	case messageType == 0x07: // NLMInitalizeRoutingTableAck
-		_childTemp, typeSwitchError = NLMInitalizeRoutingTableAckParseWithBuffer(readBuffer, apduLength, messageType)
+		_childTemp, typeSwitchError = NLMInitalizeRoutingTableAckParseWithBuffer(readBuffer, apduLength)
 	case messageType == 0x08: // NLMEstablishConnectionToNetwork
-		_childTemp, typeSwitchError = NLMEstablishConnectionToNetworkParseWithBuffer(readBuffer, apduLength, messageType)
+		_childTemp, typeSwitchError = NLMEstablishConnectionToNetworkParseWithBuffer(readBuffer, apduLength)
 	case messageType == 0x09: // NLMDisconnectConnectionToNetwork
-		_childTemp, typeSwitchError = NLMDisconnectConnectionToNetworkParseWithBuffer(readBuffer, apduLength, messageType)
+		_childTemp, typeSwitchError = NLMDisconnectConnectionToNetworkParseWithBuffer(readBuffer, apduLength)
+	case messageType == 0x0A: // NLMChallengeRequest
+		_childTemp, typeSwitchError = NLMChallengeRequestParseWithBuffer(readBuffer, apduLength)
+	case messageType == 0x0B: // NLMSecurityPayload
+		_childTemp, typeSwitchError = NLMSecurityPayloadParseWithBuffer(readBuffer, apduLength)
+	case messageType == 0x0C: // NLMSecurityResponse
+		_childTemp, typeSwitchError = NLMSecurityResponseParseWithBuffer(readBuffer, apduLength)
+	case messageType == 0x0D: // NLMRequestKeyUpdate
+		_childTemp, typeSwitchError = NLMRequestKeyUpdateParseWithBuffer(readBuffer, apduLength)
+	case messageType == 0x0E: // NLMUpdateKeyUpdate
+		_childTemp, typeSwitchError = NLMUpdateKeyUpdateParseWithBuffer(readBuffer, apduLength)
+	case messageType == 0x0F: // NLMUpdateKeyDistributionKey
+		_childTemp, typeSwitchError = NLMUpdateKeyDistributionKeyParseWithBuffer(readBuffer, apduLength)
+	case messageType == 0x10: // NLMRequestMasterKey
+		_childTemp, typeSwitchError = NLMRequestMasterKeyParseWithBuffer(readBuffer, apduLength)
+	case messageType == 0x11: // NLMSetMasterKey
+		_childTemp, typeSwitchError = NLMSetMasterKeyParseWithBuffer(readBuffer, apduLength)
+	case messageType == 0x12: // NLMWhatIsNetworkNumber
+		_childTemp, typeSwitchError = NLMWhatIsNetworkNumberParseWithBuffer(readBuffer, apduLength)
+	case messageType == 0x13: // NLMNetworkNumberIs
+		_childTemp, typeSwitchError = NLMNetworkNumberIsParseWithBuffer(readBuffer, apduLength)
+	case 0 == 0 && isVendorProprietaryMessage == bool(false): // NLMReserved
+		_childTemp, typeSwitchError = NLMReservedParseWithBuffer(readBuffer, apduLength)
+	case 0 == 0: // NLMVendorProprietaryMessage
+		_childTemp, typeSwitchError = NLMVendorProprietaryMessageParseWithBuffer(readBuffer, apduLength)
 	default:
-		typeSwitchError = errors.Errorf("Unmapped type for parameters [messageType=%v]", messageType)
+		typeSwitchError = errors.Errorf("Unmapped type for parameters [messageType=%v, isVendorProprietaryMessage=%v]", messageType, isVendorProprietaryMessage)
 	}
 	if typeSwitchError != nil {
 		return nil, errors.Wrap(typeSwitchError, "Error parsing sub-type for type-switch of NLM")
@@ -203,7 +212,7 @@ func NLMParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLM, er
 	}
 
 	// Finish initializing
-	_child.InitializeParent(_child, vendorId)
+	_child.InitializeParent(_child)
 	return _child, nil
 }
 
@@ -224,21 +233,9 @@ func (pm *_NLM) SerializeParent(writeBuffer utils.WriteBuffer, child NLM, serial
 	if _messageTypeErr != nil {
 		return errors.Wrap(_messageTypeErr, "Error serializing 'messageType' field")
 	}
-
-	// Optional Field (vendorId) (Can be skipped, if the value is null)
-	var vendorId *BACnetVendorId = nil
-	if m.GetVendorId() != nil {
-		if pushErr := writeBuffer.PushContext("vendorId"); pushErr != nil {
-			return errors.Wrap(pushErr, "Error pushing for vendorId")
-		}
-		vendorId = m.GetVendorId()
-		_vendorIdErr := writeBuffer.WriteSerializable(vendorId)
-		if popErr := writeBuffer.PopContext("vendorId"); popErr != nil {
-			return errors.Wrap(popErr, "Error popping for vendorId")
-		}
-		if _vendorIdErr != nil {
-			return errors.Wrap(_vendorIdErr, "Error serializing 'vendorId' field")
-		}
+	// Virtual field
+	if _isVendorProprietaryMessageErr := writeBuffer.WriteVirtual("isVendorProprietaryMessage", m.GetIsVendorProprietaryMessage()); _isVendorProprietaryMessageErr != nil {
+		return errors.Wrap(_isVendorProprietaryMessageErr, "Error serializing 'isVendorProprietaryMessage' field")
 	}
 
 	// Switch field (Depending on the discriminator values, passes the serialization to a sub-type)
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMChallengeRequest.go b/plc4go/protocols/bacnetip/readwrite/model/NLMChallengeRequest.go
new file mode 100644
index 0000000000..344ba4e9e3
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMChallengeRequest.go
@@ -0,0 +1,259 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMChallengeRequest is the corresponding interface of NLMChallengeRequest
+type NLMChallengeRequest interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+	// GetMessageChallenge returns MessageChallenge (property field)
+	GetMessageChallenge() byte
+	// GetOriginalMessageId returns OriginalMessageId (property field)
+	GetOriginalMessageId() uint32
+	// GetOriginalTimestamp returns OriginalTimestamp (property field)
+	GetOriginalTimestamp() uint32
+}
+
+// NLMChallengeRequestExactly can be used when we want exactly this type and not a type which fulfills NLMChallengeRequest.
+// This is useful for switch cases.
+type NLMChallengeRequestExactly interface {
+	NLMChallengeRequest
+	isNLMChallengeRequest() bool
+}
+
+// _NLMChallengeRequest is the data-structure of this message
+type _NLMChallengeRequest struct {
+	*_NLM
+	MessageChallenge  byte
+	OriginalMessageId uint32
+	OriginalTimestamp uint32
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMChallengeRequest) GetMessageType() uint8 {
+	return 0x0A
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMChallengeRequest) InitializeParent(parent NLM) {}
+
+func (m *_NLMChallengeRequest) GetParent() NLM {
+	return m._NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMChallengeRequest) GetMessageChallenge() byte {
+	return m.MessageChallenge
+}
+
+func (m *_NLMChallengeRequest) GetOriginalMessageId() uint32 {
+	return m.OriginalMessageId
+}
+
+func (m *_NLMChallengeRequest) GetOriginalTimestamp() uint32 {
+	return m.OriginalTimestamp
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMChallengeRequest factory function for _NLMChallengeRequest
+func NewNLMChallengeRequest(messageChallenge byte, originalMessageId uint32, originalTimestamp uint32, apduLength uint16) *_NLMChallengeRequest {
+	_result := &_NLMChallengeRequest{
+		MessageChallenge:  messageChallenge,
+		OriginalMessageId: originalMessageId,
+		OriginalTimestamp: originalTimestamp,
+		_NLM:              NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMChallengeRequest(structType interface{}) NLMChallengeRequest {
+	if casted, ok := structType.(NLMChallengeRequest); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMChallengeRequest); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMChallengeRequest) GetTypeName() string {
+	return "NLMChallengeRequest"
+}
+
+func (m *_NLMChallengeRequest) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMChallengeRequest) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (messageChallenge)
+	lengthInBits += 8
+
+	// Simple field (originalMessageId)
+	lengthInBits += 32
+
+	// Simple field (originalTimestamp)
+	lengthInBits += 32
+
+	return lengthInBits
+}
+
+func (m *_NLMChallengeRequest) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMChallengeRequestParse(theBytes []byte, apduLength uint16) (NLMChallengeRequest, error) {
+	return NLMChallengeRequestParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMChallengeRequestParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMChallengeRequest, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMChallengeRequest"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMChallengeRequest")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (messageChallenge)
+	_messageChallenge, _messageChallengeErr := readBuffer.ReadByte("messageChallenge")
+	if _messageChallengeErr != nil {
+		return nil, errors.Wrap(_messageChallengeErr, "Error parsing 'messageChallenge' field of NLMChallengeRequest")
+	}
+	messageChallenge := _messageChallenge
+
+	// Simple Field (originalMessageId)
+	_originalMessageId, _originalMessageIdErr := readBuffer.ReadUint32("originalMessageId", 32)
+	if _originalMessageIdErr != nil {
+		return nil, errors.Wrap(_originalMessageIdErr, "Error parsing 'originalMessageId' field of NLMChallengeRequest")
+	}
+	originalMessageId := _originalMessageId
+
+	// Simple Field (originalTimestamp)
+	_originalTimestamp, _originalTimestampErr := readBuffer.ReadUint32("originalTimestamp", 32)
+	if _originalTimestampErr != nil {
+		return nil, errors.Wrap(_originalTimestampErr, "Error parsing 'originalTimestamp' field of NLMChallengeRequest")
+	}
+	originalTimestamp := _originalTimestamp
+
+	if closeErr := readBuffer.CloseContext("NLMChallengeRequest"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMChallengeRequest")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMChallengeRequest{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+		MessageChallenge:  messageChallenge,
+		OriginalMessageId: originalMessageId,
+		OriginalTimestamp: originalTimestamp,
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMChallengeRequest) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMChallengeRequest) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMChallengeRequest"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMChallengeRequest")
+		}
+
+		// Simple Field (messageChallenge)
+		messageChallenge := byte(m.GetMessageChallenge())
+		_messageChallengeErr := writeBuffer.WriteByte("messageChallenge", (messageChallenge))
+		if _messageChallengeErr != nil {
+			return errors.Wrap(_messageChallengeErr, "Error serializing 'messageChallenge' field")
+		}
+
+		// Simple Field (originalMessageId)
+		originalMessageId := uint32(m.GetOriginalMessageId())
+		_originalMessageIdErr := writeBuffer.WriteUint32("originalMessageId", 32, (originalMessageId))
+		if _originalMessageIdErr != nil {
+			return errors.Wrap(_originalMessageIdErr, "Error serializing 'originalMessageId' field")
+		}
+
+		// Simple Field (originalTimestamp)
+		originalTimestamp := uint32(m.GetOriginalTimestamp())
+		_originalTimestampErr := writeBuffer.WriteUint32("originalTimestamp", 32, (originalTimestamp))
+		if _originalTimestampErr != nil {
+			return errors.Wrap(_originalTimestampErr, "Error serializing 'originalTimestamp' field")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMChallengeRequest"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMChallengeRequest")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMChallengeRequest) isNLMChallengeRequest() bool {
+	return true
+}
+
+func (m *_NLMChallengeRequest) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMDisconnectConnectionToNetwork.go b/plc4go/protocols/bacnetip/readwrite/model/NLMDisconnectConnectionToNetwork.go
index 5b3329ecfd..d5307e4194 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/NLMDisconnectConnectionToNetwork.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMDisconnectConnectionToNetwork.go
@@ -63,9 +63,7 @@ func (m *_NLMDisconnectConnectionToNetwork) GetMessageType() uint8 {
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
-func (m *_NLMDisconnectConnectionToNetwork) InitializeParent(parent NLM, vendorId *BACnetVendorId) {
-	m.VendorId = vendorId
-}
+func (m *_NLMDisconnectConnectionToNetwork) InitializeParent(parent NLM) {}
 
 func (m *_NLMDisconnectConnectionToNetwork) GetParent() NLM {
 	return m._NLM
@@ -86,10 +84,10 @@ func (m *_NLMDisconnectConnectionToNetwork) GetDestinationNetworkAddress() uint1
 ///////////////////////////////////////////////////////////
 
 // NewNLMDisconnectConnectionToNetwork factory function for _NLMDisconnectConnectionToNetwork
-func NewNLMDisconnectConnectionToNetwork(destinationNetworkAddress uint16, vendorId *BACnetVendorId, apduLength uint16) *_NLMDisconnectConnectionToNetwork {
+func NewNLMDisconnectConnectionToNetwork(destinationNetworkAddress uint16, apduLength uint16) *_NLMDisconnectConnectionToNetwork {
 	_result := &_NLMDisconnectConnectionToNetwork{
 		DestinationNetworkAddress: destinationNetworkAddress,
-		_NLM:                      NewNLM(vendorId, apduLength),
+		_NLM:                      NewNLM(apduLength),
 	}
 	_result._NLM._NLMChildRequirements = _result
 	return _result
@@ -127,11 +125,11 @@ func (m *_NLMDisconnectConnectionToNetwork) GetLengthInBytes() uint16 {
 	return m.GetLengthInBits() / 8
 }
 
-func NLMDisconnectConnectionToNetworkParse(theBytes []byte, apduLength uint16, messageType uint8) (NLMDisconnectConnectionToNetwork, error) {
-	return NLMDisconnectConnectionToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength, messageType) // TODO: get endianness from mspec
+func NLMDisconnectConnectionToNetworkParse(theBytes []byte, apduLength uint16) (NLMDisconnectConnectionToNetwork, error) {
+	return NLMDisconnectConnectionToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
 }
 
-func NLMDisconnectConnectionToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16, messageType uint8) (NLMDisconnectConnectionToNetwork, error) {
+func NLMDisconnectConnectionToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMDisconnectConnectionToNetwork, error) {
 	positionAware := readBuffer
 	_ = positionAware
 	if pullErr := readBuffer.PullContext("NLMDisconnectConnectionToNetwork"); pullErr != nil {
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMEstablishConnectionToNetwork.go b/plc4go/protocols/bacnetip/readwrite/model/NLMEstablishConnectionToNetwork.go
index df29950882..c0d58c5f57 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/NLMEstablishConnectionToNetwork.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMEstablishConnectionToNetwork.go
@@ -66,9 +66,7 @@ func (m *_NLMEstablishConnectionToNetwork) GetMessageType() uint8 {
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
-func (m *_NLMEstablishConnectionToNetwork) InitializeParent(parent NLM, vendorId *BACnetVendorId) {
-	m.VendorId = vendorId
-}
+func (m *_NLMEstablishConnectionToNetwork) InitializeParent(parent NLM) {}
 
 func (m *_NLMEstablishConnectionToNetwork) GetParent() NLM {
 	return m._NLM
@@ -93,11 +91,11 @@ func (m *_NLMEstablishConnectionToNetwork) GetTerminationTime() uint8 {
 ///////////////////////////////////////////////////////////
 
 // NewNLMEstablishConnectionToNetwork factory function for _NLMEstablishConnectionToNetwork
-func NewNLMEstablishConnectionToNetwork(destinationNetworkAddress uint16, terminationTime uint8, vendorId *BACnetVendorId, apduLength uint16) *_NLMEstablishConnectionToNetwork {
+func NewNLMEstablishConnectionToNetwork(destinationNetworkAddress uint16, terminationTime uint8, apduLength uint16) *_NLMEstablishConnectionToNetwork {
 	_result := &_NLMEstablishConnectionToNetwork{
 		DestinationNetworkAddress: destinationNetworkAddress,
 		TerminationTime:           terminationTime,
-		_NLM:                      NewNLM(vendorId, apduLength),
+		_NLM:                      NewNLM(apduLength),
 	}
 	_result._NLM._NLMChildRequirements = _result
 	return _result
@@ -138,11 +136,11 @@ func (m *_NLMEstablishConnectionToNetwork) GetLengthInBytes() uint16 {
 	return m.GetLengthInBits() / 8
 }
 
-func NLMEstablishConnectionToNetworkParse(theBytes []byte, apduLength uint16, messageType uint8) (NLMEstablishConnectionToNetwork, error) {
-	return NLMEstablishConnectionToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength, messageType) // TODO: get endianness from mspec
+func NLMEstablishConnectionToNetworkParse(theBytes []byte, apduLength uint16) (NLMEstablishConnectionToNetwork, error) {
+	return NLMEstablishConnectionToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
 }
 
-func NLMEstablishConnectionToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16, messageType uint8) (NLMEstablishConnectionToNetwork, error) {
+func NLMEstablishConnectionToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMEstablishConnectionToNetwork, error) {
 	positionAware := readBuffer
 	_ = positionAware
 	if pullErr := readBuffer.PullContext("NLMEstablishConnectionToNetwork"); pullErr != nil {
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMIAmRouterToNetwork.go b/plc4go/protocols/bacnetip/readwrite/model/NLMIAmRouterToNetwork.go
index c37a43a9b9..4c7e06912c 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/NLMIAmRouterToNetwork.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMIAmRouterToNetwork.go
@@ -63,9 +63,7 @@ func (m *_NLMIAmRouterToNetwork) GetMessageType() uint8 {
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
-func (m *_NLMIAmRouterToNetwork) InitializeParent(parent NLM, vendorId *BACnetVendorId) {
-	m.VendorId = vendorId
-}
+func (m *_NLMIAmRouterToNetwork) InitializeParent(parent NLM) {}
 
 func (m *_NLMIAmRouterToNetwork) GetParent() NLM {
 	return m._NLM
@@ -86,10 +84,10 @@ func (m *_NLMIAmRouterToNetwork) GetDestinationNetworkAddress() []uint16 {
 ///////////////////////////////////////////////////////////
 
 // NewNLMIAmRouterToNetwork factory function for _NLMIAmRouterToNetwork
-func NewNLMIAmRouterToNetwork(destinationNetworkAddress []uint16, vendorId *BACnetVendorId, apduLength uint16) *_NLMIAmRouterToNetwork {
+func NewNLMIAmRouterToNetwork(destinationNetworkAddress []uint16, apduLength uint16) *_NLMIAmRouterToNetwork {
 	_result := &_NLMIAmRouterToNetwork{
 		DestinationNetworkAddress: destinationNetworkAddress,
-		_NLM:                      NewNLM(vendorId, apduLength),
+		_NLM:                      NewNLM(apduLength),
 	}
 	_result._NLM._NLMChildRequirements = _result
 	return _result
@@ -129,11 +127,11 @@ func (m *_NLMIAmRouterToNetwork) GetLengthInBytes() uint16 {
 	return m.GetLengthInBits() / 8
 }
 
-func NLMIAmRouterToNetworkParse(theBytes []byte, apduLength uint16, messageType uint8) (NLMIAmRouterToNetwork, error) {
-	return NLMIAmRouterToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength, messageType) // TODO: get endianness from mspec
+func NLMIAmRouterToNetworkParse(theBytes []byte, apduLength uint16) (NLMIAmRouterToNetwork, error) {
+	return NLMIAmRouterToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
 }
 
-func NLMIAmRouterToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16, messageType uint8) (NLMIAmRouterToNetwork, error) {
+func NLMIAmRouterToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMIAmRouterToNetwork, error) {
 	positionAware := readBuffer
 	_ = positionAware
 	if pullErr := readBuffer.PullContext("NLMIAmRouterToNetwork"); pullErr != nil {
@@ -149,7 +147,7 @@ func NLMIAmRouterToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLengt
 	// Length array
 	var destinationNetworkAddress []uint16
 	{
-		_destinationNetworkAddressLength := uint16(apduLength) - uint16((utils.InlineIf((bool((bool((messageType) >= (128)))) && bool((bool((messageType) <= (255))))), func() interface{} { return uint16(uint16(3)) }, func() interface{} { return uint16(uint16(1)) }).(uint16)))
+		_destinationNetworkAddressLength := uint16(apduLength) - uint16(uint16(1))
 		_destinationNetworkAddressEndPos := positionAware.GetPos() + uint16(_destinationNetworkAddressLength)
 		for positionAware.GetPos() < _destinationNetworkAddressEndPos {
 			_item, _err := readBuffer.ReadUint16("", 16)
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMICouldBeRouterToNetwork.go b/plc4go/protocols/bacnetip/readwrite/model/NLMICouldBeRouterToNetwork.go
index c6a75eb50f..7a20c14250 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/NLMICouldBeRouterToNetwork.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMICouldBeRouterToNetwork.go
@@ -66,9 +66,7 @@ func (m *_NLMICouldBeRouterToNetwork) GetMessageType() uint8 {
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
-func (m *_NLMICouldBeRouterToNetwork) InitializeParent(parent NLM, vendorId *BACnetVendorId) {
-	m.VendorId = vendorId
-}
+func (m *_NLMICouldBeRouterToNetwork) InitializeParent(parent NLM) {}
 
 func (m *_NLMICouldBeRouterToNetwork) GetParent() NLM {
 	return m._NLM
@@ -93,11 +91,11 @@ func (m *_NLMICouldBeRouterToNetwork) GetPerformanceIndex() uint8 {
 ///////////////////////////////////////////////////////////
 
 // NewNLMICouldBeRouterToNetwork factory function for _NLMICouldBeRouterToNetwork
-func NewNLMICouldBeRouterToNetwork(destinationNetworkAddress uint16, performanceIndex uint8, vendorId *BACnetVendorId, apduLength uint16) *_NLMICouldBeRouterToNetwork {
+func NewNLMICouldBeRouterToNetwork(destinationNetworkAddress uint16, performanceIndex uint8, apduLength uint16) *_NLMICouldBeRouterToNetwork {
 	_result := &_NLMICouldBeRouterToNetwork{
 		DestinationNetworkAddress: destinationNetworkAddress,
 		PerformanceIndex:          performanceIndex,
-		_NLM:                      NewNLM(vendorId, apduLength),
+		_NLM:                      NewNLM(apduLength),
 	}
 	_result._NLM._NLMChildRequirements = _result
 	return _result
@@ -138,11 +136,11 @@ func (m *_NLMICouldBeRouterToNetwork) GetLengthInBytes() uint16 {
 	return m.GetLengthInBits() / 8
 }
 
-func NLMICouldBeRouterToNetworkParse(theBytes []byte, apduLength uint16, messageType uint8) (NLMICouldBeRouterToNetwork, error) {
-	return NLMICouldBeRouterToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength, messageType) // TODO: get endianness from mspec
+func NLMICouldBeRouterToNetworkParse(theBytes []byte, apduLength uint16) (NLMICouldBeRouterToNetwork, error) {
+	return NLMICouldBeRouterToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
 }
 
-func NLMICouldBeRouterToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16, messageType uint8) (NLMICouldBeRouterToNetwork, error) {
+func NLMICouldBeRouterToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMICouldBeRouterToNetwork, error) {
 	positionAware := readBuffer
 	_ = positionAware
 	if pullErr := readBuffer.PullContext("NLMICouldBeRouterToNetwork"); pullErr != nil {
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMInitalizeRoutingTable.go b/plc4go/protocols/bacnetip/readwrite/model/NLMInitalizeRoutingTable.go
index 279ebda513..3231738af6 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/NLMInitalizeRoutingTable.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMInitalizeRoutingTable.go
@@ -66,9 +66,7 @@ func (m *_NLMInitalizeRoutingTable) GetMessageType() uint8 {
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
-func (m *_NLMInitalizeRoutingTable) InitializeParent(parent NLM, vendorId *BACnetVendorId) {
-	m.VendorId = vendorId
-}
+func (m *_NLMInitalizeRoutingTable) InitializeParent(parent NLM) {}
 
 func (m *_NLMInitalizeRoutingTable) GetParent() NLM {
 	return m._NLM
@@ -93,11 +91,11 @@ func (m *_NLMInitalizeRoutingTable) GetPortMappings() []NLMInitalizeRoutingTable
 ///////////////////////////////////////////////////////////
 
 // NewNLMInitalizeRoutingTable factory function for _NLMInitalizeRoutingTable
-func NewNLMInitalizeRoutingTable(numberOfPorts uint8, portMappings []NLMInitalizeRoutingTablePortMapping, vendorId *BACnetVendorId, apduLength uint16) *_NLMInitalizeRoutingTable {
+func NewNLMInitalizeRoutingTable(numberOfPorts uint8, portMappings []NLMInitalizeRoutingTablePortMapping, apduLength uint16) *_NLMInitalizeRoutingTable {
 	_result := &_NLMInitalizeRoutingTable{
 		NumberOfPorts: numberOfPorts,
 		PortMappings:  portMappings,
-		_NLM:          NewNLM(vendorId, apduLength),
+		_NLM:          NewNLM(apduLength),
 	}
 	_result._NLM._NLMChildRequirements = _result
 	return _result
@@ -143,11 +141,11 @@ func (m *_NLMInitalizeRoutingTable) GetLengthInBytes() uint16 {
 	return m.GetLengthInBits() / 8
 }
 
-func NLMInitalizeRoutingTableParse(theBytes []byte, apduLength uint16, messageType uint8) (NLMInitalizeRoutingTable, error) {
-	return NLMInitalizeRoutingTableParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength, messageType) // TODO: get endianness from mspec
+func NLMInitalizeRoutingTableParse(theBytes []byte, apduLength uint16) (NLMInitalizeRoutingTable, error) {
+	return NLMInitalizeRoutingTableParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
 }
 
-func NLMInitalizeRoutingTableParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16, messageType uint8) (NLMInitalizeRoutingTable, error) {
+func NLMInitalizeRoutingTableParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMInitalizeRoutingTable, error) {
 	positionAware := readBuffer
 	_ = positionAware
 	if pullErr := readBuffer.PullContext("NLMInitalizeRoutingTable"); pullErr != nil {
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMInitalizeRoutingTableAck.go b/plc4go/protocols/bacnetip/readwrite/model/NLMInitalizeRoutingTableAck.go
index 44fba510c7..f90df96955 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/NLMInitalizeRoutingTableAck.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMInitalizeRoutingTableAck.go
@@ -66,9 +66,7 @@ func (m *_NLMInitalizeRoutingTableAck) GetMessageType() uint8 {
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
-func (m *_NLMInitalizeRoutingTableAck) InitializeParent(parent NLM, vendorId *BACnetVendorId) {
-	m.VendorId = vendorId
-}
+func (m *_NLMInitalizeRoutingTableAck) InitializeParent(parent NLM) {}
 
 func (m *_NLMInitalizeRoutingTableAck) GetParent() NLM {
 	return m._NLM
@@ -93,11 +91,11 @@ func (m *_NLMInitalizeRoutingTableAck) GetPortMappings() []NLMInitalizeRoutingTa
 ///////////////////////////////////////////////////////////
 
 // NewNLMInitalizeRoutingTableAck factory function for _NLMInitalizeRoutingTableAck
-func NewNLMInitalizeRoutingTableAck(numberOfPorts uint8, portMappings []NLMInitalizeRoutingTablePortMapping, vendorId *BACnetVendorId, apduLength uint16) *_NLMInitalizeRoutingTableAck {
+func NewNLMInitalizeRoutingTableAck(numberOfPorts uint8, portMappings []NLMInitalizeRoutingTablePortMapping, apduLength uint16) *_NLMInitalizeRoutingTableAck {
 	_result := &_NLMInitalizeRoutingTableAck{
 		NumberOfPorts: numberOfPorts,
 		PortMappings:  portMappings,
-		_NLM:          NewNLM(vendorId, apduLength),
+		_NLM:          NewNLM(apduLength),
 	}
 	_result._NLM._NLMChildRequirements = _result
 	return _result
@@ -143,11 +141,11 @@ func (m *_NLMInitalizeRoutingTableAck) GetLengthInBytes() uint16 {
 	return m.GetLengthInBits() / 8
 }
 
-func NLMInitalizeRoutingTableAckParse(theBytes []byte, apduLength uint16, messageType uint8) (NLMInitalizeRoutingTableAck, error) {
-	return NLMInitalizeRoutingTableAckParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength, messageType) // TODO: get endianness from mspec
+func NLMInitalizeRoutingTableAckParse(theBytes []byte, apduLength uint16) (NLMInitalizeRoutingTableAck, error) {
+	return NLMInitalizeRoutingTableAckParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
 }
 
-func NLMInitalizeRoutingTableAckParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16, messageType uint8) (NLMInitalizeRoutingTableAck, error) {
+func NLMInitalizeRoutingTableAckParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMInitalizeRoutingTableAck, error) {
 	positionAware := readBuffer
 	_ = positionAware
 	if pullErr := readBuffer.PullContext("NLMInitalizeRoutingTableAck"); pullErr != nil {
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMNetworkNumberIs.go b/plc4go/protocols/bacnetip/readwrite/model/NLMNetworkNumberIs.go
new file mode 100644
index 0000000000..a394ef6248
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMNetworkNumberIs.go
@@ -0,0 +1,272 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMNetworkNumberIs is the corresponding interface of NLMNetworkNumberIs
+type NLMNetworkNumberIs interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+	// GetNetworkNumber returns NetworkNumber (property field)
+	GetNetworkNumber() uint16
+	// GetNetworkNumberConfigured returns NetworkNumberConfigured (property field)
+	GetNetworkNumberConfigured() bool
+}
+
+// NLMNetworkNumberIsExactly can be used when we want exactly this type and not a type which fulfills NLMNetworkNumberIs.
+// This is useful for switch cases.
+type NLMNetworkNumberIsExactly interface {
+	NLMNetworkNumberIs
+	isNLMNetworkNumberIs() bool
+}
+
+// _NLMNetworkNumberIs is the data-structure of this message
+type _NLMNetworkNumberIs struct {
+	*_NLM
+	NetworkNumber           uint16
+	NetworkNumberConfigured bool
+	// Reserved Fields
+	reservedField0 *uint8
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMNetworkNumberIs) GetMessageType() uint8 {
+	return 0x13
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMNetworkNumberIs) InitializeParent(parent NLM) {}
+
+func (m *_NLMNetworkNumberIs) GetParent() NLM {
+	return m._NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMNetworkNumberIs) GetNetworkNumber() uint16 {
+	return m.NetworkNumber
+}
+
+func (m *_NLMNetworkNumberIs) GetNetworkNumberConfigured() bool {
+	return m.NetworkNumberConfigured
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMNetworkNumberIs factory function for _NLMNetworkNumberIs
+func NewNLMNetworkNumberIs(networkNumber uint16, networkNumberConfigured bool, apduLength uint16) *_NLMNetworkNumberIs {
+	_result := &_NLMNetworkNumberIs{
+		NetworkNumber:           networkNumber,
+		NetworkNumberConfigured: networkNumberConfigured,
+		_NLM:                    NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMNetworkNumberIs(structType interface{}) NLMNetworkNumberIs {
+	if casted, ok := structType.(NLMNetworkNumberIs); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMNetworkNumberIs); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMNetworkNumberIs) GetTypeName() string {
+	return "NLMNetworkNumberIs"
+}
+
+func (m *_NLMNetworkNumberIs) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMNetworkNumberIs) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (networkNumber)
+	lengthInBits += 16
+
+	// Reserved Field (reserved)
+	lengthInBits += 7
+
+	// Simple field (networkNumberConfigured)
+	lengthInBits += 1
+
+	return lengthInBits
+}
+
+func (m *_NLMNetworkNumberIs) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMNetworkNumberIsParse(theBytes []byte, apduLength uint16) (NLMNetworkNumberIs, error) {
+	return NLMNetworkNumberIsParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMNetworkNumberIsParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMNetworkNumberIs, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMNetworkNumberIs"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMNetworkNumberIs")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (networkNumber)
+	_networkNumber, _networkNumberErr := readBuffer.ReadUint16("networkNumber", 16)
+	if _networkNumberErr != nil {
+		return nil, errors.Wrap(_networkNumberErr, "Error parsing 'networkNumber' field of NLMNetworkNumberIs")
+	}
+	networkNumber := _networkNumber
+
+	var reservedField0 *uint8
+	// Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+	{
+		reserved, _err := readBuffer.ReadUint8("reserved", 7)
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'reserved' field of NLMNetworkNumberIs")
+		}
+		if reserved != uint8(0) {
+			Plc4xModelLog.Info().Fields(map[string]interface{}{
+				"expected value": uint8(0),
+				"got value":      reserved,
+			}).Msg("Got unexpected response for reserved field.")
+			// We save the value, so it can be re-serialized
+			reservedField0 = &reserved
+		}
+	}
+
+	// Simple Field (networkNumberConfigured)
+	_networkNumberConfigured, _networkNumberConfiguredErr := readBuffer.ReadBit("networkNumberConfigured")
+	if _networkNumberConfiguredErr != nil {
+		return nil, errors.Wrap(_networkNumberConfiguredErr, "Error parsing 'networkNumberConfigured' field of NLMNetworkNumberIs")
+	}
+	networkNumberConfigured := _networkNumberConfigured
+
+	if closeErr := readBuffer.CloseContext("NLMNetworkNumberIs"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMNetworkNumberIs")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMNetworkNumberIs{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+		NetworkNumber:           networkNumber,
+		NetworkNumberConfigured: networkNumberConfigured,
+		reservedField0:          reservedField0,
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMNetworkNumberIs) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMNetworkNumberIs) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMNetworkNumberIs"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMNetworkNumberIs")
+		}
+
+		// Simple Field (networkNumber)
+		networkNumber := uint16(m.GetNetworkNumber())
+		_networkNumberErr := writeBuffer.WriteUint16("networkNumber", 16, (networkNumber))
+		if _networkNumberErr != nil {
+			return errors.Wrap(_networkNumberErr, "Error serializing 'networkNumber' field")
+		}
+
+		// Reserved Field (reserved)
+		{
+			var reserved uint8 = uint8(0)
+			if m.reservedField0 != nil {
+				Plc4xModelLog.Info().Fields(map[string]interface{}{
+					"expected value": uint8(0),
+					"got value":      reserved,
+				}).Msg("Overriding reserved field with unexpected value.")
+				reserved = *m.reservedField0
+			}
+			_err := writeBuffer.WriteUint8("reserved", 7, reserved)
+			if _err != nil {
+				return errors.Wrap(_err, "Error serializing 'reserved' field")
+			}
+		}
+
+		// Simple Field (networkNumberConfigured)
+		networkNumberConfigured := bool(m.GetNetworkNumberConfigured())
+		_networkNumberConfiguredErr := writeBuffer.WriteBit("networkNumberConfigured", (networkNumberConfigured))
+		if _networkNumberConfiguredErr != nil {
+			return errors.Wrap(_networkNumberConfiguredErr, "Error serializing 'networkNumberConfigured' field")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMNetworkNumberIs"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMNetworkNumberIs")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMNetworkNumberIs) isNLMNetworkNumberIs() bool {
+	return true
+}
+
+func (m *_NLMNetworkNumberIs) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMRejectRouterToNetwork.go b/plc4go/protocols/bacnetip/readwrite/model/NLMRejectRouterToNetwork.go
index c6f20818a9..aea4d731ff 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/NLMRejectRouterToNetwork.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMRejectRouterToNetwork.go
@@ -66,9 +66,7 @@ func (m *_NLMRejectRouterToNetwork) GetMessageType() uint8 {
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
-func (m *_NLMRejectRouterToNetwork) InitializeParent(parent NLM, vendorId *BACnetVendorId) {
-	m.VendorId = vendorId
-}
+func (m *_NLMRejectRouterToNetwork) InitializeParent(parent NLM) {}
 
 func (m *_NLMRejectRouterToNetwork) GetParent() NLM {
 	return m._NLM
@@ -93,11 +91,11 @@ func (m *_NLMRejectRouterToNetwork) GetDestinationNetworkAddress() uint16 {
 ///////////////////////////////////////////////////////////
 
 // NewNLMRejectRouterToNetwork factory function for _NLMRejectRouterToNetwork
-func NewNLMRejectRouterToNetwork(rejectReason NLMRejectRouterToNetworkRejectReason, destinationNetworkAddress uint16, vendorId *BACnetVendorId, apduLength uint16) *_NLMRejectRouterToNetwork {
+func NewNLMRejectRouterToNetwork(rejectReason NLMRejectRouterToNetworkRejectReason, destinationNetworkAddress uint16, apduLength uint16) *_NLMRejectRouterToNetwork {
 	_result := &_NLMRejectRouterToNetwork{
 		RejectReason:              rejectReason,
 		DestinationNetworkAddress: destinationNetworkAddress,
-		_NLM:                      NewNLM(vendorId, apduLength),
+		_NLM:                      NewNLM(apduLength),
 	}
 	_result._NLM._NLMChildRequirements = _result
 	return _result
@@ -138,11 +136,11 @@ func (m *_NLMRejectRouterToNetwork) GetLengthInBytes() uint16 {
 	return m.GetLengthInBits() / 8
 }
 
-func NLMRejectRouterToNetworkParse(theBytes []byte, apduLength uint16, messageType uint8) (NLMRejectRouterToNetwork, error) {
-	return NLMRejectRouterToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength, messageType) // TODO: get endianness from mspec
+func NLMRejectRouterToNetworkParse(theBytes []byte, apduLength uint16) (NLMRejectRouterToNetwork, error) {
+	return NLMRejectRouterToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
 }
 
-func NLMRejectRouterToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16, messageType uint8) (NLMRejectRouterToNetwork, error) {
+func NLMRejectRouterToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMRejectRouterToNetwork, error) {
 	positionAware := readBuffer
 	_ = positionAware
 	if pullErr := readBuffer.PullContext("NLMRejectRouterToNetwork"); pullErr != nil {
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMRequestKeyUpdate.go b/plc4go/protocols/bacnetip/readwrite/model/NLMRequestKeyUpdate.go
new file mode 100644
index 0000000000..068fa6cd4d
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMRequestKeyUpdate.go
@@ -0,0 +1,363 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMRequestKeyUpdate is the corresponding interface of NLMRequestKeyUpdate
+type NLMRequestKeyUpdate interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+	// GetSet1KeyRevision returns Set1KeyRevision (property field)
+	GetSet1KeyRevision() byte
+	// GetSet1ActivationTime returns Set1ActivationTime (property field)
+	GetSet1ActivationTime() uint32
+	// GetSet1ExpirationTime returns Set1ExpirationTime (property field)
+	GetSet1ExpirationTime() uint32
+	// GetSet2KeyRevision returns Set2KeyRevision (property field)
+	GetSet2KeyRevision() byte
+	// GetSet2ActivationTime returns Set2ActivationTime (property field)
+	GetSet2ActivationTime() uint32
+	// GetSet2ExpirationTime returns Set2ExpirationTime (property field)
+	GetSet2ExpirationTime() uint32
+	// GetDistributionKeyRevision returns DistributionKeyRevision (property field)
+	GetDistributionKeyRevision() byte
+}
+
+// NLMRequestKeyUpdateExactly can be used when we want exactly this type and not a type which fulfills NLMRequestKeyUpdate.
+// This is useful for switch cases.
+type NLMRequestKeyUpdateExactly interface {
+	NLMRequestKeyUpdate
+	isNLMRequestKeyUpdate() bool
+}
+
+// _NLMRequestKeyUpdate is the data-structure of this message
+type _NLMRequestKeyUpdate struct {
+	*_NLM
+	Set1KeyRevision         byte
+	Set1ActivationTime      uint32
+	Set1ExpirationTime      uint32
+	Set2KeyRevision         byte
+	Set2ActivationTime      uint32
+	Set2ExpirationTime      uint32
+	DistributionKeyRevision byte
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMRequestKeyUpdate) GetMessageType() uint8 {
+	return 0x0D
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMRequestKeyUpdate) InitializeParent(parent NLM) {}
+
+func (m *_NLMRequestKeyUpdate) GetParent() NLM {
+	return m._NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMRequestKeyUpdate) GetSet1KeyRevision() byte {
+	return m.Set1KeyRevision
+}
+
+func (m *_NLMRequestKeyUpdate) GetSet1ActivationTime() uint32 {
+	return m.Set1ActivationTime
+}
+
+func (m *_NLMRequestKeyUpdate) GetSet1ExpirationTime() uint32 {
+	return m.Set1ExpirationTime
+}
+
+func (m *_NLMRequestKeyUpdate) GetSet2KeyRevision() byte {
+	return m.Set2KeyRevision
+}
+
+func (m *_NLMRequestKeyUpdate) GetSet2ActivationTime() uint32 {
+	return m.Set2ActivationTime
+}
+
+func (m *_NLMRequestKeyUpdate) GetSet2ExpirationTime() uint32 {
+	return m.Set2ExpirationTime
+}
+
+func (m *_NLMRequestKeyUpdate) GetDistributionKeyRevision() byte {
+	return m.DistributionKeyRevision
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMRequestKeyUpdate factory function for _NLMRequestKeyUpdate
+func NewNLMRequestKeyUpdate(set1KeyRevision byte, set1ActivationTime uint32, set1ExpirationTime uint32, set2KeyRevision byte, set2ActivationTime uint32, set2ExpirationTime uint32, distributionKeyRevision byte, apduLength uint16) *_NLMRequestKeyUpdate {
+	_result := &_NLMRequestKeyUpdate{
+		Set1KeyRevision:         set1KeyRevision,
+		Set1ActivationTime:      set1ActivationTime,
+		Set1ExpirationTime:      set1ExpirationTime,
+		Set2KeyRevision:         set2KeyRevision,
+		Set2ActivationTime:      set2ActivationTime,
+		Set2ExpirationTime:      set2ExpirationTime,
+		DistributionKeyRevision: distributionKeyRevision,
+		_NLM:                    NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMRequestKeyUpdate(structType interface{}) NLMRequestKeyUpdate {
+	if casted, ok := structType.(NLMRequestKeyUpdate); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMRequestKeyUpdate); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMRequestKeyUpdate) GetTypeName() string {
+	return "NLMRequestKeyUpdate"
+}
+
+func (m *_NLMRequestKeyUpdate) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMRequestKeyUpdate) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (set1KeyRevision)
+	lengthInBits += 8
+
+	// Simple field (set1ActivationTime)
+	lengthInBits += 32
+
+	// Simple field (set1ExpirationTime)
+	lengthInBits += 32
+
+	// Simple field (set2KeyRevision)
+	lengthInBits += 8
+
+	// Simple field (set2ActivationTime)
+	lengthInBits += 32
+
+	// Simple field (set2ExpirationTime)
+	lengthInBits += 32
+
+	// Simple field (distributionKeyRevision)
+	lengthInBits += 8
+
+	return lengthInBits
+}
+
+func (m *_NLMRequestKeyUpdate) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMRequestKeyUpdateParse(theBytes []byte, apduLength uint16) (NLMRequestKeyUpdate, error) {
+	return NLMRequestKeyUpdateParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMRequestKeyUpdateParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMRequestKeyUpdate, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMRequestKeyUpdate"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMRequestKeyUpdate")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (set1KeyRevision)
+	_set1KeyRevision, _set1KeyRevisionErr := readBuffer.ReadByte("set1KeyRevision")
+	if _set1KeyRevisionErr != nil {
+		return nil, errors.Wrap(_set1KeyRevisionErr, "Error parsing 'set1KeyRevision' field of NLMRequestKeyUpdate")
+	}
+	set1KeyRevision := _set1KeyRevision
+
+	// Simple Field (set1ActivationTime)
+	_set1ActivationTime, _set1ActivationTimeErr := readBuffer.ReadUint32("set1ActivationTime", 32)
+	if _set1ActivationTimeErr != nil {
+		return nil, errors.Wrap(_set1ActivationTimeErr, "Error parsing 'set1ActivationTime' field of NLMRequestKeyUpdate")
+	}
+	set1ActivationTime := _set1ActivationTime
+
+	// Simple Field (set1ExpirationTime)
+	_set1ExpirationTime, _set1ExpirationTimeErr := readBuffer.ReadUint32("set1ExpirationTime", 32)
+	if _set1ExpirationTimeErr != nil {
+		return nil, errors.Wrap(_set1ExpirationTimeErr, "Error parsing 'set1ExpirationTime' field of NLMRequestKeyUpdate")
+	}
+	set1ExpirationTime := _set1ExpirationTime
+
+	// Simple Field (set2KeyRevision)
+	_set2KeyRevision, _set2KeyRevisionErr := readBuffer.ReadByte("set2KeyRevision")
+	if _set2KeyRevisionErr != nil {
+		return nil, errors.Wrap(_set2KeyRevisionErr, "Error parsing 'set2KeyRevision' field of NLMRequestKeyUpdate")
+	}
+	set2KeyRevision := _set2KeyRevision
+
+	// Simple Field (set2ActivationTime)
+	_set2ActivationTime, _set2ActivationTimeErr := readBuffer.ReadUint32("set2ActivationTime", 32)
+	if _set2ActivationTimeErr != nil {
+		return nil, errors.Wrap(_set2ActivationTimeErr, "Error parsing 'set2ActivationTime' field of NLMRequestKeyUpdate")
+	}
+	set2ActivationTime := _set2ActivationTime
+
+	// Simple Field (set2ExpirationTime)
+	_set2ExpirationTime, _set2ExpirationTimeErr := readBuffer.ReadUint32("set2ExpirationTime", 32)
+	if _set2ExpirationTimeErr != nil {
+		return nil, errors.Wrap(_set2ExpirationTimeErr, "Error parsing 'set2ExpirationTime' field of NLMRequestKeyUpdate")
+	}
+	set2ExpirationTime := _set2ExpirationTime
+
+	// Simple Field (distributionKeyRevision)
+	_distributionKeyRevision, _distributionKeyRevisionErr := readBuffer.ReadByte("distributionKeyRevision")
+	if _distributionKeyRevisionErr != nil {
+		return nil, errors.Wrap(_distributionKeyRevisionErr, "Error parsing 'distributionKeyRevision' field of NLMRequestKeyUpdate")
+	}
+	distributionKeyRevision := _distributionKeyRevision
+
+	if closeErr := readBuffer.CloseContext("NLMRequestKeyUpdate"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMRequestKeyUpdate")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMRequestKeyUpdate{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+		Set1KeyRevision:         set1KeyRevision,
+		Set1ActivationTime:      set1ActivationTime,
+		Set1ExpirationTime:      set1ExpirationTime,
+		Set2KeyRevision:         set2KeyRevision,
+		Set2ActivationTime:      set2ActivationTime,
+		Set2ExpirationTime:      set2ExpirationTime,
+		DistributionKeyRevision: distributionKeyRevision,
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMRequestKeyUpdate) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMRequestKeyUpdate) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMRequestKeyUpdate"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMRequestKeyUpdate")
+		}
+
+		// Simple Field (set1KeyRevision)
+		set1KeyRevision := byte(m.GetSet1KeyRevision())
+		_set1KeyRevisionErr := writeBuffer.WriteByte("set1KeyRevision", (set1KeyRevision))
+		if _set1KeyRevisionErr != nil {
+			return errors.Wrap(_set1KeyRevisionErr, "Error serializing 'set1KeyRevision' field")
+		}
+
+		// Simple Field (set1ActivationTime)
+		set1ActivationTime := uint32(m.GetSet1ActivationTime())
+		_set1ActivationTimeErr := writeBuffer.WriteUint32("set1ActivationTime", 32, (set1ActivationTime))
+		if _set1ActivationTimeErr != nil {
+			return errors.Wrap(_set1ActivationTimeErr, "Error serializing 'set1ActivationTime' field")
+		}
+
+		// Simple Field (set1ExpirationTime)
+		set1ExpirationTime := uint32(m.GetSet1ExpirationTime())
+		_set1ExpirationTimeErr := writeBuffer.WriteUint32("set1ExpirationTime", 32, (set1ExpirationTime))
+		if _set1ExpirationTimeErr != nil {
+			return errors.Wrap(_set1ExpirationTimeErr, "Error serializing 'set1ExpirationTime' field")
+		}
+
+		// Simple Field (set2KeyRevision)
+		set2KeyRevision := byte(m.GetSet2KeyRevision())
+		_set2KeyRevisionErr := writeBuffer.WriteByte("set2KeyRevision", (set2KeyRevision))
+		if _set2KeyRevisionErr != nil {
+			return errors.Wrap(_set2KeyRevisionErr, "Error serializing 'set2KeyRevision' field")
+		}
+
+		// Simple Field (set2ActivationTime)
+		set2ActivationTime := uint32(m.GetSet2ActivationTime())
+		_set2ActivationTimeErr := writeBuffer.WriteUint32("set2ActivationTime", 32, (set2ActivationTime))
+		if _set2ActivationTimeErr != nil {
+			return errors.Wrap(_set2ActivationTimeErr, "Error serializing 'set2ActivationTime' field")
+		}
+
+		// Simple Field (set2ExpirationTime)
+		set2ExpirationTime := uint32(m.GetSet2ExpirationTime())
+		_set2ExpirationTimeErr := writeBuffer.WriteUint32("set2ExpirationTime", 32, (set2ExpirationTime))
+		if _set2ExpirationTimeErr != nil {
+			return errors.Wrap(_set2ExpirationTimeErr, "Error serializing 'set2ExpirationTime' field")
+		}
+
+		// Simple Field (distributionKeyRevision)
+		distributionKeyRevision := byte(m.GetDistributionKeyRevision())
+		_distributionKeyRevisionErr := writeBuffer.WriteByte("distributionKeyRevision", (distributionKeyRevision))
+		if _distributionKeyRevisionErr != nil {
+			return errors.Wrap(_distributionKeyRevisionErr, "Error serializing 'distributionKeyRevision' field")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMRequestKeyUpdate"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMRequestKeyUpdate")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMRequestKeyUpdate) isNLMRequestKeyUpdate() bool {
+	return true
+}
+
+func (m *_NLMRequestKeyUpdate) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMRequestMasterKey.go b/plc4go/protocols/bacnetip/readwrite/model/NLMRequestMasterKey.go
new file mode 100644
index 0000000000..39574697b1
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMRequestMasterKey.go
@@ -0,0 +1,233 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMRequestMasterKey is the corresponding interface of NLMRequestMasterKey
+type NLMRequestMasterKey interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+	// GetNumberOfSupportedKeyAlgorithms returns NumberOfSupportedKeyAlgorithms (property field)
+	GetNumberOfSupportedKeyAlgorithms() uint8
+	// GetEncryptionAndSignatureAlgorithms returns EncryptionAndSignatureAlgorithms (property field)
+	GetEncryptionAndSignatureAlgorithms() []byte
+}
+
+// NLMRequestMasterKeyExactly can be used when we want exactly this type and not a type which fulfills NLMRequestMasterKey.
+// This is useful for switch cases.
+type NLMRequestMasterKeyExactly interface {
+	NLMRequestMasterKey
+	isNLMRequestMasterKey() bool
+}
+
+// _NLMRequestMasterKey is the data-structure of this message
+type _NLMRequestMasterKey struct {
+	*_NLM
+	NumberOfSupportedKeyAlgorithms   uint8
+	EncryptionAndSignatureAlgorithms []byte
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMRequestMasterKey) GetMessageType() uint8 {
+	return 0x10
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMRequestMasterKey) InitializeParent(parent NLM) {}
+
+func (m *_NLMRequestMasterKey) GetParent() NLM {
+	return m._NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMRequestMasterKey) GetNumberOfSupportedKeyAlgorithms() uint8 {
+	return m.NumberOfSupportedKeyAlgorithms
+}
+
+func (m *_NLMRequestMasterKey) GetEncryptionAndSignatureAlgorithms() []byte {
+	return m.EncryptionAndSignatureAlgorithms
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMRequestMasterKey factory function for _NLMRequestMasterKey
+func NewNLMRequestMasterKey(numberOfSupportedKeyAlgorithms uint8, encryptionAndSignatureAlgorithms []byte, apduLength uint16) *_NLMRequestMasterKey {
+	_result := &_NLMRequestMasterKey{
+		NumberOfSupportedKeyAlgorithms:   numberOfSupportedKeyAlgorithms,
+		EncryptionAndSignatureAlgorithms: encryptionAndSignatureAlgorithms,
+		_NLM:                             NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMRequestMasterKey(structType interface{}) NLMRequestMasterKey {
+	if casted, ok := structType.(NLMRequestMasterKey); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMRequestMasterKey); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMRequestMasterKey) GetTypeName() string {
+	return "NLMRequestMasterKey"
+}
+
+func (m *_NLMRequestMasterKey) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMRequestMasterKey) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (numberOfSupportedKeyAlgorithms)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.EncryptionAndSignatureAlgorithms) > 0 {
+		lengthInBits += 8 * uint16(len(m.EncryptionAndSignatureAlgorithms))
+	}
+
+	return lengthInBits
+}
+
+func (m *_NLMRequestMasterKey) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMRequestMasterKeyParse(theBytes []byte, apduLength uint16) (NLMRequestMasterKey, error) {
+	return NLMRequestMasterKeyParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMRequestMasterKeyParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMRequestMasterKey, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMRequestMasterKey"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMRequestMasterKey")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (numberOfSupportedKeyAlgorithms)
+	_numberOfSupportedKeyAlgorithms, _numberOfSupportedKeyAlgorithmsErr := readBuffer.ReadUint8("numberOfSupportedKeyAlgorithms", 8)
+	if _numberOfSupportedKeyAlgorithmsErr != nil {
+		return nil, errors.Wrap(_numberOfSupportedKeyAlgorithmsErr, "Error parsing 'numberOfSupportedKeyAlgorithms' field of NLMRequestMasterKey")
+	}
+	numberOfSupportedKeyAlgorithms := _numberOfSupportedKeyAlgorithms
+	// Byte Array field (encryptionAndSignatureAlgorithms)
+	numberOfBytesencryptionAndSignatureAlgorithms := int(uint16(apduLength) - uint16(uint16(2)))
+	encryptionAndSignatureAlgorithms, _readArrayErr := readBuffer.ReadByteArray("encryptionAndSignatureAlgorithms", numberOfBytesencryptionAndSignatureAlgorithms)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'encryptionAndSignatureAlgorithms' field of NLMRequestMasterKey")
+	}
+
+	if closeErr := readBuffer.CloseContext("NLMRequestMasterKey"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMRequestMasterKey")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMRequestMasterKey{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+		NumberOfSupportedKeyAlgorithms:   numberOfSupportedKeyAlgorithms,
+		EncryptionAndSignatureAlgorithms: encryptionAndSignatureAlgorithms,
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMRequestMasterKey) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMRequestMasterKey) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMRequestMasterKey"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMRequestMasterKey")
+		}
+
+		// Simple Field (numberOfSupportedKeyAlgorithms)
+		numberOfSupportedKeyAlgorithms := uint8(m.GetNumberOfSupportedKeyAlgorithms())
+		_numberOfSupportedKeyAlgorithmsErr := writeBuffer.WriteUint8("numberOfSupportedKeyAlgorithms", 8, (numberOfSupportedKeyAlgorithms))
+		if _numberOfSupportedKeyAlgorithmsErr != nil {
+			return errors.Wrap(_numberOfSupportedKeyAlgorithmsErr, "Error serializing 'numberOfSupportedKeyAlgorithms' field")
+		}
+
+		// Array Field (encryptionAndSignatureAlgorithms)
+		// Byte Array field (encryptionAndSignatureAlgorithms)
+		if err := writeBuffer.WriteByteArray("encryptionAndSignatureAlgorithms", m.GetEncryptionAndSignatureAlgorithms()); err != nil {
+			return errors.Wrap(err, "Error serializing 'encryptionAndSignatureAlgorithms' field")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMRequestMasterKey"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMRequestMasterKey")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMRequestMasterKey) isNLMRequestMasterKey() bool {
+	return true
+}
+
+func (m *_NLMRequestMasterKey) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMReserved.go b/plc4go/protocols/bacnetip/readwrite/model/NLMReserved.go
new file mode 100644
index 0000000000..af2e08fa92
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMReserved.go
@@ -0,0 +1,207 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMReserved is the corresponding interface of NLMReserved
+type NLMReserved interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+	// GetUnknownBytes returns UnknownBytes (property field)
+	GetUnknownBytes() []byte
+}
+
+// NLMReservedExactly can be used when we want exactly this type and not a type which fulfills NLMReserved.
+// This is useful for switch cases.
+type NLMReservedExactly interface {
+	NLMReserved
+	isNLMReserved() bool
+}
+
+// _NLMReserved is the data-structure of this message
+type _NLMReserved struct {
+	*_NLM
+	UnknownBytes []byte
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMReserved) GetMessageType() uint8 {
+	return 0
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMReserved) InitializeParent(parent NLM) {}
+
+func (m *_NLMReserved) GetParent() NLM {
+	return m._NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMReserved) GetUnknownBytes() []byte {
+	return m.UnknownBytes
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMReserved factory function for _NLMReserved
+func NewNLMReserved(unknownBytes []byte, apduLength uint16) *_NLMReserved {
+	_result := &_NLMReserved{
+		UnknownBytes: unknownBytes,
+		_NLM:         NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMReserved(structType interface{}) NLMReserved {
+	if casted, ok := structType.(NLMReserved); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMReserved); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMReserved) GetTypeName() string {
+	return "NLMReserved"
+}
+
+func (m *_NLMReserved) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMReserved) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Array field
+	if len(m.UnknownBytes) > 0 {
+		lengthInBits += 8 * uint16(len(m.UnknownBytes))
+	}
+
+	return lengthInBits
+}
+
+func (m *_NLMReserved) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMReservedParse(theBytes []byte, apduLength uint16) (NLMReserved, error) {
+	return NLMReservedParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMReservedParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMReserved, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMReserved"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMReserved")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+	// Byte Array field (unknownBytes)
+	numberOfBytesunknownBytes := int(utils.InlineIf((bool((apduLength) > (0))), func() interface{} { return uint16((uint16(apduLength) - uint16(uint16(1)))) }, func() interface{} { return uint16(uint16(0)) }).(uint16))
+	unknownBytes, _readArrayErr := readBuffer.ReadByteArray("unknownBytes", numberOfBytesunknownBytes)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'unknownBytes' field of NLMReserved")
+	}
+
+	if closeErr := readBuffer.CloseContext("NLMReserved"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMReserved")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMReserved{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+		UnknownBytes: unknownBytes,
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMReserved) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMReserved) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMReserved"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMReserved")
+		}
+
+		// Array Field (unknownBytes)
+		// Byte Array field (unknownBytes)
+		if err := writeBuffer.WriteByteArray("unknownBytes", m.GetUnknownBytes()); err != nil {
+			return errors.Wrap(err, "Error serializing 'unknownBytes' field")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMReserved"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMReserved")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMReserved) isNLMReserved() bool {
+	return true
+}
+
+func (m *_NLMReserved) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMRouterAvailableToNetwork.go b/plc4go/protocols/bacnetip/readwrite/model/NLMRouterAvailableToNetwork.go
index 142ad0b6eb..a748a33faf 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/NLMRouterAvailableToNetwork.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMRouterAvailableToNetwork.go
@@ -63,9 +63,7 @@ func (m *_NLMRouterAvailableToNetwork) GetMessageType() uint8 {
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
-func (m *_NLMRouterAvailableToNetwork) InitializeParent(parent NLM, vendorId *BACnetVendorId) {
-	m.VendorId = vendorId
-}
+func (m *_NLMRouterAvailableToNetwork) InitializeParent(parent NLM) {}
 
 func (m *_NLMRouterAvailableToNetwork) GetParent() NLM {
 	return m._NLM
@@ -86,10 +84,10 @@ func (m *_NLMRouterAvailableToNetwork) GetDestinationNetworkAddress() []uint16 {
 ///////////////////////////////////////////////////////////
 
 // NewNLMRouterAvailableToNetwork factory function for _NLMRouterAvailableToNetwork
-func NewNLMRouterAvailableToNetwork(destinationNetworkAddress []uint16, vendorId *BACnetVendorId, apduLength uint16) *_NLMRouterAvailableToNetwork {
+func NewNLMRouterAvailableToNetwork(destinationNetworkAddress []uint16, apduLength uint16) *_NLMRouterAvailableToNetwork {
 	_result := &_NLMRouterAvailableToNetwork{
 		DestinationNetworkAddress: destinationNetworkAddress,
-		_NLM:                      NewNLM(vendorId, apduLength),
+		_NLM:                      NewNLM(apduLength),
 	}
 	_result._NLM._NLMChildRequirements = _result
 	return _result
@@ -129,11 +127,11 @@ func (m *_NLMRouterAvailableToNetwork) GetLengthInBytes() uint16 {
 	return m.GetLengthInBits() / 8
 }
 
-func NLMRouterAvailableToNetworkParse(theBytes []byte, apduLength uint16, messageType uint8) (NLMRouterAvailableToNetwork, error) {
-	return NLMRouterAvailableToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength, messageType) // TODO: get endianness from mspec
+func NLMRouterAvailableToNetworkParse(theBytes []byte, apduLength uint16) (NLMRouterAvailableToNetwork, error) {
+	return NLMRouterAvailableToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
 }
 
-func NLMRouterAvailableToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16, messageType uint8) (NLMRouterAvailableToNetwork, error) {
+func NLMRouterAvailableToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMRouterAvailableToNetwork, error) {
 	positionAware := readBuffer
 	_ = positionAware
 	if pullErr := readBuffer.PullContext("NLMRouterAvailableToNetwork"); pullErr != nil {
@@ -149,7 +147,7 @@ func NLMRouterAvailableToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apd
 	// Length array
 	var destinationNetworkAddress []uint16
 	{
-		_destinationNetworkAddressLength := uint16(apduLength) - uint16((utils.InlineIf((bool((bool((messageType) >= (128)))) && bool((bool((messageType) <= (255))))), func() interface{} { return uint16(uint16(3)) }, func() interface{} { return uint16(uint16(1)) }).(uint16)))
+		_destinationNetworkAddressLength := uint16(apduLength) - uint16(uint16(1))
 		_destinationNetworkAddressEndPos := positionAware.GetPos() + uint16(_destinationNetworkAddressLength)
 		for positionAware.GetPos() < _destinationNetworkAddressEndPos {
 			_item, _err := readBuffer.ReadUint16("", 16)
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMRouterBusyToNetwork.go b/plc4go/protocols/bacnetip/readwrite/model/NLMRouterBusyToNetwork.go
index a6325f9471..5ebb2f8198 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/NLMRouterBusyToNetwork.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMRouterBusyToNetwork.go
@@ -63,9 +63,7 @@ func (m *_NLMRouterBusyToNetwork) GetMessageType() uint8 {
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
-func (m *_NLMRouterBusyToNetwork) InitializeParent(parent NLM, vendorId *BACnetVendorId) {
-	m.VendorId = vendorId
-}
+func (m *_NLMRouterBusyToNetwork) InitializeParent(parent NLM) {}
 
 func (m *_NLMRouterBusyToNetwork) GetParent() NLM {
 	return m._NLM
@@ -86,10 +84,10 @@ func (m *_NLMRouterBusyToNetwork) GetDestinationNetworkAddress() []uint16 {
 ///////////////////////////////////////////////////////////
 
 // NewNLMRouterBusyToNetwork factory function for _NLMRouterBusyToNetwork
-func NewNLMRouterBusyToNetwork(destinationNetworkAddress []uint16, vendorId *BACnetVendorId, apduLength uint16) *_NLMRouterBusyToNetwork {
+func NewNLMRouterBusyToNetwork(destinationNetworkAddress []uint16, apduLength uint16) *_NLMRouterBusyToNetwork {
 	_result := &_NLMRouterBusyToNetwork{
 		DestinationNetworkAddress: destinationNetworkAddress,
-		_NLM:                      NewNLM(vendorId, apduLength),
+		_NLM:                      NewNLM(apduLength),
 	}
 	_result._NLM._NLMChildRequirements = _result
 	return _result
@@ -129,11 +127,11 @@ func (m *_NLMRouterBusyToNetwork) GetLengthInBytes() uint16 {
 	return m.GetLengthInBits() / 8
 }
 
-func NLMRouterBusyToNetworkParse(theBytes []byte, apduLength uint16, messageType uint8) (NLMRouterBusyToNetwork, error) {
-	return NLMRouterBusyToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength, messageType) // TODO: get endianness from mspec
+func NLMRouterBusyToNetworkParse(theBytes []byte, apduLength uint16) (NLMRouterBusyToNetwork, error) {
+	return NLMRouterBusyToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
 }
 
-func NLMRouterBusyToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16, messageType uint8) (NLMRouterBusyToNetwork, error) {
+func NLMRouterBusyToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMRouterBusyToNetwork, error) {
 	positionAware := readBuffer
 	_ = positionAware
 	if pullErr := readBuffer.PullContext("NLMRouterBusyToNetwork"); pullErr != nil {
@@ -149,7 +147,7 @@ func NLMRouterBusyToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLeng
 	// Length array
 	var destinationNetworkAddress []uint16
 	{
-		_destinationNetworkAddressLength := uint16(apduLength) - uint16((utils.InlineIf((bool((bool((messageType) >= (128)))) && bool((bool((messageType) <= (255))))), func() interface{} { return uint16(uint16(3)) }, func() interface{} { return uint16(uint16(1)) }).(uint16)))
+		_destinationNetworkAddressLength := uint16(apduLength) - uint16(uint16(1))
 		_destinationNetworkAddressEndPos := positionAware.GetPos() + uint16(_destinationNetworkAddressLength)
 		for positionAware.GetPos() < _destinationNetworkAddressEndPos {
 			_item, _err := readBuffer.ReadUint16("", 16)
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMSecurityPayload.go b/plc4go/protocols/bacnetip/readwrite/model/NLMSecurityPayload.go
new file mode 100644
index 0000000000..39a70261cd
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMSecurityPayload.go
@@ -0,0 +1,233 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMSecurityPayload is the corresponding interface of NLMSecurityPayload
+type NLMSecurityPayload interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+	// GetPayloadLength returns PayloadLength (property field)
+	GetPayloadLength() uint16
+	// GetPayload returns Payload (property field)
+	GetPayload() []byte
+}
+
+// NLMSecurityPayloadExactly can be used when we want exactly this type and not a type which fulfills NLMSecurityPayload.
+// This is useful for switch cases.
+type NLMSecurityPayloadExactly interface {
+	NLMSecurityPayload
+	isNLMSecurityPayload() bool
+}
+
+// _NLMSecurityPayload is the data-structure of this message
+type _NLMSecurityPayload struct {
+	*_NLM
+	PayloadLength uint16
+	Payload       []byte
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMSecurityPayload) GetMessageType() uint8 {
+	return 0x0B
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMSecurityPayload) InitializeParent(parent NLM) {}
+
+func (m *_NLMSecurityPayload) GetParent() NLM {
+	return m._NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMSecurityPayload) GetPayloadLength() uint16 {
+	return m.PayloadLength
+}
+
+func (m *_NLMSecurityPayload) GetPayload() []byte {
+	return m.Payload
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMSecurityPayload factory function for _NLMSecurityPayload
+func NewNLMSecurityPayload(payloadLength uint16, payload []byte, apduLength uint16) *_NLMSecurityPayload {
+	_result := &_NLMSecurityPayload{
+		PayloadLength: payloadLength,
+		Payload:       payload,
+		_NLM:          NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMSecurityPayload(structType interface{}) NLMSecurityPayload {
+	if casted, ok := structType.(NLMSecurityPayload); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMSecurityPayload); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMSecurityPayload) GetTypeName() string {
+	return "NLMSecurityPayload"
+}
+
+func (m *_NLMSecurityPayload) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMSecurityPayload) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (payloadLength)
+	lengthInBits += 16
+
+	// Array field
+	if len(m.Payload) > 0 {
+		lengthInBits += 8 * uint16(len(m.Payload))
+	}
+
+	return lengthInBits
+}
+
+func (m *_NLMSecurityPayload) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMSecurityPayloadParse(theBytes []byte, apduLength uint16) (NLMSecurityPayload, error) {
+	return NLMSecurityPayloadParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMSecurityPayloadParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMSecurityPayload, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMSecurityPayload"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMSecurityPayload")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (payloadLength)
+	_payloadLength, _payloadLengthErr := readBuffer.ReadUint16("payloadLength", 16)
+	if _payloadLengthErr != nil {
+		return nil, errors.Wrap(_payloadLengthErr, "Error parsing 'payloadLength' field of NLMSecurityPayload")
+	}
+	payloadLength := _payloadLength
+	// Byte Array field (payload)
+	numberOfBytespayload := int(payloadLength)
+	payload, _readArrayErr := readBuffer.ReadByteArray("payload", numberOfBytespayload)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'payload' field of NLMSecurityPayload")
+	}
+
+	if closeErr := readBuffer.CloseContext("NLMSecurityPayload"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMSecurityPayload")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMSecurityPayload{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+		PayloadLength: payloadLength,
+		Payload:       payload,
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMSecurityPayload) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMSecurityPayload) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMSecurityPayload"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMSecurityPayload")
+		}
+
+		// Simple Field (payloadLength)
+		payloadLength := uint16(m.GetPayloadLength())
+		_payloadLengthErr := writeBuffer.WriteUint16("payloadLength", 16, (payloadLength))
+		if _payloadLengthErr != nil {
+			return errors.Wrap(_payloadLengthErr, "Error serializing 'payloadLength' field")
+		}
+
+		// Array Field (payload)
+		// Byte Array field (payload)
+		if err := writeBuffer.WriteByteArray("payload", m.GetPayload()); err != nil {
+			return errors.Wrap(err, "Error serializing 'payload' field")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMSecurityPayload"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMSecurityPayload")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMSecurityPayload) isNLMSecurityPayload() bool {
+	return true
+}
+
+func (m *_NLMSecurityPayload) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMSecurityResponse.go b/plc4go/protocols/bacnetip/readwrite/model/NLMSecurityResponse.go
new file mode 100644
index 0000000000..83f4534410
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMSecurityResponse.go
@@ -0,0 +1,296 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMSecurityResponse is the corresponding interface of NLMSecurityResponse
+type NLMSecurityResponse interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+	// GetResponseCode returns ResponseCode (property field)
+	GetResponseCode() SecurityResponseCode
+	// GetOriginalMessageId returns OriginalMessageId (property field)
+	GetOriginalMessageId() uint32
+	// GetOriginalTimestamp returns OriginalTimestamp (property field)
+	GetOriginalTimestamp() uint32
+	// GetVariableParameters returns VariableParameters (property field)
+	GetVariableParameters() []byte
+}
+
+// NLMSecurityResponseExactly can be used when we want exactly this type and not a type which fulfills NLMSecurityResponse.
+// This is useful for switch cases.
+type NLMSecurityResponseExactly interface {
+	NLMSecurityResponse
+	isNLMSecurityResponse() bool
+}
+
+// _NLMSecurityResponse is the data-structure of this message
+type _NLMSecurityResponse struct {
+	*_NLM
+	ResponseCode       SecurityResponseCode
+	OriginalMessageId  uint32
+	OriginalTimestamp  uint32
+	VariableParameters []byte
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMSecurityResponse) GetMessageType() uint8 {
+	return 0x0C
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMSecurityResponse) InitializeParent(parent NLM) {}
+
+func (m *_NLMSecurityResponse) GetParent() NLM {
+	return m._NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMSecurityResponse) GetResponseCode() SecurityResponseCode {
+	return m.ResponseCode
+}
+
+func (m *_NLMSecurityResponse) GetOriginalMessageId() uint32 {
+	return m.OriginalMessageId
+}
+
+func (m *_NLMSecurityResponse) GetOriginalTimestamp() uint32 {
+	return m.OriginalTimestamp
+}
+
+func (m *_NLMSecurityResponse) GetVariableParameters() []byte {
+	return m.VariableParameters
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMSecurityResponse factory function for _NLMSecurityResponse
+func NewNLMSecurityResponse(responseCode SecurityResponseCode, originalMessageId uint32, originalTimestamp uint32, variableParameters []byte, apduLength uint16) *_NLMSecurityResponse {
+	_result := &_NLMSecurityResponse{
+		ResponseCode:       responseCode,
+		OriginalMessageId:  originalMessageId,
+		OriginalTimestamp:  originalTimestamp,
+		VariableParameters: variableParameters,
+		_NLM:               NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMSecurityResponse(structType interface{}) NLMSecurityResponse {
+	if casted, ok := structType.(NLMSecurityResponse); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMSecurityResponse); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMSecurityResponse) GetTypeName() string {
+	return "NLMSecurityResponse"
+}
+
+func (m *_NLMSecurityResponse) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMSecurityResponse) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (responseCode)
+	lengthInBits += 8
+
+	// Simple field (originalMessageId)
+	lengthInBits += 32
+
+	// Simple field (originalTimestamp)
+	lengthInBits += 32
+
+	// Array field
+	if len(m.VariableParameters) > 0 {
+		lengthInBits += 8 * uint16(len(m.VariableParameters))
+	}
+
+	return lengthInBits
+}
+
+func (m *_NLMSecurityResponse) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMSecurityResponseParse(theBytes []byte, apduLength uint16) (NLMSecurityResponse, error) {
+	return NLMSecurityResponseParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMSecurityResponseParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMSecurityResponse, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMSecurityResponse"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMSecurityResponse")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (responseCode)
+	if pullErr := readBuffer.PullContext("responseCode"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for responseCode")
+	}
+	_responseCode, _responseCodeErr := SecurityResponseCodeParseWithBuffer(readBuffer)
+	if _responseCodeErr != nil {
+		return nil, errors.Wrap(_responseCodeErr, "Error parsing 'responseCode' field of NLMSecurityResponse")
+	}
+	responseCode := _responseCode
+	if closeErr := readBuffer.CloseContext("responseCode"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for responseCode")
+	}
+
+	// Simple Field (originalMessageId)
+	_originalMessageId, _originalMessageIdErr := readBuffer.ReadUint32("originalMessageId", 32)
+	if _originalMessageIdErr != nil {
+		return nil, errors.Wrap(_originalMessageIdErr, "Error parsing 'originalMessageId' field of NLMSecurityResponse")
+	}
+	originalMessageId := _originalMessageId
+
+	// Simple Field (originalTimestamp)
+	_originalTimestamp, _originalTimestampErr := readBuffer.ReadUint32("originalTimestamp", 32)
+	if _originalTimestampErr != nil {
+		return nil, errors.Wrap(_originalTimestampErr, "Error parsing 'originalTimestamp' field of NLMSecurityResponse")
+	}
+	originalTimestamp := _originalTimestamp
+	// Byte Array field (variableParameters)
+	numberOfBytesvariableParameters := int(uint16(apduLength) - uint16((uint16(uint16(uint16(uint16(1))+uint16(uint16(1)))+uint16(uint16(4))) + uint16(uint16(4)))))
+	variableParameters, _readArrayErr := readBuffer.ReadByteArray("variableParameters", numberOfBytesvariableParameters)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'variableParameters' field of NLMSecurityResponse")
+	}
+
+	if closeErr := readBuffer.CloseContext("NLMSecurityResponse"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMSecurityResponse")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMSecurityResponse{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+		ResponseCode:       responseCode,
+		OriginalMessageId:  originalMessageId,
+		OriginalTimestamp:  originalTimestamp,
+		VariableParameters: variableParameters,
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMSecurityResponse) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMSecurityResponse) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMSecurityResponse"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMSecurityResponse")
+		}
+
+		// Simple Field (responseCode)
+		if pushErr := writeBuffer.PushContext("responseCode"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for responseCode")
+		}
+		_responseCodeErr := writeBuffer.WriteSerializable(m.GetResponseCode())
+		if popErr := writeBuffer.PopContext("responseCode"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for responseCode")
+		}
+		if _responseCodeErr != nil {
+			return errors.Wrap(_responseCodeErr, "Error serializing 'responseCode' field")
+		}
+
+		// Simple Field (originalMessageId)
+		originalMessageId := uint32(m.GetOriginalMessageId())
+		_originalMessageIdErr := writeBuffer.WriteUint32("originalMessageId", 32, (originalMessageId))
+		if _originalMessageIdErr != nil {
+			return errors.Wrap(_originalMessageIdErr, "Error serializing 'originalMessageId' field")
+		}
+
+		// Simple Field (originalTimestamp)
+		originalTimestamp := uint32(m.GetOriginalTimestamp())
+		_originalTimestampErr := writeBuffer.WriteUint32("originalTimestamp", 32, (originalTimestamp))
+		if _originalTimestampErr != nil {
+			return errors.Wrap(_originalTimestampErr, "Error serializing 'originalTimestamp' field")
+		}
+
+		// Array Field (variableParameters)
+		// Byte Array field (variableParameters)
+		if err := writeBuffer.WriteByteArray("variableParameters", m.GetVariableParameters()); err != nil {
+			return errors.Wrap(err, "Error serializing 'variableParameters' field")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMSecurityResponse"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMSecurityResponse")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMSecurityResponse) isNLMSecurityResponse() bool {
+	return true
+}
+
+func (m *_NLMSecurityResponse) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMSetMasterKey.go b/plc4go/protocols/bacnetip/readwrite/model/NLMSetMasterKey.go
new file mode 100644
index 0000000000..e3bf5c099f
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMSetMasterKey.go
@@ -0,0 +1,218 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMSetMasterKey is the corresponding interface of NLMSetMasterKey
+type NLMSetMasterKey interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+	// GetKey returns Key (property field)
+	GetKey() NLMUpdateKeyUpdateKeyEntry
+}
+
+// NLMSetMasterKeyExactly can be used when we want exactly this type and not a type which fulfills NLMSetMasterKey.
+// This is useful for switch cases.
+type NLMSetMasterKeyExactly interface {
+	NLMSetMasterKey
+	isNLMSetMasterKey() bool
+}
+
+// _NLMSetMasterKey is the data-structure of this message
+type _NLMSetMasterKey struct {
+	*_NLM
+	Key NLMUpdateKeyUpdateKeyEntry
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMSetMasterKey) GetMessageType() uint8 {
+	return 0x11
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMSetMasterKey) InitializeParent(parent NLM) {}
+
+func (m *_NLMSetMasterKey) GetParent() NLM {
+	return m._NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMSetMasterKey) GetKey() NLMUpdateKeyUpdateKeyEntry {
+	return m.Key
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMSetMasterKey factory function for _NLMSetMasterKey
+func NewNLMSetMasterKey(key NLMUpdateKeyUpdateKeyEntry, apduLength uint16) *_NLMSetMasterKey {
+	_result := &_NLMSetMasterKey{
+		Key:  key,
+		_NLM: NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMSetMasterKey(structType interface{}) NLMSetMasterKey {
+	if casted, ok := structType.(NLMSetMasterKey); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMSetMasterKey); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMSetMasterKey) GetTypeName() string {
+	return "NLMSetMasterKey"
+}
+
+func (m *_NLMSetMasterKey) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMSetMasterKey) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (key)
+	lengthInBits += m.Key.GetLengthInBits()
+
+	return lengthInBits
+}
+
+func (m *_NLMSetMasterKey) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMSetMasterKeyParse(theBytes []byte, apduLength uint16) (NLMSetMasterKey, error) {
+	return NLMSetMasterKeyParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMSetMasterKeyParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMSetMasterKey, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMSetMasterKey"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMSetMasterKey")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (key)
+	if pullErr := readBuffer.PullContext("key"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for key")
+	}
+	_key, _keyErr := NLMUpdateKeyUpdateKeyEntryParseWithBuffer(readBuffer)
+	if _keyErr != nil {
+		return nil, errors.Wrap(_keyErr, "Error parsing 'key' field of NLMSetMasterKey")
+	}
+	key := _key.(NLMUpdateKeyUpdateKeyEntry)
+	if closeErr := readBuffer.CloseContext("key"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for key")
+	}
+
+	if closeErr := readBuffer.CloseContext("NLMSetMasterKey"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMSetMasterKey")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMSetMasterKey{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+		Key: key,
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMSetMasterKey) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMSetMasterKey) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMSetMasterKey"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMSetMasterKey")
+		}
+
+		// Simple Field (key)
+		if pushErr := writeBuffer.PushContext("key"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for key")
+		}
+		_keyErr := writeBuffer.WriteSerializable(m.GetKey())
+		if popErr := writeBuffer.PopContext("key"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for key")
+		}
+		if _keyErr != nil {
+			return errors.Wrap(_keyErr, "Error serializing 'key' field")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMSetMasterKey"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMSetMasterKey")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMSetMasterKey) isNLMSetMasterKey() bool {
+	return true
+}
+
+func (m *_NLMSetMasterKey) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyDistributionKey.go b/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyDistributionKey.go
new file mode 100644
index 0000000000..08a35ea557
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyDistributionKey.go
@@ -0,0 +1,244 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMUpdateKeyDistributionKey is the corresponding interface of NLMUpdateKeyDistributionKey
+type NLMUpdateKeyDistributionKey interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+	// GetKeyRevision returns KeyRevision (property field)
+	GetKeyRevision() byte
+	// GetKey returns Key (property field)
+	GetKey() NLMUpdateKeyUpdateKeyEntry
+}
+
+// NLMUpdateKeyDistributionKeyExactly can be used when we want exactly this type and not a type which fulfills NLMUpdateKeyDistributionKey.
+// This is useful for switch cases.
+type NLMUpdateKeyDistributionKeyExactly interface {
+	NLMUpdateKeyDistributionKey
+	isNLMUpdateKeyDistributionKey() bool
+}
+
+// _NLMUpdateKeyDistributionKey is the data-structure of this message
+type _NLMUpdateKeyDistributionKey struct {
+	*_NLM
+	KeyRevision byte
+	Key         NLMUpdateKeyUpdateKeyEntry
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMUpdateKeyDistributionKey) GetMessageType() uint8 {
+	return 0x0F
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMUpdateKeyDistributionKey) InitializeParent(parent NLM) {}
+
+func (m *_NLMUpdateKeyDistributionKey) GetParent() NLM {
+	return m._NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMUpdateKeyDistributionKey) GetKeyRevision() byte {
+	return m.KeyRevision
+}
+
+func (m *_NLMUpdateKeyDistributionKey) GetKey() NLMUpdateKeyUpdateKeyEntry {
+	return m.Key
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMUpdateKeyDistributionKey factory function for _NLMUpdateKeyDistributionKey
+func NewNLMUpdateKeyDistributionKey(keyRevision byte, key NLMUpdateKeyUpdateKeyEntry, apduLength uint16) *_NLMUpdateKeyDistributionKey {
+	_result := &_NLMUpdateKeyDistributionKey{
+		KeyRevision: keyRevision,
+		Key:         key,
+		_NLM:        NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMUpdateKeyDistributionKey(structType interface{}) NLMUpdateKeyDistributionKey {
+	if casted, ok := structType.(NLMUpdateKeyDistributionKey); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMUpdateKeyDistributionKey); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMUpdateKeyDistributionKey) GetTypeName() string {
+	return "NLMUpdateKeyDistributionKey"
+}
+
+func (m *_NLMUpdateKeyDistributionKey) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMUpdateKeyDistributionKey) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (keyRevision)
+	lengthInBits += 8
+
+	// Simple field (key)
+	lengthInBits += m.Key.GetLengthInBits()
+
+	return lengthInBits
+}
+
+func (m *_NLMUpdateKeyDistributionKey) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMUpdateKeyDistributionKeyParse(theBytes []byte, apduLength uint16) (NLMUpdateKeyDistributionKey, error) {
+	return NLMUpdateKeyDistributionKeyParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMUpdateKeyDistributionKeyParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMUpdateKeyDistributionKey, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMUpdateKeyDistributionKey"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMUpdateKeyDistributionKey")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (keyRevision)
+	_keyRevision, _keyRevisionErr := readBuffer.ReadByte("keyRevision")
+	if _keyRevisionErr != nil {
+		return nil, errors.Wrap(_keyRevisionErr, "Error parsing 'keyRevision' field of NLMUpdateKeyDistributionKey")
+	}
+	keyRevision := _keyRevision
+
+	// Simple Field (key)
+	if pullErr := readBuffer.PullContext("key"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for key")
+	}
+	_key, _keyErr := NLMUpdateKeyUpdateKeyEntryParseWithBuffer(readBuffer)
+	if _keyErr != nil {
+		return nil, errors.Wrap(_keyErr, "Error parsing 'key' field of NLMUpdateKeyDistributionKey")
+	}
+	key := _key.(NLMUpdateKeyUpdateKeyEntry)
+	if closeErr := readBuffer.CloseContext("key"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for key")
+	}
+
+	if closeErr := readBuffer.CloseContext("NLMUpdateKeyDistributionKey"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMUpdateKeyDistributionKey")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMUpdateKeyDistributionKey{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+		KeyRevision: keyRevision,
+		Key:         key,
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMUpdateKeyDistributionKey) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMUpdateKeyDistributionKey) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMUpdateKeyDistributionKey"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMUpdateKeyDistributionKey")
+		}
+
+		// Simple Field (keyRevision)
+		keyRevision := byte(m.GetKeyRevision())
+		_keyRevisionErr := writeBuffer.WriteByte("keyRevision", (keyRevision))
+		if _keyRevisionErr != nil {
+			return errors.Wrap(_keyRevisionErr, "Error serializing 'keyRevision' field")
+		}
+
+		// Simple Field (key)
+		if pushErr := writeBuffer.PushContext("key"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for key")
+		}
+		_keyErr := writeBuffer.WriteSerializable(m.GetKey())
+		if popErr := writeBuffer.PopContext("key"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for key")
+		}
+		if _keyErr != nil {
+			return errors.Wrap(_keyErr, "Error serializing 'key' field")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMUpdateKeyDistributionKey"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMUpdateKeyDistributionKey")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMUpdateKeyDistributionKey) isNLMUpdateKeyDistributionKey() bool {
+	return true
+}
+
+func (m *_NLMUpdateKeyDistributionKey) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyUpdate.go b/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyUpdate.go
new file mode 100644
index 0000000000..e3cd06d513
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyUpdate.go
@@ -0,0 +1,598 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMUpdateKeyUpdate is the corresponding interface of NLMUpdateKeyUpdate
+type NLMUpdateKeyUpdate interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+	// GetControlFlags returns ControlFlags (property field)
+	GetControlFlags() NLMUpdateKeyUpdateControlFlags
+	// GetSet1KeyRevision returns Set1KeyRevision (property field)
+	GetSet1KeyRevision() *byte
+	// GetSet1ActivationTime returns Set1ActivationTime (property field)
+	GetSet1ActivationTime() *uint32
+	// GetSet1ExpirationTime returns Set1ExpirationTime (property field)
+	GetSet1ExpirationTime() *uint32
+	// GetSet1KeyCount returns Set1KeyCount (property field)
+	GetSet1KeyCount() *uint8
+	// GetSet1Keys returns Set1Keys (property field)
+	GetSet1Keys() []NLMUpdateKeyUpdateKeyEntry
+	// GetSet2KeyRevision returns Set2KeyRevision (property field)
+	GetSet2KeyRevision() *byte
+	// GetSet2ActivationTime returns Set2ActivationTime (property field)
+	GetSet2ActivationTime() *uint32
+	// GetSet2ExpirationTime returns Set2ExpirationTime (property field)
+	GetSet2ExpirationTime() *uint32
+	// GetSet2KeyCount returns Set2KeyCount (property field)
+	GetSet2KeyCount() *uint8
+	// GetSet2Keys returns Set2Keys (property field)
+	GetSet2Keys() []NLMUpdateKeyUpdateKeyEntry
+}
+
+// NLMUpdateKeyUpdateExactly can be used when we want exactly this type and not a type which fulfills NLMUpdateKeyUpdate.
+// This is useful for switch cases.
+type NLMUpdateKeyUpdateExactly interface {
+	NLMUpdateKeyUpdate
+	isNLMUpdateKeyUpdate() bool
+}
+
+// _NLMUpdateKeyUpdate is the data-structure of this message
+type _NLMUpdateKeyUpdate struct {
+	*_NLM
+	ControlFlags       NLMUpdateKeyUpdateControlFlags
+	Set1KeyRevision    *byte
+	Set1ActivationTime *uint32
+	Set1ExpirationTime *uint32
+	Set1KeyCount       *uint8
+	Set1Keys           []NLMUpdateKeyUpdateKeyEntry
+	Set2KeyRevision    *byte
+	Set2ActivationTime *uint32
+	Set2ExpirationTime *uint32
+	Set2KeyCount       *uint8
+	Set2Keys           []NLMUpdateKeyUpdateKeyEntry
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMUpdateKeyUpdate) GetMessageType() uint8 {
+	return 0x0E
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMUpdateKeyUpdate) InitializeParent(parent NLM) {}
+
+func (m *_NLMUpdateKeyUpdate) GetParent() NLM {
+	return m._NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMUpdateKeyUpdate) GetControlFlags() NLMUpdateKeyUpdateControlFlags {
+	return m.ControlFlags
+}
+
+func (m *_NLMUpdateKeyUpdate) GetSet1KeyRevision() *byte {
+	return m.Set1KeyRevision
+}
+
+func (m *_NLMUpdateKeyUpdate) GetSet1ActivationTime() *uint32 {
+	return m.Set1ActivationTime
+}
+
+func (m *_NLMUpdateKeyUpdate) GetSet1ExpirationTime() *uint32 {
+	return m.Set1ExpirationTime
+}
+
+func (m *_NLMUpdateKeyUpdate) GetSet1KeyCount() *uint8 {
+	return m.Set1KeyCount
+}
+
+func (m *_NLMUpdateKeyUpdate) GetSet1Keys() []NLMUpdateKeyUpdateKeyEntry {
+	return m.Set1Keys
+}
+
+func (m *_NLMUpdateKeyUpdate) GetSet2KeyRevision() *byte {
+	return m.Set2KeyRevision
+}
+
+func (m *_NLMUpdateKeyUpdate) GetSet2ActivationTime() *uint32 {
+	return m.Set2ActivationTime
+}
+
+func (m *_NLMUpdateKeyUpdate) GetSet2ExpirationTime() *uint32 {
+	return m.Set2ExpirationTime
+}
+
+func (m *_NLMUpdateKeyUpdate) GetSet2KeyCount() *uint8 {
+	return m.Set2KeyCount
+}
+
+func (m *_NLMUpdateKeyUpdate) GetSet2Keys() []NLMUpdateKeyUpdateKeyEntry {
+	return m.Set2Keys
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMUpdateKeyUpdate factory function for _NLMUpdateKeyUpdate
+func NewNLMUpdateKeyUpdate(controlFlags NLMUpdateKeyUpdateControlFlags, set1KeyRevision *byte, set1ActivationTime *uint32, set1ExpirationTime *uint32, set1KeyCount *uint8, set1Keys []NLMUpdateKeyUpdateKeyEntry, set2KeyRevision *byte, set2ActivationTime *uint32, set2ExpirationTime *uint32, set2KeyCount *uint8, set2Keys []NLMUpdateKeyUpdateKeyEntry, apduLength uint16) *_NLMUpdateKeyUpdate {
+	_result := &_NLMUpdateKeyUpdate{
+		ControlFlags:       controlFlags,
+		Set1KeyRevision:    set1KeyRevision,
+		Set1ActivationTime: set1ActivationTime,
+		Set1ExpirationTime: set1ExpirationTime,
+		Set1KeyCount:       set1KeyCount,
+		Set1Keys:           set1Keys,
+		Set2KeyRevision:    set2KeyRevision,
+		Set2ActivationTime: set2ActivationTime,
+		Set2ExpirationTime: set2ExpirationTime,
+		Set2KeyCount:       set2KeyCount,
+		Set2Keys:           set2Keys,
+		_NLM:               NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMUpdateKeyUpdate(structType interface{}) NLMUpdateKeyUpdate {
+	if casted, ok := structType.(NLMUpdateKeyUpdate); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMUpdateKeyUpdate); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMUpdateKeyUpdate) GetTypeName() string {
+	return "NLMUpdateKeyUpdate"
+}
+
+func (m *_NLMUpdateKeyUpdate) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMUpdateKeyUpdate) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (controlFlags)
+	lengthInBits += m.ControlFlags.GetLengthInBits()
+
+	// Optional Field (set1KeyRevision)
+	if m.Set1KeyRevision != nil {
+		lengthInBits += 8
+	}
+
+	// Optional Field (set1ActivationTime)
+	if m.Set1ActivationTime != nil {
+		lengthInBits += 32
+	}
+
+	// Optional Field (set1ExpirationTime)
+	if m.Set1ExpirationTime != nil {
+		lengthInBits += 32
+	}
+
+	// Optional Field (set1KeyCount)
+	if m.Set1KeyCount != nil {
+		lengthInBits += 8
+	}
+
+	// Array field
+	if len(m.Set1Keys) > 0 {
+		for i, element := range m.Set1Keys {
+			last := i == len(m.Set1Keys)-1
+			lengthInBits += element.(interface{ GetLengthInBitsConditional(bool) uint16 }).GetLengthInBitsConditional(last)
+		}
+	}
+
+	// Optional Field (set2KeyRevision)
+	if m.Set2KeyRevision != nil {
+		lengthInBits += 8
+	}
+
+	// Optional Field (set2ActivationTime)
+	if m.Set2ActivationTime != nil {
+		lengthInBits += 32
+	}
+
+	// Optional Field (set2ExpirationTime)
+	if m.Set2ExpirationTime != nil {
+		lengthInBits += 32
+	}
+
+	// Optional Field (set2KeyCount)
+	if m.Set2KeyCount != nil {
+		lengthInBits += 8
+	}
+
+	// Array field
+	if len(m.Set2Keys) > 0 {
+		for i, element := range m.Set2Keys {
+			last := i == len(m.Set2Keys)-1
+			lengthInBits += element.(interface{ GetLengthInBitsConditional(bool) uint16 }).GetLengthInBitsConditional(last)
+		}
+	}
+
+	return lengthInBits
+}
+
+func (m *_NLMUpdateKeyUpdate) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMUpdateKeyUpdateParse(theBytes []byte, apduLength uint16) (NLMUpdateKeyUpdate, error) {
+	return NLMUpdateKeyUpdateParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMUpdateKeyUpdateParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMUpdateKeyUpdate, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMUpdateKeyUpdate"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMUpdateKeyUpdate")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (controlFlags)
+	if pullErr := readBuffer.PullContext("controlFlags"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for controlFlags")
+	}
+	_controlFlags, _controlFlagsErr := NLMUpdateKeyUpdateControlFlagsParseWithBuffer(readBuffer)
+	if _controlFlagsErr != nil {
+		return nil, errors.Wrap(_controlFlagsErr, "Error parsing 'controlFlags' field of NLMUpdateKeyUpdate")
+	}
+	controlFlags := _controlFlags.(NLMUpdateKeyUpdateControlFlags)
+	if closeErr := readBuffer.CloseContext("controlFlags"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for controlFlags")
+	}
+
+	// Optional Field (set1KeyRevision) (Can be skipped, if a given expression evaluates to false)
+	var set1KeyRevision *byte = nil
+	if controlFlags.GetSet1KeyRevisionActivationTimeExpirationTimePresent() {
+		_val, _err := readBuffer.ReadByte("set1KeyRevision")
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'set1KeyRevision' field of NLMUpdateKeyUpdate")
+		}
+		set1KeyRevision = &_val
+	}
+
+	// Optional Field (set1ActivationTime) (Can be skipped, if a given expression evaluates to false)
+	var set1ActivationTime *uint32 = nil
+	if controlFlags.GetSet1KeyRevisionActivationTimeExpirationTimePresent() {
+		_val, _err := readBuffer.ReadUint32("set1ActivationTime", 32)
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'set1ActivationTime' field of NLMUpdateKeyUpdate")
+		}
+		set1ActivationTime = &_val
+	}
+
+	// Optional Field (set1ExpirationTime) (Can be skipped, if a given expression evaluates to false)
+	var set1ExpirationTime *uint32 = nil
+	if controlFlags.GetSet1KeyCountKeyParametersPresent() {
+		_val, _err := readBuffer.ReadUint32("set1ExpirationTime", 32)
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'set1ExpirationTime' field of NLMUpdateKeyUpdate")
+		}
+		set1ExpirationTime = &_val
+	}
+
+	// Optional Field (set1KeyCount) (Can be skipped, if a given expression evaluates to false)
+	var set1KeyCount *uint8 = nil
+	if controlFlags.GetSet1KeyCountKeyParametersPresent() {
+		_val, _err := readBuffer.ReadUint8("set1KeyCount", 8)
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'set1KeyCount' field of NLMUpdateKeyUpdate")
+		}
+		set1KeyCount = &_val
+	}
+
+	// Array field (set1Keys)
+	if pullErr := readBuffer.PullContext("set1Keys", utils.WithRenderAsList(true)); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for set1Keys")
+	}
+	// Count array
+	set1Keys := make([]NLMUpdateKeyUpdateKeyEntry, utils.InlineIf(bool((set1KeyCount) != (nil)), func() interface{} { return uint16((*set1KeyCount)) }, func() interface{} { return uint16(uint16(0)) }).(uint16))
+	// This happens when the size is set conditional to 0
+	if len(set1Keys) == 0 {
+		set1Keys = nil
+	}
+	{
+		for curItem := uint16(0); curItem < uint16(utils.InlineIf(bool((set1KeyCount) != (nil)), func() interface{} { return uint16((*set1KeyCount)) }, func() interface{} { return uint16(uint16(0)) }).(uint16)); curItem++ {
+			_item, _err := NLMUpdateKeyUpdateKeyEntryParseWithBuffer(readBuffer)
+			if _err != nil {
+				return nil, errors.Wrap(_err, "Error parsing 'set1Keys' field of NLMUpdateKeyUpdate")
+			}
+			set1Keys[curItem] = _item.(NLMUpdateKeyUpdateKeyEntry)
+		}
+	}
+	if closeErr := readBuffer.CloseContext("set1Keys", utils.WithRenderAsList(true)); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for set1Keys")
+	}
+
+	// Optional Field (set2KeyRevision) (Can be skipped, if a given expression evaluates to false)
+	var set2KeyRevision *byte = nil
+	if controlFlags.GetSet1KeyRevisionActivationTimeExpirationTimePresent() {
+		_val, _err := readBuffer.ReadByte("set2KeyRevision")
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'set2KeyRevision' field of NLMUpdateKeyUpdate")
+		}
+		set2KeyRevision = &_val
+	}
+
+	// Optional Field (set2ActivationTime) (Can be skipped, if a given expression evaluates to false)
+	var set2ActivationTime *uint32 = nil
+	if controlFlags.GetSet1KeyRevisionActivationTimeExpirationTimePresent() {
+		_val, _err := readBuffer.ReadUint32("set2ActivationTime", 32)
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'set2ActivationTime' field of NLMUpdateKeyUpdate")
+		}
+		set2ActivationTime = &_val
+	}
+
+	// Optional Field (set2ExpirationTime) (Can be skipped, if a given expression evaluates to false)
+	var set2ExpirationTime *uint32 = nil
+	if controlFlags.GetSet1KeyCountKeyParametersPresent() {
+		_val, _err := readBuffer.ReadUint32("set2ExpirationTime", 32)
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'set2ExpirationTime' field of NLMUpdateKeyUpdate")
+		}
+		set2ExpirationTime = &_val
+	}
+
+	// Optional Field (set2KeyCount) (Can be skipped, if a given expression evaluates to false)
+	var set2KeyCount *uint8 = nil
+	if controlFlags.GetSet1KeyCountKeyParametersPresent() {
+		_val, _err := readBuffer.ReadUint8("set2KeyCount", 8)
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'set2KeyCount' field of NLMUpdateKeyUpdate")
+		}
+		set2KeyCount = &_val
+	}
+
+	// Array field (set2Keys)
+	if pullErr := readBuffer.PullContext("set2Keys", utils.WithRenderAsList(true)); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for set2Keys")
+	}
+	// Count array
+	set2Keys := make([]NLMUpdateKeyUpdateKeyEntry, utils.InlineIf(bool((set1KeyCount) != (nil)), func() interface{} { return uint16((*set1KeyCount)) }, func() interface{} { return uint16(uint16(0)) }).(uint16))
+	// This happens when the size is set conditional to 0
+	if len(set2Keys) == 0 {
+		set2Keys = nil
+	}
+	{
+		for curItem := uint16(0); curItem < uint16(utils.InlineIf(bool((set1KeyCount) != (nil)), func() interface{} { return uint16((*set1KeyCount)) }, func() interface{} { return uint16(uint16(0)) }).(uint16)); curItem++ {
+			_item, _err := NLMUpdateKeyUpdateKeyEntryParseWithBuffer(readBuffer)
+			if _err != nil {
+				return nil, errors.Wrap(_err, "Error parsing 'set2Keys' field of NLMUpdateKeyUpdate")
+			}
+			set2Keys[curItem] = _item.(NLMUpdateKeyUpdateKeyEntry)
+		}
+	}
+	if closeErr := readBuffer.CloseContext("set2Keys", utils.WithRenderAsList(true)); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for set2Keys")
+	}
+
+	if closeErr := readBuffer.CloseContext("NLMUpdateKeyUpdate"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMUpdateKeyUpdate")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMUpdateKeyUpdate{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+		ControlFlags:       controlFlags,
+		Set1KeyRevision:    set1KeyRevision,
+		Set1ActivationTime: set1ActivationTime,
+		Set1ExpirationTime: set1ExpirationTime,
+		Set1KeyCount:       set1KeyCount,
+		Set1Keys:           set1Keys,
+		Set2KeyRevision:    set2KeyRevision,
+		Set2ActivationTime: set2ActivationTime,
+		Set2ExpirationTime: set2ExpirationTime,
+		Set2KeyCount:       set2KeyCount,
+		Set2Keys:           set2Keys,
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMUpdateKeyUpdate) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMUpdateKeyUpdate) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMUpdateKeyUpdate"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMUpdateKeyUpdate")
+		}
+
+		// Simple Field (controlFlags)
+		if pushErr := writeBuffer.PushContext("controlFlags"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for controlFlags")
+		}
+		_controlFlagsErr := writeBuffer.WriteSerializable(m.GetControlFlags())
+		if popErr := writeBuffer.PopContext("controlFlags"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for controlFlags")
+		}
+		if _controlFlagsErr != nil {
+			return errors.Wrap(_controlFlagsErr, "Error serializing 'controlFlags' field")
+		}
+
+		// Optional Field (set1KeyRevision) (Can be skipped, if the value is null)
+		var set1KeyRevision *byte = nil
+		if m.GetSet1KeyRevision() != nil {
+			set1KeyRevision = m.GetSet1KeyRevision()
+			_set1KeyRevisionErr := writeBuffer.WriteByte("set1KeyRevision", *(set1KeyRevision))
+			if _set1KeyRevisionErr != nil {
+				return errors.Wrap(_set1KeyRevisionErr, "Error serializing 'set1KeyRevision' field")
+			}
+		}
+
+		// Optional Field (set1ActivationTime) (Can be skipped, if the value is null)
+		var set1ActivationTime *uint32 = nil
+		if m.GetSet1ActivationTime() != nil {
+			set1ActivationTime = m.GetSet1ActivationTime()
+			_set1ActivationTimeErr := writeBuffer.WriteUint32("set1ActivationTime", 32, *(set1ActivationTime))
+			if _set1ActivationTimeErr != nil {
+				return errors.Wrap(_set1ActivationTimeErr, "Error serializing 'set1ActivationTime' field")
+			}
+		}
+
+		// Optional Field (set1ExpirationTime) (Can be skipped, if the value is null)
+		var set1ExpirationTime *uint32 = nil
+		if m.GetSet1ExpirationTime() != nil {
+			set1ExpirationTime = m.GetSet1ExpirationTime()
+			_set1ExpirationTimeErr := writeBuffer.WriteUint32("set1ExpirationTime", 32, *(set1ExpirationTime))
+			if _set1ExpirationTimeErr != nil {
+				return errors.Wrap(_set1ExpirationTimeErr, "Error serializing 'set1ExpirationTime' field")
+			}
+		}
+
+		// Optional Field (set1KeyCount) (Can be skipped, if the value is null)
+		var set1KeyCount *uint8 = nil
+		if m.GetSet1KeyCount() != nil {
+			set1KeyCount = m.GetSet1KeyCount()
+			_set1KeyCountErr := writeBuffer.WriteUint8("set1KeyCount", 8, *(set1KeyCount))
+			if _set1KeyCountErr != nil {
+				return errors.Wrap(_set1KeyCountErr, "Error serializing 'set1KeyCount' field")
+			}
+		}
+
+		// Array Field (set1Keys)
+		if pushErr := writeBuffer.PushContext("set1Keys", utils.WithRenderAsList(true)); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for set1Keys")
+		}
+		for _, _element := range m.GetSet1Keys() {
+			_elementErr := writeBuffer.WriteSerializable(_element)
+			if _elementErr != nil {
+				return errors.Wrap(_elementErr, "Error serializing 'set1Keys' field")
+			}
+		}
+		if popErr := writeBuffer.PopContext("set1Keys", utils.WithRenderAsList(true)); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for set1Keys")
+		}
+
+		// Optional Field (set2KeyRevision) (Can be skipped, if the value is null)
+		var set2KeyRevision *byte = nil
+		if m.GetSet2KeyRevision() != nil {
+			set2KeyRevision = m.GetSet2KeyRevision()
+			_set2KeyRevisionErr := writeBuffer.WriteByte("set2KeyRevision", *(set2KeyRevision))
+			if _set2KeyRevisionErr != nil {
+				return errors.Wrap(_set2KeyRevisionErr, "Error serializing 'set2KeyRevision' field")
+			}
+		}
+
+		// Optional Field (set2ActivationTime) (Can be skipped, if the value is null)
+		var set2ActivationTime *uint32 = nil
+		if m.GetSet2ActivationTime() != nil {
+			set2ActivationTime = m.GetSet2ActivationTime()
+			_set2ActivationTimeErr := writeBuffer.WriteUint32("set2ActivationTime", 32, *(set2ActivationTime))
+			if _set2ActivationTimeErr != nil {
+				return errors.Wrap(_set2ActivationTimeErr, "Error serializing 'set2ActivationTime' field")
+			}
+		}
+
+		// Optional Field (set2ExpirationTime) (Can be skipped, if the value is null)
+		var set2ExpirationTime *uint32 = nil
+		if m.GetSet2ExpirationTime() != nil {
+			set2ExpirationTime = m.GetSet2ExpirationTime()
+			_set2ExpirationTimeErr := writeBuffer.WriteUint32("set2ExpirationTime", 32, *(set2ExpirationTime))
+			if _set2ExpirationTimeErr != nil {
+				return errors.Wrap(_set2ExpirationTimeErr, "Error serializing 'set2ExpirationTime' field")
+			}
+		}
+
+		// Optional Field (set2KeyCount) (Can be skipped, if the value is null)
+		var set2KeyCount *uint8 = nil
+		if m.GetSet2KeyCount() != nil {
+			set2KeyCount = m.GetSet2KeyCount()
+			_set2KeyCountErr := writeBuffer.WriteUint8("set2KeyCount", 8, *(set2KeyCount))
+			if _set2KeyCountErr != nil {
+				return errors.Wrap(_set2KeyCountErr, "Error serializing 'set2KeyCount' field")
+			}
+		}
+
+		// Array Field (set2Keys)
+		if pushErr := writeBuffer.PushContext("set2Keys", utils.WithRenderAsList(true)); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for set2Keys")
+		}
+		for _, _element := range m.GetSet2Keys() {
+			_elementErr := writeBuffer.WriteSerializable(_element)
+			if _elementErr != nil {
+				return errors.Wrap(_elementErr, "Error serializing 'set2Keys' field")
+			}
+		}
+		if popErr := writeBuffer.PopContext("set2Keys", utils.WithRenderAsList(true)); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for set2Keys")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMUpdateKeyUpdate"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMUpdateKeyUpdate")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMUpdateKeyUpdate) isNLMUpdateKeyUpdate() bool {
+	return true
+}
+
+func (m *_NLMUpdateKeyUpdate) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyUpdateControlFlags.go b/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyUpdateControlFlags.go
new file mode 100644
index 0000000000..0bbd0b5077
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyUpdateControlFlags.go
@@ -0,0 +1,347 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMUpdateKeyUpdateControlFlags is the corresponding interface of NLMUpdateKeyUpdateControlFlags
+type NLMUpdateKeyUpdateControlFlags interface {
+	utils.LengthAware
+	utils.Serializable
+	// GetSet1KeyRevisionActivationTimeExpirationTimePresent returns Set1KeyRevisionActivationTimeExpirationTimePresent (property field)
+	GetSet1KeyRevisionActivationTimeExpirationTimePresent() bool
+	// GetSet1KeyCountKeyParametersPresent returns Set1KeyCountKeyParametersPresent (property field)
+	GetSet1KeyCountKeyParametersPresent() bool
+	// GetSet1ShouldBeCleared returns Set1ShouldBeCleared (property field)
+	GetSet1ShouldBeCleared() bool
+	// GetSet2KeyRevisionActivationTimeExpirationTimePresent returns Set2KeyRevisionActivationTimeExpirationTimePresent (property field)
+	GetSet2KeyRevisionActivationTimeExpirationTimePresent() bool
+	// GetSet2KeyCountKeyParametersPresent returns Set2KeyCountKeyParametersPresent (property field)
+	GetSet2KeyCountKeyParametersPresent() bool
+	// GetSet2ShouldBeCleared returns Set2ShouldBeCleared (property field)
+	GetSet2ShouldBeCleared() bool
+	// GetMoreMessagesToBeExpected returns MoreMessagesToBeExpected (property field)
+	GetMoreMessagesToBeExpected() bool
+	// GetRemoveAllKeys returns RemoveAllKeys (property field)
+	GetRemoveAllKeys() bool
+}
+
+// NLMUpdateKeyUpdateControlFlagsExactly can be used when we want exactly this type and not a type which fulfills NLMUpdateKeyUpdateControlFlags.
+// This is useful for switch cases.
+type NLMUpdateKeyUpdateControlFlagsExactly interface {
+	NLMUpdateKeyUpdateControlFlags
+	isNLMUpdateKeyUpdateControlFlags() bool
+}
+
+// _NLMUpdateKeyUpdateControlFlags is the data-structure of this message
+type _NLMUpdateKeyUpdateControlFlags struct {
+	Set1KeyRevisionActivationTimeExpirationTimePresent bool
+	Set1KeyCountKeyParametersPresent                   bool
+	Set1ShouldBeCleared                                bool
+	Set2KeyRevisionActivationTimeExpirationTimePresent bool
+	Set2KeyCountKeyParametersPresent                   bool
+	Set2ShouldBeCleared                                bool
+	MoreMessagesToBeExpected                           bool
+	RemoveAllKeys                                      bool
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetSet1KeyRevisionActivationTimeExpirationTimePresent() bool {
+	return m.Set1KeyRevisionActivationTimeExpirationTimePresent
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetSet1KeyCountKeyParametersPresent() bool {
+	return m.Set1KeyCountKeyParametersPresent
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetSet1ShouldBeCleared() bool {
+	return m.Set1ShouldBeCleared
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetSet2KeyRevisionActivationTimeExpirationTimePresent() bool {
+	return m.Set2KeyRevisionActivationTimeExpirationTimePresent
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetSet2KeyCountKeyParametersPresent() bool {
+	return m.Set2KeyCountKeyParametersPresent
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetSet2ShouldBeCleared() bool {
+	return m.Set2ShouldBeCleared
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetMoreMessagesToBeExpected() bool {
+	return m.MoreMessagesToBeExpected
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetRemoveAllKeys() bool {
+	return m.RemoveAllKeys
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMUpdateKeyUpdateControlFlags factory function for _NLMUpdateKeyUpdateControlFlags
+func NewNLMUpdateKeyUpdateControlFlags(set1KeyRevisionActivationTimeExpirationTimePresent bool, set1KeyCountKeyParametersPresent bool, set1ShouldBeCleared bool, set2KeyRevisionActivationTimeExpirationTimePresent bool, set2KeyCountKeyParametersPresent bool, set2ShouldBeCleared bool, moreMessagesToBeExpected bool, removeAllKeys bool) *_NLMUpdateKeyUpdateControlFlags {
+	return &_NLMUpdateKeyUpdateControlFlags{Set1KeyRevisionActivationTimeExpirationTimePresent: set1KeyRevisionActivationTimeExpirationTimePresent, Set1KeyCountKeyParametersPresent: set1KeyCountKeyParametersPresent, Set1ShouldBeCleared: set1ShouldBeCleared, Set2KeyRevisionActivationTimeExpirationTimePresent: set2KeyRevisionActivationTimeExpirationTimePresent, Set2KeyCountKeyParametersPresent: set2KeyCountKeyParametersPresent, Set2ShouldBeCleared: set2ShouldBeCleared, MoreMessagesToBeExpecte [...]
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMUpdateKeyUpdateControlFlags(structType interface{}) NLMUpdateKeyUpdateControlFlags {
+	if casted, ok := structType.(NLMUpdateKeyUpdateControlFlags); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMUpdateKeyUpdateControlFlags); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetTypeName() string {
+	return "NLMUpdateKeyUpdateControlFlags"
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(0)
+
+	// Simple field (set1KeyRevisionActivationTimeExpirationTimePresent)
+	lengthInBits += 1
+
+	// Simple field (set1KeyCountKeyParametersPresent)
+	lengthInBits += 1
+
+	// Simple field (set1ShouldBeCleared)
+	lengthInBits += 1
+
+	// Simple field (set2KeyRevisionActivationTimeExpirationTimePresent)
+	lengthInBits += 1
+
+	// Simple field (set2KeyCountKeyParametersPresent)
+	lengthInBits += 1
+
+	// Simple field (set2ShouldBeCleared)
+	lengthInBits += 1
+
+	// Simple field (moreMessagesToBeExpected)
+	lengthInBits += 1
+
+	// Simple field (removeAllKeys)
+	lengthInBits += 1
+
+	return lengthInBits
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMUpdateKeyUpdateControlFlagsParse(theBytes []byte) (NLMUpdateKeyUpdateControlFlags, error) {
+	return NLMUpdateKeyUpdateControlFlagsParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian))) // TODO: get endianness from mspec
+}
+
+func NLMUpdateKeyUpdateControlFlagsParseWithBuffer(readBuffer utils.ReadBuffer) (NLMUpdateKeyUpdateControlFlags, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMUpdateKeyUpdateControlFlags"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMUpdateKeyUpdateControlFlags")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (set1KeyRevisionActivationTimeExpirationTimePresent)
+	_set1KeyRevisionActivationTimeExpirationTimePresent, _set1KeyRevisionActivationTimeExpirationTimePresentErr := readBuffer.ReadBit("set1KeyRevisionActivationTimeExpirationTimePresent")
+	if _set1KeyRevisionActivationTimeExpirationTimePresentErr != nil {
+		return nil, errors.Wrap(_set1KeyRevisionActivationTimeExpirationTimePresentErr, "Error parsing 'set1KeyRevisionActivationTimeExpirationTimePresent' field of NLMUpdateKeyUpdateControlFlags")
+	}
+	set1KeyRevisionActivationTimeExpirationTimePresent := _set1KeyRevisionActivationTimeExpirationTimePresent
+
+	// Simple Field (set1KeyCountKeyParametersPresent)
+	_set1KeyCountKeyParametersPresent, _set1KeyCountKeyParametersPresentErr := readBuffer.ReadBit("set1KeyCountKeyParametersPresent")
+	if _set1KeyCountKeyParametersPresentErr != nil {
+		return nil, errors.Wrap(_set1KeyCountKeyParametersPresentErr, "Error parsing 'set1KeyCountKeyParametersPresent' field of NLMUpdateKeyUpdateControlFlags")
+	}
+	set1KeyCountKeyParametersPresent := _set1KeyCountKeyParametersPresent
+
+	// Simple Field (set1ShouldBeCleared)
+	_set1ShouldBeCleared, _set1ShouldBeClearedErr := readBuffer.ReadBit("set1ShouldBeCleared")
+	if _set1ShouldBeClearedErr != nil {
+		return nil, errors.Wrap(_set1ShouldBeClearedErr, "Error parsing 'set1ShouldBeCleared' field of NLMUpdateKeyUpdateControlFlags")
+	}
+	set1ShouldBeCleared := _set1ShouldBeCleared
+
+	// Simple Field (set2KeyRevisionActivationTimeExpirationTimePresent)
+	_set2KeyRevisionActivationTimeExpirationTimePresent, _set2KeyRevisionActivationTimeExpirationTimePresentErr := readBuffer.ReadBit("set2KeyRevisionActivationTimeExpirationTimePresent")
+	if _set2KeyRevisionActivationTimeExpirationTimePresentErr != nil {
+		return nil, errors.Wrap(_set2KeyRevisionActivationTimeExpirationTimePresentErr, "Error parsing 'set2KeyRevisionActivationTimeExpirationTimePresent' field of NLMUpdateKeyUpdateControlFlags")
+	}
+	set2KeyRevisionActivationTimeExpirationTimePresent := _set2KeyRevisionActivationTimeExpirationTimePresent
+
+	// Simple Field (set2KeyCountKeyParametersPresent)
+	_set2KeyCountKeyParametersPresent, _set2KeyCountKeyParametersPresentErr := readBuffer.ReadBit("set2KeyCountKeyParametersPresent")
+	if _set2KeyCountKeyParametersPresentErr != nil {
+		return nil, errors.Wrap(_set2KeyCountKeyParametersPresentErr, "Error parsing 'set2KeyCountKeyParametersPresent' field of NLMUpdateKeyUpdateControlFlags")
+	}
+	set2KeyCountKeyParametersPresent := _set2KeyCountKeyParametersPresent
+
+	// Simple Field (set2ShouldBeCleared)
+	_set2ShouldBeCleared, _set2ShouldBeClearedErr := readBuffer.ReadBit("set2ShouldBeCleared")
+	if _set2ShouldBeClearedErr != nil {
+		return nil, errors.Wrap(_set2ShouldBeClearedErr, "Error parsing 'set2ShouldBeCleared' field of NLMUpdateKeyUpdateControlFlags")
+	}
+	set2ShouldBeCleared := _set2ShouldBeCleared
+
+	// Simple Field (moreMessagesToBeExpected)
+	_moreMessagesToBeExpected, _moreMessagesToBeExpectedErr := readBuffer.ReadBit("moreMessagesToBeExpected")
+	if _moreMessagesToBeExpectedErr != nil {
+		return nil, errors.Wrap(_moreMessagesToBeExpectedErr, "Error parsing 'moreMessagesToBeExpected' field of NLMUpdateKeyUpdateControlFlags")
+	}
+	moreMessagesToBeExpected := _moreMessagesToBeExpected
+
+	// Simple Field (removeAllKeys)
+	_removeAllKeys, _removeAllKeysErr := readBuffer.ReadBit("removeAllKeys")
+	if _removeAllKeysErr != nil {
+		return nil, errors.Wrap(_removeAllKeysErr, "Error parsing 'removeAllKeys' field of NLMUpdateKeyUpdateControlFlags")
+	}
+	removeAllKeys := _removeAllKeys
+
+	if closeErr := readBuffer.CloseContext("NLMUpdateKeyUpdateControlFlags"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMUpdateKeyUpdateControlFlags")
+	}
+
+	// Create the instance
+	return &_NLMUpdateKeyUpdateControlFlags{
+		Set1KeyRevisionActivationTimeExpirationTimePresent: set1KeyRevisionActivationTimeExpirationTimePresent,
+		Set1KeyCountKeyParametersPresent:                   set1KeyCountKeyParametersPresent,
+		Set1ShouldBeCleared:                                set1ShouldBeCleared,
+		Set2KeyRevisionActivationTimeExpirationTimePresent: set2KeyRevisionActivationTimeExpirationTimePresent,
+		Set2KeyCountKeyParametersPresent:                   set2KeyCountKeyParametersPresent,
+		Set2ShouldBeCleared:                                set2ShouldBeCleared,
+		MoreMessagesToBeExpected:                           moreMessagesToBeExpected,
+		RemoveAllKeys:                                      removeAllKeys,
+	}, nil
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	if pushErr := writeBuffer.PushContext("NLMUpdateKeyUpdateControlFlags"); pushErr != nil {
+		return errors.Wrap(pushErr, "Error pushing for NLMUpdateKeyUpdateControlFlags")
+	}
+
+	// Simple Field (set1KeyRevisionActivationTimeExpirationTimePresent)
+	set1KeyRevisionActivationTimeExpirationTimePresent := bool(m.GetSet1KeyRevisionActivationTimeExpirationTimePresent())
+	_set1KeyRevisionActivationTimeExpirationTimePresentErr := writeBuffer.WriteBit("set1KeyRevisionActivationTimeExpirationTimePresent", (set1KeyRevisionActivationTimeExpirationTimePresent))
+	if _set1KeyRevisionActivationTimeExpirationTimePresentErr != nil {
+		return errors.Wrap(_set1KeyRevisionActivationTimeExpirationTimePresentErr, "Error serializing 'set1KeyRevisionActivationTimeExpirationTimePresent' field")
+	}
+
+	// Simple Field (set1KeyCountKeyParametersPresent)
+	set1KeyCountKeyParametersPresent := bool(m.GetSet1KeyCountKeyParametersPresent())
+	_set1KeyCountKeyParametersPresentErr := writeBuffer.WriteBit("set1KeyCountKeyParametersPresent", (set1KeyCountKeyParametersPresent))
+	if _set1KeyCountKeyParametersPresentErr != nil {
+		return errors.Wrap(_set1KeyCountKeyParametersPresentErr, "Error serializing 'set1KeyCountKeyParametersPresent' field")
+	}
+
+	// Simple Field (set1ShouldBeCleared)
+	set1ShouldBeCleared := bool(m.GetSet1ShouldBeCleared())
+	_set1ShouldBeClearedErr := writeBuffer.WriteBit("set1ShouldBeCleared", (set1ShouldBeCleared))
+	if _set1ShouldBeClearedErr != nil {
+		return errors.Wrap(_set1ShouldBeClearedErr, "Error serializing 'set1ShouldBeCleared' field")
+	}
+
+	// Simple Field (set2KeyRevisionActivationTimeExpirationTimePresent)
+	set2KeyRevisionActivationTimeExpirationTimePresent := bool(m.GetSet2KeyRevisionActivationTimeExpirationTimePresent())
+	_set2KeyRevisionActivationTimeExpirationTimePresentErr := writeBuffer.WriteBit("set2KeyRevisionActivationTimeExpirationTimePresent", (set2KeyRevisionActivationTimeExpirationTimePresent))
+	if _set2KeyRevisionActivationTimeExpirationTimePresentErr != nil {
+		return errors.Wrap(_set2KeyRevisionActivationTimeExpirationTimePresentErr, "Error serializing 'set2KeyRevisionActivationTimeExpirationTimePresent' field")
+	}
+
+	// Simple Field (set2KeyCountKeyParametersPresent)
+	set2KeyCountKeyParametersPresent := bool(m.GetSet2KeyCountKeyParametersPresent())
+	_set2KeyCountKeyParametersPresentErr := writeBuffer.WriteBit("set2KeyCountKeyParametersPresent", (set2KeyCountKeyParametersPresent))
+	if _set2KeyCountKeyParametersPresentErr != nil {
+		return errors.Wrap(_set2KeyCountKeyParametersPresentErr, "Error serializing 'set2KeyCountKeyParametersPresent' field")
+	}
+
+	// Simple Field (set2ShouldBeCleared)
+	set2ShouldBeCleared := bool(m.GetSet2ShouldBeCleared())
+	_set2ShouldBeClearedErr := writeBuffer.WriteBit("set2ShouldBeCleared", (set2ShouldBeCleared))
+	if _set2ShouldBeClearedErr != nil {
+		return errors.Wrap(_set2ShouldBeClearedErr, "Error serializing 'set2ShouldBeCleared' field")
+	}
+
+	// Simple Field (moreMessagesToBeExpected)
+	moreMessagesToBeExpected := bool(m.GetMoreMessagesToBeExpected())
+	_moreMessagesToBeExpectedErr := writeBuffer.WriteBit("moreMessagesToBeExpected", (moreMessagesToBeExpected))
+	if _moreMessagesToBeExpectedErr != nil {
+		return errors.Wrap(_moreMessagesToBeExpectedErr, "Error serializing 'moreMessagesToBeExpected' field")
+	}
+
+	// Simple Field (removeAllKeys)
+	removeAllKeys := bool(m.GetRemoveAllKeys())
+	_removeAllKeysErr := writeBuffer.WriteBit("removeAllKeys", (removeAllKeys))
+	if _removeAllKeysErr != nil {
+		return errors.Wrap(_removeAllKeysErr, "Error serializing 'removeAllKeys' field")
+	}
+
+	if popErr := writeBuffer.PopContext("NLMUpdateKeyUpdateControlFlags"); popErr != nil {
+		return errors.Wrap(popErr, "Error popping for NLMUpdateKeyUpdateControlFlags")
+	}
+	return nil
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) isNLMUpdateKeyUpdateControlFlags() bool {
+	return true
+}
+
+func (m *_NLMUpdateKeyUpdateControlFlags) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyUpdateKeyEntry.go b/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyUpdateKeyEntry.go
new file mode 100644
index 0000000000..cafced0c96
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMUpdateKeyUpdateKeyEntry.go
@@ -0,0 +1,222 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMUpdateKeyUpdateKeyEntry is the corresponding interface of NLMUpdateKeyUpdateKeyEntry
+type NLMUpdateKeyUpdateKeyEntry interface {
+	utils.LengthAware
+	utils.Serializable
+	// GetKeyIdentifier returns KeyIdentifier (property field)
+	GetKeyIdentifier() uint16
+	// GetKeySize returns KeySize (property field)
+	GetKeySize() uint8
+	// GetKey returns Key (property field)
+	GetKey() []byte
+}
+
+// NLMUpdateKeyUpdateKeyEntryExactly can be used when we want exactly this type and not a type which fulfills NLMUpdateKeyUpdateKeyEntry.
+// This is useful for switch cases.
+type NLMUpdateKeyUpdateKeyEntryExactly interface {
+	NLMUpdateKeyUpdateKeyEntry
+	isNLMUpdateKeyUpdateKeyEntry() bool
+}
+
+// _NLMUpdateKeyUpdateKeyEntry is the data-structure of this message
+type _NLMUpdateKeyUpdateKeyEntry struct {
+	KeyIdentifier uint16
+	KeySize       uint8
+	Key           []byte
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMUpdateKeyUpdateKeyEntry) GetKeyIdentifier() uint16 {
+	return m.KeyIdentifier
+}
+
+func (m *_NLMUpdateKeyUpdateKeyEntry) GetKeySize() uint8 {
+	return m.KeySize
+}
+
+func (m *_NLMUpdateKeyUpdateKeyEntry) GetKey() []byte {
+	return m.Key
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMUpdateKeyUpdateKeyEntry factory function for _NLMUpdateKeyUpdateKeyEntry
+func NewNLMUpdateKeyUpdateKeyEntry(keyIdentifier uint16, keySize uint8, key []byte) *_NLMUpdateKeyUpdateKeyEntry {
+	return &_NLMUpdateKeyUpdateKeyEntry{KeyIdentifier: keyIdentifier, KeySize: keySize, Key: key}
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMUpdateKeyUpdateKeyEntry(structType interface{}) NLMUpdateKeyUpdateKeyEntry {
+	if casted, ok := structType.(NLMUpdateKeyUpdateKeyEntry); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMUpdateKeyUpdateKeyEntry); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMUpdateKeyUpdateKeyEntry) GetTypeName() string {
+	return "NLMUpdateKeyUpdateKeyEntry"
+}
+
+func (m *_NLMUpdateKeyUpdateKeyEntry) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMUpdateKeyUpdateKeyEntry) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(0)
+
+	// Simple field (keyIdentifier)
+	lengthInBits += 16
+
+	// Simple field (keySize)
+	lengthInBits += 8
+
+	// Array field
+	if len(m.Key) > 0 {
+		lengthInBits += 8 * uint16(len(m.Key))
+	}
+
+	return lengthInBits
+}
+
+func (m *_NLMUpdateKeyUpdateKeyEntry) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMUpdateKeyUpdateKeyEntryParse(theBytes []byte) (NLMUpdateKeyUpdateKeyEntry, error) {
+	return NLMUpdateKeyUpdateKeyEntryParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian))) // TODO: get endianness from mspec
+}
+
+func NLMUpdateKeyUpdateKeyEntryParseWithBuffer(readBuffer utils.ReadBuffer) (NLMUpdateKeyUpdateKeyEntry, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMUpdateKeyUpdateKeyEntry"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMUpdateKeyUpdateKeyEntry")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (keyIdentifier)
+	_keyIdentifier, _keyIdentifierErr := readBuffer.ReadUint16("keyIdentifier", 16)
+	if _keyIdentifierErr != nil {
+		return nil, errors.Wrap(_keyIdentifierErr, "Error parsing 'keyIdentifier' field of NLMUpdateKeyUpdateKeyEntry")
+	}
+	keyIdentifier := _keyIdentifier
+
+	// Simple Field (keySize)
+	_keySize, _keySizeErr := readBuffer.ReadUint8("keySize", 8)
+	if _keySizeErr != nil {
+		return nil, errors.Wrap(_keySizeErr, "Error parsing 'keySize' field of NLMUpdateKeyUpdateKeyEntry")
+	}
+	keySize := _keySize
+	// Byte Array field (key)
+	numberOfByteskey := int(keySize)
+	key, _readArrayErr := readBuffer.ReadByteArray("key", numberOfByteskey)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'key' field of NLMUpdateKeyUpdateKeyEntry")
+	}
+
+	if closeErr := readBuffer.CloseContext("NLMUpdateKeyUpdateKeyEntry"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMUpdateKeyUpdateKeyEntry")
+	}
+
+	// Create the instance
+	return &_NLMUpdateKeyUpdateKeyEntry{
+		KeyIdentifier: keyIdentifier,
+		KeySize:       keySize,
+		Key:           key,
+	}, nil
+}
+
+func (m *_NLMUpdateKeyUpdateKeyEntry) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMUpdateKeyUpdateKeyEntry) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	if pushErr := writeBuffer.PushContext("NLMUpdateKeyUpdateKeyEntry"); pushErr != nil {
+		return errors.Wrap(pushErr, "Error pushing for NLMUpdateKeyUpdateKeyEntry")
+	}
+
+	// Simple Field (keyIdentifier)
+	keyIdentifier := uint16(m.GetKeyIdentifier())
+	_keyIdentifierErr := writeBuffer.WriteUint16("keyIdentifier", 16, (keyIdentifier))
+	if _keyIdentifierErr != nil {
+		return errors.Wrap(_keyIdentifierErr, "Error serializing 'keyIdentifier' field")
+	}
+
+	// Simple Field (keySize)
+	keySize := uint8(m.GetKeySize())
+	_keySizeErr := writeBuffer.WriteUint8("keySize", 8, (keySize))
+	if _keySizeErr != nil {
+		return errors.Wrap(_keySizeErr, "Error serializing 'keySize' field")
+	}
+
+	// Array Field (key)
+	// Byte Array field (key)
+	if err := writeBuffer.WriteByteArray("key", m.GetKey()); err != nil {
+		return errors.Wrap(err, "Error serializing 'key' field")
+	}
+
+	if popErr := writeBuffer.PopContext("NLMUpdateKeyUpdateKeyEntry"); popErr != nil {
+		return errors.Wrap(popErr, "Error popping for NLMUpdateKeyUpdateKeyEntry")
+	}
+	return nil
+}
+
+func (m *_NLMUpdateKeyUpdateKeyEntry) isNLMUpdateKeyUpdateKeyEntry() bool {
+	return true
+}
+
+func (m *_NLMUpdateKeyUpdateKeyEntry) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMVendorProprietaryMessage.go b/plc4go/protocols/bacnetip/readwrite/model/NLMVendorProprietaryMessage.go
new file mode 100644
index 0000000000..946294db16
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMVendorProprietaryMessage.go
@@ -0,0 +1,244 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMVendorProprietaryMessage is the corresponding interface of NLMVendorProprietaryMessage
+type NLMVendorProprietaryMessage interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+	// GetVendorId returns VendorId (property field)
+	GetVendorId() BACnetVendorId
+	// GetProprietaryMessage returns ProprietaryMessage (property field)
+	GetProprietaryMessage() []byte
+}
+
+// NLMVendorProprietaryMessageExactly can be used when we want exactly this type and not a type which fulfills NLMVendorProprietaryMessage.
+// This is useful for switch cases.
+type NLMVendorProprietaryMessageExactly interface {
+	NLMVendorProprietaryMessage
+	isNLMVendorProprietaryMessage() bool
+}
+
+// _NLMVendorProprietaryMessage is the data-structure of this message
+type _NLMVendorProprietaryMessage struct {
+	*_NLM
+	VendorId           BACnetVendorId
+	ProprietaryMessage []byte
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMVendorProprietaryMessage) GetMessageType() uint8 {
+	return 0
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMVendorProprietaryMessage) InitializeParent(parent NLM) {}
+
+func (m *_NLMVendorProprietaryMessage) GetParent() NLM {
+	return m._NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_NLMVendorProprietaryMessage) GetVendorId() BACnetVendorId {
+	return m.VendorId
+}
+
+func (m *_NLMVendorProprietaryMessage) GetProprietaryMessage() []byte {
+	return m.ProprietaryMessage
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewNLMVendorProprietaryMessage factory function for _NLMVendorProprietaryMessage
+func NewNLMVendorProprietaryMessage(vendorId BACnetVendorId, proprietaryMessage []byte, apduLength uint16) *_NLMVendorProprietaryMessage {
+	_result := &_NLMVendorProprietaryMessage{
+		VendorId:           vendorId,
+		ProprietaryMessage: proprietaryMessage,
+		_NLM:               NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMVendorProprietaryMessage(structType interface{}) NLMVendorProprietaryMessage {
+	if casted, ok := structType.(NLMVendorProprietaryMessage); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMVendorProprietaryMessage); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMVendorProprietaryMessage) GetTypeName() string {
+	return "NLMVendorProprietaryMessage"
+}
+
+func (m *_NLMVendorProprietaryMessage) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMVendorProprietaryMessage) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (vendorId)
+	lengthInBits += 16
+
+	// Array field
+	if len(m.ProprietaryMessage) > 0 {
+		lengthInBits += 8 * uint16(len(m.ProprietaryMessage))
+	}
+
+	return lengthInBits
+}
+
+func (m *_NLMVendorProprietaryMessage) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMVendorProprietaryMessageParse(theBytes []byte, apduLength uint16) (NLMVendorProprietaryMessage, error) {
+	return NLMVendorProprietaryMessageParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMVendorProprietaryMessageParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMVendorProprietaryMessage, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMVendorProprietaryMessage"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMVendorProprietaryMessage")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (vendorId)
+	if pullErr := readBuffer.PullContext("vendorId"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for vendorId")
+	}
+	_vendorId, _vendorIdErr := BACnetVendorIdParseWithBuffer(readBuffer)
+	if _vendorIdErr != nil {
+		return nil, errors.Wrap(_vendorIdErr, "Error parsing 'vendorId' field of NLMVendorProprietaryMessage")
+	}
+	vendorId := _vendorId
+	if closeErr := readBuffer.CloseContext("vendorId"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for vendorId")
+	}
+	// Byte Array field (proprietaryMessage)
+	numberOfBytesproprietaryMessage := int(utils.InlineIf((bool((apduLength) > (0))), func() interface{} { return uint16((uint16(apduLength) - uint16(uint16(3)))) }, func() interface{} { return uint16(uint16(0)) }).(uint16))
+	proprietaryMessage, _readArrayErr := readBuffer.ReadByteArray("proprietaryMessage", numberOfBytesproprietaryMessage)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'proprietaryMessage' field of NLMVendorProprietaryMessage")
+	}
+
+	if closeErr := readBuffer.CloseContext("NLMVendorProprietaryMessage"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMVendorProprietaryMessage")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMVendorProprietaryMessage{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+		VendorId:           vendorId,
+		ProprietaryMessage: proprietaryMessage,
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMVendorProprietaryMessage) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMVendorProprietaryMessage) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMVendorProprietaryMessage"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMVendorProprietaryMessage")
+		}
+
+		// Simple Field (vendorId)
+		if pushErr := writeBuffer.PushContext("vendorId"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for vendorId")
+		}
+		_vendorIdErr := writeBuffer.WriteSerializable(m.GetVendorId())
+		if popErr := writeBuffer.PopContext("vendorId"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for vendorId")
+		}
+		if _vendorIdErr != nil {
+			return errors.Wrap(_vendorIdErr, "Error serializing 'vendorId' field")
+		}
+
+		// Array Field (proprietaryMessage)
+		// Byte Array field (proprietaryMessage)
+		if err := writeBuffer.WriteByteArray("proprietaryMessage", m.GetProprietaryMessage()); err != nil {
+			return errors.Wrap(err, "Error serializing 'proprietaryMessage' field")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMVendorProprietaryMessage"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMVendorProprietaryMessage")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMVendorProprietaryMessage) isNLMVendorProprietaryMessage() bool {
+	return true
+}
+
+func (m *_NLMVendorProprietaryMessage) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMWhatIsNetworkNumber.go b/plc4go/protocols/bacnetip/readwrite/model/NLMWhatIsNetworkNumber.go
new file mode 100644
index 0000000000..24db69122b
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMWhatIsNetworkNumber.go
@@ -0,0 +1,171 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// NLMWhatIsNetworkNumber is the corresponding interface of NLMWhatIsNetworkNumber
+type NLMWhatIsNetworkNumber interface {
+	utils.LengthAware
+	utils.Serializable
+	NLM
+}
+
+// NLMWhatIsNetworkNumberExactly can be used when we want exactly this type and not a type which fulfills NLMWhatIsNetworkNumber.
+// This is useful for switch cases.
+type NLMWhatIsNetworkNumberExactly interface {
+	NLMWhatIsNetworkNumber
+	isNLMWhatIsNetworkNumber() bool
+}
+
+// _NLMWhatIsNetworkNumber is the data-structure of this message
+type _NLMWhatIsNetworkNumber struct {
+	*_NLM
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *_NLMWhatIsNetworkNumber) GetMessageType() uint8 {
+	return 0x12
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_NLMWhatIsNetworkNumber) InitializeParent(parent NLM) {}
+
+func (m *_NLMWhatIsNetworkNumber) GetParent() NLM {
+	return m._NLM
+}
+
+// NewNLMWhatIsNetworkNumber factory function for _NLMWhatIsNetworkNumber
+func NewNLMWhatIsNetworkNumber(apduLength uint16) *_NLMWhatIsNetworkNumber {
+	_result := &_NLMWhatIsNetworkNumber{
+		_NLM: NewNLM(apduLength),
+	}
+	_result._NLM._NLMChildRequirements = _result
+	return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastNLMWhatIsNetworkNumber(structType interface{}) NLMWhatIsNetworkNumber {
+	if casted, ok := structType.(NLMWhatIsNetworkNumber); ok {
+		return casted
+	}
+	if casted, ok := structType.(*NLMWhatIsNetworkNumber); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_NLMWhatIsNetworkNumber) GetTypeName() string {
+	return "NLMWhatIsNetworkNumber"
+}
+
+func (m *_NLMWhatIsNetworkNumber) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_NLMWhatIsNetworkNumber) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	return lengthInBits
+}
+
+func (m *_NLMWhatIsNetworkNumber) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func NLMWhatIsNetworkNumberParse(theBytes []byte, apduLength uint16) (NLMWhatIsNetworkNumber, error) {
+	return NLMWhatIsNetworkNumberParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
+}
+
+func NLMWhatIsNetworkNumberParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMWhatIsNetworkNumber, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("NLMWhatIsNetworkNumber"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for NLMWhatIsNetworkNumber")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	if closeErr := readBuffer.CloseContext("NLMWhatIsNetworkNumber"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for NLMWhatIsNetworkNumber")
+	}
+
+	// Create a partially initialized instance
+	_child := &_NLMWhatIsNetworkNumber{
+		_NLM: &_NLM{
+			ApduLength: apduLength,
+		},
+	}
+	_child._NLM._NLMChildRequirements = _child
+	return _child, nil
+}
+
+func (m *_NLMWhatIsNetworkNumber) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_NLMWhatIsNetworkNumber) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("NLMWhatIsNetworkNumber"); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for NLMWhatIsNetworkNumber")
+		}
+
+		if popErr := writeBuffer.PopContext("NLMWhatIsNetworkNumber"); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for NLMWhatIsNetworkNumber")
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_NLMWhatIsNetworkNumber) isNLMWhatIsNetworkNumber() bool {
+	return true
+}
+
+func (m *_NLMWhatIsNetworkNumber) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/NLMWhoIsRouterToNetwork.go b/plc4go/protocols/bacnetip/readwrite/model/NLMWhoIsRouterToNetwork.go
index 4781ea3fed..bacccf390a 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/NLMWhoIsRouterToNetwork.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/NLMWhoIsRouterToNetwork.go
@@ -63,9 +63,7 @@ func (m *_NLMWhoIsRouterToNetwork) GetMessageType() uint8 {
 ///////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////
 
-func (m *_NLMWhoIsRouterToNetwork) InitializeParent(parent NLM, vendorId *BACnetVendorId) {
-	m.VendorId = vendorId
-}
+func (m *_NLMWhoIsRouterToNetwork) InitializeParent(parent NLM) {}
 
 func (m *_NLMWhoIsRouterToNetwork) GetParent() NLM {
 	return m._NLM
@@ -86,10 +84,10 @@ func (m *_NLMWhoIsRouterToNetwork) GetDestinationNetworkAddress() []uint16 {
 ///////////////////////////////////////////////////////////
 
 // NewNLMWhoIsRouterToNetwork factory function for _NLMWhoIsRouterToNetwork
-func NewNLMWhoIsRouterToNetwork(destinationNetworkAddress []uint16, vendorId *BACnetVendorId, apduLength uint16) *_NLMWhoIsRouterToNetwork {
+func NewNLMWhoIsRouterToNetwork(destinationNetworkAddress []uint16, apduLength uint16) *_NLMWhoIsRouterToNetwork {
 	_result := &_NLMWhoIsRouterToNetwork{
 		DestinationNetworkAddress: destinationNetworkAddress,
-		_NLM:                      NewNLM(vendorId, apduLength),
+		_NLM:                      NewNLM(apduLength),
 	}
 	_result._NLM._NLMChildRequirements = _result
 	return _result
@@ -129,11 +127,11 @@ func (m *_NLMWhoIsRouterToNetwork) GetLengthInBytes() uint16 {
 	return m.GetLengthInBits() / 8
 }
 
-func NLMWhoIsRouterToNetworkParse(theBytes []byte, apduLength uint16, messageType uint8) (NLMWhoIsRouterToNetwork, error) {
-	return NLMWhoIsRouterToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength, messageType) // TODO: get endianness from mspec
+func NLMWhoIsRouterToNetworkParse(theBytes []byte, apduLength uint16) (NLMWhoIsRouterToNetwork, error) {
+	return NLMWhoIsRouterToNetworkParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), apduLength) // TODO: get endianness from mspec
 }
 
-func NLMWhoIsRouterToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16, messageType uint8) (NLMWhoIsRouterToNetwork, error) {
+func NLMWhoIsRouterToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLength uint16) (NLMWhoIsRouterToNetwork, error) {
 	positionAware := readBuffer
 	_ = positionAware
 	if pullErr := readBuffer.PullContext("NLMWhoIsRouterToNetwork"); pullErr != nil {
@@ -149,7 +147,7 @@ func NLMWhoIsRouterToNetworkParseWithBuffer(readBuffer utils.ReadBuffer, apduLen
 	// Length array
 	var destinationNetworkAddress []uint16
 	{
-		_destinationNetworkAddressLength := uint16(apduLength) - uint16((utils.InlineIf((bool((bool((messageType) >= (128)))) && bool((bool((messageType) <= (255))))), func() interface{} { return uint16(uint16(3)) }, func() interface{} { return uint16(uint16(1)) }).(uint16)))
+		_destinationNetworkAddressLength := uint16(apduLength) - uint16(uint16(1))
 		_destinationNetworkAddressEndPos := positionAware.GetPos() + uint16(_destinationNetworkAddressLength)
 		for positionAware.GetPos() < _destinationNetworkAddressEndPos {
 			_item, _err := readBuffer.ReadUint16("", 16)
diff --git a/plc4go/protocols/bacnetip/readwrite/model/SecurityResponseCode.go b/plc4go/protocols/bacnetip/readwrite/model/SecurityResponseCode.go
new file mode 100644
index 0000000000..0d83ab2210
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/SecurityResponseCode.go
@@ -0,0 +1,334 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// SecurityResponseCode is an enum
+type SecurityResponseCode uint8
+
+type ISecurityResponseCode interface {
+	utils.Serializable
+}
+
+const (
+	SecurityResponseCode_SUCCESS                        SecurityResponseCode = 0x00
+	SecurityResponseCode_ACCESS_DENIED                  SecurityResponseCode = 0x01
+	SecurityResponseCode_BAD_DESTINATION_ADDRESS        SecurityResponseCode = 0x02
+	SecurityResponseCode_BAD_DESTINATION_DEVICE_ID      SecurityResponseCode = 0x03
+	SecurityResponseCode_BAD_SIGNATURE                  SecurityResponseCode = 0x04
+	SecurityResponseCode_BAD_SOURCE_ADDRESS             SecurityResponseCode = 0x05
+	SecurityResponseCode_BAD_TIMESTAMP                  SecurityResponseCode = 0x06
+	SecurityResponseCode_CANNOT_USE_KEY                 SecurityResponseCode = 0x07
+	SecurityResponseCode_CANNOT_VERIFY_MESSAGE_ID       SecurityResponseCode = 0x08
+	SecurityResponseCode_CORRECT_KEY_REVISION           SecurityResponseCode = 0x09
+	SecurityResponseCode_DESTINATION_DEVICE_ID_REQUIRED SecurityResponseCode = 0x0A
+	SecurityResponseCode_DUPLICATE_MESSAGE              SecurityResponseCode = 0x0B
+	SecurityResponseCode_ENCRYPTION_NOT_CONFIGURED      SecurityResponseCode = 0x0C
+	SecurityResponseCode_ENCRYPTION_REQUIRED            SecurityResponseCode = 0x0D
+	SecurityResponseCode_INCORRECT_KEY                  SecurityResponseCode = 0x0E
+	SecurityResponseCode_INVALID_KEY_DATA               SecurityResponseCode = 0x0F
+	SecurityResponseCode_KEY_UPDATE_IN_PROGRESS         SecurityResponseCode = 0x10
+	SecurityResponseCode_MALFORMED_MESSAGE              SecurityResponseCode = 0x11
+	SecurityResponseCode_NOT_KEY_SERVER                 SecurityResponseCode = 0x12
+	SecurityResponseCode_SECURITY_NOT_CONFIGURED        SecurityResponseCode = 0x13
+	SecurityResponseCode_SOURCE_SECURITY_REQUIRED       SecurityResponseCode = 0x14
+	SecurityResponseCode_TOO_MANY_KEYS                  SecurityResponseCode = 0x15
+	SecurityResponseCode_UNKNOWN_AUTHENTICATION_TYPE    SecurityResponseCode = 0x16
+	SecurityResponseCode_UNKNOWN_KEY                    SecurityResponseCode = 0x17
+	SecurityResponseCode_UNKNOWN_KEY_REVISION           SecurityResponseCode = 0x18
+	SecurityResponseCode_UNKNOWN_SOURCE_MESSAGE         SecurityResponseCode = 0x19
+)
+
+var SecurityResponseCodeValues []SecurityResponseCode
+
+func init() {
+	_ = errors.New
+	SecurityResponseCodeValues = []SecurityResponseCode{
+		SecurityResponseCode_SUCCESS,
+		SecurityResponseCode_ACCESS_DENIED,
+		SecurityResponseCode_BAD_DESTINATION_ADDRESS,
+		SecurityResponseCode_BAD_DESTINATION_DEVICE_ID,
+		SecurityResponseCode_BAD_SIGNATURE,
+		SecurityResponseCode_BAD_SOURCE_ADDRESS,
+		SecurityResponseCode_BAD_TIMESTAMP,
+		SecurityResponseCode_CANNOT_USE_KEY,
+		SecurityResponseCode_CANNOT_VERIFY_MESSAGE_ID,
+		SecurityResponseCode_CORRECT_KEY_REVISION,
+		SecurityResponseCode_DESTINATION_DEVICE_ID_REQUIRED,
+		SecurityResponseCode_DUPLICATE_MESSAGE,
+		SecurityResponseCode_ENCRYPTION_NOT_CONFIGURED,
+		SecurityResponseCode_ENCRYPTION_REQUIRED,
+		SecurityResponseCode_INCORRECT_KEY,
+		SecurityResponseCode_INVALID_KEY_DATA,
+		SecurityResponseCode_KEY_UPDATE_IN_PROGRESS,
+		SecurityResponseCode_MALFORMED_MESSAGE,
+		SecurityResponseCode_NOT_KEY_SERVER,
+		SecurityResponseCode_SECURITY_NOT_CONFIGURED,
+		SecurityResponseCode_SOURCE_SECURITY_REQUIRED,
+		SecurityResponseCode_TOO_MANY_KEYS,
+		SecurityResponseCode_UNKNOWN_AUTHENTICATION_TYPE,
+		SecurityResponseCode_UNKNOWN_KEY,
+		SecurityResponseCode_UNKNOWN_KEY_REVISION,
+		SecurityResponseCode_UNKNOWN_SOURCE_MESSAGE,
+	}
+}
+
+func SecurityResponseCodeByValue(value uint8) (enum SecurityResponseCode, ok bool) {
+	switch value {
+	case 0x00:
+		return SecurityResponseCode_SUCCESS, true
+	case 0x01:
+		return SecurityResponseCode_ACCESS_DENIED, true
+	case 0x02:
+		return SecurityResponseCode_BAD_DESTINATION_ADDRESS, true
+	case 0x03:
+		return SecurityResponseCode_BAD_DESTINATION_DEVICE_ID, true
+	case 0x04:
+		return SecurityResponseCode_BAD_SIGNATURE, true
+	case 0x05:
+		return SecurityResponseCode_BAD_SOURCE_ADDRESS, true
+	case 0x06:
+		return SecurityResponseCode_BAD_TIMESTAMP, true
+	case 0x07:
+		return SecurityResponseCode_CANNOT_USE_KEY, true
+	case 0x08:
+		return SecurityResponseCode_CANNOT_VERIFY_MESSAGE_ID, true
+	case 0x09:
+		return SecurityResponseCode_CORRECT_KEY_REVISION, true
+	case 0x0A:
+		return SecurityResponseCode_DESTINATION_DEVICE_ID_REQUIRED, true
+	case 0x0B:
+		return SecurityResponseCode_DUPLICATE_MESSAGE, true
+	case 0x0C:
+		return SecurityResponseCode_ENCRYPTION_NOT_CONFIGURED, true
+	case 0x0D:
+		return SecurityResponseCode_ENCRYPTION_REQUIRED, true
+	case 0x0E:
+		return SecurityResponseCode_INCORRECT_KEY, true
+	case 0x0F:
+		return SecurityResponseCode_INVALID_KEY_DATA, true
+	case 0x10:
+		return SecurityResponseCode_KEY_UPDATE_IN_PROGRESS, true
+	case 0x11:
+		return SecurityResponseCode_MALFORMED_MESSAGE, true
+	case 0x12:
+		return SecurityResponseCode_NOT_KEY_SERVER, true
+	case 0x13:
+		return SecurityResponseCode_SECURITY_NOT_CONFIGURED, true
+	case 0x14:
+		return SecurityResponseCode_SOURCE_SECURITY_REQUIRED, true
+	case 0x15:
+		return SecurityResponseCode_TOO_MANY_KEYS, true
+	case 0x16:
+		return SecurityResponseCode_UNKNOWN_AUTHENTICATION_TYPE, true
+	case 0x17:
+		return SecurityResponseCode_UNKNOWN_KEY, true
+	case 0x18:
+		return SecurityResponseCode_UNKNOWN_KEY_REVISION, true
+	case 0x19:
+		return SecurityResponseCode_UNKNOWN_SOURCE_MESSAGE, true
+	}
+	return 0, false
+}
+
+func SecurityResponseCodeByName(value string) (enum SecurityResponseCode, ok bool) {
+	switch value {
+	case "SUCCESS":
+		return SecurityResponseCode_SUCCESS, true
+	case "ACCESS_DENIED":
+		return SecurityResponseCode_ACCESS_DENIED, true
+	case "BAD_DESTINATION_ADDRESS":
+		return SecurityResponseCode_BAD_DESTINATION_ADDRESS, true
+	case "BAD_DESTINATION_DEVICE_ID":
+		return SecurityResponseCode_BAD_DESTINATION_DEVICE_ID, true
+	case "BAD_SIGNATURE":
+		return SecurityResponseCode_BAD_SIGNATURE, true
+	case "BAD_SOURCE_ADDRESS":
+		return SecurityResponseCode_BAD_SOURCE_ADDRESS, true
+	case "BAD_TIMESTAMP":
+		return SecurityResponseCode_BAD_TIMESTAMP, true
+	case "CANNOT_USE_KEY":
+		return SecurityResponseCode_CANNOT_USE_KEY, true
+	case "CANNOT_VERIFY_MESSAGE_ID":
+		return SecurityResponseCode_CANNOT_VERIFY_MESSAGE_ID, true
+	case "CORRECT_KEY_REVISION":
+		return SecurityResponseCode_CORRECT_KEY_REVISION, true
+	case "DESTINATION_DEVICE_ID_REQUIRED":
+		return SecurityResponseCode_DESTINATION_DEVICE_ID_REQUIRED, true
+	case "DUPLICATE_MESSAGE":
+		return SecurityResponseCode_DUPLICATE_MESSAGE, true
+	case "ENCRYPTION_NOT_CONFIGURED":
+		return SecurityResponseCode_ENCRYPTION_NOT_CONFIGURED, true
+	case "ENCRYPTION_REQUIRED":
+		return SecurityResponseCode_ENCRYPTION_REQUIRED, true
+	case "INCORRECT_KEY":
+		return SecurityResponseCode_INCORRECT_KEY, true
+	case "INVALID_KEY_DATA":
+		return SecurityResponseCode_INVALID_KEY_DATA, true
+	case "KEY_UPDATE_IN_PROGRESS":
+		return SecurityResponseCode_KEY_UPDATE_IN_PROGRESS, true
+	case "MALFORMED_MESSAGE":
+		return SecurityResponseCode_MALFORMED_MESSAGE, true
+	case "NOT_KEY_SERVER":
+		return SecurityResponseCode_NOT_KEY_SERVER, true
+	case "SECURITY_NOT_CONFIGURED":
+		return SecurityResponseCode_SECURITY_NOT_CONFIGURED, true
+	case "SOURCE_SECURITY_REQUIRED":
+		return SecurityResponseCode_SOURCE_SECURITY_REQUIRED, true
+	case "TOO_MANY_KEYS":
+		return SecurityResponseCode_TOO_MANY_KEYS, true
+	case "UNKNOWN_AUTHENTICATION_TYPE":
+		return SecurityResponseCode_UNKNOWN_AUTHENTICATION_TYPE, true
+	case "UNKNOWN_KEY":
+		return SecurityResponseCode_UNKNOWN_KEY, true
+	case "UNKNOWN_KEY_REVISION":
+		return SecurityResponseCode_UNKNOWN_KEY_REVISION, true
+	case "UNKNOWN_SOURCE_MESSAGE":
+		return SecurityResponseCode_UNKNOWN_SOURCE_MESSAGE, true
+	}
+	return 0, false
+}
+
+func SecurityResponseCodeKnows(value uint8) bool {
+	for _, typeValue := range SecurityResponseCodeValues {
+		if uint8(typeValue) == value {
+			return true
+		}
+	}
+	return false
+}
+
+func CastSecurityResponseCode(structType interface{}) SecurityResponseCode {
+	castFunc := func(typ interface{}) SecurityResponseCode {
+		if sSecurityResponseCode, ok := typ.(SecurityResponseCode); ok {
+			return sSecurityResponseCode
+		}
+		return 0
+	}
+	return castFunc(structType)
+}
+
+func (m SecurityResponseCode) GetLengthInBits() uint16 {
+	return 8
+}
+
+func (m SecurityResponseCode) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func SecurityResponseCodeParse(theBytes []byte) (SecurityResponseCode, error) {
+	return SecurityResponseCodeParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian))) // TODO: get endianness from mspec
+}
+
+func SecurityResponseCodeParseWithBuffer(readBuffer utils.ReadBuffer) (SecurityResponseCode, error) {
+	val, err := readBuffer.ReadUint8("SecurityResponseCode", 8)
+	if err != nil {
+		return 0, errors.Wrap(err, "error reading SecurityResponseCode")
+	}
+	if enum, ok := SecurityResponseCodeByValue(val); !ok {
+		Plc4xModelLog.Debug().Msgf("no value %x found for RequestType", val)
+		return SecurityResponseCode(val), nil
+	} else {
+		return enum, nil
+	}
+}
+
+func (e SecurityResponseCode) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian)) // TODO: get endianness from mspec
+	if err := e.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (e SecurityResponseCode) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	return writeBuffer.WriteUint8("SecurityResponseCode", 8, uint8(e), utils.WithAdditionalStringRepresentation(e.PLC4XEnumName()))
+}
+
+// PLC4XEnumName returns the name that is used in code to identify this enum
+func (e SecurityResponseCode) PLC4XEnumName() string {
+	switch e {
+	case SecurityResponseCode_SUCCESS:
+		return "SUCCESS"
+	case SecurityResponseCode_ACCESS_DENIED:
+		return "ACCESS_DENIED"
+	case SecurityResponseCode_BAD_DESTINATION_ADDRESS:
+		return "BAD_DESTINATION_ADDRESS"
+	case SecurityResponseCode_BAD_DESTINATION_DEVICE_ID:
+		return "BAD_DESTINATION_DEVICE_ID"
+	case SecurityResponseCode_BAD_SIGNATURE:
+		return "BAD_SIGNATURE"
+	case SecurityResponseCode_BAD_SOURCE_ADDRESS:
+		return "BAD_SOURCE_ADDRESS"
+	case SecurityResponseCode_BAD_TIMESTAMP:
+		return "BAD_TIMESTAMP"
+	case SecurityResponseCode_CANNOT_USE_KEY:
+		return "CANNOT_USE_KEY"
+	case SecurityResponseCode_CANNOT_VERIFY_MESSAGE_ID:
+		return "CANNOT_VERIFY_MESSAGE_ID"
+	case SecurityResponseCode_CORRECT_KEY_REVISION:
+		return "CORRECT_KEY_REVISION"
+	case SecurityResponseCode_DESTINATION_DEVICE_ID_REQUIRED:
+		return "DESTINATION_DEVICE_ID_REQUIRED"
+	case SecurityResponseCode_DUPLICATE_MESSAGE:
+		return "DUPLICATE_MESSAGE"
+	case SecurityResponseCode_ENCRYPTION_NOT_CONFIGURED:
+		return "ENCRYPTION_NOT_CONFIGURED"
+	case SecurityResponseCode_ENCRYPTION_REQUIRED:
+		return "ENCRYPTION_REQUIRED"
+	case SecurityResponseCode_INCORRECT_KEY:
+		return "INCORRECT_KEY"
+	case SecurityResponseCode_INVALID_KEY_DATA:
+		return "INVALID_KEY_DATA"
+	case SecurityResponseCode_KEY_UPDATE_IN_PROGRESS:
+		return "KEY_UPDATE_IN_PROGRESS"
+	case SecurityResponseCode_MALFORMED_MESSAGE:
+		return "MALFORMED_MESSAGE"
+	case SecurityResponseCode_NOT_KEY_SERVER:
+		return "NOT_KEY_SERVER"
+	case SecurityResponseCode_SECURITY_NOT_CONFIGURED:
+		return "SECURITY_NOT_CONFIGURED"
+	case SecurityResponseCode_SOURCE_SECURITY_REQUIRED:
+		return "SOURCE_SECURITY_REQUIRED"
+	case SecurityResponseCode_TOO_MANY_KEYS:
+		return "TOO_MANY_KEYS"
+	case SecurityResponseCode_UNKNOWN_AUTHENTICATION_TYPE:
+		return "UNKNOWN_AUTHENTICATION_TYPE"
+	case SecurityResponseCode_UNKNOWN_KEY:
+		return "UNKNOWN_KEY"
+	case SecurityResponseCode_UNKNOWN_KEY_REVISION:
+		return "UNKNOWN_KEY_REVISION"
+	case SecurityResponseCode_UNKNOWN_SOURCE_MESSAGE:
+		return "UNKNOWN_SOURCE_MESSAGE"
+	}
+	return ""
+}
+
+func (e SecurityResponseCode) String() string {
+	return e.PLC4XEnumName()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/SecurityResponseCodeTagged.go b/plc4go/protocols/bacnetip/readwrite/model/SecurityResponseCodeTagged.go
new file mode 100644
index 0000000000..1dd48d15d3
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/SecurityResponseCodeTagged.go
@@ -0,0 +1,239 @@
+/*
+ * 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
+ *
+ *   https://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 (
+	"encoding/binary"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// SecurityResponseCodeTagged is the corresponding interface of SecurityResponseCodeTagged
+type SecurityResponseCodeTagged interface {
+	utils.LengthAware
+	utils.Serializable
+	// GetHeader returns Header (property field)
+	GetHeader() BACnetTagHeader
+	// GetValue returns Value (property field)
+	GetValue() SecurityResponseCode
+}
+
+// SecurityResponseCodeTaggedExactly can be used when we want exactly this type and not a type which fulfills SecurityResponseCodeTagged.
+// This is useful for switch cases.
+type SecurityResponseCodeTaggedExactly interface {
+	SecurityResponseCodeTagged
+	isSecurityResponseCodeTagged() bool
+}
+
+// _SecurityResponseCodeTagged is the data-structure of this message
+type _SecurityResponseCodeTagged struct {
+	Header BACnetTagHeader
+	Value  SecurityResponseCode
+
+	// Arguments.
+	TagNumber uint8
+	TagClass  TagClass
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_SecurityResponseCodeTagged) GetHeader() BACnetTagHeader {
+	return m.Header
+}
+
+func (m *_SecurityResponseCodeTagged) GetValue() SecurityResponseCode {
+	return m.Value
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewSecurityResponseCodeTagged factory function for _SecurityResponseCodeTagged
+func NewSecurityResponseCodeTagged(header BACnetTagHeader, value SecurityResponseCode, tagNumber uint8, tagClass TagClass) *_SecurityResponseCodeTagged {
+	return &_SecurityResponseCodeTagged{Header: header, Value: value, TagNumber: tagNumber, TagClass: tagClass}
+}
+
+// Deprecated: use the interface for direct cast
+func CastSecurityResponseCodeTagged(structType interface{}) SecurityResponseCodeTagged {
+	if casted, ok := structType.(SecurityResponseCodeTagged); ok {
+		return casted
+	}
+	if casted, ok := structType.(*SecurityResponseCodeTagged); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_SecurityResponseCodeTagged) GetTypeName() string {
+	return "SecurityResponseCodeTagged"
+}
+
+func (m *_SecurityResponseCodeTagged) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_SecurityResponseCodeTagged) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(0)
+
+	// Simple field (header)
+	lengthInBits += m.Header.GetLengthInBits()
+
+	// Manual Field (value)
+	lengthInBits += uint16(int32(m.GetHeader().GetActualLength()) * int32(int32(8)))
+
+	return lengthInBits
+}
+
+func (m *_SecurityResponseCodeTagged) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func SecurityResponseCodeTaggedParse(theBytes []byte, tagNumber uint8, tagClass TagClass) (SecurityResponseCodeTagged, error) {
+	return SecurityResponseCodeTaggedParseWithBuffer(utils.NewReadBufferByteBased(theBytes, utils.WithByteOrderForReadBufferByteBased(binary.BigEndian)), tagNumber, tagClass) // TODO: get endianness from mspec
+}
+
+func SecurityResponseCodeTaggedParseWithBuffer(readBuffer utils.ReadBuffer, tagNumber uint8, tagClass TagClass) (SecurityResponseCodeTagged, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("SecurityResponseCodeTagged"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for SecurityResponseCodeTagged")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (header)
+	if pullErr := readBuffer.PullContext("header"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for header")
+	}
+	_header, _headerErr := BACnetTagHeaderParseWithBuffer(readBuffer)
+	if _headerErr != nil {
+		return nil, errors.Wrap(_headerErr, "Error parsing 'header' field of SecurityResponseCodeTagged")
+	}
+	header := _header.(BACnetTagHeader)
+	if closeErr := readBuffer.CloseContext("header"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for header")
+	}
+
+	// Validation
+	if !(bool((header.GetTagClass()) == (tagClass))) {
+		return nil, errors.WithStack(utils.ParseValidationError{"tag class doesn't match"})
+	}
+
+	// Validation
+	if !(bool((bool((header.GetTagClass()) == (TagClass_APPLICATION_TAGS)))) || bool((bool((header.GetActualTagNumber()) == (tagNumber))))) {
+		return nil, errors.WithStack(utils.ParseAssertError{"tagnumber doesn't match"})
+	}
+
+	// Manual Field (value)
+	_value, _valueErr := ReadEnumGenericFailing(readBuffer, header.GetActualLength(), SecurityResponseCode_SUCCESS)
+	if _valueErr != nil {
+		return nil, errors.Wrap(_valueErr, "Error parsing 'value' field of SecurityResponseCodeTagged")
+	}
+	var value SecurityResponseCode
+	if _value != nil {
+		value = _value.(SecurityResponseCode)
+	}
+
+	if closeErr := readBuffer.CloseContext("SecurityResponseCodeTagged"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for SecurityResponseCodeTagged")
+	}
+
+	// Create the instance
+	return &_SecurityResponseCodeTagged{
+		TagNumber: tagNumber,
+		TagClass:  tagClass,
+		Header:    header,
+		Value:     value,
+	}, nil
+}
+
+func (m *_SecurityResponseCodeTagged) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian), utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes()))) // TODO: get endianness from mspec
+	if err := m.SerializeWithWriteBuffer(wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m *_SecurityResponseCodeTagged) SerializeWithWriteBuffer(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	if pushErr := writeBuffer.PushContext("SecurityResponseCodeTagged"); pushErr != nil {
+		return errors.Wrap(pushErr, "Error pushing for SecurityResponseCodeTagged")
+	}
+
+	// Simple Field (header)
+	if pushErr := writeBuffer.PushContext("header"); pushErr != nil {
+		return errors.Wrap(pushErr, "Error pushing for header")
+	}
+	_headerErr := writeBuffer.WriteSerializable(m.GetHeader())
+	if popErr := writeBuffer.PopContext("header"); popErr != nil {
+		return errors.Wrap(popErr, "Error popping for header")
+	}
+	if _headerErr != nil {
+		return errors.Wrap(_headerErr, "Error serializing 'header' field")
+	}
+
+	// Manual Field (value)
+	_valueErr := WriteEnumGeneric(writeBuffer, m.GetValue())
+	if _valueErr != nil {
+		return errors.Wrap(_valueErr, "Error serializing 'value' field")
+	}
+
+	if popErr := writeBuffer.PopContext("SecurityResponseCodeTagged"); popErr != nil {
+		return errors.Wrap(popErr, "Error popping for SecurityResponseCodeTagged")
+	}
+	return nil
+}
+
+////
+// Arguments Getter
+
+func (m *_SecurityResponseCodeTagged) GetTagNumber() uint8 {
+	return m.TagNumber
+}
+func (m *_SecurityResponseCodeTagged) GetTagClass() TagClass {
+	return m.TagClass
+}
+
+//
+////
+
+func (m *_SecurityResponseCodeTagged) isSecurityResponseCodeTagged() bool {
+	return true
+}
+
+func (m *_SecurityResponseCodeTagged) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnet-private-enums.mspec b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnet-private-enums.mspec
index 77060b9768..640ca53ed4 100644
--- a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnet-private-enums.mspec
+++ b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnet-private-enums.mspec
@@ -518,3 +518,33 @@
     ['0xE' RESERVED_BY_ASHRAE_09    ]
     ['0xF' RESERVED_BY_ASHRAE_10    ]
 ]
+
+// Attention: No proprietary extension allowed
+[enum uint 8 SecurityResponseCode
+    ['0x00' SUCCESS                         ]
+    ['0x01' ACCESS_DENIED                   ]
+    ['0x02' BAD_DESTINATION_ADDRESS         ]
+    ['0x03' BAD_DESTINATION_DEVICE_ID       ]
+    ['0x04' BAD_SIGNATURE                   ]
+    ['0x05' BAD_SOURCE_ADDRESS              ]
+    ['0x06' BAD_TIMESTAMP                   ]
+    ['0x07' CANNOT_USE_KEY                  ]
+    ['0x08' CANNOT_VERIFY_MESSAGE_ID        ]
+    ['0x09' CORRECT_KEY_REVISION            ]
+    ['0x0A' DESTINATION_DEVICE_ID_REQUIRED  ]
+    ['0x0B' DUPLICATE_MESSAGE               ]
+    ['0x0C' ENCRYPTION_NOT_CONFIGURED       ]
+    ['0x0D' ENCRYPTION_REQUIRED             ]
+    ['0x0E' INCORRECT_KEY                   ]
+    ['0x0F' INVALID_KEY_DATA                ]
+    ['0x10' KEY_UPDATE_IN_PROGRESS          ]
+    ['0x11' MALFORMED_MESSAGE               ]
+    ['0x12' NOT_KEY_SERVER                  ]
+    ['0x13' SECURITY_NOT_CONFIGURED         ]
+    ['0x14' SOURCE_SECURITY_REQUIRED        ]
+    ['0x15' TOO_MANY_KEYS                   ]
+    ['0x16' UNKNOWN_AUTHENTICATION_TYPE     ]
+    ['0x17' UNKNOWN_KEY                     ]
+    ['0x18' UNKNOWN_KEY_REVISION            ]
+    ['0x19' UNKNOWN_SOURCE_MESSAGE          ]
+]
diff --git a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
index 91149d7962..0af5248f08 100644
--- a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
+++ b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
@@ -133,49 +133,120 @@
 
 [discriminatedType NLM(uint 16 apduLength)
     [discriminator uint 8   messageType                   ]
-    [optional      BACnetVendorId
-                            vendorId '(messageType >= 128) && (messageType <= 255)']
-    [typeSwitch messageType
-        ['0x00' *WhoIsRouterToNetwork(uint 8 messageType)
-            [array      uint 16     destinationNetworkAddress length 'apduLength - (((messageType >= 128) && (messageType <= 255)) ? 3 : 1)']
+    [virtual       bit      isVendorProprietaryMessage 'messageType >= 128']
+    [typeSwitch messageType, isVendorProprietaryMessage
+        ['0x00' *WhoIsRouterToNetwork
+            [array      uint 16     destinationNetworkAddress length 'apduLength - 1']
         ]
-        ['0x01' *IAmRouterToNetwork(uint 8 messageType)
-            [array      uint 16     destinationNetworkAddress length 'apduLength - (((messageType >= 128) && (messageType <= 255)) ? 3 : 1)']
+        ['0x01' *IAmRouterToNetwork
+            [array      uint 16     destinationNetworkAddress length 'apduLength - 1']
         ]
-        ['0x02' *ICouldBeRouterToNetwork(uint 8 messageType)
+        ['0x02' *ICouldBeRouterToNetwork
             [simple   uint 16     destinationNetworkAddress   ]
             [simple   uint 8      performanceIndex            ]
         ]
-        ['0x03' *RejectRouterToNetwork(uint 8 messageType)
+        ['0x03' *RejectRouterToNetwork
             [simple   NLMRejectRouterToNetworkRejectReason
                                     rejectReason              ]
             [simple   uint 16     destinationNetworkAddress   ]
         ]
-        ['0x04' *RouterBusyToNetwork(uint 8 messageType)
-            [array      uint 16     destinationNetworkAddress length 'apduLength - (((messageType >= 128) && (messageType <= 255)) ? 3 : 1)']
+        ['0x04' *RouterBusyToNetwork
+            [array    uint 16     destinationNetworkAddress length 'apduLength - 1']
         ]
-        ['0x05' *RouterAvailableToNetwork(uint 8 messageType)
-            [array      uint 16     destinationNetworkAddress length 'apduLength - (((messageType >= 128) && (messageType <= 255)) ? 3 : 1)']
+        ['0x05' *RouterAvailableToNetwork
+            [array    uint 16     destinationNetworkAddress length 'apduLength - 1']
         ]
-        ['0x06' *InitalizeRoutingTable(uint 8 messageType)
+        ['0x06' *InitalizeRoutingTable
             [simple   uint 8      numberOfPorts               ]
-            [array      NLMInitalizeRoutingTablePortMapping
+            [array    NLMInitalizeRoutingTablePortMapping
                                     portMappings
                         count 'numberOfPorts'                 ]
         ]
-        ['0x07' *InitalizeRoutingTableAck(uint 8 messageType)
+        ['0x07' *InitalizeRoutingTableAck
             [simple   uint 8      numberOfPorts               ]
-            [array      NLMInitalizeRoutingTablePortMapping
+            [array    NLMInitalizeRoutingTablePortMapping
                                     portMappings
                         count 'numberOfPorts'                 ]
         ]
-        ['0x08' *EstablishConnectionToNetwork(uint 8 messageType)
+        ['0x08' *EstablishConnectionToNetwork
             [simple   uint 16     destinationNetworkAddress   ]
             [simple   uint 8      terminationTime             ]
         ]
-        ['0x09' *DisconnectConnectionToNetwork(uint 8 messageType)
+        ['0x09' *DisconnectConnectionToNetwork
             [simple   uint 16     destinationNetworkAddress   ]
         ]
+        ['0x0A' *ChallengeRequest
+            [simple   byte        messageChallenge            ]
+            [simple   uint 32     originalMessageId           ]
+            [simple   uint 32     originalTimestamp           ]
+        ]
+        ['0x0B' *SecurityPayload
+            [simple   uint 16     payloadLength               ]
+            [array    byte        payload length 'payloadLength']
+        ]
+        ['0x0C' *SecurityResponse
+            [simple   SecurityResponseCode
+                                  responseCode                ]
+            [simple   uint 32     originalMessageId           ]
+            [simple   uint 32     originalTimestamp           ]
+            // TODO: type out variable parameters
+            [array    byte      variableParameters length 'apduLength-(1+1+4+4)'            ]
+        ]
+        ['0x0D' *RequestKeyUpdate
+            [simple   byte      set1KeyRevision              ]
+            [simple   uint 32   set1ActivationTime           ]
+            [simple   uint 32   set1ExpirationTime           ]
+            [simple   byte      set2KeyRevision              ]
+            [simple   uint 32   set2ActivationTime           ]
+            [simple   uint 32   set2ExpirationTime           ]
+            [simple   byte      distributionKeyRevision      ]
+        ]
+        ['0x0E' *UpdateKeyUpdate
+            [simple   NLMUpdateKeyUpdateControlFlags
+                                controlFlags                 ]
+            [optional byte      set1KeyRevision     'controlFlags.set1KeyRevisionActivationTimeExpirationTimePresent'   ]
+            [optional uint 32   set1ActivationTime  'controlFlags.set1KeyRevisionActivationTimeExpirationTimePresent'   ]
+            [optional uint 32   set1ExpirationTime  'controlFlags.set1KeyCountKeyParametersPresent'                     ]
+            [optional uint 8    set1KeyCount        'controlFlags.set1KeyCountKeyParametersPresent'                     ]
+            [array    NLMUpdateKeyUpdateKeyEntry
+                                set1Keys count 'set1KeyCount!=null?set1KeyCount:0'                                      ]
+            [optional byte      set2KeyRevision     'controlFlags.set1KeyRevisionActivationTimeExpirationTimePresent'   ]
+            [optional uint 32   set2ActivationTime  'controlFlags.set1KeyRevisionActivationTimeExpirationTimePresent'   ]
+            [optional uint 32   set2ExpirationTime  'controlFlags.set1KeyCountKeyParametersPresent'                     ]
+            [optional uint 8    set2KeyCount        'controlFlags.set1KeyCountKeyParametersPresent'                     ]
+            [array    NLMUpdateKeyUpdateKeyEntry
+                                set2Keys count 'set1KeyCount!=null?set1KeyCount:0'                                      ]
+        ]
+        ['0x0F' *UpdateKeyDistributionKey
+            [simple   byte      keyRevision                 ]
+            [simple   NLMUpdateKeyUpdateKeyEntry
+                                key                         ]
+        ]
+        ['0x10' *RequestMasterKey
+            [simple   uint 8    numberOfSupportedKeyAlgorithms  ]
+            [array    byte      encryptionAndSignatureAlgorithms
+                                    length  'apduLength-2'      ] // TODO: type those
+        ]
+        ['0x11' *SetMasterKey
+            [simple   NLMUpdateKeyUpdateKeyEntry
+                                key                         ]
+        ]
+        ['0x12' *WhatIsNetworkNumber
+            // No content
+        ]
+        ['0x13' *NetworkNumberIs
+            [simple   uint 16   networkNumber               ]
+            [reserved uint 7    '0'                         ]
+            [simple   bit       networkNumberConfigured     ]
+        ]
+        [*,'false' *Reserved
+            [array    byte      unknownBytes length '(apduLength>0)?(apduLength-1):0'       ]
+        ]
+        [* *VendorProprietaryMessage
+            [simple   BACnetVendorId
+                                vendorId]
+            [array    byte      proprietaryMessage length '(apduLength>0)?(apduLength-3):0' ]
+        ]
     ]
 ]
 
@@ -183,7 +254,24 @@
     [simple   uint 16     destinationNetworkAddress       ]
     [simple   uint 8      portId                          ]
     [simple   uint 8      portInfoLength                  ]
-    [array      byte        portInfo count 'portInfoLength' ]
+    [array    byte        portInfo count 'portInfoLength' ]
+]
+
+[type NLMUpdateKeyUpdateControlFlags
+    [simple   bit       set1KeyRevisionActivationTimeExpirationTimePresent  ]
+    [simple   bit       set1KeyCountKeyParametersPresent                    ]
+    [simple   bit       set1ShouldBeCleared                                 ]
+    [simple   bit       set2KeyRevisionActivationTimeExpirationTimePresent  ]
+    [simple   bit       set2KeyCountKeyParametersPresent                    ]
+    [simple   bit       set2ShouldBeCleared                                 ]
+    [simple   bit       moreMessagesToBeExpected                            ]
+    [simple   bit       removeAllKeys                                       ]
+]
+
+[type NLMUpdateKeyUpdateKeyEntry
+    [simple   uint 16   keyIdentifier                   ]
+    [simple   uint 8    keySize                         ]
+    [array    byte      key length 'keySize'            ]
 ]
 
 [discriminatedType APDU(uint 16 apduLength)