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 2021/12/01 10:41:31 UTC

[plc4x] branch develop updated (7d9f7b7 -> 457919b)

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

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


    from 7d9f7b7  fix(plc4go/codegen): avoid opening contexts for manual fields
     new cfcd6e3  feat(plc4go/pcap): dump packages on debug for better inspection
     new 457919b  fix(bacnet): implement BACnetErrorPasswordFailure

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../plc4go/bacnetip/readwrite/model/BACnetError.go |   2 +
 .../readwrite/model/BACnetErrorPasswordFailure.go  | 196 +++++++++++++++++++++
 .../readwrite/model/BACnetErrorReadProperty.go     | 191 +++++---------------
 .../plc4go/spi/transports/pcap/Transport.go        |   5 +-
 .../resources/protocols/bacnetip/bacnetip.mspec    |  12 +-
 5 files changed, 251 insertions(+), 155 deletions(-)
 create mode 100644 plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorPasswordFailure.go

[plc4x] 01/02: feat(plc4go/pcap): dump packages on debug for better inspection

Posted by sr...@apache.org.
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 cfcd6e363f2d47a87b7ce1c5ada70830f6191e60
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Wed Dec 1 11:16:32 2021 +0100

    feat(plc4go/pcap): dump packages on debug for better inspection
---
 plc4go/internal/plc4go/spi/transports/pcap/Transport.go | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/plc4go/internal/plc4go/spi/transports/pcap/Transport.go b/plc4go/internal/plc4go/spi/transports/pcap/Transport.go
