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 2024/08/25 10:25:28 UTC

(plc4x) branch develop updated: fix(plc4go/bacnetip): fixed several issues

This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new 4d178af29d fix(plc4go/bacnetip): fixed several issues
4d178af29d is described below

commit 4d178af29dd18111435bebfffd8952649457e0eb
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Sun Aug 25 12:25:21 2024 +0200

    fix(plc4go/bacnetip): fixed several issues
    
    - enabled several tests
---
 plc4go/internal/bacnetip/PDU.go                    |  25 ++
 plc4go/internal/bacnetip/apdu.go                   | 475 ++++++++++++++++++++-
 plc4go/internal/bacnetip/constructeddata.go        | 178 ++++++++
 .../internal/bacnetip/{ => constructors}/apdu.go   |  32 +-
 .../{apdu.go => constructors/constructeddata.go}   |  36 +-
 .../bacnetip/{apdu.go => constructors/pdu.go}      |  42 +-
 .../bacnetip/constructors/primitivedata.go         | 286 +++++++++++++
 plc4go/internal/bacnetip/primitivedata.go          |   8 +
 plc4go/internal/bacnetip/tests/state_machine.go    |  16 +-
 .../test_primitive_data/test_bit_string_test.go    |   9 +-
 .../tests/test_primitive_data/test_boolean_test.go |  16 +-
 .../test_character_string_test.go                  |  16 +-
 .../tests/test_primitive_data/test_date_test.go    |  16 +-
 .../tests/test_primitive_data/test_double_test.go  |  16 +-
 .../test_primitive_data/test_enumerated_test.go    |   9 +-
 .../tests/test_primitive_data/test_integer_test.go |  17 +-
 .../tests/test_primitive_data/test_null_test.go    |  16 +-
 .../test_object_identifier_test.go                 |  16 +-
 .../test_primitive_data/test_object_type_test.go   |  16 +-
 .../test_primitive_data/test_octet_string_test.go  |  16 +-
 .../tests/test_primitive_data/test_real_test.go    |  16 +-
 .../tests/test_primitive_data/test_tag_test.go     |  45 +-
 .../tests/test_primitive_data/test_time_test.go    |  16 +-
 .../test_primitive_data/test_unsigned_test.go      |  46 +-
 .../tests/test_segmentation/test_1_test.go         | 124 +-----
 .../test_utilities/test_state_machine_test.go      |   5 +-
 .../tests/test_vlan/test_ipnetwork_test.go         | 109 ++---
 .../bacnetip/tests/test_vlan/test_network_test.go  |  11 -
 plc4go/internal/bacnetip/tests/util.go             |  28 +-
 plc4go/internal/bacnetip/vlan.go                   |  13 +-
 30 files changed, 1109 insertions(+), 565 deletions(-)

diff --git a/plc4go/internal/bacnetip/PDU.go b/plc4go/internal/bacnetip/PDU.go
index 6b11b91f05..c4b4c24fe5 100644
--- a/plc4go/internal/bacnetip/PDU.go
+++ b/plc4go/internal/bacnetip/PDU.go
@@ -652,6 +652,14 @@ func (a *Address) Equals(other any) bool {
 			a.log.Debug().Str("thisString", thisString).Str("otherString", otherString).Msg("Mismatch")
 		}
 		return equals
+	case AddressTuple[string, uint16]:
+		thisString := a.AddrTuple.String()
+		otherString := other.String()
+		equals := thisString == otherString
+		if !equals {
+			a.log.Debug().Str("thisString", thisString).Str("otherString", otherString).Msg("Mismatch")
+		}
+		return equals
 	case *AddressTuple[string, uint16]:
 		thisString := a.AddrTuple.String()
 		otherString := other.String()
@@ -660,7 +668,24 @@ func (a *Address) Equals(other any) bool {
 			a.log.Debug().Str("thisString", thisString).Str("otherString", otherString).Msg("Mismatch")
 		}
 		return equals
+	case AddressTuple[string, int]:
+		thisString := a.AddrTuple.String()
+		otherString := other.String()
+		equals := thisString == otherString
+		if !equals {
+			a.log.Debug().Str("thisString", thisString).Str("otherString", otherString).Msg("Mismatch")
+		}
+		return equals
+	case *AddressTuple[string, int]:
+		thisString := a.AddrTuple.String()
+		otherString := other.String()
+		equals := thisString == otherString
+		if !equals {
+			a.log.Debug().Str("thisString", thisString).Str("otherString", otherString).Msg("Mismatch")
+		}
+		return equals
 	default:
+		a.log.Debug().Type("otherType", other).Msg("Unmapped type comparison")
 		return false
 	}
 }
diff --git a/plc4go/internal/bacnetip/apdu.go b/plc4go/internal/bacnetip/apdu.go
index 22b9546345..7826a7b8bf 100644
--- a/plc4go/internal/bacnetip/apdu.go
+++ b/plc4go/internal/bacnetip/apdu.go
@@ -47,4 +47,477 @@ type ___APDU struct {
 	*__APDU
 }
 
