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 0f46d4d6d3abf2b662ab7822d39acfb6df97cc2e Author: Sebastian Rühl <[email protected]> AuthorDate: Thu Apr 28 14:07:26 2022 +0200 feat(bacnet): added support for more read replies fix(bacnet): fixed a issue with contructed elements of length six --- .../plc4go/bacnetip/readwrite/ParserHelper.go | 12 +- .../plc4go/bacnetip/readwrite/XmlParserHelper.go | 14 +- .../readwrite/model/BACnetConstructedData.go | 2 + .../model/BACnetConstructedDataElement.go | 6 +- ...onstructedDataListOfObjectPropertyReferences.go | 219 ++++++++++ .../model/BACnetDeviceObjectPropertyReference.go | 81 +--- .../BACnetDeviceObjectPropertyReferenceEnclosed.go | 229 ++++++++++ .../BACnetNotificationParametersBufferReady.go | 14 +- ...CnetNotificationParametersExtendedParameters.go | 16 +- .../bacnetip/readwrite/model/StaticHelper.go | 4 +- .../bacnetip/readwrite/utils/StaticHelper.java | 479 ++++++++++++++++++++- .../plc4x/java/bacnetip/RandomPackagesTest.java | 7 +- .../plc4x/java/bacnetip/TrickyPackagesTest.java | 111 +++++ .../resources/protocols/bacnetip/bacnetip.mspec | 45 +- 14 files changed, 1099 insertions(+), 140 deletions(-) diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/ParserHelper.go b/plc4go/internal/plc4go/bacnetip/readwrite/ParserHelper.go index 7011aaa8cf..dcb7e2b0b8 100644 --- a/plc4go/internal/plc4go/bacnetip/readwrite/ParserHelper.go +++ b/plc4go/internal/plc4go/bacnetip/readwrite/ParserHelper.go @@ -92,6 +92,12 @@ func (m BacnetipParserHelper) Parse(typeName string, arguments []string, io util return model.BACnetServiceAckAtomicReadFileStreamOrRecordParse(io) case "NPDUControl": return model.NPDUControlParse(io) + case "BACnetDeviceObjectPropertyReferenceEnclosed": + tagNumber, err := utils.StrToUint8(arguments[0]) + if err != nil { + return nil, errors.Wrap(err, "Error parsing") + } + return model.BACnetDeviceObjectPropertyReferenceEnclosedParse(io, tagNumber) case "BACnetPropertyStates": tagNumber, err := utils.StrToUint8(arguments[0]) if err != nil { @@ -201,11 +207,7 @@ func (m BacnetipParserHelper) Parse(typeName string, arguments []string, io util } return model.BACnetTagPayloadBitStringParse(io, actualLength) case "BACnetDeviceObjectPropertyReference": - tagNumber, err := utils.StrToUint8(arguments[0]) - if err != nil { - return nil, errors.Wrap(err, "Error parsing") - } - return model.BACnetDeviceObjectPropertyReferenceParse(io, tagNumber) + return model.BACnetDeviceObjectPropertyReferenceParse(io) case "BACnetConstructedDataElement": objectType := model.BACnetObjectTypeByName(arguments[0]) var propertyIdentifier model.BACnetContextTagPropertyIdentifier diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/XmlParserHelper.go b/plc4go/internal/plc4go/bacnetip/readwrite/XmlParserHelper.go index 7e8c5b3364..0b5c810e71 100644 --- a/plc4go/internal/plc4go/bacnetip/readwrite/XmlParserHelper.go +++ b/plc4go/internal/plc4go/bacnetip/readwrite/XmlParserHelper.go @@ -109,6 +109,13 @@ func (m BacnetipXmlParserHelper) Parse(typeName string, xmlString string, parser return model.BACnetServiceAckAtomicReadFileStreamOrRecordParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString))) case "NPDUControl": return model.NPDUControlParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString))) + case "BACnetDeviceObjectPropertyReferenceEnclosed": + parsedUint0, err := strconv.ParseUint(parserArguments[0], 10, 8) + if err != nil { + return nil, err + } + tagNumber := uint8(parsedUint0) + return model.BACnetDeviceObjectPropertyReferenceEnclosedParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)), tagNumber) case "BACnetPropertyStates": parsedUint0, err := strconv.ParseUint(parserArguments[0], 10, 8) if err != nil { @@ -232,12 +239,7 @@ func (m BacnetipXmlParserHelper) Parse(typeName string, xmlString string, parser actualLength := uint32(parsedUint0) return model.BACnetTagPayloadBitStringParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)), actualLength) case "BACnetDeviceObjectPropertyReference": - parsedUint0, err := strconv.ParseUint(parserArguments[0], 10, 8) - if err != nil { - return nil, err - } - tagNumber := uint8(parsedUint0) - return model.BACnetDeviceObjectPropertyReferenceParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)), tagNumber) + return model.BACnetDeviceObjectPropertyReferenceParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString))) case "BACnetConstructedDataElement": objectType := model.BACnetObjectTypeByName(parserArguments[0]) // TODO: find a way to parse the sub types diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConstructedData.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConstructedData.go index efc72bb8f4..d181657104 100644 --- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConstructedData.go +++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConstructedData.go @@ -187,6 +187,8 @@ func BACnetConstructedDataParse(readBuffer utils.ReadBuffer, tagNumber uint8, ob _child, typeSwitchError = BACnetConstructedDataLifeSafetyZoneParse(readBuffer, tagNumber, objectType, propertyIdentifierArgument) case true && propertyIdentifierEnum == BACnetPropertyIdentifier_EVENT_TIME_STAMPS: // BACnetConstructedDataEventTimestamps _child, typeSwitchError = BACnetConstructedDataEventTimestampsParse(readBuffer, tagNumber, objectType, propertyIdentifierArgument) + case true && propertyIdentifierEnum == BACnetPropertyIdentifier_LIST_OF_OBJECT_PROPERTY_REFERENCES: // BACnetConstructedDataListOfObjectPropertyReferences + _child, typeSwitchError = BACnetConstructedDataListOfObjectPropertyReferencesParse(readBuffer, tagNumber, objectType, propertyIdentifierArgument) case true: // BACnetConstructedDataUnspecified _child, typeSwitchError = BACnetConstructedDataUnspecifiedParse(readBuffer, tagNumber, objectType, propertyIdentifierArgument) default: diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConstructedDataElement.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConstructedDataElement.go index 1ff6ac7969..dbe1423b80 100644 --- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConstructedDataElement.go +++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConstructedDataElement.go @@ -122,7 +122,7 @@ func (m *BACnetConstructedDataElement) GetIsConstructedData() bool { _ = contextTag constructedData := m.ConstructedData _ = constructedData - return bool(bool(!(m.GetIsApplicationTag())) && bool(bool((m.GetPeekedTagHeader().GetActualLength()) == (0x6)))) + return bool(bool(!(m.GetIsApplicationTag())) && bool(bool((m.GetPeekedTagHeader().GetLengthValueType()) == (0x6)))) } func (m *BACnetConstructedDataElement) GetIsContextTag() bool { @@ -222,7 +222,7 @@ func BACnetConstructedDataElementParse(readBuffer utils.ReadBuffer, objectType B _ = isApplicationTag // Virtual field - _isConstructedData := bool(!(isApplicationTag)) && bool(bool((peekedTagHeader.GetActualLength()) == (0x6))) + _isConstructedData := bool(!(isApplicationTag)) && bool(bool((peekedTagHeader.GetLengthValueType()) == (0x6))) isConstructedData := bool(_isConstructedData) _ = isConstructedData @@ -259,7 +259,7 @@ func BACnetConstructedDataElementParse(readBuffer utils.ReadBuffer, objectType B if pullErr := readBuffer.PullContext("contextTag"); pullErr != nil { return nil, pullErr } - _val, _err := BACnetContextTagParse(readBuffer, peekedTagNumber, GuessDataType(objectType)) + _val, _err := BACnetContextTagParse(readBuffer, peekedTagNumber, GuessDataType(objectType, propertyIdentifier)) switch { case errors.Is(_err, utils.ParseAssertError{}) || errors.Is(_err, io.EOF): readBuffer.Reset(currentPos) diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConstructedDataListOfObjectPropertyReferences.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConstructedDataListOfObjectPropertyReferences.go new file mode 100644 index 0000000000..3b5759d54e --- /dev/null +++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConstructedDataListOfObjectPropertyReferences.go @@ -0,0 +1,219 @@ +/* + * 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. + +// BACnetConstructedDataListOfObjectPropertyReferences is the data-structure of this message +type BACnetConstructedDataListOfObjectPropertyReferences struct { + *BACnetConstructedData + References []*BACnetDeviceObjectPropertyReference + + // Arguments. + TagNumber uint8 + PropertyIdentifierArgument BACnetContextTagPropertyIdentifier +} + +// IBACnetConstructedDataListOfObjectPropertyReferences is the corresponding interface of BACnetConstructedDataListOfObjectPropertyReferences +type IBACnetConstructedDataListOfObjectPropertyReferences interface { + IBACnetConstructedData + // GetReferences returns References (property field) + GetReferences() []*BACnetDeviceObjectPropertyReference + // GetLengthInBytes returns the length in bytes + GetLengthInBytes() uint16 + // GetLengthInBits returns the length in bits + GetLengthInBits() uint16 + // Serialize serializes this type + Serialize(writeBuffer utils.WriteBuffer) error +} + +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////// Accessors for discriminator values. +/////////////////////// + +func (m *BACnetConstructedDataListOfObjectPropertyReferences) GetObjectType() BACnetObjectType { + return 0 +} + +/////////////////////// +/////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +func (m *BACnetConstructedDataListOfObjectPropertyReferences) InitializeParent(parent *BACnetConstructedData, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag) { + m.BACnetConstructedData.OpeningTag = openingTag + m.BACnetConstructedData.ClosingTag = closingTag +} + +func (m *BACnetConstructedDataListOfObjectPropertyReferences) GetParent() *BACnetConstructedData { + return m.BACnetConstructedData +} + +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////// Accessors for property fields. +/////////////////////// + +func (m *BACnetConstructedDataListOfObjectPropertyReferences) GetReferences() []*BACnetDeviceObjectPropertyReference { + return m.References +} + +/////////////////////// +/////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +// NewBACnetConstructedDataListOfObjectPropertyReferences factory function for BACnetConstructedDataListOfObjectPropertyReferences +func NewBACnetConstructedDataListOfObjectPropertyReferences(references []*BACnetDeviceObjectPropertyReference, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag, tagNumber uint8, propertyIdentifierArgument BACnetContextTagPropertyIdentifier) *BACnetConstructedDataListOfObjectPropertyReferences { + _result := &BACnetConstructedDataListOfObjectPropertyReferences{ + References: references, + BACnetConstructedData: NewBACnetConstructedData(openingTag, closingTag, tagNumber, propertyIdentifierArgument), + } + _result.Child = _result + return _result +} + +func CastBACnetConstructedDataListOfObjectPropertyReferences(structType interface{}) *BACnetConstructedDataListOfObjectPropertyReferences { + if casted, ok := structType.(BACnetConstructedDataListOfObjectPropertyReferences); ok { + return &casted + } + if casted, ok := structType.(*BACnetConstructedDataListOfObjectPropertyReferences); ok { + return casted + } + if casted, ok := structType.(BACnetConstructedData); ok { + return CastBACnetConstructedDataListOfObjectPropertyReferences(casted.Child) + } + if casted, ok := structType.(*BACnetConstructedData); ok { + return CastBACnetConstructedDataListOfObjectPropertyReferences(casted.Child) + } + return nil +} + +func (m *BACnetConstructedDataListOfObjectPropertyReferences) GetTypeName() string { + return "BACnetConstructedDataListOfObjectPropertyReferences" +} + +func (m *BACnetConstructedDataListOfObjectPropertyReferences) GetLengthInBits() uint16 { + return m.GetLengthInBitsConditional(false) +} + +func (m *BACnetConstructedDataListOfObjectPropertyReferences) GetLengthInBitsConditional(lastItem bool) uint16 { + lengthInBits := uint16(m.GetParentLengthInBits()) + + // Array field + if len(m.References) > 0 { + for _, element := range m.References { + lengthInBits += element.GetLengthInBits() + } + } + + return lengthInBits +} + +func (m *BACnetConstructedDataListOfObjectPropertyReferences) GetLengthInBytes() uint16 { + return m.GetLengthInBits() / 8 +} + +func BACnetConstructedDataListOfObjectPropertyReferencesParse(readBuffer utils.ReadBuffer, tagNumber uint8, objectType BACnetObjectType, propertyIdentifierArgument *BACnetContextTagPropertyIdentifier) (*BACnetConstructedDataListOfObjectPropertyReferences, error) { + if pullErr := readBuffer.PullContext("BACnetConstructedDataListOfObjectPropertyReferences"); pullErr != nil { + return nil, pullErr + } + currentPos := readBuffer.GetPos() + _ = currentPos + + // Array field (references) + if pullErr := readBuffer.PullContext("references", utils.WithRenderAsList(true)); pullErr != nil { + return nil, pullErr + } + // Terminated array + references := make([]*BACnetDeviceObjectPropertyReference, 0) + { + for !bool(IsBACnetConstructedDataClosingTag(readBuffer, false, tagNumber)) { + _item, _err := BACnetDeviceObjectPropertyReferenceParse(readBuffer) + if _err != nil { + return nil, errors.Wrap(_err, "Error parsing 'references' field") + } + references = append(references, CastBACnetDeviceObjectPropertyReference(_item)) + + } + } + if closeErr := readBuffer.CloseContext("references", utils.WithRenderAsList(true)); closeErr != nil { + return nil, closeErr + } + + if closeErr := readBuffer.CloseContext("BACnetConstructedDataListOfObjectPropertyReferences"); closeErr != nil { + return nil, closeErr + } + + // Create a partially initialized instance + _child := &BACnetConstructedDataListOfObjectPropertyReferences{ + References: references, + BACnetConstructedData: &BACnetConstructedData{}, + } + _child.BACnetConstructedData.Child = _child + return _child, nil +} + +func (m *BACnetConstructedDataListOfObjectPropertyReferences) Serialize(writeBuffer utils.WriteBuffer) error { + ser := func() error { + if pushErr := writeBuffer.PushContext("BACnetConstructedDataListOfObjectPropertyReferences"); pushErr != nil { + return pushErr + } + + // Array Field (references) + if m.References != nil { + if pushErr := writeBuffer.PushContext("references", utils.WithRenderAsList(true)); pushErr != nil { + return pushErr + } + for _, _element := range m.References { + _elementErr := _element.Serialize(writeBuffer) + if _elementErr != nil { + return errors.Wrap(_elementErr, "Error serializing 'references' field") + } + } + if popErr := writeBuffer.PopContext("references", utils.WithRenderAsList(true)); popErr != nil { + return popErr + } + } + + if popErr := writeBuffer.PopContext("BACnetConstructedDataListOfObjectPropertyReferences"); popErr != nil { + return popErr + } + return nil + } + return m.SerializeParent(writeBuffer, m, ser) +} + +func (m *BACnetConstructedDataListOfObjectPropertyReferences) String() string { + if m == nil { + return "<nil>" + } + buffer := utils.NewBoxedWriteBufferWithOptions(true, true) + if err := m.Serialize(buffer); err != nil { + return err.Error() + } + return buffer.GetBox().String() +} diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetDeviceObjectPropertyReference.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetDeviceObjectPropertyReference.go index d6ecfef12f..0297aae1dc 100644 --- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetDeviceObjectPropertyReference.go +++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetDeviceObjectPropertyReference.go @@ -29,21 +29,14 @@ import ( // BACnetDeviceObjectPropertyReference is the data-structure of this message type BACnetDeviceObjectPropertyReference struct { - OpeningTag *BACnetOpeningTag ObjectIdentifier *BACnetContextTagObjectIdentifier PropertyIdentifier *BACnetContextTagPropertyIdentifier ArrayIndex *BACnetContextTagUnsignedInteger DeviceIdentifier *BACnetContextTagObjectIdentifier - ClosingTag *BACnetClosingTag - - // Arguments. - TagNumber uint8 } // IBACnetDeviceObjectPropertyReference is the corresponding interface of BACnetDeviceObjectPropertyReference type IBACnetDeviceObjectPropertyReference interface { - // GetOpeningTag returns OpeningTag (property field) - GetOpeningTag() *BACnetOpeningTag // GetObjectIdentifier returns ObjectIdentifier (property field) GetObjectIdentifier() *BACnetContextTagObjectIdentifier // GetPropertyIdentifier returns PropertyIdentifier (property field) @@ -52,8 +45,6 @@ type IBACnetDeviceObjectPropertyReference interface { GetArrayIndex() *BACnetContextTagUnsignedInteger // GetDeviceIdentifier returns DeviceIdentifier (property field) GetDeviceIdentifier() *BACnetContextTagObjectIdentifier - // GetClosingTag returns ClosingTag (property field) - GetClosingTag() *BACnetClosingTag // GetLengthInBytes returns the length in bytes GetLengthInBytes() uint16 // GetLengthInBits returns the length in bits @@ -67,10 +58,6 @@ type IBACnetDeviceObjectPropertyReference interface { /////////////////////// Accessors for property fields. /////////////////////// -func (m *BACnetDeviceObjectPropertyReference) GetOpeningTag() *BACnetOpeningTag { - return m.OpeningTag -} - func (m *BACnetDeviceObjectPropertyReference) GetObjectIdentifier() *BACnetContextTagObjectIdentifier { return m.ObjectIdentifier } @@ -87,18 +74,14 @@ func (m *BACnetDeviceObjectPropertyReference) GetDeviceIdentifier() *BACnetConte return m.DeviceIdentifier } -func (m *BACnetDeviceObjectPropertyReference) GetClosingTag() *BACnetClosingTag { - return m.ClosingTag -} - /////////////////////// /////////////////////// /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// // NewBACnetDeviceObjectPropertyReference factory function for BACnetDeviceObjectPropertyReference -func NewBACnetDeviceObjectPropertyReference(openingTag *BACnetOpeningTag, objectIdentifier *BACnetContextTagObjectIdentifier, propertyIdentifier *BACnetContextTagPropertyIdentifier, arrayIndex *BACnetContextTagUnsignedInteger, deviceIdentifier *BACnetContextTagObjectIdentifier, closingTag *BACnetClosingTag, tagNumber uint8) *BACnetDeviceObjectPropertyReference { - return &BACnetDeviceObjectPropertyReference{OpeningTag: openingTag, ObjectIdentifier: objectIdentifier, PropertyIdentifier: propertyIdentifier, ArrayIndex: arrayIndex, DeviceIdentifier: deviceIdentifier, ClosingTag: closingTag, TagNumber: tagNumber} +func NewBACnetDeviceObjectPropertyReference(objectIdentifier *BACnetContextTagObjectIdentifier, propertyIdentifier *BACnetContextTagPropertyIdentifier, arrayIndex *BACnetContextTagUnsignedInteger, deviceIdentifier *BACnetContextTagObjectIdentifier) *BACnetDeviceObjectPropertyReference { + return &BACnetDeviceObjectPropertyReference{ObjectIdentifier: objectIdentifier, PropertyIdentifier: propertyIdentifier, ArrayIndex: arrayIndex, DeviceIdentifier: deviceIdentifier} } func CastBACnetDeviceObjectPropertyReference(structType interface{}) *BACnetDeviceObjectPropertyReference { @@ -122,9 +105,6 @@ func (m *BACnetDeviceObjectPropertyReference) GetLengthInBits() uint16 { func (m *BACnetDeviceObjectPropertyReference) GetLengthInBitsConditional(lastItem bool) uint16 { lengthInBits := uint16(0) - // Simple field (openingTag) - lengthInBits += m.OpeningTag.GetLengthInBits() - // Simple field (objectIdentifier) lengthInBits += m.ObjectIdentifier.GetLengthInBits() @@ -141,9 +121,6 @@ func (m *BACnetDeviceObjectPropertyReference) GetLengthInBitsConditional(lastIte lengthInBits += (*m.DeviceIdentifier).GetLengthInBits() } - // Simple field (closingTag) - lengthInBits += m.ClosingTag.GetLengthInBits() - return lengthInBits } @@ -151,26 +128,13 @@ func (m *BACnetDeviceObjectPropertyReference) GetLengthInBytes() uint16 { return m.GetLengthInBits() / 8 } -func BACnetDeviceObjectPropertyReferenceParse(readBuffer utils.ReadBuffer, tagNumber uint8) (*BACnetDeviceObjectPropertyReference, error) { +func BACnetDeviceObjectPropertyReferenceParse(readBuffer utils.ReadBuffer) (*BACnetDeviceObjectPropertyReference, error) { if pullErr := readBuffer.PullContext("BACnetDeviceObjectPropertyReference"); pullErr != nil { return nil, pullErr } currentPos := readBuffer.GetPos() _ = currentPos - // Simple Field (openingTag) - if pullErr := readBuffer.PullContext("openingTag"); pullErr != nil { - return nil, pullErr - } - _openingTag, _openingTagErr := BACnetContextTagParse(readBuffer, uint8(tagNumber), BACnetDataType(BACnetDataType_OPENING_TAG)) - if _openingTagErr != nil { - return nil, errors.Wrap(_openingTagErr, "Error parsing 'openingTag' field") - } - openingTag := CastBACnetOpeningTag(_openingTag) - if closeErr := readBuffer.CloseContext("openingTag"); closeErr != nil { - return nil, closeErr - } - // Simple Field (objectIdentifier) if pullErr := readBuffer.PullContext("objectIdentifier"); pullErr != nil { return nil, pullErr @@ -239,25 +203,12 @@ func BACnetDeviceObjectPropertyReferenceParse(readBuffer utils.ReadBuffer, tagNu } } - // Simple Field (closingTag) - if pullErr := readBuffer.PullContext("closingTag"); pullErr != nil { - return nil, pullErr - } - _closingTag, _closingTagErr := BACnetContextTagParse(readBuffer, uint8(tagNumber), BACnetDataType(BACnetDataType_CLOSING_TAG)) - if _closingTagErr != nil { - return nil, errors.Wrap(_closingTagErr, "Error parsing 'closingTag' field") - } - closingTag := CastBACnetClosingTag(_closingTag) - if closeErr := readBuffer.CloseContext("closingTag"); closeErr != nil { - return nil, closeErr - } - if closeErr := readBuffer.CloseContext("BACnetDeviceObjectPropertyReference"); closeErr != nil { return nil, closeErr } // Create the instance - return NewBACnetDeviceObjectPropertyReference(openingTag, objectIdentifier, propertyIdentifier, arrayIndex, deviceIdentifier, closingTag, tagNumber), nil + return NewBACnetDeviceObjectPropertyReference(objectIdentifier, propertyIdentifier, arrayIndex, deviceIdentifier), nil } func (m *BACnetDeviceObjectPropertyReference) Serialize(writeBuffer utils.WriteBuffer) error { @@ -265,18 +216,6 @@ func (m *BACnetDeviceObjectPropertyReference) Serialize(writeBuffer utils.WriteB return pushErr } - // Simple Field (openingTag) - if pushErr := writeBuffer.PushContext("openingTag"); pushErr != nil { - return pushErr - } - _openingTagErr := m.OpeningTag.Serialize(writeBuffer) - if popErr := writeBuffer.PopContext("openingTag"); popErr != nil { - return popErr - } - if _openingTagErr != nil { - return errors.Wrap(_openingTagErr, "Error serializing 'openingTag' field") - } - // Simple Field (objectIdentifier) if pushErr := writeBuffer.PushContext("objectIdentifier"); pushErr != nil { return pushErr @@ -333,18 +272,6 @@ func (m *BACnetDeviceObjectPropertyReference) Serialize(writeBuffer utils.WriteB } } - // Simple Field (closingTag) - if pushErr := writeBuffer.PushContext("closingTag"); pushErr != nil { - return pushErr - } - _closingTagErr := m.ClosingTag.Serialize(writeBuffer) - if popErr := writeBuffer.PopContext("closingTag"); popErr != nil { - return popErr - } - if _closingTagErr != nil { - return errors.Wrap(_closingTagErr, "Error serializing 'closingTag' field") - } - if popErr := writeBuffer.PopContext("BACnetDeviceObjectPropertyReference"); popErr != nil { return popErr } diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetDeviceObjectPropertyReferenceEnclosed.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetDeviceObjectPropertyReferenceEnclosed.go new file mode 100644 index 0000000000..4d6b7fdf52 --- /dev/null +++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetDeviceObjectPropertyReferenceEnclosed.go @@ -0,0 +1,229 @@ +/* + * 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. + +// BACnetDeviceObjectPropertyReferenceEnclosed is the data-structure of this message +type BACnetDeviceObjectPropertyReferenceEnclosed struct { + OpeningTag *BACnetOpeningTag + Value *BACnetDeviceObjectPropertyReference + ClosingTag *BACnetClosingTag + + // Arguments. + TagNumber uint8 +} + +// IBACnetDeviceObjectPropertyReferenceEnclosed is the corresponding interface of BACnetDeviceObjectPropertyReferenceEnclosed +type IBACnetDeviceObjectPropertyReferenceEnclosed interface { + // GetOpeningTag returns OpeningTag (property field) + GetOpeningTag() *BACnetOpeningTag + // GetValue returns Value (property field) + GetValue() *BACnetDeviceObjectPropertyReference + // GetClosingTag returns ClosingTag (property field) + GetClosingTag() *BACnetClosingTag + // GetLengthInBytes returns the length in bytes + GetLengthInBytes() uint16 + // GetLengthInBits returns the length in bits + GetLengthInBits() uint16 + // Serialize serializes this type + Serialize(writeBuffer utils.WriteBuffer) error +} + +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////// Accessors for property fields. +/////////////////////// + +func (m *BACnetDeviceObjectPropertyReferenceEnclosed) GetOpeningTag() *BACnetOpeningTag { + return m.OpeningTag +} + +func (m *BACnetDeviceObjectPropertyReferenceEnclosed) GetValue() *BACnetDeviceObjectPropertyReference { + return m.Value +} + +func (m *BACnetDeviceObjectPropertyReferenceEnclosed) GetClosingTag() *BACnetClosingTag { + return m.ClosingTag +} + +/////////////////////// +/////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +// NewBACnetDeviceObjectPropertyReferenceEnclosed factory function for BACnetDeviceObjectPropertyReferenceEnclosed +func NewBACnetDeviceObjectPropertyReferenceEnclosed(openingTag *BACnetOpeningTag, value *BACnetDeviceObjectPropertyReference, closingTag *BACnetClosingTag, tagNumber uint8) *BACnetDeviceObjectPropertyReferenceEnclosed { + return &BACnetDeviceObjectPropertyReferenceEnclosed{OpeningTag: openingTag, Value: value, ClosingTag: closingTag, TagNumber: tagNumber} +} + +func CastBACnetDeviceObjectPropertyReferenceEnclosed(structType interface{}) *BACnetDeviceObjectPropertyReferenceEnclosed { + if casted, ok := structType.(BACnetDeviceObjectPropertyReferenceEnclosed); ok { + return &casted + } + if casted, ok := structType.(*BACnetDeviceObjectPropertyReferenceEnclosed); ok { + return casted + } + return nil +} + +func (m *BACnetDeviceObjectPropertyReferenceEnclosed) GetTypeName() string { + return "BACnetDeviceObjectPropertyReferenceEnclosed" +} + +func (m *BACnetDeviceObjectPropertyReferenceEnclosed) GetLengthInBits() uint16 { + return m.GetLengthInBitsConditional(false) +} + +func (m *BACnetDeviceObjectPropertyReferenceEnclosed) GetLengthInBitsConditional(lastItem bool) uint16 { + lengthInBits := uint16(0) + + // Simple field (openingTag) + lengthInBits += m.OpeningTag.GetLengthInBits() + + // Simple field (value) + lengthInBits += m.Value.GetLengthInBits() + + // Simple field (closingTag) + lengthInBits += m.ClosingTag.GetLengthInBits() + + return lengthInBits +} + +func (m *BACnetDeviceObjectPropertyReferenceEnclosed) GetLengthInBytes() uint16 { + return m.GetLengthInBits() / 8 +} + +func BACnetDeviceObjectPropertyReferenceEnclosedParse(readBuffer utils.ReadBuffer, tagNumber uint8) (*BACnetDeviceObjectPropertyReferenceEnclosed, error) { + if pullErr := readBuffer.PullContext("BACnetDeviceObjectPropertyReferenceEnclosed"); pullErr != nil { + return nil, pullErr + } + currentPos := readBuffer.GetPos() + _ = currentPos + + // Simple Field (openingTag) + if pullErr := readBuffer.PullContext("openingTag"); pullErr != nil { + return nil, pullErr + } + _openingTag, _openingTagErr := BACnetContextTagParse(readBuffer, uint8(tagNumber), BACnetDataType(BACnetDataType_OPENING_TAG)) + if _openingTagErr != nil { + return nil, errors.Wrap(_openingTagErr, "Error parsing 'openingTag' field") + } + openingTag := CastBACnetOpeningTag(_openingTag) + if closeErr := readBuffer.CloseContext("openingTag"); closeErr != nil { + return nil, closeErr + } + + // Simple Field (value) + if pullErr := readBuffer.PullContext("value"); pullErr != nil { + return nil, pullErr + } + _value, _valueErr := BACnetDeviceObjectPropertyReferenceParse(readBuffer) + if _valueErr != nil { + return nil, errors.Wrap(_valueErr, "Error parsing 'value' field") + } + value := CastBACnetDeviceObjectPropertyReference(_value) + if closeErr := readBuffer.CloseContext("value"); closeErr != nil { + return nil, closeErr + } + + // Simple Field (closingTag) + if pullErr := readBuffer.PullContext("closingTag"); pullErr != nil { + return nil, pullErr + } + _closingTag, _closingTagErr := BACnetContextTagParse(readBuffer, uint8(tagNumber), BACnetDataType(BACnetDataType_CLOSING_TAG)) + if _closingTagErr != nil { + return nil, errors.Wrap(_closingTagErr, "Error parsing 'closingTag' field") + } + closingTag := CastBACnetClosingTag(_closingTag) + if closeErr := readBuffer.CloseContext("closingTag"); closeErr != nil { + return nil, closeErr + } + + if closeErr := readBuffer.CloseContext("BACnetDeviceObjectPropertyReferenceEnclosed"); closeErr != nil { + return nil, closeErr + } + + // Create the instance + return NewBACnetDeviceObjectPropertyReferenceEnclosed(openingTag, value, closingTag, tagNumber), nil +} + +func (m *BACnetDeviceObjectPropertyReferenceEnclosed) Serialize(writeBuffer utils.WriteBuffer) error { + if pushErr := writeBuffer.PushContext("BACnetDeviceObjectPropertyReferenceEnclosed"); pushErr != nil { + return pushErr + } + + // Simple Field (openingTag) + if pushErr := writeBuffer.PushContext("openingTag"); pushErr != nil { + return pushErr + } + _openingTagErr := m.OpeningTag.Serialize(writeBuffer) + if popErr := writeBuffer.PopContext("openingTag"); popErr != nil { + return popErr + } + if _openingTagErr != nil { + return errors.Wrap(_openingTagErr, "Error serializing 'openingTag' field") + } + + // Simple Field (value) + if pushErr := writeBuffer.PushContext("value"); pushErr != nil { + return pushErr + } + _valueErr := m.Value.Serialize(writeBuffer) + if popErr := writeBuffer.PopContext("value"); popErr != nil { + return popErr + } + if _valueErr != nil { + return errors.Wrap(_valueErr, "Error serializing 'value' field") + } + + // Simple Field (closingTag) + if pushErr := writeBuffer.PushContext("closingTag"); pushErr != nil { + return pushErr + } + _closingTagErr := m.ClosingTag.Serialize(writeBuffer) + if popErr := writeBuffer.PopContext("closingTag"); popErr != nil { + return popErr + } + if _closingTagErr != nil { + return errors.Wrap(_closingTagErr, "Error serializing 'closingTag' field") + } + + if popErr := writeBuffer.PopContext("BACnetDeviceObjectPropertyReferenceEnclosed"); popErr != nil { + return popErr + } + return nil +} + +func (m *BACnetDeviceObjectPropertyReferenceEnclosed) String() string { + if m == nil { + return "<nil>" + } + buffer := utils.NewBoxedWriteBufferWithOptions(true, true) + if err := m.Serialize(buffer); err != nil { + return err.Error() + } + return buffer.GetBox().String() +} diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotificationParametersBufferReady.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotificationParametersBufferReady.go index f380e0756d..6d9447fac4 100644 --- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotificationParametersBufferReady.go +++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotificationParametersBufferReady.go @@ -30,7 +30,7 @@ import ( type BACnetNotificationParametersBufferReady struct { *BACnetNotificationParameters InnerOpeningTag *BACnetOpeningTag - BufferProperty *BACnetDeviceObjectPropertyReference + BufferProperty *BACnetDeviceObjectPropertyReferenceEnclosed PreviousNotification *BACnetContextTagUnsignedInteger CurrentNotification *BACnetContextTagUnsignedInteger InnerClosingTag *BACnetClosingTag @@ -46,7 +46,7 @@ type IBACnetNotificationParametersBufferReady interface { // GetInnerOpeningTag returns InnerOpeningTag (property field) GetInnerOpeningTag() *BACnetOpeningTag // GetBufferProperty returns BufferProperty (property field) - GetBufferProperty() *BACnetDeviceObjectPropertyReference + GetBufferProperty() *BACnetDeviceObjectPropertyReferenceEnclosed // GetPreviousNotification returns PreviousNotification (property field) GetPreviousNotification() *BACnetContextTagUnsignedInteger // GetCurrentNotification returns CurrentNotification (property field) @@ -90,7 +90,7 @@ func (m *BACnetNotificationParametersBufferReady) GetInnerOpeningTag() *BACnetOp return m.InnerOpeningTag } -func (m *BACnetNotificationParametersBufferReady) GetBufferProperty() *BACnetDeviceObjectPropertyReference { +func (m *BACnetNotificationParametersBufferReady) GetBufferProperty() *BACnetDeviceObjectPropertyReferenceEnclosed { return m.BufferProperty } @@ -112,7 +112,7 @@ func (m *BACnetNotificationParametersBufferReady) GetInnerClosingTag() *BACnetCl /////////////////////////////////////////////////////////// // NewBACnetNotificationParametersBufferReady factory function for BACnetNotificationParametersBufferReady -func NewBACnetNotificationParametersBufferReady(innerOpeningTag *BACnetOpeningTag, bufferProperty *BACnetDeviceObjectPropertyReference, previousNotification *BACnetContextTagUnsignedInteger, currentNotification *BACnetContextTagUnsignedInteger, innerClosingTag *BACnetClosingTag, openingTag *BACnetOpeningTag, peekedTagHeader *BACnetTagHeader, closingTag *BACnetClosingTag, tagNumber uint8, objectType BACnetObjectType) *BACnetNotificationParametersBufferReady { +func NewBACnetNotificationParametersBufferReady(innerOpeningTag *BACnetOpeningTag, bufferProperty *BACnetDeviceObjectPropertyReferenceEnclosed, previousNotification *BACnetContextTagUnsignedInteger, currentNotification *BACnetContextTagUnsignedInteger, innerClosingTag *BACnetClosingTag, openingTag *BACnetOpeningTag, peekedTagHeader *BACnetTagHeader, closingTag *BACnetClosingTag, tagNumber uint8, objectType BACnetObjectType) *BACnetNotificationParametersBufferReady { _result := &BACnetNotificationParametersBufferReady{ InnerOpeningTag: innerOpeningTag, BufferProperty: bufferProperty, @@ -198,11 +198,11 @@ func BACnetNotificationParametersBufferReadyParse(readBuffer utils.ReadBuffer, t if pullErr := readBuffer.PullContext("bufferProperty"); pullErr != nil { return nil, pullErr } - _bufferProperty, _bufferPropertyErr := BACnetDeviceObjectPropertyReferenceParse(readBuffer, uint8(uint8(0))) + _bufferProperty, _bufferPropertyErr := BACnetDeviceObjectPropertyReferenceEnclosedParse(readBuffer, uint8(uint8(0))) if _bufferPropertyErr != nil { return nil, errors.Wrap(_bufferPropertyErr, "Error parsing 'bufferProperty' field") } - bufferProperty := CastBACnetDeviceObjectPropertyReference(_bufferProperty) + bufferProperty := CastBACnetDeviceObjectPropertyReferenceEnclosed(_bufferProperty) if closeErr := readBuffer.CloseContext("bufferProperty"); closeErr != nil { return nil, closeErr } @@ -253,7 +253,7 @@ func BACnetNotificationParametersBufferReadyParse(readBuffer utils.ReadBuffer, t // Create a partially initialized instance _child := &BACnetNotificationParametersBufferReady{ InnerOpeningTag: CastBACnetOpeningTag(innerOpeningTag), - BufferProperty: CastBACnetDeviceObjectPropertyReference(bufferProperty), + BufferProperty: CastBACnetDeviceObjectPropertyReferenceEnclosed(bufferProperty), PreviousNotification: CastBACnetContextTagUnsignedInteger(previousNotification), CurrentNotification: CastBACnetContextTagUnsignedInteger(currentNotification), InnerClosingTag: CastBACnetClosingTag(innerClosingTag), diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotificationParametersExtendedParameters.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotificationParametersExtendedParameters.go index ffbbe43b4e..ba32c6ebae 100644 --- a/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotificationParametersExtendedParameters.go +++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetNotificationParametersExtendedParameters.go @@ -43,7 +43,7 @@ type BACnetNotificationParametersExtendedParameters struct { DateValue *BACnetApplicationTagDate TimeValue *BACnetApplicationTagTime ObjectIdentifier *BACnetApplicationTagObjectIdentifier - Reference *BACnetDeviceObjectPropertyReference + Reference *BACnetDeviceObjectPropertyReferenceEnclosed ClosingTag *BACnetClosingTag // Arguments. @@ -81,7 +81,7 @@ type IBACnetNotificationParametersExtendedParameters interface { // GetObjectIdentifier returns ObjectIdentifier (property field) GetObjectIdentifier() *BACnetApplicationTagObjectIdentifier // GetReference returns Reference (property field) - GetReference() *BACnetDeviceObjectPropertyReference + GetReference() *BACnetDeviceObjectPropertyReferenceEnclosed // GetClosingTag returns ClosingTag (property field) GetClosingTag() *BACnetClosingTag // GetLengthInBytes returns the length in bytes @@ -153,7 +153,7 @@ func (m *BACnetNotificationParametersExtendedParameters) GetObjectIdentifier() * return m.ObjectIdentifier } -func (m *BACnetNotificationParametersExtendedParameters) GetReference() *BACnetDeviceObjectPropertyReference { +func (m *BACnetNotificationParametersExtendedParameters) GetReference() *BACnetDeviceObjectPropertyReferenceEnclosed { return m.Reference } @@ -167,7 +167,7 @@ func (m *BACnetNotificationParametersExtendedParameters) GetClosingTag() *BACnet /////////////////////////////////////////////////////////// // NewBACnetNotificationParametersExtendedParameters factory function for BACnetNotificationParametersExtendedParameters -func NewBACnetNotificationParametersExtendedParameters(openingTag *BACnetOpeningTag, nullValue *BACnetApplicationTagNull, realValue *BACnetApplicationTagReal, unsignedValue *BACnetApplicationTagUnsignedInteger, booleanValue *BACnetApplicationTagBoolean, integerValue *BACnetApplicationTagSignedInteger, doubleValue *BACnetApplicationTagDouble, octetStringValue *BACnetApplicationTagOctetString, characterStringValue *BACnetApplicationTagCharacterString, bitStringValue *BACnetApplicationTagBi [...] +func NewBACnetNotificationParametersExtendedParameters(openingTag *BACnetOpeningTag, nullValue *BACnetApplicationTagNull, realValue *BACnetApplicationTagReal, unsignedValue *BACnetApplicationTagUnsignedInteger, booleanValue *BACnetApplicationTagBoolean, integerValue *BACnetApplicationTagSignedInteger, doubleValue *BACnetApplicationTagDouble, octetStringValue *BACnetApplicationTagOctetString, characterStringValue *BACnetApplicationTagCharacterString, bitStringValue *BACnetApplicationTagBi [...] return &BACnetNotificationParametersExtendedParameters{OpeningTag: openingTag, NullValue: nullValue, RealValue: realValue, UnsignedValue: unsignedValue, BooleanValue: booleanValue, IntegerValue: integerValue, DoubleValue: doubleValue, OctetStringValue: octetStringValue, CharacterStringValue: characterStringValue, BitStringValue: bitStringValue, EnumeratedValue: enumeratedValue, DateValue: dateValue, TimeValue: timeValue, ObjectIdentifier: objectIdentifier, Reference: reference, ClosingT [...] } @@ -569,20 +569,20 @@ func BACnetNotificationParametersExtendedParametersParse(readBuffer utils.ReadBu } // Optional Field (reference) (Can be skipped, if a given expression evaluates to false) - var reference *BACnetDeviceObjectPropertyReference = nil + var reference *BACnetDeviceObjectPropertyReferenceEnclosed = nil { currentPos = readBuffer.GetPos() if pullErr := readBuffer.PullContext("reference"); pullErr != nil { return nil, pullErr } - _val, _err := BACnetDeviceObjectPropertyReferenceParse(readBuffer, uint8(0)) + _val, _err := BACnetDeviceObjectPropertyReferenceEnclosedParse(readBuffer, uint8(0)) switch { case errors.Is(_err, utils.ParseAssertError{}) || errors.Is(_err, io.EOF): readBuffer.Reset(currentPos) case _err != nil: return nil, errors.Wrap(_err, "Error parsing 'reference' field") default: - reference = CastBACnetDeviceObjectPropertyReference(_val) + reference = CastBACnetDeviceObjectPropertyReferenceEnclosed(_val) if closeErr := readBuffer.CloseContext("reference"); closeErr != nil { return nil, closeErr } @@ -836,7 +836,7 @@ func (m *BACnetNotificationParametersExtendedParameters) Serialize(writeBuffer u } // Optional Field (reference) (Can be skipped, if the value is null) - var reference *BACnetDeviceObjectPropertyReference = nil + var reference *BACnetDeviceObjectPropertyReferenceEnclosed = nil if m.Reference != nil { if pushErr := writeBuffer.PushContext("reference"); pushErr != nil { return pushErr diff --git a/plc4go/internal/plc4go/bacnetip/readwrite/model/StaticHelper.go b/plc4go/internal/plc4go/bacnetip/readwrite/model/StaticHelper.go index 8093bd4974..4b95d7e8c5 100644 --- a/plc4go/internal/plc4go/bacnetip/readwrite/model/StaticHelper.go +++ b/plc4go/internal/plc4go/bacnetip/readwrite/model/StaticHelper.go @@ -292,9 +292,9 @@ func IsBACnetConstructedDataClosingTag(readBuffer utils.ReadBuffer, instantTermi return foundOurClosingTag } -func GuessDataType(objectType BACnetObjectType) BACnetDataType { +func GuessDataType(objectType BACnetObjectType, propertyIdentifier *BACnetContextTagPropertyIdentifier) BACnetDataType { // TODO: implement me - return BACnetDataType_BACNET_PROPERTY_IDENTIFIER + return BACnetDataType_ENUMERATED } func ParseVarUint(data []byte) uint32 { diff --git a/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/readwrite/utils/StaticHelper.java b/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/readwrite/utils/StaticHelper.java index 1af8c86af1..67bf86cc69 100644 --- a/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/readwrite/utils/StaticHelper.java +++ b/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/readwrite/utils/StaticHelper.java @@ -258,7 +258,467 @@ public class StaticHelper { } } - public static BACnetDataType guessDataType(BACnetObjectType objectType) { + public static BACnetDataType guessDataType(BACnetObjectType objectType, BACnetContextTagPropertyIdentifier propertyIdentifier) { + switch (propertyIdentifier.getPropertyIdentifier()) { + case ABSENTEE_LIMIT: + case ACCEPTED_MODES: + case ACCESS_ALARM_EVENTS: + case ACCESS_DOORS: + case ACCESS_EVENT: + case ACCESS_EVENT_AUTHENTICATION_FACTOR: + case ACCESS_EVENT_CREDENTIAL: + case ACCESS_EVENT_TAG: + case ACCESS_EVENT_TIME: + case ACCESS_TRANSACTION_EVENTS: + case ACCOMPANIMENT: + case ACCOMPANIMENT_TIME: + case ACK_REQUIRED: + case ACKED_TRANSITIONS: + case ACTION: + case ACTION_TEXT: + case ACTIVATION_TIME: + case ACTIVE_AUTHENTICATION_POLICY: + case ACTIVE_COV_MULTIPLE_SUBSCRIPTIONS: + case ACTIVE_COV_SUBSCRIPTIONS: + case ACTIVE_TEXT: + case ACTIVE_VT_SESSIONS: + case ACTUAL_SHED_LEVEL: + case ADJUST_VALUE: + case ALARM_VALUE: + case ALARM_VALUES: + case ALIGN_INTERVALS: + case ALL: + case ALL_WRITES_SUCCESSFUL: + case ALLOW_GROUP_DELAY_INHIBIT: + case APDU_LENGTH: + case APDU_SEGMENT_TIMEOUT: + case APDU_TIMEOUT: + case APPLICATION_SOFTWARE_VERSION: + case ARCHIVE: + case ASSIGNED_ACCESS_RIGHTS: + case ASSIGNED_LANDING_CALLS: + case ATTEMPTED_SAMPLES: + case AUTHENTICATION_FACTORS: + case AUTHENTICATION_POLICY_LIST: + case AUTHENTICATION_POLICY_NAMES: + case AUTHENTICATION_STATUS: + case AUTHORIZATION_EXEMPTIONS: + case AUTHORIZATION_MODE: + case AUTO_SLAVE_DISCOVERY: + case AVERAGE_VALUE: + case BACKUP_AND_RESTORE_STATE: + case BACKUP_FAILURE_TIMEOUT: + case BACKUP_PREPARATION_TIME: + case BACNET_IP_GLOBAL_ADDRESS: + case BACNET_IP_MODE: + case BACNET_IP_MULTICAST_ADDRESS: + case BACNET_IP_NAT_TRAVERSAL: + case BACNET_IP_UDP_PORT: + case BACNET_IPV6_MODE: + case BACNET_IPV6_UDP_PORT: + case BACNET_IPV6_MULTICAST_ADDRESS: + case BASE_DEVICE_SECURITY_POLICY: + case BBMD_ACCEPT_FD_REGISTRATIONS: + case BBMD_BROADCAST_DISTRIBUTION_TABLE: + case BBMD_FOREIGN_DEVICE_TABLE: + case BELONGS_TO: + case BIAS: + case BIT_MASK: + case BIT_TEXT: + case BLINK_WARN_ENABLE: + case BUFFER_SIZE: + case CAR_ASSIGNED_DIRECTION: + case CAR_DOOR_COMMAND: + case CAR_DOOR_STATUS: + case CAR_DOOR_TEXT: + case CAR_DOOR_ZONE: + case CAR_DRIVE_STATUS: + case CAR_LOAD: + case CAR_LOAD_UNITS: + case CAR_MODE: + case CAR_MOVING_DIRECTION: + case CAR_POSITION: + case CHANGE_OF_STATE_COUNT: + case CHANGE_OF_STATE_TIME: + case CHANGES_PENDING: + case CHANNEL_NUMBER: + case CLIENT_COV_INCREMENT: + case COMMAND: + case COMMAND_TIME_ARRAY: + case CONFIGURATION_FILES: + case CONTROL_GROUPS: + case CONTROLLED_VARIABLE_REFERENCE: + case CONTROLLED_VARIABLE_UNITS: + case CONTROLLED_VARIABLE_VALUE: + case COUNT: + case COUNT_BEFORE_CHANGE: + case COUNT_CHANGE_TIME: + case COV_INCREMENT: + case COV_PERIOD: + case COV_RESUBSCRIPTION_INTERVAL: + case COVU_PERIOD: + case COVU_RECIPIENTS: + case CREDENTIAL_DISABLE: + case CREDENTIAL_STATUS: + case CREDENTIALS: + case CREDENTIALS_IN_ZONE: + case CURRENT_COMMAND_PRIORITY: + case DATABASE_REVISION: + case DATE_LIST: + case DAYLIGHT_SAVINGS_STATUS: + case DAYS_REMAINING: + case DEADBAND: + case DEFAULT_FADE_TIME: + case DEFAULT_RAMP_RATE: + case DEFAULT_STEP_INCREMENT: + case DEFAULT_SUBORDINATE_RELATIONSHIP: + case DEFAULT_TIMEOUT: + case DEPLOYED_PROFILE_LOCATION: + case DERIVATIVE_CONSTANT: + case DERIVATIVE_CONSTANT_UNITS: + case DESCRIPTION: + case DESCRIPTION_OF_HALT: + case DEVICE_ADDRESS_BINDING: + case DEVICE_TYPE: + case DIRECT_READING: + case DISTRIBUTION_KEY_REVISION: + case DO_NOT_HIDE: + case DOOR_ALARM_STATE: + case DOOR_EXTENDED_PULSE_TIME: + case DOOR_MEMBERS: + case DOOR_OPEN_TOO_LONG_TIME: + case DOOR_PULSE_TIME: + case DOOR_STATUS: + case DOOR_UNLOCK_DELAY_TIME: + case DUTY_WINDOW: + case EFFECTIVE_PERIOD: + case EGRESS_ACTIVE: + case EGRESS_TIME: + case ELAPSED_ACTIVE_TIME: + case ELEVATOR_GROUP: + case ENABLE: + case ENERGY_METER: + case ENERGY_METER_REF: + case ENTRY_POINTS: + case ERROR_LIMIT: + case ESCALATOR_MODE: + case EVENT_ALGORITHM_INHIBIT: + case EVENT_ALGORITHM_INHIBIT_REF: + case EVENT_DETECTION_ENABLE: + case EVENT_ENABLE: + case EVENT_MESSAGE_TEXTS: + case EVENT_MESSAGE_TEXTS_CONFIG: + case EVENT_PARAMETERS: + case EVENT_STATE: + case EVENT_TIME_STAMPS: + case EVENT_TYPE: + case EXCEPTION_SCHEDULE: + case EXECUTION_DELAY: + case EXIT_POINTS: + case EXPECTED_SHED_LEVEL: + case EXPIRATION_TIME: + case EXTENDED_TIME_ENABLE: + case FAILED_ATTEMPT_EVENTS: + case FAILED_ATTEMPTS: + case FAILED_ATTEMPTS_TIME: + case FAULT_HIGH_LIMIT: + case FAULT_LOW_LIMIT: + case FAULT_PARAMETERS: + case FAULT_SIGNALS: + case FAULT_TYPE: + case FAULT_VALUES: + case FD_BBMD_ADDRESS: + case FD_SUBSCRIPTION_LIFETIME: + case FEEDBACK_VALUE: + case FILE_ACCESS_METHOD: + case FILE_SIZE: + case FILE_TYPE: + case FIRMWARE_REVISION: + case FLOOR_TEXT: + case FULL_DUTY_BASELINE: + case GLOBAL_IDENTIFIER: + case GROUP_ID: + case GROUP_MEMBER_NAMES: + case GROUP_MEMBERS: + case GROUP_MODE: + case HIGH_LIMIT: + case HIGHER_DECK: + case IN_PROCESS: + case IN_PROGRESS: + case INACTIVE_TEXT: + case INITIAL_TIMEOUT: + case INPUT_REFERENCE: + case INSTALLATION_ID: + case INSTANCE_OF: + case INSTANTANEOUS_POWER: + case INTEGRAL_CONSTANT: + case INTEGRAL_CONSTANT_UNITS: + case INTERFACE_VALUE: + case INTERVAL_OFFSET: + case IP_ADDRESS: + case IP_DEFAULT_GATEWAY: + case IP_DHCP_ENABLE: + case IP_DHCP_LEASE_TIME: + case IP_DHCP_LEASE_TIME_REMAINING: + case IP_DHCP_SERVER: + case IP_DNS_SERVER: + case IP_SUBNET_MASK: + case IPV6_ADDRESS: + case IPV6_AUTO_ADDRESSING_ENABLE: + case IPV6_DEFAULT_GATEWAY: + case IPV6_DHCP_LEASE_TIME: + case IPV6_DHCP_LEASE_TIME_REMAINING: + case IPV6_DHCP_SERVER: + case IPV6_DNS_SERVER: + case IPV6_PREFIX_LENGTH: + case IPV6_ZONE_INDEX: + case IS_UTC: + case KEY_SETS: + case LANDING_CALL_CONTROL: + case LANDING_CALLS: + case LANDING_DOOR_STATUS: + case LAST_ACCESS_EVENT: + case LAST_ACCESS_POINT: + case LAST_COMMAND_TIME: + case LAST_CREDENTIAL_ADDED: + case LAST_CREDENTIAL_ADDED_TIME: + case LAST_CREDENTIAL_REMOVED: + case LAST_CREDENTIAL_REMOVED_TIME: + case LAST_KEY_SERVER: + case LAST_NOTIFY_RECORD: + case LAST_PRIORITY: + case LAST_RESTART_REASON: + case LAST_RESTORE_TIME: + case LAST_STATE_CHANGE: + case LAST_USE_TIME: + case LIFE_SAFETY_ALARM_VALUES: + case LIGHTING_COMMAND: + case LIGHTING_COMMAND_DEFAULT_PRIORITY: + case LIMIT_ENABLE: + case LIMIT_MONITORING_INTERVAL: + case LINK_SPEED: + case LINK_SPEED_AUTONEGOTIATE: + case LINK_SPEEDS: + case LIST_OF_GROUP_MEMBERS: + case LIST_OF_OBJECT_PROPERTY_REFERENCES: + case LOCAL_DATE: + case LOCAL_FORWARDING_ONLY: + case LOCAL_TIME: + case LOCATION: + case LOCK_STATUS: + case LOCKOUT: + case LOCKOUT_RELINQUISH_TIME: + case LOG_BUFFER: + case LOG_DEVICE_OBJECT_PROPERTY: + case LOG_INTERVAL: + case LOGGING_OBJECT: + case LOGGING_RECORD: + case LOGGING_TYPE: + case LOW_DIFF_LIMIT: + case LOW_LIMIT: + case LOWER_DECK: + case MAC_ADDRESS: + case MACHINE_ROOM_ID: + case MAINTENANCE_REQUIRED: + case MAKING_CAR_CALL: + case MANIPULATED_VARIABLE_REFERENCE: + case MANUAL_SLAVE_ADDRESS_BINDING: + case MASKED_ALARM_VALUES: + case MAX_ACTUAL_VALUE: + case MAX_APDU_LENGTH_ACCEPTED: + case MAX_FAILED_ATTEMPTS: + case MAX_INFO_FRAMES: + case MAX_MASTER: + case MAX_PRES_VALUE: + case MAX_SEGMENTS_ACCEPTED: + case MAXIMUM_OUTPUT: + case MAXIMUM_VALUE: + case MAXIMUM_VALUE_TIMESTAMP: + case MEMBER_OF: + case MEMBER_STATUS_FLAGS: + case MEMBERS: + case MIN_ACTUAL_VALUE: + case MIN_PRES_VALUE: + case MINIMUM_OFF_TIME: + case MINIMUM_ON_TIME: + case MINIMUM_OUTPUT: + case MINIMUM_VALUE: + case MINIMUM_VALUE_TIMESTAMP: + case MODE: + case MODEL_NAME: + case MODIFICATION_DATE: + case MUSTER_POINT: + case NEGATIVE_ACCESS_RULES: + case NETWORK_ACCESS_SECURITY_POLICIES: + case NETWORK_INTERFACE_NAME: + case NETWORK_NUMBER: + case NETWORK_NUMBER_QUALITY: + case NETWORK_TYPE: + case NEXT_STOPPING_FLOOR: + case NODE_SUBTYPE: + case NODE_TYPE: + case NOTIFICATION_CLASS: + case NOTIFICATION_THRESHOLD: + case NOTIFY_TYPE: + case NUMBER_OF_APDU_RETRIES: + case NUMBER_OF_AUTHENTICATION_POLICIES: + case NUMBER_OF_STATES: + case OBJECT_IDENTIFIER: + case OBJECT_LIST: + case OBJECT_NAME: + case OBJECT_PROPERTY_REFERENCE: + case OBJECT_TYPE: + case OCCUPANCY_COUNT: + case OCCUPANCY_COUNT_ADJUST: + case OCCUPANCY_COUNT_ENABLE: + case OCCUPANCY_LOWER_LIMIT: + case OCCUPANCY_LOWER_LIMIT_ENFORCED: + case OCCUPANCY_STATE: + case OCCUPANCY_UPPER_LIMIT: + case OCCUPANCY_UPPER_LIMIT_ENFORCED: + case OPERATION_DIRECTION: + case OPERATION_EXPECTED: + case OPTIONAL: + case OUT_OF_SERVICE: + case OUTPUT_UNITS: + case PACKET_REORDER_TIME: + case PASSBACK_MODE: + case PASSBACK_TIMEOUT: + case PASSENGER_ALARM: + case POLARITY: + case PORT_FILTER: + case POSITIVE_ACCESS_RULES: + case POWER: + case POWER_MODE: + case PRESCALE: + case PRESENT_VALUE: + case PRIORITY: + case PRIORITY_ARRAY: + case PRIORITY_FOR_WRITING: + case PROCESS_IDENTIFIER: + case PROCESS_IDENTIFIER_FILTER: + case PROFILE_LOCATION: + case PROFILE_NAME: + case PROGRAM_CHANGE: + case PROGRAM_LOCATION: + case PROGRAM_STATE: + case PROPERTY_LIST: + case PROPORTIONAL_CONSTANT: + case PROPORTIONAL_CONSTANT_UNITS: + case PROTOCOL_LEVEL: + case PROTOCOL_CONFORMANCE_CLASS: + case PROTOCOL_OBJECT_TYPES_SUPPORTED: + case PROTOCOL_REVISION: + case PROTOCOL_SERVICES_SUPPORTED: + case PROTOCOL_VERSION: + case PULSE_RATE: + case READ_ONLY: + case REASON_FOR_DISABLE: + case REASON_FOR_HALT: + case RECIPIENT_LIST: + case RECORD_COUNT: + case RECORDS_SINCE_NOTIFICATION: + case REFERENCE_PORT: + case REGISTERED_CAR_CALL: + case RELIABILITY: + case RELIABILITY_EVALUATION_INHIBIT: + case RELINQUISH_DEFAULT: + case REPRESENTS: + case REQUESTED_SHED_LEVEL: + case REQUESTED_UPDATE_INTERVAL: + case REQUIRED: + case RESOLUTION: + case RESTART_NOTIFICATION_RECIPIENTS: + case RESTORE_COMPLETION_TIME: + case RESTORE_PREPARATION_TIME: + case ROUTING_TABLE: + case SCALE: + case SCALE_FACTOR: + case SCHEDULE_DEFAULT: + case SECURED_STATUS: + case SECURITY_PDU_TIMEOUT: + case SECURITY_TIME_WINDOW: + case SEGMENTATION_SUPPORTED: + case SERIAL_NUMBER: + case SETPOINT: + case SETPOINT_REFERENCE: + case SETTING: + case SHED_DURATION: + case SHED_LEVEL_DESCRIPTIONS: + case SHED_LEVELS: + case SILENCED: + case SLAVE_ADDRESS_BINDING: + case SLAVE_PROXY_ENABLE: + case START_TIME: + case STATE_CHANGE_VALUES: + case STATE_DESCRIPTION: + case STATE_TEXT: + case STATUS_FLAGS: + case STOP_TIME: + case STOP_WHEN_FULL: + case STRIKE_COUNT: + case STRUCTURED_OBJECT_LIST: + case SUBORDINATE_ANNOTATIONS: + case SUBORDINATE_LIST: + case SUBORDINATE_NODE_TYPES: + case SUBORDINATE_RELATIONSHIPS: + case SUBORDINATE_TAGS: + case SUBSCRIBED_RECIPIENTS: + case SUPPORTED_FORMAT_CLASSES: + case SUPPORTED_FORMATS: + case SUPPORTED_SECURITY_ALGORITHMS: + case SYSTEM_STATUS: + case TAGS: + case THREAT_AUTHORITY: + case THREAT_LEVEL: + case TIME_DELAY: + case TIME_DELAY_NORMAL: + case TIME_OF_ACTIVE_TIME_RESET: + case TIME_OF_DEVICE_RESTART: + case TIME_OF_STATE_COUNT_RESET: + case TIME_OF_STRIKE_COUNT_RESET: + case TIME_SYNCHRONIZATION_INTERVAL: + case TIME_SYNCHRONIZATION_RECIPIENTS: + case TIMER_RUNNING: + case TIMER_STATE: + case TOTAL_RECORD_COUNT: + case TRACE_FLAG: + case TRACKING_VALUE: + case TRANSACTION_NOTIFICATION_CLASS: + case TRANSITION: + case TRIGGER: + case UNITS: + case UPDATE_INTERVAL: + case UPDATE_KEY_SET_TIMEOUT: + case UPDATE_TIME: + case USER_EXTERNAL_IDENTIFIER: + case USER_INFORMATION_REFERENCE: + case USER_NAME: + case USER_TYPE: + case USES_REMAINING: + case UTC_OFFSET: + case UTC_TIME_SYNCHRONIZATION_RECIPIENTS: + case VALID_SAMPLES: + case VALUE_BEFORE_CHANGE: + case VALUE_CHANGE_TIME: + case VALUE_SET: + case VALUE_SOURCE: + case VALUE_SOURCE_ARRAY: + case VARIANCE_VALUE: + case VENDOR_IDENTIFIER: + case VENDOR_NAME: + case VERIFICATION_TIME: + case VIRTUAL_MAC_ADDRESS_TABLE: + case VT_CLASSES_SUPPORTED: + case WEEKLY_SCHEDULE: + case WINDOW_INTERVAL: + case WINDOW_SAMPLES: + case WRITE_STATUS: + case ZONE_FROM: + case ZONE_MEMBERS: + case ZONE_TO: + case VENDOR_PROPRIETARY_VALUE: + } switch (objectType) { case ACCESS_CREDENTIAL: case ACCESS_DOOR: @@ -267,11 +727,9 @@ public class StaticHelper { case ACCESS_USER: case ACCESS_ZONE: case ACCUMULATOR: - // TODO: temporary - return BACnetDataType.BACNET_PROPERTY_IDENTIFIER; + break; case ALERT_ENROLLMENT: - // TODO: temporary - return BACnetDataType.BACNET_PROPERTY_IDENTIFIER; + break; case ANALOG_INPUT: case ANALOG_OUTPUT: return BACnetDataType.REAL; @@ -281,8 +739,7 @@ public class StaticHelper { case BINARY_LIGHTING_OUTPUT: case BINARY_OUTPUT: case BINARY_VALUE: - // TODO: temporary - return BACnetDataType.BACNET_PROPERTY_IDENTIFIER; + break; case BITSTRING_VALUE: return BACnetDataType.BIT_STRING; case CALENDAR: @@ -302,8 +759,7 @@ public class StaticHelper { case FILE: case GLOBAL_GROUP: case GROUP: - // TODO: temporary - return BACnetDataType.BACNET_PROPERTY_IDENTIFIER; + break; case INTEGER_VALUE: return BACnetDataType.SIGNED_INTEGER; case LARGE_ANALOG_VALUE: @@ -314,6 +770,7 @@ public class StaticHelper { return BACnetDataType.BACNET_OBJECT_IDENTIFIER; case LIFT: case LIGHTING_OUTPUT: + break; case LOAD_CONTROL: // TODO: temporary // FIXME: this is just so tags get consumed return BACnetDataType.ENUMERATED; @@ -330,6 +787,7 @@ public class StaticHelper { case PROGRAM: case PULSE_CONVERTER: case SCHEDULE: + break; case STRUCTURED_VIEW: // TODO: temporary return BACnetDataType.BACNET_OBJECT_IDENTIFIER; @@ -340,8 +798,7 @@ public class StaticHelper { case TREND_LOG_MULTIPLE: return BACnetDataType.ENUMERATED; } - // TODO: temporary - return BACnetDataType.BACNET_PROPERTY_IDENTIFIER; + return BACnetDataType.ENUMERATED; } public static long parseVarUint(byte[] data) { diff --git a/plc4j/drivers/bacnet/src/test/java/org/apache/plc4x/java/bacnetip/RandomPackagesTest.java b/plc4j/drivers/bacnet/src/test/java/org/apache/plc4x/java/bacnetip/RandomPackagesTest.java index 12bbc157b8..14674e3284 100644 --- a/plc4j/drivers/bacnet/src/test/java/org/apache/plc4x/java/bacnetip/RandomPackagesTest.java +++ b/plc4j/drivers/bacnet/src/test/java/org/apache/plc4x/java/bacnetip/RandomPackagesTest.java @@ -58,7 +58,6 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; @RequirePcapNg public class RandomPackagesTest { - private static final Logger LOGGER = LoggerFactory.getLogger(RandomPackagesTest.class); public static final String BACNET_BPF_FILTER_UDP = "udp port 47808"; @@ -893,9 +892,9 @@ public class RandomPackagesTest { } { BACnetNotificationParametersBufferReady baCnetNotificationParametersBufferReady = (BACnetNotificationParametersBufferReady) baCnetConfirmedServiceRequestConfirmedEventNotification.getEventValues(); - assertEquals(BACnetObjectType.TREND_LOG, baCnetNotificationParametersBufferReady.getBufferProperty().getObjectIdentifier().getObjectType()); - assertEquals(BACnetPropertyIdentifier.LOG_BUFFER, baCnetNotificationParametersBufferReady.getBufferProperty().getPropertyIdentifier().getPropertyIdentifier()); - assertEquals(BACnetObjectType.DEVICE, baCnetNotificationParametersBufferReady.getBufferProperty().getDeviceIdentifier().getObjectType()); + assertEquals(BACnetObjectType.TREND_LOG, baCnetNotificationParametersBufferReady.getBufferProperty().getValue().getObjectIdentifier().getObjectType()); + assertEquals(BACnetPropertyIdentifier.LOG_BUFFER, baCnetNotificationParametersBufferReady.getBufferProperty().getValue().getPropertyIdentifier().getPropertyIdentifier()); + assertEquals(BACnetObjectType.DEVICE, baCnetNotificationParametersBufferReady.getBufferProperty().getValue().getDeviceIdentifier().getObjectType()); assertEquals(1640, baCnetNotificationParametersBufferReady.getPreviousNotification().getPayload().getActualValue().longValue()); assertEquals(1653, baCnetNotificationParametersBufferReady.getCurrentNotification().getPayload().getActualValue().longValue()); } diff --git a/plc4j/drivers/bacnet/src/test/java/org/apache/plc4x/java/bacnetip/TrickyPackagesTest.java b/plc4j/drivers/bacnet/src/test/java/org/apache/plc4x/java/bacnetip/TrickyPackagesTest.java new file mode 100644 index 0000000000..5790d8e89d --- /dev/null +++ b/plc4j/drivers/bacnet/src/test/java/org/apache/plc4x/java/bacnetip/TrickyPackagesTest.java @@ -0,0 +1,111 @@ +/* + * 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 org.apache.plc4x.java.bacnetip; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.plc4x.java.bacnetip.readwrite.BVLC; +import org.apache.plc4x.java.spi.generation.ReadBufferByteBased; +import org.junit.Test; + +import java.util.stream.IntStream; + +import static org.junit.Assert.assertNotNull; + +public class TrickyPackagesTest { + + // from plugfest-tridium-1.pcap + @Test + public void testTridium255() throws Exception { + int[] rawBytesAsInts = new int[]{ + /*0000*/ 0x00, 0x1d, 0x09, 0xbc, 0x43, 0x5f, 0x00, 0x01, 0xf0, 0x8c, 0x11, 0x50, 0x08, 0x00, 0x45, 0x00, + /*0010*/ 0x01, 0xfc, 0x7e, 0x47, 0x00, 0x00, 0x40, 0x11, 0x27, 0x92, 0xac, 0x10, 0x24, 0xcd, 0xac, 0x10, + /*0020*/ 0x56, 0x2a, 0xba, 0xc0, 0xba, 0xc0, 0x01, 0xe8, 0x24, 0xd9, 0x81, 0x0a, 0x01, 0xe0, 0x01, 0x00, + /*0030*/ 0x30, 0x6e, 0x0e, 0x0c, 0x04, 0x40, 0x00, 0x01, 0x1e, 0x29, 0x4b, 0x4e, 0xc4, 0x04, 0x40, 0x00, + /*0040*/ 0x01, 0x4f, 0x29, 0x4d, 0x4e, 0x75, 0x13, 0x00, 0x53, 0x63, 0x68, 0x65, 0x64, 0x2e, 0x45, 0x6e, + /*0050*/ 0x75, 0x6d, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x4f, 0x29, 0x4f, 0x4e, 0x91, 0x11, + /*0060*/ 0x4f, 0x29, 0x55, 0x4e, 0x21, 0x07, 0x4f, 0x29, 0x20, 0x4e, 0xa4, 0xff, 0xff, 0xff, 0xff, 0xa4, + /*0070*/ 0xff, 0xff, 0xff, 0xff, 0x4f, 0x29, 0xae, 0x4e, 0x21, 0x01, 0x4f, 0x29, 0x36, 0x4e, 0x0c, 0x04, + /*0080*/ 0xc0, 0x00, 0x66, 0x19, 0x57, 0x29, 0x0a, 0x0c, 0x04, 0xc0, 0x00, 0x65, 0x19, 0x57, 0x29, 0x0a, + /*0090*/ 0x4f, 0x29, 0x58, 0x4e, 0x21, 0x10, 0x4f, 0x29, 0x6f, 0x4e, 0x82, 0x04, 0x00, 0x4f, 0x29, 0x67, + /*00a0*/ 0x4e, 0x91, 0x00, 0x4f, 0x29, 0x51, 0x4e, 0x10, 0x4f, 0x29, 0x7b, 0x4e, 0x0e, 0xb4, 0x06, 0x00, + /*00b0*/ 0x00, 0x00, 0x21, 0x01, 0xb4, 0x09, 0x00, 0x00, 0x00, 0x21, 0x02, 0xb4, 0x0c, 0x00, 0x00, 0x00, + /*00c0*/ 0x21, 0x03, 0xb4, 0x0f, 0x00, 0x00, 0x00, 0x21, 0x04, 0xb4, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0f, + /*00d0*/ 0x0e, 0xb4, 0x06, 0x00, 0x00, 0x00, 0x21, 0x01, 0xb4, 0x09, 0x00, 0x00, 0x00, 0x21, 0x02, 0xb4, + /*00e0*/ 0x0c, 0x00, 0x00, 0x00, 0x21, 0x03, 0xb4, 0x0f, 0x00, 0x00, 0x00, 0x21, 0x04, 0xb4, 0x12, 0x00, + /*00f0*/ 0x00, 0x00, 0x00, 0x0f, 0x0e, 0xb4, 0x06, 0x00, 0x00, 0x00, 0x21, 0x01, 0xb4, 0x09, 0x00, 0x00, + /*0100*/ 0x00, 0x21, 0x02, 0xb4, 0x0c, 0x00, 0x00, 0x00, 0x21, 0x03, 0xb4, 0x0f, 0x00, 0x00, 0x00, 0x21, + /*0110*/ 0x04, 0xb4, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0e, 0xb4, 0x06, 0x00, 0x00, 0x00, 0x21, 0x01, + /*0120*/ 0xb4, 0x09, 0x00, 0x00, 0x00, 0x21, 0x02, 0xb4, 0x0c, 0x00, 0x00, 0x00, 0x21, 0x03, 0xb4, 0x0f, + /*0130*/ 0x00, 0x00, 0x00, 0x21, 0x04, 0xb4, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0e, 0xb4, 0x06, 0x00, + /*0140*/ 0x00, 0x00, 0x21, 0x01, 0xb4, 0x09, 0x00, 0x00, 0x00, 0x21, 0x02, 0xb4, 0x0c, 0x00, 0x00, 0x00, + /*0150*/ 0x21, 0x03, 0xb4, 0x0f, 0x00, 0x00, 0x00, 0x21, 0x04, 0xb4, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0f, + /*0160*/ 0x0e, 0xb4, 0x06, 0x00, 0x00, 0x00, 0x21, 0x05, 0xb4, 0x0c, 0x00, 0x00, 0x00, 0x21, 0x06, 0xb4, + /*0170*/ 0x12, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0e, 0xb4, 0x06, 0x00, 0x00, 0x00, 0x21, 0x05, 0xb4, 0x0c, + /*0180*/ 0x00, 0x00, 0x00, 0x21, 0x06, 0xb4, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x4f, 0x29, 0x26, 0x4e, + /*0190*/ 0x0e, 0x0c, 0xff, 0xff, 0xff, 0x03, 0x0f, 0x2e, 0x2f, 0x39, 0x10, 0x1c, 0x01, 0x80, 0x00, 0x01, + /*01a0*/ 0x2e, 0xb4, 0x09, 0x00, 0x00, 0x00, 0x21, 0x08, 0xb4, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x0f, + /*01b0*/ 0x1e, 0x00, 0x00, 0x21, 0x08, 0xb4, 0x12, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x39, 0x10, 0x1c, 0x01, + /*01c0*/ 0x80, 0x00, 0x00, 0x2e, 0xb4, 0x03, 0x00, 0x00, 0x00, 0x21, 0x07, 0xb4, 0x06, 0x00, 0x00, 0x00, + /*01d0*/ 0x00, 0xb4, 0x07, 0x1e, 0x00, 0x00, 0x21, 0x07, 0xb4, 0x09, 0x1e, 0x00, 0x00, 0x00, 0xb4, 0x0a, + /*01e0*/ 0x1e, 0x00, 0x00, 0x21, 0x07, 0xb4, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x0e, 0x1e, 0x00, 0x00, + /*01f0*/ 0x21, 0x07, 0xb4, 0x11, 0x1e, 0x00, 0x00, 0x00, 0xb4, 0x13, 0x00, 0x00, 0x00, 0x21, 0x07, 0xb4, + /*0200*/ 0x14, 0x1e, 0x00, 0x00, 0x00, 0x2f, 0x39, 0x10, 0x4f, 0x1f, + }; + var rawBytes = (byte[]) ArrayUtils.toPrimitive(IntStream.of(rawBytesAsInts).boxed().map(Integer::byteValue).toArray(Byte[]::new)); + rawBytes = ArrayUtils.subarray(rawBytes, 42, rawBytes.length); + BVLC bvlc = BVLC.staticParse(new ReadBufferByteBased(rawBytes)); + assertNotNull(bvlc); + System.out.println(bvlc); + } + + // from plugfest-delta-2b.cap + @Test + public void testDelta1204() throws Exception { + int[] rawBytesAsInts = new int[]{ + /*0000*/ 0x00, 0x06, 0x5b, 0xd6, 0x9f, 0xfe, 0x00, 0x40, 0xae, 0x00, 0x45, 0xd7, 0x08, 0x00, 0x45, 0x00, + /*0010*/ 0x01, 0x5e, 0x28, 0x64, 0x00, 0x00, 0x3c, 0x11, 0xec, 0xc9, 0xac, 0x10, 0x08, 0x0a, 0xac, 0x10, + /*0020*/ 0x08, 0x37, 0xba, 0xc0, 0xba, 0xc0, 0x01, 0x4a, 0x00, 0x00, 0x81, 0x0a, 0x01, 0x42, 0x01, 0x00, + /*0030*/ 0x30, 0xef, 0x0e, 0x0c, 0x45, 0x80, 0x00, 0x01, 0x1e, 0x29, 0x1c, 0x4e, 0x71, 0x00, 0x4f, 0x2a, + /*0040*/ 0x04, 0x0a, 0x4e, 0x91, 0x00, 0x4f, 0x2a, 0x04, 0x0c, 0x4e, 0x0e, 0x09, 0x01, 0x19, 0x04, 0x2c, + /*0050*/ 0x01, 0xfe, 0xed, 0xd8, 0x3d, 0x06, 0x03, 0xff, 0x3b, 0xe8, 0x3e, 0xf1, 0x4a, 0x04, 0x57, 0x5a, + /*0060*/ 0x01, 0xe0, 0x69, 0x64, 0x79, 0x0a, 0x89, 0x2a, 0x99, 0x32, 0xaa, 0x13, 0x88, 0xba, 0x0b, 0xb8, + /*0070*/ 0xca, 0x1b, 0x58, 0xd9, 0x03, 0xea, 0x13, 0x88, 0xfa, 0x0f, 0x01, 0xe0, 0xf9, 0x10, 0x00, 0x0f, + /*0080*/ 0x4f, 0x2a, 0x04, 0x27, 0x4e, 0x0a, 0x02, 0x51, 0x19, 0x00, 0x29, 0x00, 0x39, 0x00, 0x4a, 0x06, + /*0090*/ 0x0b, 0x59, 0x00, 0x69, 0x00, 0x79, 0x00, 0x89, 0x00, 0x99, 0x00, 0xa9, 0x00, 0x4f, 0x2a, 0x04, + /*00a0*/ 0x3a, 0x39, 0x00, 0x4e, 0x21, 0x05, 0x4f, 0x2a, 0x04, 0x3a, 0x4e, 0x09, 0x00, 0x19, 0x00, 0x29, + /*00b0*/ 0x01, 0x39, 0x01, 0x4c, 0x45, 0x80, 0x00, 0x01, 0x59, 0x01, 0x69, 0x06, 0x79, 0x01, 0x8e, 0x0b, + /*00c0*/ 0x01, 0xea, 0xc9, 0x19, 0x00, 0x29, 0x00, 0x39, 0x00, 0x49, 0x00, 0x8f, 0x9c, 0x00, 0x00, 0x00, + /*00d0*/ 0x00, 0x09, 0x00, 0x19, 0x00, 0x29, 0x01, 0x39, 0x01, 0x4c, 0x45, 0x80, 0x00, 0x01, 0x59, 0x02, + /*00e0*/ 0x69, 0x06, 0x79, 0x02, 0x8e, 0x0a, 0x79, 0xef, 0x19, 0x00, 0x2b, 0x01, 0x80, 0x7e, 0x3a, 0x05, + /*00f0*/ 0xe7, 0x49, 0x32, 0x8f, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x19, 0x00, 0x29, 0x01, 0x39, + /*0100*/ 0x01, 0x4c, 0x45, 0x80, 0x00, 0x01, 0x59, 0x01, 0x69, 0x01, 0x79, 0x03, 0x8e, 0x0a, 0x01, 0x01, + /*0110*/ 0x19, 0x00, 0x29, 0x00, 0x39, 0x00, 0x49, 0x00, 0x8f, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, + /*0120*/ 0x19, 0x00, 0x29, 0x01, 0x39, 0x01, 0x4c, 0x45, 0x80, 0x00, 0x01, 0x59, 0x04, 0x69, 0x01, 0x79, + /*0130*/ 0x05, 0x8e, 0x0a, 0x31, 0x20, 0x19, 0x00, 0x2a, 0x2f, 0x37, 0x39, 0xc3, 0x49, 0x00, 0x8f, 0x9c, + /*0140*/ 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x19, 0x00, 0x29, 0x01, 0x39, 0x01, 0x4c, 0x45, 0x80, 0x00, + /*0150*/ 0x01, 0x59, 0x05, 0x69, 0x01, 0x79, 0x07, 0x8e, 0x0a, 0x26, 0xe1, 0x19, 0x00, 0x2a, 0x25, 0xb9, + /*0160*/ 0x39, 0x00, 0x49, 0x00, 0x8f, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x1f, + }; + var rawBytes = (byte[]) ArrayUtils.toPrimitive(IntStream.of(rawBytesAsInts).boxed().map(Integer::byteValue).toArray(Byte[]::new)); + rawBytes = ArrayUtils.subarray(rawBytes, 42, rawBytes.length); + BVLC bvlc = BVLC.staticParse(new ReadBufferByteBased(rawBytes)); + assertNotNull(bvlc); + System.out.println(bvlc); + } +} diff --git a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec index d3b5db0849..ffb8a9d7b5 100644 --- a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec +++ b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec @@ -919,7 +919,7 @@ [simple BACnetOpeningTag('peekedTagNumber', 'BACnetDataType.OPENING_TAG') innerOpeningTag ] - [simple BACnetDeviceObjectPropertyReference('0') + [simple BACnetDeviceObjectPropertyReferenceEnclosed('0') bufferProperty ] [simple BACnetContextTagUnsignedInteger('1', 'BACnetDataType.UNSIGNED_INTEGER') @@ -1013,7 +1013,7 @@ timeValue] [optional BACnetApplicationTagObjectIdentifier objectIdentifier] - [optional BACnetDeviceObjectPropertyReference('0') + [optional BACnetDeviceObjectPropertyReferenceEnclosed('0') reference] [simple BACnetClosingTag('tagNumber', 'BACnetDataType.CLOSING_TAG') closingTag @@ -1041,14 +1041,11 @@ [optional BACnetContextTagUnsignedInteger('3', 'BACnetDataType.UNSIGNED_INTEGER') priority ] ] -[type BACnetDeviceObjectPropertyReference(uint 8 tagNumber) +[type BACnetDeviceObjectPropertyReferenceEnclosed(uint 8 tagNumber) [simple BACnetOpeningTag('tagNumber', 'BACnetDataType.OPENING_TAG') openingTag ] - [simple BACnetContextTagObjectIdentifier('0', 'BACnetDataType.BACNET_OBJECT_IDENTIFIER') objectIdentifier ] - [simple BACnetContextTagPropertyIdentifier('1', 'BACnetDataType.BACNET_PROPERTY_IDENTIFIER') propertyIdentifier ] - [optional BACnetContextTagUnsignedInteger('2', 'BACnetDataType.UNSIGNED_INTEGER') arrayIndex ] - [optional BACnetContextTagObjectIdentifier('3', 'BACnetDataType.BACNET_OBJECT_IDENTIFIER') deviceIdentifier ] + [simple BACnetDeviceObjectPropertyReference value ] [simple BACnetClosingTag('tagNumber', 'BACnetDataType.CLOSING_TAG') closingTag ] @@ -1588,33 +1585,47 @@ [simple BACnetDateTime('2') toNormal ] ] + [*, 'LIST_OF_OBJECT_PROPERTY_REFERENCES' BACnetConstructedDataListOfObjectPropertyReferences + [array BACnetDeviceObjectPropertyReference + references terminated + 'STATIC_CALL("isBACnetConstructedDataClosingTag", readBuffer, false, tagNumber)'] + ] [BACnetConstructedDataUnspecified - [array BACnetConstructedDataElement('objectType', 'propertyIdentifierArgument') - data - terminated - 'STATIC_CALL("isBACnetConstructedDataClosingTag", readBuffer, false, tagNumber)' ] - [virtual bit hasData 'COUNT(data) != 0'] + [array BACnetConstructedDataElement('objectType', 'propertyIdentifierArgument') + data terminated + 'STATIC_CALL("isBACnetConstructedDataClosingTag", readBuffer, false, tagNumber)'] + [virtual bit hasData 'COUNT(data) != 0'] [optional BACnetContextTagPropertyIdentifier('0', 'BACnetDataType.BACNET_PROPERTY_IDENTIFIER') - propertyIdentifier - 'hasData' ] + propertyIdentifier 'hasData' ] [optional BACnetApplicationTag - content 'hasData' ] + content 'hasData' ] ] ] [simple BACnetClosingTag('tagNumber', 'BACnetDataType.CLOSING_TAG') closingTag ] ] +[type BACnetDeviceObjectPropertyReference + [simple BACnetContextTagObjectIdentifier('0', 'BACnetDataType.BACNET_OBJECT_IDENTIFIER') + objectIdentifier ] + [simple BACnetContextTagPropertyIdentifier('1', 'BACnetDataType.BACNET_PROPERTY_IDENTIFIER') + propertyIdentifier ] + [optional BACnetContextTagUnsignedInteger('2', 'BACnetDataType.UNSIGNED_INTEGER') + arrayIndex ] + [optional BACnetContextTagObjectIdentifier('3', 'BACnetDataType.BACNET_OBJECT_IDENTIFIER') + deviceIdentifier ] +] + [type BACnetConstructedDataElement(BACnetObjectType objectType, BACnetContextTagPropertyIdentifier propertyIdentifier) [peek BACnetTagHeader peekedTagHeader ] [virtual uint 8 peekedTagNumber 'peekedTagHeader.actualTagNumber'] [virtual bit isApplicationTag 'peekedTagHeader.tagClass == TagClass.APPLICATION_TAGS' ] - [virtual bit isConstructedData '!isApplicationTag && peekedTagHeader.actualLength == 0x6' ] + [virtual bit isConstructedData '!isApplicationTag && peekedTagHeader.lengthValueType == 0x6' ] [virtual bit isContextTag '!isConstructedData && !isApplicationTag' ] [optional BACnetApplicationTag applicationTag 'isApplicationTag' ] - [optional BACnetContextTag('peekedTagNumber', 'STATIC_CALL("guessDataType", objectType)') + [optional BACnetContextTag('peekedTagNumber', 'STATIC_CALL("guessDataType", objectType, propertyIdentifier)') contextTag 'isContextTag' ] [optional BACnetConstructedData('peekedTagNumber', 'objectType', 'propertyIdentifier') constructedData 'isConstructedData' ]