index 77aac03..c4e4902 100644
--- a/plc4go/internal/plc4go/spi/transports/pcap/Transport.go
+++ b/plc4go/internal/plc4go/spi/transports/pcap/Transport.go
@@ -129,10 +129,12 @@ func (m *TransportInstance) Connect() error {
 	m.reader = bufio.NewReader(buffer)
 
 	go func(m *TransportInstance, buffer *bytes.Buffer) {
+		packageCount := 0
 		var lastPacketTime *time.Time
 		for m.connected {
 			packetData, captureInfo, err := m.handle.ReadPacketData()
-			log.Info().Msgf("Read new package %#v", captureInfo)
+			packageCount++
+			log.Info().Msgf("Read new package (nr. %d) %#v", packageCount, captureInfo)
 			if err != nil {
 				if err == io.EOF {
 					log.Info().Msg("Done reading pcap")
@@ -150,6 +152,7 @@ func (m *TransportInstance) Connect() error {
 
 			// Decode a packet
 			packet := gopacket.NewPacket(packetData, layers.LayerTypeEthernet, gopacket.Default)
+			log.Debug().Msgf("Packet dump (nr. %d):\n%s", packageCount, packet.Dump())
 			var payload []byte
 			switch m.transportType {
 			case TCP:

[plc4x] 02/02: fix(bacnet): implement BACnetErrorPasswordFailure

Posted by sr...@apache.org.
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 457919ba1324b33f936e25db8299c7b61ebce8e9
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Wed Dec 1 11:39:48 2021 +0100

    fix(bacnet): implement BACnetErrorPasswordFailure
---
 .../plc4go/bacnetip/readwrite/model/BACnetError.go |   2 +
 .../readwrite/model/BACnetErrorPasswordFailure.go  | 196 +++++++++++++++++++++
 .../readwrite/model/BACnetErrorReadProperty.go     | 191 +++++---------------
 .../resources/protocols/bacnetip/bacnetip.mspec    |  12 +-
 4 files changed, 247 insertions(+), 154 deletions(-)

diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetError.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetError.go
index af412b8..b7eccbf 100644
--- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetError.go
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetError.go
@@ -127,6 +127,8 @@ func BACnetErrorParse(readBuffer utils.ReadBuffer) (*BACnetError, error) {
 		_parent, typeSwitchError = BACnetErrorReadRangeParse(readBuffer)
 	case serviceChoice == 0x12: // BACnetErrorConfirmedPrivateTransfer
 		_parent, typeSwitchError = BACnetErrorConfirmedPrivateTransferParse(readBuffer)
+	case serviceChoice == 0x14: // BACnetErrorPasswordFailure
+		_parent, typeSwitchError = BACnetErrorPasswordFailureParse(readBuffer)
 	case serviceChoice == 0x15: // BACnetErrorVTOpen
 		_parent, typeSwitchError = BACnetErrorVTOpenParse(readBuffer)
 	case serviceChoice == 0x17: // BACnetErrorVTData
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorPasswordFailure.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorPasswordFailure.go
new file mode 100644
index 0000000..0d952dd
--- /dev/null
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorPasswordFailure.go
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package model
+
+import (
+	"github.com/apache/plc4x/plc4go/internal/plc4go/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// The data-structure of this message
+type BACnetErrorPasswordFailure struct {
+	*BACnetError
+	ErrorClass *BACnetTagApplicationEnumerated
+	ErrorCode  *BACnetTagApplicationEnumerated
+}
+
+// The corresponding interface
+type IBACnetErrorPasswordFailure interface {
+	LengthInBytes() uint16
+	LengthInBits() uint16
+	Serialize(writeBuffer utils.WriteBuffer) error
+}
+
+///////////////////////////////////////////////////////////
+// Accessors for discriminator values.
+///////////////////////////////////////////////////////////
+func (m *BACnetErrorPasswordFailure) ServiceChoice() uint8 {
+	return 0x14
+}
+
+func (m *BACnetErrorPasswordFailure) InitializeParent(parent *BACnetError) {
+}
+
+func NewBACnetErrorPasswordFailure(errorClass *BACnetTagApplicationEnumerated, errorCode *BACnetTagApplicationEnumerated) *BACnetError {
+	child := &BACnetErrorPasswordFailure{
+		ErrorClass:  errorClass,
+		ErrorCode:   errorCode,
+		BACnetError: NewBACnetError(),
+	}
+	child.Child = child
+	return child.BACnetError
+}
+
+func CastBACnetErrorPasswordFailure(structType interface{}) *BACnetErrorPasswordFailure {
+	castFunc := func(typ interface{}) *BACnetErrorPasswordFailure {
+		if casted, ok := typ.(BACnetErrorPasswordFailure); ok {
+			return &casted
+		}
+		if casted, ok := typ.(*BACnetErrorPasswordFailure); ok {
+			return casted
+		}
+		if casted, ok := typ.(BACnetError); ok {
+			return CastBACnetErrorPasswordFailure(casted.Child)
+		}
+		if casted, ok := typ.(*BACnetError); ok {
+			return CastBACnetErrorPasswordFailure(casted.Child)
+		}
+		return nil
+	}
+	return castFunc(structType)
+}
+
+func (m *BACnetErrorPasswordFailure) GetTypeName() string {
+	return "BACnetErrorPasswordFailure"
+}
+
+func (m *BACnetErrorPasswordFailure) LengthInBits() uint16 {
+	return m.LengthInBitsConditional(false)
+}
+
+func (m *BACnetErrorPasswordFailure) LengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.ParentLengthInBits())
+
+	// Simple field (errorClass)
+	lengthInBits += m.ErrorClass.LengthInBits()
+
+	// Simple field (errorCode)
+	lengthInBits += m.ErrorCode.LengthInBits()
+
+	return lengthInBits
+}
+
+func (m *BACnetErrorPasswordFailure) LengthInBytes() uint16 {
+	return m.LengthInBits() / 8
+}
+
+func BACnetErrorPasswordFailureParse(readBuffer utils.ReadBuffer) (*BACnetError, error) {
+	if pullErr := readBuffer.PullContext("BACnetErrorPasswordFailure"); pullErr != nil {
+		return nil, pullErr
+	}
+
+	// Simple Field (errorClass)
+	if pullErr := readBuffer.PullContext("errorClass"); pullErr != nil {
+		return nil, pullErr
+	}
+	_errorClass, _errorClassErr := BACnetTagParse(readBuffer)
+	if _errorClassErr != nil {
+		return nil, errors.Wrap(_errorClassErr, "Error parsing 'errorClass' field")
+	}
+	errorClass := CastBACnetTagApplicationEnumerated(_errorClass)
+	if closeErr := readBuffer.CloseContext("errorClass"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	// Simple Field (errorCode)
+	if pullErr := readBuffer.PullContext("errorCode"); pullErr != nil {
+		return nil, pullErr
+	}
+	_errorCode, _errorCodeErr := BACnetTagParse(readBuffer)
+	if _errorCodeErr != nil {
+		return nil, errors.Wrap(_errorCodeErr, "Error parsing 'errorCode' field")
+	}
+	errorCode := CastBACnetTagApplicationEnumerated(_errorCode)
+	if closeErr := readBuffer.CloseContext("errorCode"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	if closeErr := readBuffer.CloseContext("BACnetErrorPasswordFailure"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	// Create a partially initialized instance
+	_child := &BACnetErrorPasswordFailure{
+		ErrorClass:  CastBACnetTagApplicationEnumerated(errorClass),
+		ErrorCode:   CastBACnetTagApplicationEnumerated(errorCode),
+		BACnetError: &BACnetError{},
+	}
+	_child.BACnetError.Child = _child
+	return _child.BACnetError, nil
+}
+
+func (m *BACnetErrorPasswordFailure) Serialize(writeBuffer utils.WriteBuffer) error {
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("BACnetErrorPasswordFailure"); pushErr != nil {
+			return pushErr
+		}
+
+		// Simple Field (errorClass)
+		if pushErr := writeBuffer.PushContext("errorClass"); pushErr != nil {
+			return pushErr
+		}
+		_errorClassErr := m.ErrorClass.Serialize(writeBuffer)
+		if popErr := writeBuffer.PopContext("errorClass"); popErr != nil {
+			return popErr
+		}
+		if _errorClassErr != nil {
+			return errors.Wrap(_errorClassErr, "Error serializing 'errorClass' field")
+		}
+
+		// Simple Field (errorCode)
+		if pushErr := writeBuffer.PushContext("errorCode"); pushErr != nil {
+			return pushErr
+		}
+		_errorCodeErr := m.ErrorCode.Serialize(writeBuffer)
+		if popErr := writeBuffer.PopContext("errorCode"); popErr != nil {
+			return popErr
+		}
+		if _errorCodeErr != nil {
+			return errors.Wrap(_errorCodeErr, "Error serializing 'errorCode' field")
+		}
+
+		if popErr := writeBuffer.PopContext("BACnetErrorPasswordFailure"); popErr != nil {
+			return popErr
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *BACnetErrorPasswordFailure) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	buffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	m.Serialize(buffer)
+	return buffer.GetBox().String()
+}
diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go
index 26008f3..590056d 100644
--- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go
+++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go
@@ -20,24 +20,17 @@
 package model
 
 import (
-	"fmt"
 	"github.com/apache/plc4x/plc4go/internal/plc4go/spi/utils"
 	"github.com/pkg/errors"
 )
 
 // Code generated by code-generation. DO NOT EDIT.
 
-// Constant values.
-const BACnetErrorReadProperty_ERRORCLASSHEADER uint8 = 0x12
-const BACnetErrorReadProperty_ERRORCODEHEADER uint8 = 0x12
-
 // The data-structure of this message
 type BACnetErrorReadProperty struct {
 	*BACnetError
-	ErrorClassLength uint8
-	ErrorClass       []int8
-	ErrorCodeLength  uint8
-	ErrorCode        []int8
+	ErrorClass *BACnetTagApplicationEnumerated
+	ErrorCode  *BACnetTagApplicationEnumerated
 }
 
 // The corresponding interface
@@ -57,13 +50,11 @@ func (m *BACnetErrorReadProperty) ServiceChoice() uint8 {
 func (m *BACnetErrorReadProperty) InitializeParent(parent *BACnetError) {
 }
 
-func NewBACnetErrorReadProperty(errorClassLength uint8, errorClass []int8, errorCodeLength uint8, errorCode []int8) *BACnetError {
+func NewBACnetErrorReadProperty(errorClass *BACnetTagApplicationEnumerated, errorCode *BACnetTagApplicationEnumerated) *BACnetError {
 	child := &BACnetErrorReadProperty{
-		ErrorClassLength: errorClassLength,
-		ErrorClass:       errorClass,
-		ErrorCodeLength:  errorCodeLength,
-		ErrorCode:        errorCode,
-		BACnetError:      NewBACnetError(),
+		ErrorClass:  errorClass,
+		ErrorCode:   errorCode,
+		BACnetError: NewBACnetError(),
 	}
 	child.Child = child
 	return child.BACnetError
@@ -99,27 +90,11 @@ func (m *BACnetErrorReadProperty) LengthInBits() uint16 {
 func (m *BACnetErrorReadProperty) LengthInBitsConditional(lastItem bool) uint16 {
 	lengthInBits := uint16(m.ParentLengthInBits())
 
-	// Const Field (errorClassHeader)
-	lengthInBits += 5
-
-	// Simple field (errorClassLength)
-	lengthInBits += 3
-
-	// Array field
-	if len(m.ErrorClass) > 0 {
-		lengthInBits += 8 * uint16(len(m.ErrorClass))
-	}
+	// Simple field (errorClass)
+	lengthInBits += m.ErrorClass.LengthInBits()
 
-	// Const Field (errorCodeHeader)
-	lengthInBits += 5
-
-	// Simple field (errorCodeLength)
-	lengthInBits += 3
-
-	// Array field
-	if len(m.ErrorCode) > 0 {
-		lengthInBits += 8 * uint16(len(m.ErrorCode))
-	}
+	// Simple field (errorCode)
+	lengthInBits += m.ErrorCode.LengthInBits()
 
 	return lengthInBits
 }
@@ -133,73 +108,29 @@ func BACnetErrorReadPropertyParse(readBuffer utils.ReadBuffer) (*BACnetError, er
 		return nil, pullErr
 	}
 
-	// Const Field (errorClassHeader)
-	errorClassHeader, _errorClassHeaderErr := readBuffer.ReadUint8("errorClassHeader", 5)
-	if _errorClassHeaderErr != nil {
-		return nil, errors.Wrap(_errorClassHeaderErr, "Error parsing 'errorClassHeader' field")
-	}
-	if errorClassHeader != BACnetErrorReadProperty_ERRORCLASSHEADER {
-		return nil, errors.New("Expected constant value " + fmt.Sprintf("%d", BACnetErrorReadProperty_ERRORCLASSHEADER) + " but got " + fmt.Sprintf("%d", errorClassHeader))
-	}
-
-	// Simple Field (errorClassLength)
-	_errorClassLength, _errorClassLengthErr := readBuffer.ReadUint8("errorClassLength", 3)
-	if _errorClassLengthErr != nil {
-		return nil, errors.Wrap(_errorClassLengthErr, "Error parsing 'errorClassLength' field")
-	}
-	errorClassLength := _errorClassLength
-
-	// Array field (errorClass)
-	if pullErr := readBuffer.PullContext("errorClass", utils.WithRenderAsList(true)); pullErr != nil {
+	// Simple Field (errorClass)
+	if pullErr := readBuffer.PullContext("errorClass"); pullErr != nil {
 		return nil, pullErr
 	}
-	// Count array
-	errorClass := make([]int8, errorClassLength)
-	{
-		for curItem := uint16(0); curItem < uint16(errorClassLength); curItem++ {
-			_item, _err := readBuffer.ReadInt8("", 8)
-			if _err != nil {
-				return nil, errors.Wrap(_err, "Error parsing 'errorClass' field")
-			}
-			errorClass[curItem] = _item
-		}
+	_errorClass, _errorClassErr := BACnetTagParse(readBuffer)
+	if _errorClassErr != nil {
+		return nil, errors.Wrap(_errorClassErr, "Error parsing 'errorClass' field")
 	}
-	if closeErr := readBuffer.CloseContext("errorClass", utils.WithRenderAsList(true)); closeErr != nil {
+	errorClass := CastBACnetTagApplicationEnumerated(_errorClass)
+	if closeErr := readBuffer.CloseContext("errorClass"); closeErr != nil {
 		return nil, closeErr
 	}
 
-	// Const Field (errorCodeHeader)
-	errorCodeHeader, _errorCodeHeaderErr := readBuffer.ReadUint8("errorCodeHeader", 5)
-	if _errorCodeHeaderErr != nil {
-		return nil, errors.Wrap(_errorCodeHeaderErr, "Error parsing 'errorCodeHeader' field")
-	}
-	if errorCodeHeader != BACnetErrorReadProperty_ERRORCODEHEADER {
-		return nil, errors.New("Expected constant value " + fmt.Sprintf("%d", BACnetErrorReadProperty_ERRORCODEHEADER) + " but got " + fmt.Sprintf("%d", errorCodeHeader))
-	}
-
-	// Simple Field (errorCodeLength)
-	_errorCodeLength, _errorCodeLengthErr := readBuffer.ReadUint8("errorCodeLength", 3)
-	if _errorCodeLengthErr != nil {
-		return nil, errors.Wrap(_errorCodeLengthErr, "Error parsing 'errorCodeLength' field")
-	}
-	errorCodeLength := _errorCodeLength
-
-	// Array field (errorCode)
-	if pullErr := readBuffer.PullContext("errorCode", utils.WithRenderAsList(true)); pullErr != nil {
+	// Simple Field (errorCode)
+	if pullErr := readBuffer.PullContext("errorCode"); pullErr != nil {
 		return nil, pullErr
 	}
-	// Count array
-	errorCode := make([]int8, errorCodeLength)
-	{
-		for curItem := uint16(0); curItem < uint16(errorCodeLength); curItem++ {
-			_item, _err := readBuffer.ReadInt8("", 8)
-			if _err != nil {
-				return nil, errors.Wrap(_err, "Error parsing 'errorCode' field")
-			}
-			errorCode[curItem] = _item
-		}
+	_errorCode, _errorCodeErr := BACnetTagParse(readBuffer)
+	if _errorCodeErr != nil {
+		return nil, errors.Wrap(_errorCodeErr, "Error parsing 'errorCode' field")
 	}
-	if closeErr := readBuffer.CloseContext("errorCode", utils.WithRenderAsList(true)); closeErr != nil {
+	errorCode := CastBACnetTagApplicationEnumerated(_errorCode)
+	if closeErr := readBuffer.CloseContext("errorCode"); closeErr != nil {
 		return nil, closeErr
 	}
 
@@ -209,11 +140,9 @@ func BACnetErrorReadPropertyParse(readBuffer utils.ReadBuffer) (*BACnetError, er
 
 	// Create a partially initialized instance
 	_child := &BACnetErrorReadProperty{
-		ErrorClassLength: errorClassLength,
-		ErrorClass:       errorClass,
-		ErrorCodeLength:  errorCodeLength,
-		ErrorCode:        errorCode,
-		BACnetError:      &BACnetError{},
+		ErrorClass:  CastBACnetTagApplicationEnumerated(errorClass),
+		ErrorCode:   CastBACnetTagApplicationEnumerated(errorCode),
+		BACnetError: &BACnetError{},
 	}
 	_child.BACnetError.Child = _child
 	return _child.BACnetError, nil
@@ -225,62 +154,28 @@ func (m *BACnetErrorReadProperty) Serialize(writeBuffer utils.WriteBuffer) error
 			return pushErr
 		}
 
-		// Const Field (errorClassHeader)
-		_errorClassHeaderErr := writeBuffer.WriteUint8("errorClassHeader", 5, 0x12)
-		if _errorClassHeaderErr != nil {
-			return errors.Wrap(_errorClassHeaderErr, "Error serializing 'errorClassHeader' field")
+		// Simple Field (errorClass)
+		if pushErr := writeBuffer.PushContext("errorClass"); pushErr != nil {
+			return pushErr
 		}
-
-		// Simple Field (errorClassLength)
-		errorClassLength := uint8(m.ErrorClassLength)
-		_errorClassLengthErr := writeBuffer.WriteUint8("errorClassLength", 3, (errorClassLength))
-		if _errorClassLengthErr != nil {
-			return errors.Wrap(_errorClassLengthErr, "Error serializing 'errorClassLength' field")
+		_errorClassErr := m.ErrorClass.Serialize(writeBuffer)
+		if popErr := writeBuffer.PopContext("errorClass"); popErr != nil {
+			return popErr
 		}
-
-		// Array Field (errorClass)
-		if m.ErrorClass != nil {
-			if pushErr := writeBuffer.PushContext("errorClass", utils.WithRenderAsList(true)); pushErr != nil {
-				return pushErr
-			}
-			for _, _element := range m.ErrorClass {
-				_elementErr := writeBuffer.WriteInt8("", 8, _element)
-				if _elementErr != nil {
-					return errors.Wrap(_elementErr, "Error serializing 'errorClass' field")
-				}
-			}
-			if popErr := writeBuffer.PopContext("errorClass", utils.WithRenderAsList(true)); popErr != nil {
-				return popErr
-			}
+		if _errorClassErr != nil {
+			return errors.Wrap(_errorClassErr, "Error serializing 'errorClass' field")
 		}
 
-		// Const Field (errorCodeHeader)
-		_errorCodeHeaderErr := writeBuffer.WriteUint8("errorCodeHeader", 5, 0x12)
-		if _errorCodeHeaderErr != nil {
-			return errors.Wrap(_errorCodeHeaderErr, "Error serializing 'errorCodeHeader' field")
+		// Simple Field (errorCode)
+		if pushErr := writeBuffer.PushContext("errorCode"); pushErr != nil {
+			return pushErr
 		}
-
-		// Simple Field (errorCodeLength)
-		errorCodeLength := uint8(m.ErrorCodeLength)
-		_errorCodeLengthErr := writeBuffer.WriteUint8("errorCodeLength", 3, (errorCodeLength))
-		if _errorCodeLengthErr != nil {
-			return errors.Wrap(_errorCodeLengthErr, "Error serializing 'errorCodeLength' field")
+		_errorCodeErr := m.ErrorCode.Serialize(writeBuffer)
+		if popErr := writeBuffer.PopContext("errorCode"); popErr != nil {
+			return popErr
 		}
-
-		// Array Field (errorCode)
-		if m.ErrorCode != nil {
-			if pushErr := writeBuffer.PushContext("errorCode", utils.WithRenderAsList(true)); pushErr != nil {
-				return pushErr
-			}
-			for _, _element := range m.ErrorCode {
-				_elementErr := writeBuffer.WriteInt8("", 8, _element)
-				if _elementErr != nil {
-					return errors.Wrap(_elementErr, "Error serializing 'errorCode' field")
-				}
-			}
-			if popErr := writeBuffer.PopContext("errorCode", utils.WithRenderAsList(true)); popErr != nil {
-				return popErr
-			}
+		if _errorCodeErr != nil {
+			return errors.Wrap(_errorCodeErr, "Error serializing 'errorCode' field")
 		}
 
 		if popErr := writeBuffer.PopContext("BACnetErrorReadProperty"); popErr != nil {
diff --git a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
index 6fc0824..b835b29 100644
--- a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
+++ b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
@@ -442,12 +442,8 @@
         ['0x0A' BACnetErrorCreateObject
         ]
         ['0x0C' BACnetErrorReadProperty
-            [const uint 5 errorClassHeader 0x12]
-            [simple uint 3 errorClassLength]
-            [array int 8 errorClass count 'errorClassLength']
-            [const uint 5 errorCodeHeader 0x12]
-            [simple uint 3 errorCodeLength]
-            [array int 8 errorCode count 'errorCodeLength']
+            [simple BACnetTagApplicationEnumerated errorClass]
+            [simple BACnetTagApplicationEnumerated errorCode]
         ]
         ['0x0E' BACnetErrorReadPropertyMultiple
         ]
@@ -456,6 +452,10 @@
 
         ['0x12' BACnetErrorConfirmedPrivateTransfer
         ]
+        ['0x14' BACnetErrorPasswordFailure
+            [simple BACnetTagApplicationEnumerated errorClass]
+            [simple BACnetTagApplicationEnumerated errorCode]
+        ]
 
         ['0x15' BACnetErrorVTOpen
         ]