-//TODO: implement it...
+// TODO: implement it...
+type ConfirmedRequestPDU struct {
+	*__APDU
+}
+
+// TODO: implement it...
+type UnconfirmedRequestPDU struct {
+	*__APDU
+}
+
+// TODO: implement it...
+type SimpleAckPDU struct {
+	*__APDU
+}
+
+// TODO: implement it...
+type ComplexAckPDU struct {
+	*__APDU
+}
+
+// TODO: implement it...
+type SegmentAckPDU struct {
+	*__APDU
+}
+
+// TODO: implement it...
+type ErrorPDU struct {
+	*__APDU
+}
+
+// TODO: implement it...
+type RejectReason struct {
+	*Enumerated
+}
+
+// TODO: implement it...
+type RejectPDU struct {
+	*__APDU
+}
+
+// TODO: implement it...
+type AbortReason struct {
+	*Enumerated
+}
+
+// TODO: implement it...
+type AbortPDU struct {
+	*__APDU
+}
+
+// TODO: implement it...
+type APCISequence struct {
+	*_APCI
+	*Sequence
+}
+
+// TODO: implement it...
+type ConfirmedRequestSequence struct {
+	*APCISequence
+	*ConfirmedRequestPDU
+}
+
+// TODO: implement it...
+type ComplexAckSequence struct {
+	*APCISequence
+	*ComplexAckPDU
+}
+
+// TODO: implement it...
+type UnconfirmedRequestSequence struct {
+	*APCISequence
+	*UnconfirmedRequestPDU
+}
+
+// TODO: implement it...
+type ErrorSequence struct {
+	*APCISequence
+	*ErrorPDU
+}
+
+// TODO: implement it...
+type Error struct {
+}
+
+// TODO: implement it...
+type ChangeListError struct {
+}
+
+// TODO: implement it...
+type CreateObjectError struct {
+}
+
+// TODO: implement it...
+type ConfirmedPrivateTransferError struct {
+}
+
+// TODO: implement it...
+type WritePropertyMultipleError struct {
+}
+
+// TODO: implement it...
+type VTCloseError struct {
+}
+
+// TODO: implement it...
+type ReadPropertyRequest struct {
+}
+
+// TODO: implement it...
+type ReadPropertyACK struct {
+}
+
+// TODO: implement it...
+type ReadAccessSpecification struct {
+}
+
+// TODO: implement it...
+type ReadPropertyMultipleRequest struct {
+}
+
+// TODO: implement it...
+type ReadAccessResultElementChoice struct {
+}
+
+// TODO: implement it...
+type ReadAccessResultElement struct {
+}
+
+// TODO: implement it...
+type ReadAccessResult struct {
+}
+
+// TODO: implement it...
+type ReadPropertyMultipleACK struct {
+}
+
+// TODO: implement it...
+type RangeByPosition struct {
+}
+
+// TODO: implement it...
+type RangeBySequenceNumber struct {
+}
+
+// TODO: implement it...
+type RangeByTime struct {
+}
+
+// TODO: implement it...
+type Range struct {
+}
+
+// TODO: implement it...
+type ReadRangeRequest struct {
+}
+
+// TODO: implement it...
+type ReadRangeACK struct {
+}
+
+// TODO: implement it...
+type WritePropertyRequest struct {
+}
+
+// TODO: implement it...
+type WriteAccessSpecification struct {
+}
+
+// TODO: implement it...
+type WritePropertyMultipleRequest struct {
+}
+
+// TODO: implement it...
+type GroupChannelValue struct {
+}
+
+// TODO: implement it...
+type WriteGroupRequest struct {
+}
+
+// TODO: implement it...
+type IAmRequest struct {
+}
+
+// TODO: implement it...
+type IHaveRequest struct {
+}
+
+// TODO: implement it...
+type WhoHasLimits struct {
+}
+
+// TODO: implement it...
+type WhoHasObject struct {
+}
+
+// TODO: implement it...
+type WhoHasRequest struct {
+}
+
+// TODO: implement it...
+type WhoIsRequest struct {
+}
+
+// TODO: implement it...
+type EventNotificationParameters struct {
+}
+
+// TODO: implement it...
+type ConfirmedEventNotificationRequest struct {
+}
+
+// TODO: implement it...
+type UnconfirmedEventNotificationRequest struct {
+}
+
+// TODO: implement it...
+type COVNotificationParameters struct {
+}
+
+// TODO: implement it...
+type ConfirmedCOVNotificationRequest struct {
+}
+
+// TODO: implement it...
+type UnconfirmedCOVNotificationRequest struct {
+}
+
+// TODO: implement it...
+type UnconfirmedPrivateTransferRequest struct {
+}
+
+// TODO: implement it...
+type UnconfirmedTextMessageRequestMessageClass struct {
+}
+
+// TODO: implement it...
+type UnconfirmedTextMessageRequestMessagePriority struct {
+}
+
+// TODO: implement it...
+type UnconfirmedTextMessageRequest struct {
+}
+
+// TODO: implement it...
+type TimeSynchronizationRequest struct {
+}
+
+// TODO: implement it...
+type UTCTimeSynchronizationRequest struct {
+}
+
+// TODO: implement it...
+type AcknowledgeAlarmRequest struct {
+}
+
+// TODO: implement it...
+type GetAlarmSummaryRequest struct {
+}
+
+// TODO: implement it...
+type GetAlarmSummaryAlarmSummary struct {
+}
+
+// TODO: implement it...
+type GetAlarmSummaryACK struct {
+}
+
+// TODO: implement it...
+type GetEnrollmentSummaryRequestAcknowledgmentFilterType struct {
+}
+
+// TODO: implement it...
+type GetEnrollmentSummaryRequestEventStateFilterType struct {
+}
+
+// TODO: implement it...
+type GetEnrollmentSummaryRequestPriorityFilterType struct {
+}
+
+// TODO: implement it...
+type GetEnrollmentSummaryRequest struct {
+}
+
+// TODO: implement it...
+type GetEnrollmentSummaryEnrollmentSummary struct {
+}
+
+// TODO: implement it...
+type GetEnrollmentSummaryACK struct {
+}
+
+// TODO: implement it...
+type GetEventInformationRequest struct {
+}
+
+// TODO: implement it...
+type GetEventInformationEventSummary struct {
+}
+
+// TODO: implement it...
+type GetEventInformationACK struct {
+}
+
+// TODO: implement it...
+type LifeSafetyOperationRequest struct {
+}
+
+// TODO: implement it...
+type SubscribeCOVRequest struct {
+}
+
+// TODO: implement it...
+type SubscribeCOVPropertyRequest struct {
+}
+
+// TODO: implement it...
+type AtomicReadFileRequestAccessMethodChoiceStreamAccess struct {
+}
+
+// TODO: implement it...
+type AtomicReadFileRequestAccessMethodChoiceRecordAccess struct {
+}
+
+// TODO: implement it...
+type AtomicReadFileRequestAccessMethodChoice struct {
+}
+
+// TODO: implement it...
+type AtomicReadFileRequest struct {
+}
+
+// TODO: implement it...
+type AtomicReadFileACKAccessMethodStreamAccess struct {
+}
+
+// TODO: implement it...
+type AtomicReadFileACKAccessMethodRecordAccess struct {
+}
+
+// TODO: implement it...
+type AtomicReadFileACKAccessMethodChoice struct {
+}
+
+// TODO: implement it...
+type AtomicReadFileACK struct {
+}
+
+// TODO: implement it...
+type AtomicWriteFileRequestAccessMethodChoiceStreamAccess struct {
+}
+
+// TODO: implement it...
+type AtomicWriteFileRequestAccessMethodChoiceRecordAccess struct {
+}
+
+// TODO: implement it...
+type AtomicWriteFileRequestAccessMethodChoice struct {
+}
+
+// TODO: implement it...
+type AtomicWriteFileRequest struct {
+}
+
+// TODO: implement it...
+type AtomicWriteFileACK struct {
+}
+
+// TODO: implement it...
+type AddListElementRequest struct {
+}
+
+// TODO: implement it...
+type CreateObjectRequestObjectSpecifier struct {
+}
+
+// TODO: implement it...
+type CreateObjectRequest struct {
+}
+
+// TODO: implement it...
+type CreateObjectACK struct {
+}
+
+// TODO: implement it...
+type DeleteObjectRequest struct {
+}
+
+// TODO: implement it...
+type RemoveListElementRequest struct {
+}
+
+// TODO: implement it...
+type DeviceCommunicationControlRequestEnableDisable struct {
+}
+
+// TODO: implement it...
+type DeviceCommunicationControlRequest struct {
+}
+
+// TODO: implement it...
+type ConfirmedPrivateTransferRequest struct {
+	*ConfirmedRequestSequence
+}
+
+func NewConfirmedPrivateTransferRequest() *ConfirmedPrivateTransferRequest {
+	c := &ConfirmedPrivateTransferRequest{}
+	panic("implement me")
+	return c
+}
+
+// TODO: implement it...
+type ConfirmedPrivateTransferACK struct {
+}
+
+// TODO: implement it...
+type ConfirmedTextMessageRequestMessageClass struct {
+}
+
+// TODO: implement it...
+type ConfirmedTextMessageRequestMessagePriority struct {
+}
+
+// TODO: implement it...
+type ConfirmedTextMessageRequest struct {
+}
+
+// TODO: implement it...
+type ReinitializeDeviceRequestReinitializedStateOfDevice struct {
+}
+
+// TODO: implement it...
+type ReinitializeDeviceRequest struct {
+}
+
+// TODO: implement it...
+type VTOpenRequest struct {
+}
+
+// TODO: implement it...
+type VTOpenACK struct {
+}
+
+// TODO: implement it...
+type VTCloseRequest struct {
+}
+
+// TODO: implement it...
+type VTDataRequest struct {
+}
+
+// TODO: implement it...
+type VTDataACK struct {
+}
+
+// TODO: implement it...
+type AuthenticateRequest struct {
+}
+
+// TODO: implement it...
+type AuthenticateACK struct {
+}
+
+// TODO: implement it...
+type RequestKeyRequest struct {
+}
+
+// TODO: implement it...
+type ConfirmedServiceChoice struct {
+}
+
+// TODO: implement it...
+type UnconfirmedServiceChoice struct {
+}
diff --git a/plc4go/internal/bacnetip/constructeddata.go b/plc4go/internal/bacnetip/constructeddata.go
new file mode 100644
index 0000000000..32371c4941
--- /dev/null
+++ b/plc4go/internal/bacnetip/constructeddata.go
@@ -0,0 +1,178 @@
+/*
+ * 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 bacnetip
+
+import "github.com/pkg/errors"
+
+// TODO: finish
+type Element struct {
+}
+
+// TODO: finish
+type Sequence struct {
+}
+
+// TODO: finish
+type List struct {
+}
+
+// TODO: finish
+type Array struct {
+}
+
+// TODO: finish
+type Choice struct {
+}
+
+type AnyContract interface {
+	Encode(taglist TagList) error
+	Decode(taglist TagList) error
+	castIn(arg Arg) error
+	castOut(arg Arg) error
+}
+
+type Any struct {
+	AnyContract
+
+	tagList TagList
+}
+
+func NewAny(args Args, opts ...func(*Any)) (*Any, error) {
+	a := &Any{}
+	for _, opt := range opts {
+		opt(a)
+	}
+	if a.AnyContract == nil {
+		a.AnyContract = a
+	}
+
+	// cast the args
+	for _, arg := range args {
+		if err := a.castIn(arg); err != nil {
+			return nil, errors.Wrapf(err, "error casting arg %v", arg)
+		}
+	}
+	return a, nil
+}
+
+func WithAnyContract(contract AnyContract) func(*Any) {
+	return func(a *Any) {
+		a.AnyContract = contract
+	}
+}
+
+func (a *Any) Encode(tagList TagList) error {
+	a.tagList.Extend(tagList.tagList...)
+	return nil
+}
+
+func (a *Any) Decode(tagList TagList) error {
+	lvl := 0
+	for len(tagList.tagList) != 0 {
+		tag := tagList.Peek()
+		if tag.GetTagClass() == TagOpeningTagClass {
+			lvl++
+		} else if tag.GetTagClass() == TagClosingTagClass {
+			lvl--
+			if lvl < 0 {
+				break
+			}
+		}
+		a.tagList.Append(tagList.Pop())
+	}
+
+	// make sure everything balances
+	if lvl > 0 {
+		return errors.New("mismatched open/close tags")
+	}
+	return nil
+}
+
+func (a *Any) castIn(element Arg) error {
+	t := NewTagList(nil)
+	switch element.(type) {
+	case IsAtomic:
+		tag, err := NewTag(nil)
+		if err != nil {
+			return errors.New("error creating empty tag")
+		}
+		if err := element.(interface{ Encode(arg Arg) error }).Encode(tag); err != nil {
+			return errors.New("error encoding element")
+		}
+		t.Append(tag)
+	case IsAnyAtomic:
+		tag, err := NewTag(nil)
+		if err != nil {
+			return errors.New("error creating empty tag")
+		}
+		if err := element.(interface{ GetValue() any }).GetValue().(interface{ Encode(Tag) error }).Encode(tag); err != nil {
+			return errors.New("error encoding element")
+		}
+		t.Append(tag)
+	default:
+		if err := element.(interface{ Encode(arg Arg) error }).Encode(t); err != nil {
+			return errors.New("error encoding element")
+		}
+	}
+	a.tagList.Extend(t.tagList...)
+	return nil
+}
+
+func (a *Any) castOut(element Arg) error {
+	panic("implement me")
+	return nil
+}
+
+type IsAnyAtomic interface {
+	isAnyAtomic() bool
+}
+
+// TODO: finish me
+type AnyAtomic struct {
+	//*Atomic[int] // TODO: maybe we can't use that again
+
+	value any
+}
+
+func NewAnyAtomic(args Args, opts ...func(*AnyAtomic)) *AnyAtomic {
+	a := &AnyAtomic{}
+	for _, opt := range opts {
+		opt(a)
+	}
+	return a
+}
+
+func (a *AnyAtomic) GetValue() any {
+	return a.value
+}
+
+func (a *AnyAtomic) isAnyAtomic() bool {
+	return true
+}
+
+func (a *AnyAtomic) Encode(tag Tag) {}
+
+func (a *AnyAtomic) Decode(tag Tag) error {
+	return nil
+}
+
+// TODO: finish
+type SequenceOfAny struct {
+}
diff --git a/plc4go/internal/bacnetip/apdu.go b/plc4go/internal/bacnetip/constructors/apdu.go
similarity index 71%
copy from plc4go/internal/bacnetip/apdu.go
copy to plc4go/internal/bacnetip/constructors/apdu.go
index 22b9546345..6d9d704f32 100644
--- a/plc4go/internal/bacnetip/apdu.go
+++ b/plc4go/internal/bacnetip/constructors/apdu.go
@@ -17,34 +17,10 @@
  * under the License.
  */
 
-package bacnetip
+package constructors
 
-type APCI interface {
-	PCI
-}
-
-type _APCI struct {
-	*_PCI
-	*DebugContents
-}
-
-type APDU interface {
-	APCI
-	PDUData
-
-	GetApduInvokeID() *uint8 // TODO: check if we really need a pointer
-}
+import "github.com/apache/plc4x/plc4go/internal/bacnetip"
 
-type __APDU struct {
-	*_APCI
+func ConfirmedPrivateTransferRequest(kwargs bacnetip.KWArgs) *bacnetip.ConfirmedPrivateTransferRequest {
+	panic("implement me")
 }
-
-type _APDU interface {
-	APDU
-}
-
-type ___APDU struct {
-	*__APDU
-}
-
-//TODO: implement it...
diff --git a/plc4go/internal/bacnetip/apdu.go b/plc4go/internal/bacnetip/constructors/constructeddata.go
similarity index 71%
copy from plc4go/internal/bacnetip/apdu.go
copy to plc4go/internal/bacnetip/constructors/constructeddata.go
index 22b9546345..3768b859c3 100644
--- a/plc4go/internal/bacnetip/apdu.go
+++ b/plc4go/internal/bacnetip/constructors/constructeddata.go
@@ -17,34 +17,14 @@
  * under the License.
  */
 
-package bacnetip
+package constructors
 
-type APCI interface {
-	PCI
-}
-
-type _APCI struct {
-	*_PCI
-	*DebugContents
-}
-
-type APDU interface {
-	APCI
-	PDUData
-
-	GetApduInvokeID() *uint8 // TODO: check if we really need a pointer
-}
+import "github.com/apache/plc4x/plc4go/internal/bacnetip"
 
-type __APDU struct {
-	*_APCI
+func Any(args ...any) *bacnetip.Any {
+	newAny, err := bacnetip.NewAny(args)
+	if err != nil {
+		panic(err)
+	}
+	return newAny
 }
-
-type _APDU interface {
-	APDU
-}
-
-type ___APDU struct {
-	*__APDU
-}
-
-//TODO: implement it...
diff --git a/plc4go/internal/bacnetip/apdu.go b/plc4go/internal/bacnetip/constructors/pdu.go
similarity index 56%
copy from plc4go/internal/bacnetip/apdu.go
copy to plc4go/internal/bacnetip/constructors/pdu.go
index 22b9546345..0cc57a9b0d 100644
--- a/plc4go/internal/bacnetip/apdu.go
+++ b/plc4go/internal/bacnetip/constructors/pdu.go
@@ -17,34 +17,30 @@
  * under the License.
  */
 
-package bacnetip
+package constructors
 
-type APCI interface {
-	PCI
-}
-
-type _APCI struct {
-	*_PCI
-	*DebugContents
-}
+import (
+	"github.com/apache/plc4x/plc4go/internal/bacnetip"
 
-type APDU interface {
-	APCI
-	PDUData
+	"github.com/rs/zerolog"
+)
 
-	GetApduInvokeID() *uint8 // TODO: check if we really need a pointer
+func Address(args ...any) *bacnetip.Address {
+	address, err := bacnetip.NewAddress(zerolog.Nop(), args...)
+	if err != nil {
+		panic(err)
+	}
+	return address
 }
 
-type __APDU struct {
-	*_APCI
+func AddressTuple[L any, R any](l L, r R) *bacnetip.AddressTuple[L, R] {
+	return &bacnetip.AddressTuple[L, R]{Left: l, Right: r}
 }
 
-type _APDU interface {
-	APDU
+func PDUData(args ...any) bacnetip.PDUData {
+	if args == nil {
+		return bacnetip.NewPDUData(bacnetip.NewArgs(bacnetip.NewMessageBridge()))
+	} else {
+		return bacnetip.NewPDUData(bacnetip.NewArgs(bacnetip.NewMessageBridge(args[0].([]byte)...)))
+	}
 }
-
-type ___APDU struct {
-	*__APDU
-}
-
-//TODO: implement it...
diff --git a/plc4go/internal/bacnetip/constructors/primitivedata.go b/plc4go/internal/bacnetip/constructors/primitivedata.go
new file mode 100644
index 0000000000..b1204a9ff9
--- /dev/null
+++ b/plc4go/internal/bacnetip/constructors/primitivedata.go
@@ -0,0 +1,286 @@
+/*
+ * 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 constructors
+
+import (
+	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+)
+
+func BitString(args ...any) *bacnetip.BitString {
+	bitString, err := bacnetip.NewBitString(args)
+	if err != nil {
+		panic(err)
+	}
+	return bitString
+}
+
+func Boolean(arg ...any) *bacnetip.Boolean {
+	if len(arg) == 0 {
+		boolean, err := bacnetip.NewBoolean(nil)
+		if err != nil {
+			panic(err)
+		}
+		return boolean
+	}
+	boolean, err := bacnetip.NewBoolean(arg[0])
+	if err != nil {
+		panic(err)
+	}
+	return boolean
+}
+
+func CharacterString(arg ...any) *bacnetip.CharacterString {
+	if len(arg) == 0 {
+		CharacterString, err := bacnetip.NewCharacterString(nil)
+		if err != nil {
+			panic(err)
+		}
+		return CharacterString
+	}
+	CharacterString, err := bacnetip.NewCharacterString(arg[0])
+	if err != nil {
+		panic(err)
+	}
+	return CharacterString
+}
+
+func Date(arg ...any) *bacnetip.Date {
+	if len(arg) == 0 {
+		Date, err := bacnetip.NewDate(nil, nil)
+		if err != nil {
+			panic(err)
+		}
+		return Date
+	}
+	Date, err := bacnetip.NewDate(arg[0], nil)
+	if err != nil {
+		panic(err)
+	}
+	return Date
+}
+
+func Double(arg ...any) *bacnetip.Double {
+	if len(arg) == 0 {
+		Double, err := bacnetip.NewDouble(nil)
+		if err != nil {
+			panic(err)
+		}
+		return Double
+	}
+	Double, err := bacnetip.NewDouble(arg[0])
+	if err != nil {
+		panic(err)
+	}
+	return Double
+}
+
+func Enumerated(arg ...any) *bacnetip.Enumerated {
+	Enumerated, err := bacnetip.NewEnumerated(arg...)
+	if err != nil {
+		panic(err)
+	}
+	return Enumerated
+}
+
+func Integer(arg ...any) *bacnetip.Integer {
+	if len(arg) == 0 {
+		Integer, err := bacnetip.NewInteger(nil)
+		if err != nil {
+			panic(err)
+		}
+		return Integer
+	}
+	Integer, err := bacnetip.NewInteger(arg[0])
+	if err != nil {
+		panic(err)
+	}
+	return Integer
+}
+
+func Null(arg ...any) *bacnetip.Null {
+	if len(arg) == 0 {
+		Null, err := bacnetip.NewNull(nil)
+		if err != nil {
+			panic(err)
+		}
+		return Null
+	}
+	Null, err := bacnetip.NewNull(arg[0])
+	if err != nil {
+		panic(err)
+	}
+	return Null
+}
+
+func ObjectIdentifier(args ...any) *bacnetip.ObjectIdentifier {
+	if len(args) == 0 {
+		ObjectIdentifier, err := bacnetip.NewObjectIdentifier(nil)
+		if err != nil {
+			panic(err)
+		}
+		return ObjectIdentifier
+	}
+	ObjectIdentifier, err := bacnetip.NewObjectIdentifier(args)
+	if err != nil {
+		panic(err)
+	}
+	return ObjectIdentifier
+}
+
+func ObjectType(args ...any) *bacnetip.ObjectType {
+	if len(args) == 0 {
+		ObjectType, err := bacnetip.NewObjectType(nil)
+		if err != nil {
+			panic(err)
+		}
+		return ObjectType
+	}
+	ObjectType, err := bacnetip.NewObjectType(args)
+	if err != nil {
+		panic(err)
+	}
+	return ObjectType
+}
+
+func OctetString(args ...any) *bacnetip.OctetString {
+	if len(args) == 0 {
+		OctetString, err := bacnetip.NewOctetString(nil)
+		if err != nil {
+			panic(err)
+		}
+		return OctetString
+	}
+	OctetString, err := bacnetip.NewOctetString(args[0])
+	if err != nil {
+		panic(err)
+	}
+	return OctetString
+}
+
+func Real(arg ...any) *bacnetip.Real {
+	if len(arg) == 0 {
+		Real, err := bacnetip.NewReal(nil)
+		if err != nil {
+			panic(err)
+		}
+		return Real
+	}
+	Real, err := bacnetip.NewReal(arg[0])
+	if err != nil {
+		panic(err)
+	}
+	return Real
+}
+
+func ApplicationTag(args ...any) *bacnetip.ApplicationTag {
+	tag, err := bacnetip.NewApplicationTag(args)
+	if err != nil {
+		panic(err)
+	}
+	return tag
+}
+
+func ContextTag(args ...any) *bacnetip.ContextTag {
+	tag, err := bacnetip.NewContextTag(args)
+	if err != nil {
+		panic(err)
+	}
+	return tag
+}
+
+func OpeningTag(context any) *bacnetip.OpeningTag {
+	openingTag, err := bacnetip.NewOpeningTag(context)
+	if err != nil {
+		panic(err)
+	}
+	return openingTag
+}
+
+func ClosingTag(context any) *bacnetip.ClosingTag {
+	closingTag, err := bacnetip.NewClosingTag(context)
+	if err != nil {
+		panic(err)
+	}
+	return closingTag
+}
+
+func TagList(tags ...bacnetip.Tag) *bacnetip.TagList {
+	return bacnetip.NewTagList(tags)
+}
+
+func Time(arg ...any) *bacnetip.Time {
+	if len(arg) == 0 {
+		Time, err := bacnetip.NewTime(nil, nil)
+		if err != nil {
+			panic(err)
+		}
+		return Time
+	}
+	Time, err := bacnetip.NewTime(arg[0], nil)
+	if err != nil {
+		panic(err)
+	}
+	return Time
+}
+
+func Unsigned(arg ...any) *bacnetip.Unsigned {
+	if len(arg) == 0 {
+		unsigned, err := bacnetip.NewUnsigned(nil)
+		if err != nil {
+			panic(err)
+		}
+		return unsigned
+	}
+	unsigned, err := bacnetip.NewUnsigned(arg[0])
+	if err != nil {
+		panic(err)
+	}
+	return unsigned
+}
+
+func Unsigned8(arg ...any) *bacnetip.Unsigned8 {
+	if len(arg) == 0 {
+		unsigned, err := bacnetip.NewUnsigned8(nil)
+		if err != nil {
+			panic(err)
+		}
+		return unsigned
+	}
+	unsigned, err := bacnetip.NewUnsigned8(arg[0])
+	if err != nil {
+		panic(err)
+	}
+	return unsigned
+}
+
+func Unsigned16(arg ...any) *bacnetip.Unsigned16 {
+	if len(arg) == 0 {
+		unsigned, err := bacnetip.NewUnsigned16(nil)
+		if err != nil {
+			panic(err)
+		}
+		return unsigned
+	}
+	unsigned, err := bacnetip.NewUnsigned16(arg[0])
+	if err != nil {
+		panic(err)
+	}
+	return unsigned
+}
diff --git a/plc4go/internal/bacnetip/primitivedata.go b/plc4go/internal/bacnetip/primitivedata.go
index a1413748a0..29d9a24a59 100644
--- a/plc4go/internal/bacnetip/primitivedata.go
+++ b/plc4go/internal/bacnetip/primitivedata.go
@@ -687,6 +687,10 @@ type ComparableAndOrdered interface {
 	cmp.Ordered
 }
 
+type IsAtomic interface {
+	isAtomic() bool
+}
+
 // AtomicContract provides a set of functions which can be overwritten by a sub struct
 type AtomicContract[T ComparableAndOrdered] interface {
 	Compare(other any) int
@@ -718,6 +722,10 @@ func NewAtomic[T ComparableAndOrdered](subStruct interface {
 	}
 }
 
+func (a *Atomic[T]) isAtomic(bool) bool {
+	return true
+}
+
 func (a *Atomic[T]) Compare(other any) int {
 	otherValue := other.(AtomicContract[T]).GetValue()
 	// now compare the values
diff --git a/plc4go/internal/bacnetip/tests/state_machine.go b/plc4go/internal/bacnetip/tests/state_machine.go
index 6f5012548a..fab309b1da 100644
--- a/plc4go/internal/bacnetip/tests/state_machine.go
+++ b/plc4go/internal/bacnetip/tests/state_machine.go
@@ -156,10 +156,14 @@ func MatchPdu(localLog zerolog.Logger, pdu bacnetip.PDU, pduType any, pduAttrs m
 			}
 		case bacnetip.KWPDUData:
 			got := pdu.GetPduData()
-			want, ok := attrValue.([]byte)
-			if !ok {
-				attrLog.Debug().Msg("mismatch, attr not a byte array")
-				return false
+			var want []byte
+			switch attrValue := attrValue.(type) {
+			case []byte:
+				want = attrValue
+			case bacnetip.PDUData:
+				want = attrValue.GetPduData()
+			default:
+				attrLog.Debug().Type("type", attrValue).Msg("mismatch, attr unhandled")
 			}
 			equals := bytes.Equal(got, want)
 			if !equals {
@@ -828,9 +832,9 @@ func (s *state) Ignore(pduType any, pduAttrs map[bacnetip.KnownKey]any) State {
 	return s
 }
 
-// UnexpectedReceive Called with tPDU that did not match.  Unless this is trapped by the state, the default behaviour is
+// UnexpectedReceive Called with PDU that did not match.
 //
-//	to fail.
+// Unless this is trapped by the state, the default behaviour is to fail.
 func (s *state) UnexpectedReceive(pdu bacnetip.PDU) {
 	s.log.Debug().Stringer("pdu", pdu).Msg("UnexpectedReceive")
 	s.stateMachine.UnexpectedReceive(pdu)
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_bit_string_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_bit_string_test.go
index b8082424eb..02f1696175 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_bit_string_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_bit_string_test.go
@@ -23,20 +23,13 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
-func BitString(args ...any) *bacnetip.BitString {
-	bitString, err := bacnetip.NewBitString(args)
-	if err != nil {
-		panic(err)
-	}
-	return bitString
-}
-
 type sampleBitString struct {
 	*bacnetip.BitString
 	bitLen   int
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_boolean_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_boolean_test.go
index 96eaa17768..30d46c1e7a 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_boolean_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_boolean_test.go
@@ -23,26 +23,12 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 )
 
-func Boolean(arg ...any) *bacnetip.Boolean {
-	if len(arg) == 0 {
-		boolean, err := bacnetip.NewBoolean(nil)
-		if err != nil {
-			panic(err)
-		}
-		return boolean
-	}
-	boolean, err := bacnetip.NewBoolean(arg[0])
-	if err != nil {
-		panic(err)
-	}
-	return boolean
-}
-
 func booleanTag(value bool) bacnetip.Tag {
 	intValue := 0
 	if value {
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_character_string_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_character_string_test.go
index 75f48a92b8..2ced37c032 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_character_string_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_character_string_test.go
@@ -23,6 +23,7 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
@@ -31,21 +32,6 @@ import (
 
 const foxMessage = "the quick brown fox jumped over the lazy dog"
 
-func CharacterString(arg ...any) *bacnetip.CharacterString {
-	if len(arg) == 0 {
-		CharacterString, err := bacnetip.NewCharacterString(nil)
-		if err != nil {
-			panic(err)
-		}
-		return CharacterString
-	}
-	CharacterString, err := bacnetip.NewCharacterString(arg[0])
-	if err != nil {
-		panic(err)
-	}
-	return CharacterString
-}
-
 // Convert a hex string to a character_string application tag.
 func CharacterStringTag(x string) bacnetip.Tag {
 	b := xtob(x)
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_date_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_date_test.go
index 4f3acb4d6a..94197892b7 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_date_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_date_test.go
@@ -23,26 +23,12 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 )
 
-func Date(arg ...any) *bacnetip.Date {
-	if len(arg) == 0 {
-		Date, err := bacnetip.NewDate(nil, nil)
-		if err != nil {
-			panic(err)
-		}
-		return Date
-	}
-	Date, err := bacnetip.NewDate(arg[0], nil)
-	if err != nil {
-		panic(err)
-	}
-	return Date
-}
-
 // Convert a hex string to a character_string application tag.
 func DateTag(x string) bacnetip.Tag {
 	b := xtob(x)
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_double_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_double_test.go
index 582e505ef1..16d8496926 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_double_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_double_test.go
@@ -23,26 +23,12 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 )
 
-func Double(arg ...any) *bacnetip.Double {
-	if len(arg) == 0 {
-		Double, err := bacnetip.NewDouble(nil)
-		if err != nil {
-			panic(err)
-		}
-		return Double
-	}
-	Double, err := bacnetip.NewDouble(arg[0])
-	if err != nil {
-		panic(err)
-	}
-	return Double
-}
-
 func DoubleTag(x string) bacnetip.Tag {
 	b := xtob(x)
 	tag := Tag(model.TagClass_APPLICATION_TAGS, model.BACnetDataType_DOUBLE, len(b), b)
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_enumerated_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_enumerated_test.go
index 893089f617..7fa6078195 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_enumerated_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_enumerated_test.go
@@ -23,6 +23,7 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
@@ -54,14 +55,6 @@ func QuickBrownFox(args ...any) *quickBrownFox {
 	return q
 }
 
-func Enumerated(arg ...any) *bacnetip.Enumerated {
-	Enumerated, err := bacnetip.NewEnumerated(arg...)
-	if err != nil {
-		panic(err)
-	}
-	return Enumerated
-}
-
 func EnumeratedTag(x string) bacnetip.Tag {
 	b := xtob(x)
 	tag := Tag(model.TagClass_APPLICATION_TAGS, model.BACnetDataType_ENUMERATED, len(b), b)
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_integer_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_integer_test.go
index e8629144e5..abdede892d 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_integer_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_integer_test.go
@@ -24,28 +24,17 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 )
 
-func Integer(arg ...any) *bacnetip.Integer {
-	if len(arg) == 0 {
-		Integer, err := bacnetip.NewInteger(nil)
-		if err != nil {
-			panic(err)
-		}
-		return Integer
-	}
-	Integer, err := bacnetip.NewInteger(arg[0])
+func IntegerTag(x string) bacnetip.Tag {
+	b, err := bacnetip.Xtob(x)
 	if err != nil {
 		panic(err)
 	}
-	return Integer
-}
-
-func IntegerTag(x string) bacnetip.Tag {
-	b := xtob(x)
 	tag := Tag(model.TagClass_APPLICATION_TAGS, model.BACnetDataType_SIGNED_INTEGER, len(b), b)
 	return tag
 }
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_null_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_null_test.go
index 3c5ddce0fb..b4e9818135 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_null_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_null_test.go
@@ -23,26 +23,12 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 )
 
-func Null(arg ...any) *bacnetip.Null {
-	if len(arg) == 0 {
-		Null, err := bacnetip.NewNull(nil)
-		if err != nil {
-			panic(err)
-		}
-		return Null
-	}
-	Null, err := bacnetip.NewNull(arg[0])
-	if err != nil {
-		panic(err)
-	}
-	return Null
-}
-
 func NullTag(x string) bacnetip.Tag {
 	b := xtob(x)
 	tag := Tag(model.TagClass_APPLICATION_TAGS, model.BACnetDataType_NULL, len(b), b)
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_object_identifier_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_object_identifier_test.go
index 85c7cb49a4..ea41ce87ad 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_object_identifier_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_object_identifier_test.go
@@ -23,26 +23,12 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 )
 
-func ObjectIdentifier(args ...any) *bacnetip.ObjectIdentifier {
-	if len(args) == 0 {
-		ObjectIdentifier, err := bacnetip.NewObjectIdentifier(nil)
-		if err != nil {
-			panic(err)
-		}
-		return ObjectIdentifier
-	}
-	ObjectIdentifier, err := bacnetip.NewObjectIdentifier(args)
-	if err != nil {
-		panic(err)
-	}
-	return ObjectIdentifier
-}
-
 func ObjectIdentifierTag(x string) bacnetip.Tag {
 	b := xtob(x)
 	tag := Tag(model.TagClass_APPLICATION_TAGS, model.BACnetDataType_BACNET_OBJECT_IDENTIFIER, len(b), b)
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_object_type_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_object_type_test.go
index a7391a5192..f8934c26af 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_object_type_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_object_type_test.go
@@ -25,6 +25,7 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
@@ -68,21 +69,6 @@ func MyObjectType(args ...any) *myObjectType {
 	return o
 }
 
-func ObjectType(args ...any) *bacnetip.ObjectType {
-	if len(args) == 0 {
-		ObjectType, err := bacnetip.NewObjectType(nil)
-		if err != nil {
-			panic(err)
-		}
-		return ObjectType
-	}
-	ObjectType, err := bacnetip.NewObjectType(args)
-	if err != nil {
-		panic(err)
-	}
-	return ObjectType
-}
-
 func ObjectTypeTag(x string) bacnetip.Tag {
 	b := xtob(x)
 	tag := Tag(model.TagClass_APPLICATION_TAGS, model.BACnetDataType_ENUMERATED, len(b), b)
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_octet_string_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_octet_string_test.go
index aafa49a0a0..25c4f63177 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_octet_string_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_octet_string_test.go
@@ -23,26 +23,12 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 )
 
-func OctetString(args ...any) *bacnetip.OctetString {
-	if len(args) == 0 {
-		OctetString, err := bacnetip.NewOctetString(nil)
-		if err != nil {
-			panic(err)
-		}
-		return OctetString
-	}
-	OctetString, err := bacnetip.NewOctetString(args[0])
-	if err != nil {
-		panic(err)
-	}
-	return OctetString
-}
-
 func OctetStringTag(x string) bacnetip.Tag {
 	b := xtob(x)
 	tag := Tag(model.TagClass_APPLICATION_TAGS, model.BACnetDataType_OCTET_STRING, len(b), b)
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_real_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_real_test.go
index 042411f111..79f3c5886e 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_real_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_real_test.go
@@ -24,26 +24,12 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 )
 
-func Real(arg ...any) *bacnetip.Real {
-	if len(arg) == 0 {
-		Real, err := bacnetip.NewReal(nil)
-		if err != nil {
-			panic(err)
-		}
-		return Real
-	}
-	Real, err := bacnetip.NewReal(arg[0])
-	if err != nil {
-		panic(err)
-	}
-	return Real
-}
-
 func RealTag(x string) bacnetip.Tag {
 	b := xtob(x)
 	tag := Tag(model.TagClass_APPLICATION_TAGS, model.BACnetDataType_REAL, len(b), b)
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_tag_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_tag_test.go
index ac0800fc2d..44ca657b87 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_tag_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_tag_test.go
@@ -23,56 +23,13 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
-func ApplicationTag(args ...any) *bacnetip.ApplicationTag {
-	tag, err := bacnetip.NewApplicationTag(args)
-	if err != nil {
-		panic(err)
-	}
-	return tag
-}
-
-func ContextTag(args ...any) *bacnetip.ContextTag {
-	tag, err := bacnetip.NewContextTag(args)
-	if err != nil {
-		panic(err)
-	}
-	return tag
-}
-
-func OpeningTag(context any) *bacnetip.OpeningTag {
-	openingTag, err := bacnetip.NewOpeningTag(context)
-	if err != nil {
-		panic(err)
-	}
-	return openingTag
-}
-
-func ClosingTag(context any) *bacnetip.ClosingTag {
-	closingTag, err := bacnetip.NewClosingTag(context)
-	if err != nil {
-		panic(err)
-	}
-	return closingTag
-}
-
-func TagList(tags ...bacnetip.Tag) *bacnetip.TagList {
-	return bacnetip.NewTagList(tags)
-}
-
-func PDUData(args ...any) bacnetip.PDUData {
-	if args == nil {
-		return bacnetip.NewPDUData(bacnetip.NewArgs(bacnetip.NewMessageBridge()))
-	} else {
-		return bacnetip.NewPDUData(bacnetip.NewArgs(bacnetip.NewMessageBridge(args[0].([]byte)...)))
-	}
-}
-
 func TagTuple(tag bacnetip.Tag) (tagClass model.TagClass, tagNumber uint, tagLVT int, tagData []byte) {
 	return tag.GetTagClass(), tag.GetTagNumber(), tag.GetTagLvt(), tag.GetTagData()
 }
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_time_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_time_test.go
index 72007ea7ac..6afbf50be3 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_time_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_time_test.go
@@ -23,26 +23,12 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 )
 
-func Time(arg ...any) *bacnetip.Time {
-	if len(arg) == 0 {
-		Time, err := bacnetip.NewTime(nil, nil)
-		if err != nil {
-			panic(err)
-		}
-		return Time
-	}
-	Time, err := bacnetip.NewTime(arg[0], nil)
-	if err != nil {
-		panic(err)
-	}
-	return Time
-}
-
 // Convert a hex string to a character_string application tag.
 func timeTag(x string) bacnetip.Tag {
 	b := xtob(x)
diff --git a/plc4go/internal/bacnetip/tests/test_primitive_data/test_unsigned_test.go b/plc4go/internal/bacnetip/tests/test_primitive_data/test_unsigned_test.go
index 6e78dcbc9d..dcc288be9b 100644
--- a/plc4go/internal/bacnetip/tests/test_primitive_data/test_unsigned_test.go
+++ b/plc4go/internal/bacnetip/tests/test_primitive_data/test_unsigned_test.go
@@ -24,56 +24,12 @@ import (
 	"testing"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 
 	"github.com/stretchr/testify/assert"
 )
 
-func Unsigned(arg ...any) *bacnetip.Unsigned {
-	if len(arg) == 0 {
-		unsigned, err := bacnetip.NewUnsigned(nil)
-		if err != nil {
-			panic(err)
-		}
-		return unsigned
-	}
-	unsigned, err := bacnetip.NewUnsigned(arg[0])
-	if err != nil {
-		panic(err)
-	}
-	return unsigned
-}
-
-func Unsigned8(arg ...any) *bacnetip.Unsigned8 {
-	if len(arg) == 0 {
-		unsigned, err := bacnetip.NewUnsigned8(nil)
-		if err != nil {
-			panic(err)
-		}
-		return unsigned
-	}
-	unsigned, err := bacnetip.NewUnsigned8(arg[0])
-	if err != nil {
-		panic(err)
-	}
-	return unsigned
-}
-
-func Unsigned16(arg ...any) *bacnetip.Unsigned16 {
-	if len(arg) == 0 {
-		unsigned, err := bacnetip.NewUnsigned16(nil)
-		if err != nil {
-			panic(err)
-		}
-		return unsigned
-	}
-	unsigned, err := bacnetip.NewUnsigned16(arg[0])
-	if err != nil {
-		panic(err)
-	}
-	return unsigned
-}
-
 func UnsignedTag(x string) bacnetip.Tag {
 	b := xtob(x)
 	tag := Tag(model.TagClass_APPLICATION_TAGS, model.BACnetDataType_UNSIGNED_INTEGER, len(b), b)
diff --git a/plc4go/internal/bacnetip/tests/test_segmentation/test_1_test.go b/plc4go/internal/bacnetip/tests/test_segmentation/test_1_test.go
index 875f5b2239..c8e55c9d25 100644
--- a/plc4go/internal/bacnetip/tests/test_segmentation/test_1_test.go
+++ b/plc4go/internal/bacnetip/tests/test_segmentation/test_1_test.go
@@ -24,6 +24,7 @@ import (
 	"time"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/internal/bacnetip/tests"
 	"github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
 	"github.com/apache/plc4x/plc4go/spi/testutils"
@@ -52,13 +53,7 @@ func new_NetworkServiceElement(localLog zerolog.Logger) (*_NetworkServiceElement
 	return n, nil
 }
 
-type ApplicationNetworkRequirements interface {
-	Indication(args bacnetip.Args, kwargs bacnetip.KWArgs) error
-	Confirmation(args bacnetip.Args, kwargs bacnetip.KWArgs) error
-}
-
 type ApplicationNetwork struct {
-	ApplicationNetworkRequirements
 	*tests.StateMachineGroup
 
 	trafficLog *tests.TrafficLog
@@ -70,10 +65,9 @@ type ApplicationNetwork struct {
 	log zerolog.Logger
 }
 
-func NewApplicationNetwork(localLog zerolog.Logger, applicationNetworkRequirements ApplicationNetworkRequirements, tdDeviceObject, iutDeviceObject *bacnetip.LocalDeviceObject) (*ApplicationNetwork, error) {
+func NewApplicationNetwork(localLog zerolog.Logger, tdDeviceObject, iutDeviceObject *bacnetip.LocalDeviceObject) (*ApplicationNetwork, error) {
 	a := &ApplicationNetwork{
-		ApplicationNetworkRequirements: applicationNetworkRequirements,
-		log:                            localLog,
+		log: localLog,
 	}
 	a.StateMachineGroup = tests.NewStateMachineGroup(localLog)
 
@@ -94,14 +88,14 @@ func NewApplicationNetwork(localLog zerolog.Logger, applicationNetworkRequiremen
 	}
 
 	// test device
-	a.td, err = NewApplicationStateMachine(a.log, tdDeviceObject, a.vlan, a)
+	a.td, err = NewApplicationStateMachine(a.log, tdDeviceObject, a.vlan)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating application state machine")
 	}
 	a.Append(a.td)
 
 	// implementation under test
-	a.iut, err = NewApplicationStateMachine(a.log, iutDeviceObject, a.vlan, a)
+	a.iut, err = NewApplicationStateMachine(a.log, iutDeviceObject, a.vlan)
 	if err != nil {
 		return nil, errors.Wrap(err, "error creating application state machine")
 	}
@@ -228,12 +222,7 @@ func (s *SnifferNode) Confirmation(args bacnetip.Args, kwargs bacnetip.KWArgs) e
 	return nil
 }
 
-type ApplicationStateMachineRequirements interface {
-	Indication(args bacnetip.Args, kwargs bacnetip.KWArgs) error
-}
-
 type ApplicationStateMachine struct {
-	ApplicationStateMachineRequirements
 	*bacnetip.Application
 	tests.StateMachine
 
@@ -244,17 +233,18 @@ type ApplicationStateMachine struct {
 	nse     *_NetworkServiceElement
 	node    *bacnetip.Node
 
-	confirmedPrivateResult string
+	confirmedPrivateResult any
 
 	log zerolog.Logger
 }
 
-func NewApplicationStateMachine(localLog zerolog.Logger, localDevice *bacnetip.LocalDeviceObject, vlan *bacnetip.Network, applicationStateMachineRequirements ApplicationStateMachineRequirements) (*ApplicationStateMachine, error) {
+func NewApplicationStateMachine(localLog zerolog.Logger, localDevice *bacnetip.LocalDeviceObject, vlan *bacnetip.Network, opts ...func(*ApplicationStateMachine)) (*ApplicationStateMachine, error) {
 	a := &ApplicationStateMachine{
-		ApplicationStateMachineRequirements: applicationStateMachineRequirements,
-		log:                                 localLog,
+		log: localLog,
+	}
+	for _, opt := range opts {
+		opt(a)
 	}
-
 	// build and address and save it
 	_, instance := bacnetip.ObjectIdentifierStringToTuple(localDevice.ObjectIdentifier)
 	var err error
@@ -347,7 +337,7 @@ func (a *ApplicationStateMachine) Indication(args bacnetip.Args, kwargs bacnetip
 	}
 
 	// allow the application to process it
-	return a.ApplicationStateMachineRequirements.Indication(args, kwargs)
+	return a.Application.Indication(args, kwargs)
 }
 
 func (a *ApplicationStateMachine) Confirmation(args bacnetip.Args, kwargs bacnetip.KWArgs) error {
@@ -362,20 +352,8 @@ func (a *ApplicationStateMachine) doConfirmedPrivateTransferRequest(_ struct{})
 	// TODO: who calls that?
 }
 
-type TODOWHATTODOWITHTHAT struct {
-}
-
-func (T TODOWHATTODOWITHTHAT) Indication(args bacnetip.Args, kwargs bacnetip.KWArgs) error {
-	//TODO implement me
-	panic("implement me")
-}
-
-func (T TODOWHATTODOWITHTHAT) Confirmation(args bacnetip.Args, kwargs bacnetip.KWArgs) error {
-	//TODO implement me
-	panic("implement me")
-}
-
 func SegmentationTest(t *testing.T, prefix string, cLen, sLen int) {
+	t.Skip("not yet ready....") // TODO: finish it
 	tests.LockGlobalTimeMachine(t)
 	testingLogger := testutils.ProduceTestingLogger(t)
 	tests.NewGlobalTimeMachine(testingLogger)
@@ -405,7 +383,7 @@ func SegmentationTest(t *testing.T, prefix string, cLen, sLen int) {
 	}
 
 	// create a network
-	anet, err := NewApplicationNetwork(testingLogger, new(TODOWHATTODOWITHTHAT), tdDeviceObject, iutDeviceObject)
+	anet, err := NewApplicationNetwork(testingLogger, tdDeviceObject, iutDeviceObject)
 	require.NoError(t, err)
 
 	// tell the device info cache of the client about the server
@@ -439,68 +417,17 @@ func SegmentationTest(t *testing.T, prefix string, cLen, sLen int) {
 	}
 
 	if sLen != 0 {
-		anet.iut.confirmedPrivateResult = utils.RandomString(sLen)
-	}
-
-	wrapRequestString := func() (
-		numberOfDataElements model.BACnetApplicationTagUnsignedInteger,
-		data []model.BACnetConstructedDataElement,
-		openingTag model.BACnetOpeningTag,
-		peekedTagHeader model.BACnetTagHeader,
-		closingTag model.BACnetClosingTag,
-		tagNumber uint8,
-		arrayIndexArgument model.BACnetTagPayloadUnsignedInteger,
-	) {
-		numberOfDataElements = model.CreateBACnetApplicationTagUnsignedInteger(1)
-		elementArgCreator := func() (
-			peekedTagHeader model.BACnetTagHeader,
-			applicationTag model.BACnetApplicationTag,
-			contextTag model.BACnetContextTag,
-			constructedData model.BACnetConstructedData,
-			objectTypeArgument model.BACnetObjectType,
-			propertyIdentifierArgument model.BACnetPropertyIdentifier,
-			arrayIndexArgument model.BACnetTagPayloadUnsignedInteger,
-		) {
-			peekedTagHeader = model.CreateBACnetTagHeaderBalanced(false, 0, 0)
-			applicationTag = model.CreateBACnetApplicationTagCharacterString(model.BACnetCharacterEncoding_ISO_8859_1, requestString)
-			return
-		}
-		data = []model.BACnetConstructedDataElement{
-			model.NewBACnetConstructedDataElement(elementArgCreator()),
-		}
-		openingTag = model.CreateBACnetOpeningTag(2)
-		peekedTagHeader = model.CreateBACnetTagHeaderBalanced(false, 2, 2)
-		closingTag = model.CreateBACnetClosingTag(2)
-		return
-	}
-
-	cpt := model.NewBACnetConfirmedServiceRequestConfirmedPrivateTransfer(
-		model.CreateBACnetVendorIdContextTagged(0, 999),
-		model.CreateBACnetContextTagUnsignedInteger(1, 1),
-		model.NewBACnetConstructedDataUnspecified(wrapRequestString()),
-		0,
-	)
-
-	apdu := model.NewAPDUConfirmedRequest(
-		false,
-		false,
-		true,
-		maxSegmentsAccepted,
-		model.MaxApduLengthAccepted_NUM_OCTETS_1024,
-		0,
-		nil,
-		nil,
-		cpt,
-		nil,
-		nil,
-		0)
-
-	rq := bacnetip.NewPDU(apdu)
+		anet.iut.confirmedPrivateResult = Any(CharacterString(utils.RandomString(sLen)))
+	}
 
 	var trq model.BACnetServiceAckConfirmedPrivateTransfer
 	// send the request, get it acked
 	anet.td.GetStartState().Doc(prefix+"-0").
-		Send(rq, nil).Doc(prefix+"-1").
+		Send(bacnetip.NewPDU(ConfirmedPrivateTransferRequest(bacnetip.NewKWArgs(
+			"vendorId", 999, "serviceNumber", 1,
+			"serviceParameters", requestString,
+			"destination", anet.iut.address,
+		)), nil), nil).Doc(prefix+"-1").
 		Receive(bacnetip.NewArgs(trq), bacnetip.NoKWArgs).Doc(prefix + "-2").
 		Success("")
 
@@ -513,46 +440,37 @@ func SegmentationTest(t *testing.T, prefix string, cLen, sLen int) {
 }
 
 func Test1(t *testing.T) {
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	SegmentationTest(t, "7-1", 0, 0)
 }
 
 func Test2(t *testing.T) {
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	SegmentationTest(t, "7-2", 10, 0)
 }
 
 func Test3(t *testing.T) {
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	SegmentationTest(t, "7-3", 100, 0)
 }
 
 func Test4(t *testing.T) {
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	SegmentationTest(t, "7-4", 200, 0)
 }
 
 func Test5(t *testing.T) {
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	SegmentationTest(t, "7-5", 0, 10)
 }
 
 func Test6(t *testing.T) {
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	SegmentationTest(t, "7-6", 0, 200)
 }
 
 func Test7(t *testing.T) {
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	SegmentationTest(t, "7-7", 300, 0)
 }
 
 func Test8(t *testing.T) {
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	SegmentationTest(t, "7-8", 300, 300)
 }
 
 func Test9(t *testing.T) {
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	SegmentationTest(t, "7-9", 600, 600)
 }
diff --git a/plc4go/internal/bacnetip/tests/test_utilities/test_state_machine_test.go b/plc4go/internal/bacnetip/tests/test_utilities/test_state_machine_test.go
index 147ec8e0c4..7664c86a49 100644
--- a/plc4go/internal/bacnetip/tests/test_utilities/test_state_machine_test.go
+++ b/plc4go/internal/bacnetip/tests/test_utilities/test_state_machine_test.go
@@ -122,6 +122,7 @@ func (t TPDU) GetLengthInBits(ctx context.Context) uint16 {
 	//TODO implement me
 	panic("implement me")
 }
+
 func (t TPDU) GetPDUUserData() spi.Message {
 	//TODO implement me
 	panic("implement me")
@@ -576,9 +577,9 @@ func TestStateMachineTimeout1(t *testing.T) {
 }
 
 func TestStateMachineTimeout2(t *testing.T) {
-	t.Skip("not ready yet") // TODO: figure out why it is failing
-	tests.LockGlobalTimeMachine(t)
 	testingLogger := testutils.ProduceTestingLogger(t)
+	tests.NewGlobalTimeMachine(testingLogger) // TODO: this is really stupid because of concurrency...
+	tests.LockGlobalTimeMachine(t)
 
 	// make some pdus
 	firstPdu := TPDU{a: 1}
diff --git a/plc4go/internal/bacnetip/tests/test_vlan/test_ipnetwork_test.go b/plc4go/internal/bacnetip/tests/test_vlan/test_ipnetwork_test.go
index f25fd6eed9..deebc0a89c 100644
--- a/plc4go/internal/bacnetip/tests/test_vlan/test_ipnetwork_test.go
+++ b/plc4go/internal/bacnetip/tests/test_vlan/test_ipnetwork_test.go
@@ -21,10 +21,12 @@ package test_vlan
 
 import (
 	"fmt"
+	"strconv"
 	"testing"
 	"time"
 
 	"github.com/apache/plc4x/plc4go/internal/bacnetip"
+	. "github.com/apache/plc4x/plc4go/internal/bacnetip/constructors"
 	"github.com/apache/plc4x/plc4go/internal/bacnetip/tests"
 	"github.com/apache/plc4x/plc4go/spi/testutils"
 
@@ -59,7 +61,7 @@ func NewTIPNetwork(t *testing.T, nodeCount int, addressPattern string, promiscuo
 	for i := range nodeCount {
 		nodeAddress, err := bacnetip.NewAddress(localLog, fmt.Sprintf(addressPattern, i+1))
 		require.NoError(t, err)
-		node, err := bacnetip.NewIPNode(localLog, nodeAddress, tn.vlan, bacnetip.WithNodePromiscuous(promiscuous), bacnetip.WithNodeSpoofing(spoofing))
+		node, err := bacnetip.NewIPNode(localLog, nodeAddress, tn.vlan, bacnetip.WithNodePromiscuous(promiscuous), bacnetip.WithNodeSpoofing(spoofing), bacnetip.WithNodeName("node"+strconv.Itoa(i+1)))
 		require.NoError(t, err)
 
 		// bind a client state machine to the ndoe
@@ -109,6 +111,7 @@ func (t *TIPNetwork) Run(timeLimit time.Duration) error {
 
 func TestIPVLAN(t *testing.T) {
 	t.Run("test_idle", func(t *testing.T) { // Test that a very quiet network can exist. This is not a network test so much as a state machine group test
+		tests.NewGlobalTimeMachine(testutils.ProduceTestingLogger(t))
 		tests.LockGlobalTimeMachine(t)
 
 		// two element network
@@ -126,8 +129,7 @@ func TestIPVLAN(t *testing.T) {
 		assert.NoError(t, err)
 	})
 	t.Run("test_send_receive", func(t *testing.T) { // Test that a node can send a message to another node.
-		t.Skip("temporary disabled") // TODO: figure out why it is failing
-		testingLogger := testutils.ProduceTestingLogger(t)
+		tests.NewGlobalTimeMachine(testutils.ProduceTestingLogger(t))
 		tests.LockGlobalTimeMachine(t)
 
 		// two element network
@@ -137,26 +139,24 @@ func TestIPVLAN(t *testing.T) {
 		tnode1, tnode2 := stateMachines[0], stateMachines[1]
 
 		// make a PDU from node 1 to node 2
-		src, err := bacnetip.NewAddress(testingLogger, "192.168.2.1:47808")
-		require.NoError(t, err)
-		dest, err := bacnetip.NewAddress(testingLogger, "192.168.2.2:47808")
-		require.NoError(t, err)
-		pdu := bacnetip.NewPDU(nil, bacnetip.WithPDUSource(src), bacnetip.WithPDUDestination(dest))
+		pdu := bacnetip.NewPDU(tests.NewDummyMessage([]byte("data")...),
+			bacnetip.WithPDUSource(Address("192.168.2.1:47808")),
+			bacnetip.WithPDUDestination(Address("192.168.2.2:47808")),
+		)
 		t.Log(pdu)
 
 		// node 1 sends the pdu, mode 2 gets it
 		tnode1.GetStartState().Send(pdu, nil).Success("")
-		tnode2.GetStartState().Receive(bacnetip.NewArgs(bacnetip.NewPDU(nil)), bacnetip.NewKWArgs(
-			bacnetip.KWPPDUSource, src,
+		tnode2.GetStartState().Receive(bacnetip.NewArgs((bacnetip.PDU)(nil)), bacnetip.NewKWArgs(
+			bacnetip.KWPPDUSource, AddressTuple("192.168.2.1", 47808),
 		)).Success("")
 
 		// run the group
-		err = tnet.Run(0)
+		err := tnet.Run(0)
 		assert.NoError(t, err)
 	})
 	t.Run("test_broadcast", func(t *testing.T) { // Test that a node can send out a 'local broadcast' message which will be received by every other node.
-		t.Skip("not ready yet") // TODO: figure out why it is failing
-		testingLogger := testutils.ProduceTestingLogger(t)
+		tests.NewGlobalTimeMachine(testutils.ProduceTestingLogger(t))
 		tests.LockGlobalTimeMachine(t)
 
 		// three element network
@@ -165,30 +165,28 @@ func TestIPVLAN(t *testing.T) {
 		stateMachines := tnet.GetStateMachines()
 		tnode1, tnode2, tnode3 := stateMachines[0], stateMachines[1], stateMachines[2]
 
-		// make a PDU from node 1 to node 2
-		src, err := bacnetip.NewAddress(testingLogger, "192.168.3.1:47808")
-		require.NoError(t, err)
-		dest, err := bacnetip.NewAddress(testingLogger, "192.168.3.2:47808")
-		require.NoError(t, err)
-		pdu := bacnetip.NewPDU(nil, bacnetip.WithPDUSource(src), bacnetip.WithPDUDestination(dest))
+		// make a broadcast PDU
+		pdu := bacnetip.NewPDU(tests.NewDummyMessage([]byte("data")...),
+			bacnetip.WithPDUSource(Address("192.168.3.1:47808")),
+			bacnetip.WithPDUDestination(Address("192.168.3.255:47808")),
+		)
 		t.Log(pdu)
 
 		// node 1 sends the pdu, node 2 and 3 each get it
 		tnode1.GetStartState().Send(pdu, nil).Success("")
 		tnode2.GetStartState().Receive(bacnetip.NewArgs(bacnetip.NewPDU(nil)), bacnetip.NewKWArgs(
-			bacnetip.KWPPDUSource, src,
+			bacnetip.KWPPDUSource, AddressTuple("192.168.3.1", 47808),
 		)).Success("")
 		tnode3.GetStartState().Receive(bacnetip.NewArgs(bacnetip.NewPDU(nil)), bacnetip.NewKWArgs(
-			bacnetip.KWPPDUSource, src,
+			bacnetip.KWPPDUSource, AddressTuple("192.168.3.1", 47808),
 		)).Success("")
 
 		// run the group
-		err = tnet.Run(0)
+		err := tnet.Run(0)
 		assert.NoError(t, err)
 	})
 	t.Run("test_spoof_fail", func(t *testing.T) { // Test verifying that a node cannot send out packets with a source address other than its own, see also test_spoof_pass().
-		t.Skip("not ready yet") // TODO: figure out why it is failing
-		testingLogger := testutils.ProduceTestingLogger(t)
+		tests.NewGlobalTimeMachine(testutils.ProduceTestingLogger(t))
 		tests.LockGlobalTimeMachine(t)
 
 		// one element network
@@ -198,23 +196,21 @@ func TestIPVLAN(t *testing.T) {
 		tnode1 := stateMachines[0]
 
 		// make an unicast PDU with the wrong source
-		src, err := bacnetip.NewAddress(testingLogger, "192.168.4.1:47808")
-		require.NoError(t, err)
-		dest, err := bacnetip.NewAddress(testingLogger, "192.168.4.2:47808")
-		require.NoError(t, err)
-		pdu := bacnetip.NewPDU(nil, bacnetip.WithPDUSource(src), bacnetip.WithPDUDestination(dest))
+		pdu := bacnetip.NewPDU(tests.NewDummyMessage([]byte("data")...),
+			bacnetip.WithPDUSource(Address("192.168.4.2:47808")),
+			bacnetip.WithPDUDestination(Address("192.168.4.3:47808")),
+		)
 		t.Log(pdu)
 
-		// node 1 sends the pdu, node 2 and 3 each get it
+		// when the node attempts to send it raises an error
 		tnode1.GetStartState().Send(pdu, nil).Success("")
 
 		// run the group
-		err = tnet.Run(0)
+		err := tnet.Run(0)
 		assert.Error(t, err)
 	})
 	t.Run("test_spoof_pass", func(t *testing.T) { // Test allowing a node to send out packets with a source address other than its own, see also test_spoof_fail().
-		t.Skip("not ready yet") // TODO: figure out why it is failing
-		testingLogger := testutils.ProduceTestingLogger(t)
+		tests.NewGlobalTimeMachine(testutils.ProduceTestingLogger(t))
 		tests.LockGlobalTimeMachine(t)
 
 		// one element network
@@ -223,29 +219,28 @@ func TestIPVLAN(t *testing.T) {
 		stateMachines := tnet.GetStateMachines()
 		tnode1 := stateMachines[0]
 
-		// make an unicast PDU with the wrong source
-		src, err := bacnetip.NewAddress(testingLogger, "192.168.5.1:47808")
-		require.NoError(t, err)
-		dest, err := bacnetip.NewAddress(testingLogger, "192.168.5.2:47808")
-		require.NoError(t, err)
-		pdu := bacnetip.NewPDU(nil, bacnetip.WithPDUSource(src), bacnetip.WithPDUDestination(dest))
+		// make an unicast PDU from a fictitious node
+		pdu := bacnetip.NewPDU(tests.NewDummyMessage([]byte("data")...),
+			bacnetip.WithPDUSource(Address("192.168.5.3:47808")),
+			bacnetip.WithPDUDestination(Address("192.168.5.1:47808")),
+		)
 		t.Log(pdu)
 
 		// node 1 sends the pdu, but gets it back as if it was from node 3
 		tnode1.GetStartState().
 			Send(pdu, nil).
 			Receive(bacnetip.NewArgs(bacnetip.NewPDU(nil)), bacnetip.NewKWArgs(
-				bacnetip.KWPPDUSource, src,
+				bacnetip.KWPPDUSource, AddressTuple("192.168.5.3", 47808),
 			)).
 			Success("")
 
 		// run the group
-		err = tnet.Run(0)
+		err := tnet.Run(0)
 		assert.NoError(t, err)
 	})
 	t.Run("test_promiscuous_pass", func(t *testing.T) { // Test 'promiscuous mode' of a node which allows it to receive every packet sent on the network.  This is like the network is a hub, or the node is connected to a 'monitor' port on a managed switch.
-		t.Skip("temporary disabled") // TODO: figure out why it is failing
 		testingLogger := testutils.ProduceTestingLogger(t)
+		tests.NewGlobalTimeMachine(testutils.ProduceTestingLogger(t))
 		tests.LockGlobalTimeMachine(t)
 
 		// three element network
@@ -276,9 +271,8 @@ func TestIPVLAN(t *testing.T) {
 		assert.NoError(t, err)
 	})
 	t.Run("test_promiscuous_fail", func(t *testing.T) {
-		// TODO: figure out why it is failing
-		t.Skip("not ready yet")
 		testingLogger := testutils.ProduceTestingLogger(t)
+		tests.NewGlobalTimeMachine(testutils.ProduceTestingLogger(t))
 		tests.LockGlobalTimeMachine(t)
 
 		// three element network
@@ -320,8 +314,8 @@ type RouterSuite struct {
 
 func (suite *RouterSuite) SetupTest() {
 	t := suite.T()
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	suite.log = testutils.ProduceTestingLogger(t)
+	tests.NewGlobalTimeMachine(suite.log)
 	// create a state machine group that has all nodes on all networks
 	suite.smg = tests.NewStateMachineGroup(suite.log)
 
@@ -331,12 +325,8 @@ func (suite *RouterSuite) SetupTest() {
 
 	// make a router and add the networks
 	trouter := bacnetip.NewIPRouter(suite.log)
-	vlan10Addr, err := bacnetip.NewAddress(suite.log, "192.168.10.1/24")
-	suite.NoError(err)
-	vlan20Addr, err := bacnetip.NewAddress(suite.log, "192.168.20.1/24")
-	suite.NoError(err)
-	trouter.AddNetwork(vlan10Addr, vlan10)
-	trouter.AddNetwork(vlan20Addr, vlan20)
+	trouter.AddNetwork(Address("192.168.10.1/24"), vlan10)
+	trouter.AddNetwork(Address("192.168.20.1/24"), vlan20)
 
 	for pattern, lan := range map[string]*bacnetip.IPNetwork{
 		"192.168.10.%d/24": vlan10,
@@ -347,6 +337,7 @@ func (suite *RouterSuite) SetupTest() {
 			suite.NoError(err)
 			node, err := bacnetip.NewIPNode(suite.log, nodeAddress, lan)
 			suite.NoError(err)
+			t.Logf("Node: %v", node)
 
 			// bind a client state machine to the node
 			csm, err := tests.NewClientStateMachine(suite.log)
@@ -361,8 +352,6 @@ func (suite *RouterSuite) SetupTest() {
 }
 
 func (suite *RouterSuite) TearDownTest() {
-	t := suite.T()
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	// reset the time machine
 	tests.ResetTimeMachine(tests.StartTime)
 	suite.T().Log("time machine reset")
@@ -393,24 +382,22 @@ func (suite *RouterSuite) TestIdle() {
 
 func (suite *RouterSuite) TestSendReceive() { // Test that a node can send a message to another node.
 	t := suite.T()
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	tests.LockGlobalTimeMachine(t)
 
+	//unpack the state machines
 	stateMachines := suite.smg.GetStateMachines()
 	csm_10_2, csm_10_3, csm_20_2, csm_20_3 := stateMachines[0], stateMachines[1], stateMachines[2], stateMachines[3]
 
 	// make a PDU from network 10 node 1 to network 20 node 2
-	src, err := bacnetip.NewAddress(suite.log, "192.168.10.2:47808")
-	require.NoError(t, err)
-	dest, err := bacnetip.NewAddress(suite.log, "192.168.20.3:47808")
-	require.NoError(t, err)
-	pdu := bacnetip.NewPDU(nil, bacnetip.WithPDUSource(src), bacnetip.WithPDUDestination(dest))
+	pdu := bacnetip.NewPDU(tests.NewDummyMessage([]byte("data")...),
+		bacnetip.WithPDUSource(Address("192.168.10.2:47808")),
+		bacnetip.WithPDUDestination(Address("192.168.20.3:47808")))
 	t.Log(pdu)
 
 	// node 1 sends the pdu, mode 2 gets it
 	csm_10_2.GetStartState().Send(pdu, nil).Success("")
 	csm_20_3.GetStartState().Receive(bacnetip.NewArgs(bacnetip.NewPDU(nil)), bacnetip.NewKWArgs(
-		bacnetip.KWPPDUSource, src,
+		bacnetip.KWPPDUSource, AddressTuple("192.168.10.2", 47808),
 	)).Success("")
 
 	// other nodes get nothing
@@ -420,7 +407,6 @@ func (suite *RouterSuite) TestSendReceive() { // Test that a node can send a mes
 
 func (suite *RouterSuite) TestLocalBroadcast() { // Test that a node can send a message to all of the other nodes on the same network.
 	t := suite.T()
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	tests.LockGlobalTimeMachine(t)
 
 	stateMachines := suite.smg.GetStateMachines()
@@ -445,7 +431,6 @@ func (suite *RouterSuite) TestLocalBroadcast() { // Test that a node can send a
 
 func (suite *RouterSuite) TestRemoteBroadcast() { // Test that a node can send a message to all of the other nodes on a different network.
 	t := suite.T()
-	t.Skip("not ready yet") // TODO: figure out why it is failing
 	tests.LockGlobalTimeMachine(t)
 
 	stateMachines := suite.smg.GetStateMachines()
diff --git a/plc4go/internal/bacnetip/tests/test_vlan/test_network_test.go b/plc4go/internal/bacnetip/tests/test_vlan/test_network_test.go
index 2535fa5e0a..9202d7c8ce 100644
--- a/plc4go/internal/bacnetip/tests/test_vlan/test_network_test.go
+++ b/plc4go/internal/bacnetip/tests/test_vlan/test_network_test.go
@@ -126,8 +126,6 @@ func TestVLAN(t *testing.T) {
 		assert.NoError(t, err)
 	})
 	t.Run("test_send_receive", func(t *testing.T) { // Test that a node can send a message to another node.
-		// TODO: figure out why it is failing
-		t.Skip("not ready yet")
 		testingLogger := testutils.ProduceTestingLogger(t)
 		tests.LockGlobalTimeMachine(t)
 
@@ -156,8 +154,6 @@ func TestVLAN(t *testing.T) {
 		assert.NoError(t, err)
 	})
 	t.Run("test_broadcast", func(t *testing.T) { // Test that a node can send out a 'local broadcast' message which will be received by every other node.
-		// TODO: figure out why it is failing
-		t.Skip("not ready yet")
 		testingLogger := testutils.ProduceTestingLogger(t)
 		tests.LockGlobalTimeMachine(t)
 
@@ -214,8 +210,6 @@ func TestVLAN(t *testing.T) {
 		assert.Error(t, err)
 	})
 	t.Run("test_spoof_pass", func(t *testing.T) { // Test allowing a node to send out packets with a source address other than its own, see also test_spoof_fail().
-		// TODO: figure out why it is failing
-		t.Skip("not ready yet")
 		testingLogger := testutils.ProduceTestingLogger(t)
 		tests.LockGlobalTimeMachine(t)
 
@@ -246,8 +240,6 @@ func TestVLAN(t *testing.T) {
 		assert.NoError(t, err)
 	})
 	t.Run("test_promiscuous_pass", func(t *testing.T) { // Test 'promiscuous mode' of a node which allows it to receive every packet sent on the network.  This is like the network is a hub, or the node is connected to a 'monitor' port on a managed switch.
-		// TODO: figure out why it is failing
-		t.Skip("not ready yet")
 		testingLogger := testutils.ProduceTestingLogger(t)
 		tests.LockGlobalTimeMachine(t)
 
@@ -279,8 +271,6 @@ func TestVLAN(t *testing.T) {
 		assert.NoError(t, err)
 	})
 	t.Run("test_promiscuous_fail", func(t *testing.T) {
-		// TODO: figure out why it is failing
-		t.Skip("not ready yet")
 		testingLogger := testutils.ProduceTestingLogger(t)
 		tests.LockGlobalTimeMachine(t)
 
@@ -315,7 +305,6 @@ func TestVLAN(t *testing.T) {
 
 func TestVLANEvents(t *testing.T) {
 	t.Run("test_send_receive", func(t *testing.T) { // Test that a node can send a message to another node and use events to continue with the messages.
-		t.Skip("not yet read") // TODO: fix
 		testingLogger := testutils.ProduceTestingLogger(t)
 		tests.LockGlobalTimeMachine(t)
 
diff --git a/plc4go/internal/bacnetip/tests/util.go b/plc4go/internal/bacnetip/tests/util.go
index 9cafdc56b7..56ad73dae4 100644
--- a/plc4go/internal/bacnetip/tests/util.go
+++ b/plc4go/internal/bacnetip/tests/util.go
@@ -20,42 +20,20 @@
 package tests
 
 import (
-	"context"
-	"encoding/hex"
 	"fmt"
 	"time"
 
-	"github.com/apache/plc4x/plc4go/spi/utils"
+	"github.com/apache/plc4x/plc4go/internal/bacnetip"
 )
 
 var StartTime = time.Time{}.Add(1 * time.Hour)
 
 type DummyMessage struct {
-	Data []byte
+	bacnetip.MessageBridge
 }
 
 func NewDummyMessage(data ...byte) *DummyMessage {
-	return &DummyMessage{Data: data}
-}
-
-func (d DummyMessage) String() string {
-	return hex.EncodeToString(d.Data)
-}
-
-func (d DummyMessage) Serialize() ([]byte, error) {
-	return d.Data, nil
-}
-
-func (d DummyMessage) SerializeWithWriteBuffer(_ context.Context, writeBuffer utils.WriteBuffer) error {
-	return writeBuffer.WriteByteArray("data", d.Data)
-}
-
-func (d DummyMessage) GetLengthInBytes(_ context.Context) uint16 {
-	return uint16(len(d.Data))
-}
-
-func (d DummyMessage) GetLengthInBits(_ context.Context) uint16 {
-	return uint16(len(d.Data))
+	return &DummyMessage{bacnetip.NewMessageBridge(data...)}
 }
 
 type AssertionError struct {
diff --git a/plc4go/internal/bacnetip/vlan.go b/plc4go/internal/bacnetip/vlan.go
index a30a7fc922..71d01b5c72 100644
--- a/plc4go/internal/bacnetip/vlan.go
+++ b/plc4go/internal/bacnetip/vlan.go
@@ -21,11 +21,10 @@ package bacnetip
 
 import (
 	"fmt"
+	"math/rand"
 
 	"github.com/pkg/errors"
 	"github.com/rs/zerolog"
-
-	"math/rand"
 )
 
 type TrafficLogger interface {
@@ -188,7 +187,7 @@ func NewNode(localLog zerolog.Logger, addr *Address, lan NodeNetworkReference, o
 	for _, opt := range opts {
 		opt(n)
 	}
-	if n.name == "" {
+	if n.name != "" {
 		n.log = n.log.With().Str("name", n.name).Logger()
 	}
 	var err error
@@ -259,10 +258,6 @@ func (n *Node) SetSpoofing(spoofing bool) {
 	n.spoofing = spoofing
 }
 
-func (n *Node) String() string {
-	return fmt.Sprintf("Node: %s(%v)", n.name, n.serverID)
-}
-
 func (n *Node) bind(lan NodeNetworkReference) {
 	n.log.Debug().Interface("lan", lan).Msg("binding lan")
 	lan.AddNode(n)
@@ -293,6 +288,10 @@ func (n *Node) Indication(args Args, kwargs KWArgs) error {
 	return nil
 }
 
+func (n *Node) String() string {
+	return fmt.Sprintf("Node: %s(%v)", n.name, n.serverID)
+}
+
 // IPNetwork instances are Network objects where the addresses on the
 //
 //	network are tuples that would be used for sockets like ('1.2.3.4', 5).