You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2022/09/26 08:39:13 UTC
[plc4x] branch develop updated: chore(protocol/ads): Work on the new ADS driver - Switched the dataIo parsing of STRING and WSTRING from manual fields to simple fields with vstring - Fixed a problem in the go code generation causing problems accessing the "stringLength" serializer argument in dataIo types - Implemented the new state-machine for PLC4J ads driver
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new afd3939c6 chore(protocol/ads): Work on the new ADS driver - Switched the dataIo parsing of STRING and WSTRING from manual fields to simple fields with vstring - Fixed a problem in the go code generation causing problems accessing the "stringLength" serializer argument in dataIo types - Implemented the new state-machine for PLC4J ads driver
afd3939c6 is described below
commit afd3939c6eaf52670e69b3daaa4ecea87a5c3ab0
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon Sep 26 10:37:30 2022 +0200
chore(protocol/ads): Work on the new ADS driver
- Switched the dataIo parsing of STRING and WSTRING from manual fields to simple fields with vstring
- Fixed a problem in the go code generation causing problems accessing the "stringLength" serializer argument in dataIo types
- Implemented the new state-machine for PLC4J ads driver
---
.../language/go/GoLanguageTemplateHelper.java | 12 +-
.../mspec/model/definitions/DefaultArgument.java | 5 +
plc4go/protocols/ads/readwrite/model/DataItem.go | 44 +-
.../ads/readwrite/model/DefaultAmsPorts.go | 552 +++++++++++++++++++++
.../ads/readwrite/model/ReservedIndexGroups.go | 8 +
.../knxnetip/readwrite/model/KnxManufacturer.go | 34 +-
plc4go/protocols/s7/readwrite/model/DataItem.go | 4 +-
.../plc4x/java/ads/protocol/AdsProtocolLogic.java | 444 ++++++++++++-----
.../java/ads/readwrite/utils/StaticHelper.java | 93 ----
.../plc4x/protocol/ads/ManualAdsDriverTest.java | 50 +-
.../java/canopen/readwrite/utils/StaticHelper.java | 2 +-
.../java/s7/readwrite/utils/StaticHelper.java | 2 +-
.../plc4x/java/spi/generation/ReadBuffer.java | 4 +-
.../java/spi/generation/ReadBufferByteBased.java | 69 ++-
.../plc4x/java/spi/generation/ReadBufferTest.java | 2 +-
.../apache/plc4x/java/s7/utils/StaticHelper.java | 2 +-
.../org/apache/plc4x/test/manual/ManualTest.java | 13 +-
.../knxnetip/readwrite/model/KnxManufacturer.cs | 23 +-
.../ads/src/main/resources/protocols/ads/ads.mspec | 10 +-
19 files changed, 1060 insertions(+), 313 deletions(-)
diff --git a/code-generation/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java b/code-generation/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
index 0afc466df..858ef2c34 100644
--- a/code-generation/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
+++ b/code-generation/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
@@ -20,9 +20,11 @@ package org.apache.plc4x.language.go;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions.DefaultArgument;
import org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultBooleanTypeReference;
import org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultFloatTypeReference;
import org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultIntegerTypeReference;
+import org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultVstringTypeReference;
import org.apache.plc4x.plugins.codegenerator.language.mspec.model.terms.DefaultStringLiteral;
import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.BaseFreemarkerLanguageTemplateHelper;
import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerException;
@@ -467,7 +469,7 @@ public class GoLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelp
.orElseThrow(() -> new RuntimeException("Encoding must be a literal"))
.asStringLiteral()
.orElseThrow(() -> new RuntimeException("Encoding must be a quoted string value")).getValue();
- String lengthExpression = toExpression(field, null, vstringTypeReference.getLengthExpression(), null, null, true, false);
+ String lengthExpression = toExpression(field, null, vstringTypeReference.getLengthExpression(), null, Collections.singletonList(new DefaultArgument("stringLength", new DefaultIntegerTypeReference(SimpleTypeReference.SimpleBaseType.INT, 32))), true, false);
String length = Integer.toString(simpleTypeReference.getSizeInBits());
return "writeBuffer.WriteString(\"" + logicalName + "\", uint32(" + lengthExpression + "), \"" +
encoding + "\", " + fieldName + writerArgsString + ")";
@@ -847,7 +849,15 @@ public class GoLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelp
}
}
+ // This is a special case for DataIo string types, which need to access the stringLength
if ((serializerArguments != null) && serializerArguments.stream()
+ .anyMatch(argument -> argument.getName().equals(variableLiteralName)) && "stringLength".equals(variableLiteralName)) {
+ tracer = tracer.dive("serialization argument");
+ return tracer + variableLiteralName +
+ variableLiteral.getChild()
+ .map(child -> "." + capitalize(toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, false, suppressPointerAccess, true)))
+ .orElse("");
+ } else if ((serializerArguments != null) && serializerArguments.stream()
.anyMatch(argument -> argument.getName().equals(variableLiteralName))) {
tracer = tracer.dive("serialization argument");
return tracer + "m." + capitalize(variableLiteralName) +
diff --git a/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultArgument.java b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultArgument.java
index 93c57f81b..df1fad80e 100644
--- a/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultArgument.java
+++ b/code-generation/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultArgument.java
@@ -37,6 +37,11 @@ public class DefaultArgument implements Argument {
this.name = Objects.requireNonNull(name);
}
+ public DefaultArgument(String name, TypeReference type) {
+ this.name = Objects.requireNonNull(name);
+ this.type = type;
+ }
+
public String getName() {
return name;
}
diff --git a/plc4go/protocols/ads/readwrite/model/DataItem.go b/plc4go/protocols/ads/readwrite/model/DataItem.go
index ad0f76c64..4eb0283da 100644
--- a/plc4go/protocols/ads/readwrite/model/DataItem.go
+++ b/plc4go/protocols/ads/readwrite/model/DataItem.go
@@ -166,19 +166,29 @@ func DataItemParse(readBuffer utils.ReadBuffer, plcValueType PlcValueType, strin
readBuffer.CloseContext("DataItem")
return values.NewPlcSTRING(value), nil
case plcValueType == PlcValueType_STRING: // STRING
- // Manual Field (value)
- value, _valueErr := ParseAmsString(readBuffer, stringLength, "UTF-8")
+ // Simple Field (value)
+ value, _valueErr := readBuffer.ReadString("value", uint32((stringLength)*(8)))
if _valueErr != nil {
return nil, errors.Wrap(_valueErr, "Error parsing 'value' field")
}
+
+ // Reserved Field (Just skip the bytes)
+ if _, _err := readBuffer.ReadUint8("reserved", 8); _err != nil {
+ return nil, errors.Wrap(_err, "Error parsing reserved field")
+ }
readBuffer.CloseContext("DataItem")
return values.NewPlcSTRING(value), nil
case plcValueType == PlcValueType_WSTRING: // STRING
- // Manual Field (value)
- value, _valueErr := ParseAmsString(readBuffer, stringLength, "UTF-16")
+ // Simple Field (value)
+ value, _valueErr := readBuffer.ReadString("value", uint32(((stringLength)*(8))*(2)))
if _valueErr != nil {
return nil, errors.Wrap(_valueErr, "Error parsing 'value' field")
}
+
+ // Reserved Field (Just skip the bytes)
+ if _, _err := readBuffer.ReadUint16("reserved", 16); _err != nil {
+ return nil, errors.Wrap(_err, "Error parsing reserved field")
+ }
readBuffer.CloseContext("DataItem")
return values.NewPlcSTRING(value), nil
case plcValueType == PlcValueType_TIME: // TIME
@@ -320,20 +330,28 @@ func DataItemSerialize(writeBuffer utils.WriteBuffer, value api.PlcValue, plcVal
}
case plcValueType == PlcValueType_WCHAR: // STRING
// Simple Field (value)
- if _err := writeBuffer.WriteString("value", uint32(16), "UTF-16", value.GetString()); _err != nil {
+ if _err := writeBuffer.WriteString("value", uint32(16), "UTF-16LE", value.GetString()); _err != nil {
return errors.Wrap(_err, "Error serializing 'value' field")
}
case plcValueType == PlcValueType_STRING: // STRING
- // Manual Field (value)
- _valueErr := SerializeAmsString(writeBuffer, value, m.StringLength, "UTF-8")
- if _valueErr != nil {
- return errors.Wrap(_valueErr, "Error serializing 'value' field")
+ // Simple Field (value)
+ if _err := writeBuffer.WriteString("value", uint32((stringLength)*(8)), "UTF-8", value.GetString()); _err != nil {
+ return errors.Wrap(_err, "Error serializing 'value' field")
+ }
+
+ // Reserved Field (Just skip the bytes)
+ if _err := writeBuffer.WriteUint8("reserved", 8, uint8(0x00)); _err != nil {
+ return errors.Wrap(_err, "Error serializing reserved field")
}
case plcValueType == PlcValueType_WSTRING: // STRING
- // Manual Field (value)
- _valueErr := SerializeAmsString(writeBuffer, value, m.StringLength, "UTF-16")
- if _valueErr != nil {
- return errors.Wrap(_valueErr, "Error serializing 'value' field")
+ // Simple Field (value)
+ if _err := writeBuffer.WriteString("value", uint32(((stringLength)*(8))*(2)), "UTF-16LE", value.GetString()); _err != nil {
+ return errors.Wrap(_err, "Error serializing 'value' field")
+ }
+
+ // Reserved Field (Just skip the bytes)
+ if _err := writeBuffer.WriteUint16("reserved", 16, uint16(0x0000)); _err != nil {
+ return errors.Wrap(_err, "Error serializing reserved field")
}
case plcValueType == PlcValueType_TIME: // TIME
// Simple Field (value)
diff --git a/plc4go/protocols/ads/readwrite/model/DefaultAmsPorts.go b/plc4go/protocols/ads/readwrite/model/DefaultAmsPorts.go
new file mode 100644
index 000000000..2219b94a7
--- /dev/null
+++ b/plc4go/protocols/ads/readwrite/model/DefaultAmsPorts.go
@@ -0,0 +1,552 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package model
+
+import (
+ "github.com/apache/plc4x/plc4go/spi/utils"
+ "github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// DefaultAmsPorts is an enum
+type DefaultAmsPorts uint16
+
+type IDefaultAmsPorts interface {
+ Serialize(writeBuffer utils.WriteBuffer) error
+}
+
+const (
+ DefaultAmsPorts_CAM_CONTROLLER DefaultAmsPorts = 900
+ DefaultAmsPorts_RUNTIME_SYSTEM_01 DefaultAmsPorts = 851
+ DefaultAmsPorts_RUNTIME_SYSTEM_02 DefaultAmsPorts = 852
+ DefaultAmsPorts_RUNTIME_SYSTEM_03 DefaultAmsPorts = 853
+ DefaultAmsPorts_RUNTIME_SYSTEM_04 DefaultAmsPorts = 854
+ DefaultAmsPorts_RUNTIME_SYSTEM_05 DefaultAmsPorts = 855
+ DefaultAmsPorts_RUNTIME_SYSTEM_06 DefaultAmsPorts = 856
+ DefaultAmsPorts_RUNTIME_SYSTEM_07 DefaultAmsPorts = 857
+ DefaultAmsPorts_RUNTIME_SYSTEM_08 DefaultAmsPorts = 858
+ DefaultAmsPorts_RUNTIME_SYSTEM_09 DefaultAmsPorts = 859
+ DefaultAmsPorts_RUNTIME_SYSTEM_10 DefaultAmsPorts = 860
+ DefaultAmsPorts_RUNTIME_SYSTEM_11 DefaultAmsPorts = 861
+ DefaultAmsPorts_RUNTIME_SYSTEM_12 DefaultAmsPorts = 862
+ DefaultAmsPorts_RUNTIME_SYSTEM_13 DefaultAmsPorts = 863
+ DefaultAmsPorts_RUNTIME_SYSTEM_14 DefaultAmsPorts = 864
+ DefaultAmsPorts_RUNTIME_SYSTEM_15 DefaultAmsPorts = 865
+ DefaultAmsPorts_RUNTIME_SYSTEM_16 DefaultAmsPorts = 866
+ DefaultAmsPorts_RUNTIME_SYSTEM_17 DefaultAmsPorts = 867
+ DefaultAmsPorts_RUNTIME_SYSTEM_18 DefaultAmsPorts = 868
+ DefaultAmsPorts_RUNTIME_SYSTEM_19 DefaultAmsPorts = 869
+ DefaultAmsPorts_RUNTIME_SYSTEM_20 DefaultAmsPorts = 870
+ DefaultAmsPorts_RUNTIME_SYSTEM_21 DefaultAmsPorts = 871
+ DefaultAmsPorts_RUNTIME_SYSTEM_22 DefaultAmsPorts = 872
+ DefaultAmsPorts_RUNTIME_SYSTEM_23 DefaultAmsPorts = 873
+ DefaultAmsPorts_RUNTIME_SYSTEM_24 DefaultAmsPorts = 874
+ DefaultAmsPorts_RUNTIME_SYSTEM_25 DefaultAmsPorts = 875
+ DefaultAmsPorts_RUNTIME_SYSTEM_26 DefaultAmsPorts = 876
+ DefaultAmsPorts_RUNTIME_SYSTEM_27 DefaultAmsPorts = 877
+ DefaultAmsPorts_RUNTIME_SYSTEM_28 DefaultAmsPorts = 878
+ DefaultAmsPorts_RUNTIME_SYSTEM_29 DefaultAmsPorts = 879
+ DefaultAmsPorts_RUNTIME_SYSTEM_30 DefaultAmsPorts = 880
+ DefaultAmsPorts_RUNTIME_SYSTEM_31 DefaultAmsPorts = 881
+ DefaultAmsPorts_RUNTIME_SYSTEM_32 DefaultAmsPorts = 882
+ DefaultAmsPorts_RUNTIME_SYSTEM_33 DefaultAmsPorts = 883
+ DefaultAmsPorts_RUNTIME_SYSTEM_34 DefaultAmsPorts = 884
+ DefaultAmsPorts_RUNTIME_SYSTEM_35 DefaultAmsPorts = 885
+ DefaultAmsPorts_RUNTIME_SYSTEM_36 DefaultAmsPorts = 886
+ DefaultAmsPorts_RUNTIME_SYSTEM_37 DefaultAmsPorts = 887
+ DefaultAmsPorts_RUNTIME_SYSTEM_38 DefaultAmsPorts = 888
+ DefaultAmsPorts_RUNTIME_SYSTEM_39 DefaultAmsPorts = 889
+ DefaultAmsPorts_RUNTIME_SYSTEM_40 DefaultAmsPorts = 890
+ DefaultAmsPorts_RUNTIME_SYSTEM_41 DefaultAmsPorts = 891
+ DefaultAmsPorts_RUNTIME_SYSTEM_42 DefaultAmsPorts = 892
+ DefaultAmsPorts_RUNTIME_SYSTEM_43 DefaultAmsPorts = 893
+ DefaultAmsPorts_RUNTIME_SYSTEM_44 DefaultAmsPorts = 894
+ DefaultAmsPorts_RUNTIME_SYSTEM_45 DefaultAmsPorts = 895
+ DefaultAmsPorts_RUNTIME_SYSTEM_46 DefaultAmsPorts = 896
+ DefaultAmsPorts_RUNTIME_SYSTEM_47 DefaultAmsPorts = 897
+ DefaultAmsPorts_RUNTIME_SYSTEM_48 DefaultAmsPorts = 898
+ DefaultAmsPorts_RUNTIME_SYSTEM_49 DefaultAmsPorts = 899
+ DefaultAmsPorts_NC DefaultAmsPorts = 500
+ DefaultAmsPorts_RESERVED DefaultAmsPorts = 400
+ DefaultAmsPorts_IO DefaultAmsPorts = 300
+ DefaultAmsPorts_REAL_TIME_CORE DefaultAmsPorts = 200
+ DefaultAmsPorts_EVENT_SYSTEM_LOGGER DefaultAmsPorts = 100
+)
+
+var DefaultAmsPortsValues []DefaultAmsPorts
+
+func init() {
+ _ = errors.New
+ DefaultAmsPortsValues = []DefaultAmsPorts{
+ DefaultAmsPorts_CAM_CONTROLLER,
+ DefaultAmsPorts_RUNTIME_SYSTEM_01,
+ DefaultAmsPorts_RUNTIME_SYSTEM_02,
+ DefaultAmsPorts_RUNTIME_SYSTEM_03,
+ DefaultAmsPorts_RUNTIME_SYSTEM_04,
+ DefaultAmsPorts_RUNTIME_SYSTEM_05,
+ DefaultAmsPorts_RUNTIME_SYSTEM_06,
+ DefaultAmsPorts_RUNTIME_SYSTEM_07,
+ DefaultAmsPorts_RUNTIME_SYSTEM_08,
+ DefaultAmsPorts_RUNTIME_SYSTEM_09,
+ DefaultAmsPorts_RUNTIME_SYSTEM_10,
+ DefaultAmsPorts_RUNTIME_SYSTEM_11,
+ DefaultAmsPorts_RUNTIME_SYSTEM_12,
+ DefaultAmsPorts_RUNTIME_SYSTEM_13,
+ DefaultAmsPorts_RUNTIME_SYSTEM_14,
+ DefaultAmsPorts_RUNTIME_SYSTEM_15,
+ DefaultAmsPorts_RUNTIME_SYSTEM_16,
+ DefaultAmsPorts_RUNTIME_SYSTEM_17,
+ DefaultAmsPorts_RUNTIME_SYSTEM_18,
+ DefaultAmsPorts_RUNTIME_SYSTEM_19,
+ DefaultAmsPorts_RUNTIME_SYSTEM_20,
+ DefaultAmsPorts_RUNTIME_SYSTEM_21,
+ DefaultAmsPorts_RUNTIME_SYSTEM_22,
+ DefaultAmsPorts_RUNTIME_SYSTEM_23,
+ DefaultAmsPorts_RUNTIME_SYSTEM_24,
+ DefaultAmsPorts_RUNTIME_SYSTEM_25,
+ DefaultAmsPorts_RUNTIME_SYSTEM_26,
+ DefaultAmsPorts_RUNTIME_SYSTEM_27,
+ DefaultAmsPorts_RUNTIME_SYSTEM_28,
+ DefaultAmsPorts_RUNTIME_SYSTEM_29,
+ DefaultAmsPorts_RUNTIME_SYSTEM_30,
+ DefaultAmsPorts_RUNTIME_SYSTEM_31,
+ DefaultAmsPorts_RUNTIME_SYSTEM_32,
+ DefaultAmsPorts_RUNTIME_SYSTEM_33,
+ DefaultAmsPorts_RUNTIME_SYSTEM_34,
+ DefaultAmsPorts_RUNTIME_SYSTEM_35,
+ DefaultAmsPorts_RUNTIME_SYSTEM_36,
+ DefaultAmsPorts_RUNTIME_SYSTEM_37,
+ DefaultAmsPorts_RUNTIME_SYSTEM_38,
+ DefaultAmsPorts_RUNTIME_SYSTEM_39,
+ DefaultAmsPorts_RUNTIME_SYSTEM_40,
+ DefaultAmsPorts_RUNTIME_SYSTEM_41,
+ DefaultAmsPorts_RUNTIME_SYSTEM_42,
+ DefaultAmsPorts_RUNTIME_SYSTEM_43,
+ DefaultAmsPorts_RUNTIME_SYSTEM_44,
+ DefaultAmsPorts_RUNTIME_SYSTEM_45,
+ DefaultAmsPorts_RUNTIME_SYSTEM_46,
+ DefaultAmsPorts_RUNTIME_SYSTEM_47,
+ DefaultAmsPorts_RUNTIME_SYSTEM_48,
+ DefaultAmsPorts_RUNTIME_SYSTEM_49,
+ DefaultAmsPorts_NC,
+ DefaultAmsPorts_RESERVED,
+ DefaultAmsPorts_IO,
+ DefaultAmsPorts_REAL_TIME_CORE,
+ DefaultAmsPorts_EVENT_SYSTEM_LOGGER,
+ }
+}
+
+func DefaultAmsPortsByValue(value uint16) (enum DefaultAmsPorts, ok bool) {
+ switch value {
+ case 100:
+ return DefaultAmsPorts_EVENT_SYSTEM_LOGGER, true
+ case 200:
+ return DefaultAmsPorts_REAL_TIME_CORE, true
+ case 300:
+ return DefaultAmsPorts_IO, true
+ case 400:
+ return DefaultAmsPorts_RESERVED, true
+ case 500:
+ return DefaultAmsPorts_NC, true
+ case 851:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_01, true
+ case 852:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_02, true
+ case 853:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_03, true
+ case 854:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_04, true
+ case 855:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_05, true
+ case 856:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_06, true
+ case 857:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_07, true
+ case 858:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_08, true
+ case 859:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_09, true
+ case 860:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_10, true
+ case 861:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_11, true
+ case 862:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_12, true
+ case 863:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_13, true
+ case 864:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_14, true
+ case 865:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_15, true
+ case 866:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_16, true
+ case 867:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_17, true
+ case 868:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_18, true
+ case 869:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_19, true
+ case 870:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_20, true
+ case 871:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_21, true
+ case 872:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_22, true
+ case 873:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_23, true
+ case 874:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_24, true
+ case 875:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_25, true
+ case 876:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_26, true
+ case 877:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_27, true
+ case 878:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_28, true
+ case 879:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_29, true
+ case 880:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_30, true
+ case 881:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_31, true
+ case 882:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_32, true
+ case 883:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_33, true
+ case 884:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_34, true
+ case 885:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_35, true
+ case 886:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_36, true
+ case 887:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_37, true
+ case 888:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_38, true
+ case 889:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_39, true
+ case 890:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_40, true
+ case 891:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_41, true
+ case 892:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_42, true
+ case 893:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_43, true
+ case 894:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_44, true
+ case 895:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_45, true
+ case 896:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_46, true
+ case 897:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_47, true
+ case 898:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_48, true
+ case 899:
+ return DefaultAmsPorts_RUNTIME_SYSTEM_49, true
+ case 900:
+ return DefaultAmsPorts_CAM_CONTROLLER, true
+ }
+ return 0, false
+}
+
+func DefaultAmsPortsByName(value string) (enum DefaultAmsPorts, ok bool) {
+ switch value {
+ case "EVENT_SYSTEM_LOGGER":
+ return DefaultAmsPorts_EVENT_SYSTEM_LOGGER, true
+ case "REAL_TIME_CORE":
+ return DefaultAmsPorts_REAL_TIME_CORE, true
+ case "IO":
+ return DefaultAmsPorts_IO, true
+ case "RESERVED":
+ return DefaultAmsPorts_RESERVED, true
+ case "NC":
+ return DefaultAmsPorts_NC, true
+ case "RUNTIME_SYSTEM_01":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_01, true
+ case "RUNTIME_SYSTEM_02":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_02, true
+ case "RUNTIME_SYSTEM_03":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_03, true
+ case "RUNTIME_SYSTEM_04":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_04, true
+ case "RUNTIME_SYSTEM_05":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_05, true
+ case "RUNTIME_SYSTEM_06":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_06, true
+ case "RUNTIME_SYSTEM_07":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_07, true
+ case "RUNTIME_SYSTEM_08":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_08, true
+ case "RUNTIME_SYSTEM_09":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_09, true
+ case "RUNTIME_SYSTEM_10":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_10, true
+ case "RUNTIME_SYSTEM_11":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_11, true
+ case "RUNTIME_SYSTEM_12":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_12, true
+ case "RUNTIME_SYSTEM_13":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_13, true
+ case "RUNTIME_SYSTEM_14":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_14, true
+ case "RUNTIME_SYSTEM_15":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_15, true
+ case "RUNTIME_SYSTEM_16":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_16, true
+ case "RUNTIME_SYSTEM_17":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_17, true
+ case "RUNTIME_SYSTEM_18":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_18, true
+ case "RUNTIME_SYSTEM_19":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_19, true
+ case "RUNTIME_SYSTEM_20":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_20, true
+ case "RUNTIME_SYSTEM_21":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_21, true
+ case "RUNTIME_SYSTEM_22":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_22, true
+ case "RUNTIME_SYSTEM_23":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_23, true
+ case "RUNTIME_SYSTEM_24":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_24, true
+ case "RUNTIME_SYSTEM_25":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_25, true
+ case "RUNTIME_SYSTEM_26":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_26, true
+ case "RUNTIME_SYSTEM_27":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_27, true
+ case "RUNTIME_SYSTEM_28":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_28, true
+ case "RUNTIME_SYSTEM_29":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_29, true
+ case "RUNTIME_SYSTEM_30":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_30, true
+ case "RUNTIME_SYSTEM_31":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_31, true
+ case "RUNTIME_SYSTEM_32":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_32, true
+ case "RUNTIME_SYSTEM_33":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_33, true
+ case "RUNTIME_SYSTEM_34":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_34, true
+ case "RUNTIME_SYSTEM_35":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_35, true
+ case "RUNTIME_SYSTEM_36":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_36, true
+ case "RUNTIME_SYSTEM_37":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_37, true
+ case "RUNTIME_SYSTEM_38":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_38, true
+ case "RUNTIME_SYSTEM_39":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_39, true
+ case "RUNTIME_SYSTEM_40":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_40, true
+ case "RUNTIME_SYSTEM_41":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_41, true
+ case "RUNTIME_SYSTEM_42":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_42, true
+ case "RUNTIME_SYSTEM_43":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_43, true
+ case "RUNTIME_SYSTEM_44":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_44, true
+ case "RUNTIME_SYSTEM_45":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_45, true
+ case "RUNTIME_SYSTEM_46":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_46, true
+ case "RUNTIME_SYSTEM_47":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_47, true
+ case "RUNTIME_SYSTEM_48":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_48, true
+ case "RUNTIME_SYSTEM_49":
+ return DefaultAmsPorts_RUNTIME_SYSTEM_49, true
+ case "CAM_CONTROLLER":
+ return DefaultAmsPorts_CAM_CONTROLLER, true
+ }
+ return 0, false
+}
+
+func DefaultAmsPortsKnows(value uint16) bool {
+ for _, typeValue := range DefaultAmsPortsValues {
+ if uint16(typeValue) == value {
+ return true
+ }
+ }
+ return false
+}
+
+func CastDefaultAmsPorts(structType interface{}) DefaultAmsPorts {
+ castFunc := func(typ interface{}) DefaultAmsPorts {
+ if sDefaultAmsPorts, ok := typ.(DefaultAmsPorts); ok {
+ return sDefaultAmsPorts
+ }
+ return 0
+ }
+ return castFunc(structType)
+}
+
+func (m DefaultAmsPorts) GetLengthInBits() uint16 {
+ return 16
+}
+
+func (m DefaultAmsPorts) GetLengthInBytes() uint16 {
+ return m.GetLengthInBits() / 8
+}
+
+func DefaultAmsPortsParse(readBuffer utils.ReadBuffer) (DefaultAmsPorts, error) {
+ val, err := readBuffer.ReadUint16("DefaultAmsPorts", 16)
+ if err != nil {
+ return 0, errors.Wrap(err, "error reading DefaultAmsPorts")
+ }
+ if enum, ok := DefaultAmsPortsByValue(val); !ok {
+ Plc4xModelLog.Debug().Msgf("no value %x found for RequestType", val)
+ return DefaultAmsPorts(val), nil
+ } else {
+ return enum, nil
+ }
+}
+
+func (e DefaultAmsPorts) Serialize(writeBuffer utils.WriteBuffer) error {
+ return writeBuffer.WriteUint16("DefaultAmsPorts", 16, uint16(e), utils.WithAdditionalStringRepresentation(e.PLC4XEnumName()))
+}
+
+// PLC4XEnumName returns the name that is used in code to identify this enum
+func (e DefaultAmsPorts) PLC4XEnumName() string {
+ switch e {
+ case DefaultAmsPorts_EVENT_SYSTEM_LOGGER:
+ return "EVENT_SYSTEM_LOGGER"
+ case DefaultAmsPorts_REAL_TIME_CORE:
+ return "REAL_TIME_CORE"
+ case DefaultAmsPorts_IO:
+ return "IO"
+ case DefaultAmsPorts_RESERVED:
+ return "RESERVED"
+ case DefaultAmsPorts_NC:
+ return "NC"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_01:
+ return "RUNTIME_SYSTEM_01"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_02:
+ return "RUNTIME_SYSTEM_02"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_03:
+ return "RUNTIME_SYSTEM_03"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_04:
+ return "RUNTIME_SYSTEM_04"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_05:
+ return "RUNTIME_SYSTEM_05"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_06:
+ return "RUNTIME_SYSTEM_06"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_07:
+ return "RUNTIME_SYSTEM_07"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_08:
+ return "RUNTIME_SYSTEM_08"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_09:
+ return "RUNTIME_SYSTEM_09"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_10:
+ return "RUNTIME_SYSTEM_10"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_11:
+ return "RUNTIME_SYSTEM_11"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_12:
+ return "RUNTIME_SYSTEM_12"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_13:
+ return "RUNTIME_SYSTEM_13"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_14:
+ return "RUNTIME_SYSTEM_14"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_15:
+ return "RUNTIME_SYSTEM_15"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_16:
+ return "RUNTIME_SYSTEM_16"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_17:
+ return "RUNTIME_SYSTEM_17"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_18:
+ return "RUNTIME_SYSTEM_18"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_19:
+ return "RUNTIME_SYSTEM_19"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_20:
+ return "RUNTIME_SYSTEM_20"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_21:
+ return "RUNTIME_SYSTEM_21"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_22:
+ return "RUNTIME_SYSTEM_22"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_23:
+ return "RUNTIME_SYSTEM_23"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_24:
+ return "RUNTIME_SYSTEM_24"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_25:
+ return "RUNTIME_SYSTEM_25"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_26:
+ return "RUNTIME_SYSTEM_26"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_27:
+ return "RUNTIME_SYSTEM_27"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_28:
+ return "RUNTIME_SYSTEM_28"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_29:
+ return "RUNTIME_SYSTEM_29"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_30:
+ return "RUNTIME_SYSTEM_30"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_31:
+ return "RUNTIME_SYSTEM_31"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_32:
+ return "RUNTIME_SYSTEM_32"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_33:
+ return "RUNTIME_SYSTEM_33"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_34:
+ return "RUNTIME_SYSTEM_34"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_35:
+ return "RUNTIME_SYSTEM_35"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_36:
+ return "RUNTIME_SYSTEM_36"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_37:
+ return "RUNTIME_SYSTEM_37"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_38:
+ return "RUNTIME_SYSTEM_38"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_39:
+ return "RUNTIME_SYSTEM_39"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_40:
+ return "RUNTIME_SYSTEM_40"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_41:
+ return "RUNTIME_SYSTEM_41"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_42:
+ return "RUNTIME_SYSTEM_42"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_43:
+ return "RUNTIME_SYSTEM_43"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_44:
+ return "RUNTIME_SYSTEM_44"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_45:
+ return "RUNTIME_SYSTEM_45"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_46:
+ return "RUNTIME_SYSTEM_46"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_47:
+ return "RUNTIME_SYSTEM_47"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_48:
+ return "RUNTIME_SYSTEM_48"
+ case DefaultAmsPorts_RUNTIME_SYSTEM_49:
+ return "RUNTIME_SYSTEM_49"
+ case DefaultAmsPorts_CAM_CONTROLLER:
+ return "CAM_CONTROLLER"
+ }
+ return ""
+}
+
+func (e DefaultAmsPorts) String() string {
+ return e.PLC4XEnumName()
+}
diff --git a/plc4go/protocols/ads/readwrite/model/ReservedIndexGroups.go b/plc4go/protocols/ads/readwrite/model/ReservedIndexGroups.go
index 4ea3e9c11..11990ece9 100644
--- a/plc4go/protocols/ads/readwrite/model/ReservedIndexGroups.go
+++ b/plc4go/protocols/ads/readwrite/model/ReservedIndexGroups.go
@@ -50,6 +50,7 @@ const (
ReservedIndexGroups_ADSIGRP_DATA_TYPE_TABLE_UPLOAD ReservedIndexGroups = 0x0000F00E
ReservedIndexGroups_ADSIGRP_SYMBOL_AND_DATA_TYPE_SIZES ReservedIndexGroups = 0x0000F00F
ReservedIndexGroups_ADSIGRP_SYMNOTE ReservedIndexGroups = 0x0000F010
+ ReservedIndexGroups_ADSIGRP_DT_INFOBYNAMEEX ReservedIndexGroups = 0x0000F011
ReservedIndexGroups_ADSIGRP_IOIMAGE_RWIB ReservedIndexGroups = 0x0000F020
ReservedIndexGroups_ADSIGRP_IOIMAGE_RWIX ReservedIndexGroups = 0x0000F021
ReservedIndexGroups_ADSIGRP_IOIMAGE_RISIZE ReservedIndexGroups = 0x0000F025
@@ -92,6 +93,7 @@ func init() {
ReservedIndexGroups_ADSIGRP_DATA_TYPE_TABLE_UPLOAD,
ReservedIndexGroups_ADSIGRP_SYMBOL_AND_DATA_TYPE_SIZES,
ReservedIndexGroups_ADSIGRP_SYMNOTE,
+ ReservedIndexGroups_ADSIGRP_DT_INFOBYNAMEEX,
ReservedIndexGroups_ADSIGRP_IOIMAGE_RWIB,
ReservedIndexGroups_ADSIGRP_IOIMAGE_RWIX,
ReservedIndexGroups_ADSIGRP_IOIMAGE_RISIZE,
@@ -152,6 +154,8 @@ func ReservedIndexGroupsByValue(value uint32) (enum ReservedIndexGroups, ok bool
return ReservedIndexGroups_ADSIGRP_SYMBOL_AND_DATA_TYPE_SIZES, true
case 0x0000F010:
return ReservedIndexGroups_ADSIGRP_SYMNOTE, true
+ case 0x0000F011:
+ return ReservedIndexGroups_ADSIGRP_DT_INFOBYNAMEEX, true
case 0x0000F020:
return ReservedIndexGroups_ADSIGRP_IOIMAGE_RWIB, true
case 0x0000F021:
@@ -228,6 +232,8 @@ func ReservedIndexGroupsByName(value string) (enum ReservedIndexGroups, ok bool)
return ReservedIndexGroups_ADSIGRP_SYMBOL_AND_DATA_TYPE_SIZES, true
case "ADSIGRP_SYMNOTE":
return ReservedIndexGroups_ADSIGRP_SYMNOTE, true
+ case "ADSIGRP_DT_INFOBYNAMEEX":
+ return ReservedIndexGroups_ADSIGRP_DT_INFOBYNAMEEX, true
case "ADSIGRP_IOIMAGE_RWIB":
return ReservedIndexGroups_ADSIGRP_IOIMAGE_RWIB, true
case "ADSIGRP_IOIMAGE_RWIX":
@@ -349,6 +355,8 @@ func (e ReservedIndexGroups) PLC4XEnumName() string {
return "ADSIGRP_SYMBOL_AND_DATA_TYPE_SIZES"
case ReservedIndexGroups_ADSIGRP_SYMNOTE:
return "ADSIGRP_SYMNOTE"
+ case ReservedIndexGroups_ADSIGRP_DT_INFOBYNAMEEX:
+ return "ADSIGRP_DT_INFOBYNAMEEX"
case ReservedIndexGroups_ADSIGRP_IOIMAGE_RWIB:
return "ADSIGRP_IOIMAGE_RWIB"
case ReservedIndexGroups_ADSIGRP_IOIMAGE_RWIX:
diff --git a/plc4go/protocols/knxnetip/readwrite/model/KnxManufacturer.go b/plc4go/protocols/knxnetip/readwrite/model/KnxManufacturer.go
index 9050d1663..4c70cdae6 100644
--- a/plc4go/protocols/knxnetip/readwrite/model/KnxManufacturer.go
+++ b/plc4go/protocols/knxnetip/readwrite/model/KnxManufacturer.go
@@ -635,8 +635,9 @@ const (
KnxManufacturer_M_GUANGDONG_KANWAY KnxManufacturer = 596
KnxManufacturer_M_PHOENIX_CONTACT_2 KnxManufacturer = 597
KnxManufacturer_M_RAMIREZ_ENGINEERING_GMBH KnxManufacturer = 598
- KnxManufacturer_M_ABB___RESERVED KnxManufacturer = 599
- KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED KnxManufacturer = 600
+ KnxManufacturer_M_ZHONGSHAN_TAIYANG_IMPANDEXP__CO_LTD KnxManufacturer = 599
+ KnxManufacturer_M_ABB___RESERVED KnxManufacturer = 600
+ KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED KnxManufacturer = 601
)
var KnxManufacturerValues []KnxManufacturer
@@ -1243,6 +1244,7 @@ func init() {
KnxManufacturer_M_GUANGDONG_KANWAY,
KnxManufacturer_M_PHOENIX_CONTACT_2,
KnxManufacturer_M_RAMIREZ_ENGINEERING_GMBH,
+ KnxManufacturer_M_ZHONGSHAN_TAIYANG_IMPANDEXP__CO_LTD,
KnxManufacturer_M_ABB___RESERVED,
KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED,
}
@@ -3472,7 +3474,7 @@ func (e KnxManufacturer) Number() uint16 {
}
case 599:
{ /* '599' */
- return 43954
+ return 657
}
case 6:
{ /* '6' */
@@ -3484,6 +3486,10 @@ func (e KnxManufacturer) Number() uint16 {
}
case 600:
{ /* '600' */
+ return 43954
+ }
+ case 601:
+ { /* '601' */
return 43959
}
case 61:
@@ -5894,7 +5900,7 @@ func (e KnxManufacturer) Name() string {
}
case 599:
{ /* '599' */
- return "ABB - reserved"
+ return "Zhongshan Taiyang IMP&EXP. CO LTD"
}
case 6:
{ /* '6' */
@@ -5906,6 +5912,10 @@ func (e KnxManufacturer) Name() string {
}
case 600:
{ /* '600' */
+ return "ABB - reserved"
+ }
+ case 601:
+ { /* '601' */
return "Busch-Jaeger Elektro - reserved"
}
case 61:
@@ -7204,12 +7214,14 @@ func KnxManufacturerByValue(value uint16) (enum KnxManufacturer, ok bool) {
case 598:
return KnxManufacturer_M_RAMIREZ_ENGINEERING_GMBH, true
case 599:
- return KnxManufacturer_M_ABB___RESERVED, true
+ return KnxManufacturer_M_ZHONGSHAN_TAIYANG_IMPANDEXP__CO_LTD, true
case 6:
return KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO, true
case 60:
return KnxManufacturer_M_TECHEM, true
case 600:
+ return KnxManufacturer_M_ABB___RESERVED, true
+ case 601:
return KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED, true
case 61:
return KnxManufacturer_M_SCHNEIDER_ELECTRIC_INDUSTRIES_SAS, true
@@ -8411,12 +8423,14 @@ func KnxManufacturerByName(value string) (enum KnxManufacturer, ok bool) {
return KnxManufacturer_M_PHOENIX_CONTACT_2, true
case "M_RAMIREZ_ENGINEERING_GMBH":
return KnxManufacturer_M_RAMIREZ_ENGINEERING_GMBH, true
- case "M_ABB___RESERVED":
- return KnxManufacturer_M_ABB___RESERVED, true
+ case "M_ZHONGSHAN_TAIYANG_IMPANDEXP__CO_LTD":
+ return KnxManufacturer_M_ZHONGSHAN_TAIYANG_IMPANDEXP__CO_LTD, true
case "M_BUSCH_JAEGER_ELEKTRO":
return KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO, true
case "M_TECHEM":
return KnxManufacturer_M_TECHEM, true
+ case "M_ABB___RESERVED":
+ return KnxManufacturer_M_ABB___RESERVED, true
case "M_BUSCH_JAEGER_ELEKTRO___RESERVED":
return KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED, true
case "M_SCHNEIDER_ELECTRIC_INDUSTRIES_SAS":
@@ -9664,12 +9678,14 @@ func (e KnxManufacturer) PLC4XEnumName() string {
return "M_PHOENIX_CONTACT_2"
case KnxManufacturer_M_RAMIREZ_ENGINEERING_GMBH:
return "M_RAMIREZ_ENGINEERING_GMBH"
- case KnxManufacturer_M_ABB___RESERVED:
- return "M_ABB___RESERVED"
+ case KnxManufacturer_M_ZHONGSHAN_TAIYANG_IMPANDEXP__CO_LTD:
+ return "M_ZHONGSHAN_TAIYANG_IMPANDEXP__CO_LTD"
case KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO:
return "M_BUSCH_JAEGER_ELEKTRO"
case KnxManufacturer_M_TECHEM:
return "M_TECHEM"
+ case KnxManufacturer_M_ABB___RESERVED:
+ return "M_ABB___RESERVED"
case KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED:
return "M_BUSCH_JAEGER_ELEKTRO___RESERVED"
case KnxManufacturer_M_SCHNEIDER_ELECTRIC_INDUSTRIES_SAS:
diff --git a/plc4go/protocols/s7/readwrite/model/DataItem.go b/plc4go/protocols/s7/readwrite/model/DataItem.go
index 42010eed2..d0ad80537 100644
--- a/plc4go/protocols/s7/readwrite/model/DataItem.go
+++ b/plc4go/protocols/s7/readwrite/model/DataItem.go
@@ -410,13 +410,13 @@ func DataItemSerialize(writeBuffer utils.WriteBuffer, value api.PlcValue, dataPr
}
case dataProtocolId == "IEC61131_STRING": // STRING
// Manual Field (value)
- _valueErr := SerializeS7String(writeBuffer, value, m.StringLength, "UTF-8")
+ _valueErr := SerializeS7String(writeBuffer, value, stringLength, "UTF-8")
if _valueErr != nil {
return errors.Wrap(_valueErr, "Error serializing 'value' field")
}
case dataProtocolId == "IEC61131_WSTRING": // STRING
// Manual Field (value)
- _valueErr := SerializeS7String(writeBuffer, value, m.StringLength, "UTF-16")
+ _valueErr := SerializeS7String(writeBuffer, value, stringLength, "UTF-16")
if _valueErr != nil {
return errors.Wrap(_valueErr, "Error serializing 'value' field")
}
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
index 377334bbe..1f4fa085f 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
@@ -28,10 +28,12 @@ import org.apache.plc4x.java.ads.readwrite.DataItem;
import org.apache.plc4x.java.api.authentication.PlcUsernamePasswordAuthentication;
import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
import org.apache.plc4x.java.api.exceptions.PlcException;
+import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
import org.apache.plc4x.java.api.messages.*;
import org.apache.plc4x.java.api.model.PlcConsumerRegistration;
import org.apache.plc4x.java.api.model.PlcField;
+import org.apache.plc4x.java.api.model.PlcSubscriptionField;
import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
import org.apache.plc4x.java.api.types.PlcResponseCode;
import org.apache.plc4x.java.api.types.PlcSubscriptionType;
@@ -51,12 +53,14 @@ import org.slf4j.LoggerFactory;
import java.math.BigInteger;
import java.net.*;
+import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -67,22 +71,28 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
private AdsConfiguration configuration;
+ private String adsVersion;
+ private String deviceName;
+
private final AtomicLong invokeIdGenerator = new AtomicLong(1);
private final RequestTransactionManager tm;
private final Map<DefaultPlcConsumerRegistration, Consumer<PlcSubscriptionEvent>> consumers = new ConcurrentHashMap<>();
- // private final ConcurrentHashMap<SymbolicAdsField, DirectAdsField> symbolicFieldMapping;
private final ConcurrentHashMap<SymbolicAdsField, CompletableFuture<Void>> pendingResolutionRequests;
+ private int symbolVersion;
+ private long onlineVersion;
private final Map<String, AdsSymbolTableEntry> symbolTable;
private final Map<String, AdsDataTypeTableEntry> dataTypeTable;
+ private final ReentrantLock invalidationLock;
public AdsProtocolLogic() {
// symbolicFieldMapping = new ConcurrentHashMap<>();
pendingResolutionRequests = new ConcurrentHashMap<>();
symbolTable = new HashMap<>();
dataTypeTable = new HashMap<>();
+ invalidationLock = new ReentrantLock();
// Initialize Transaction Manager.
// Until the number of concurrent requests is successfully negotiated we set it to a
@@ -125,19 +135,104 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
// If the configuration asks us to load the symbol and data type tables, do so,
// otherwise just mark the connection as completed instantly.
setupAmsRouteFuture.whenComplete((unused, throwable) -> {
- if (configuration.isLoadSymbolAndDataTypeTables()) {
- LOGGER.debug("Fetching sizes of symbol and datatype table sizes.");
- CompletableFuture<Void> readSymbolTableFuture = readSymbolTableAndDatatypeTable(context);
- readSymbolTableFuture.whenComplete((unused2, throwable2) -> {
- if (throwable2 != null) {
- LOGGER.error("Error fetching symbol and datatype table sizes");
- } else {
- context.fireConnected();
- }
- });
- } else {
- context.fireConnected();
+ if (!configuration.isLoadSymbolAndDataTypeTables()) {
+ future.completeExceptionally(new PlcConnectionException(
+ "Lazy loading is generally planned, but not implemented yet. " +
+ "If you are in need for this feature, please reach out to the community."));
}
+ //if (configuration.isLoadSymbolAndDataTypeTables()) {
+ // Execute a ReadDeviceInfo command
+ AmsPacket readDeviceInfoRequest = new AdsReadDeviceInfoRequest(
+ configuration.getTargetAmsNetId(), DefaultAmsPorts.RUNTIME_SYSTEM_01.getValue(),
+ configuration.getSourceAmsNetId(), 800, 0, getInvokeId());
+ RequestTransactionManager.RequestTransaction readDeviceInfoTx = tm.startRequest();
+ readDeviceInfoTx.submit(() -> context.sendRequest(new AmsTCPPacket(readDeviceInfoRequest))
+ .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
+ .onTimeout(future::completeExceptionally)
+ .onError((p, e) -> future.completeExceptionally(e))
+ .check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == readDeviceInfoRequest.getInvokeId())
+ .unwrap(response -> (AdsReadDeviceInfoResponse) response.getUserdata())
+ .handle(readDeviceInfoResponse -> {
+ readDeviceInfoTx.endRequest();
+ if (readDeviceInfoResponse.getResult() != ReturnCode.OK) {
+ // TODO: Handle this
+ future.completeExceptionally(new PlcException("Result is " + readDeviceInfoResponse.getResult()));
+ return;
+ }
+
+ // Get the twin-cat version and PLC name.
+ adsVersion = String.format("%d.%d.%d", readDeviceInfoResponse.getMajorVersion(),
+ readDeviceInfoResponse.getMinorVersion(), readDeviceInfoResponse.getVersion());
+ deviceName = new String(readDeviceInfoResponse.getDevice()).trim();
+
+ // Read the online version number (Address; GroupID: 0xF004 (read symbol by name),Offset: 0, Read length: 4, ... Payload: "TwinCAT_SystemInfoVarList._AppInfo.OnlineChangeCnt")
+ AmsPacket readOnlineVersionNumberRequest = new AdsReadWriteRequest(
+ configuration.getTargetAmsNetId(), DefaultAmsPorts.RUNTIME_SYSTEM_01.getValue(),
+ configuration.getSourceAmsNetId(), 800, 0, getInvokeId(),
+ ReservedIndexGroups.ADSIGRP_SYM_VALBYNAME.getValue(), 0, 4, null,
+ "TwinCAT_SystemInfoVarList._AppInfo.OnlineChangeCnt".getBytes(StandardCharsets.UTF_8));
+ RequestTransactionManager.RequestTransaction readOnlineVersionNumberTx = tm.startRequest();
+ readOnlineVersionNumberTx.submit(() -> context.sendRequest(new AmsTCPPacket(readOnlineVersionNumberRequest))
+ .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
+ .onTimeout(future::completeExceptionally)
+ .onError((p, e) -> future.completeExceptionally(e))
+ .check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == readOnlineVersionNumberRequest.getInvokeId())
+ .unwrap(response -> (AdsReadWriteResponse) response.getUserdata())
+ .handle(readOnlineVersionNumberResponse -> {
+ readOnlineVersionNumberTx.endRequest();
+ if (readOnlineVersionNumberResponse.getResult() != ReturnCode.OK) {
+ // TODO: Handle this
+ future.completeExceptionally(new PlcException("Result is " + readOnlineVersionNumberResponse.getResult()));
+ return;
+ }
+ try {
+ ReadBuffer rb = new ReadBufferByteBased(readOnlineVersionNumberResponse.getData());
+ onlineVersion = rb.readUnsignedLong(32);
+
+ // Read the offline version number (Address: GroupID: 0xF008, Offset: 0, Read length: 1)
+ AmsPacket readSymbolVersionNumberRequest = new AdsReadRequest(
+ configuration.getTargetAmsNetId(), DefaultAmsPorts.RUNTIME_SYSTEM_01.getValue(),
+ configuration.getSourceAmsNetId(), 800, 0, getInvokeId(),
+ ReservedIndexGroups.ADSIGRP_SYM_VERSION.getValue(), 0, 1);
+ RequestTransactionManager.RequestTransaction readSymbolVersionNumberTx = tm.startRequest();
+ readSymbolVersionNumberTx.submit(() -> context.sendRequest(new AmsTCPPacket(readSymbolVersionNumberRequest))
+ .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
+ .onTimeout(future::completeExceptionally)
+ .onError((p, e) -> future.completeExceptionally(e))
+ .check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == readSymbolVersionNumberRequest.getInvokeId())
+ .unwrap(response -> (AdsReadResponse) response.getUserdata())
+ .handle(readSymbolVersionNumberResponse -> {
+ readSymbolVersionNumberTx.endRequest();
+ if (readSymbolVersionNumberResponse.getResult() != ReturnCode.OK) {
+ // TODO: Handle this
+ future.completeExceptionally(new PlcException("Result is " + readSymbolVersionNumberResponse.getResult()));
+ return;
+ }
+ try {
+ ReadBuffer rb2 = new ReadBufferByteBased(readSymbolVersionNumberResponse.getData());
+ symbolVersion = rb2.readUnsignedInt(8);
+
+ LOGGER.debug("Fetching sizes of symbol and datatype table sizes.");
+ CompletableFuture<Void> readSymbolTableFuture = readSymbolTableAndDatatypeTable(context);
+ readSymbolTableFuture.whenComplete((unused2, throwable2) -> {
+ if (throwable2 != null) {
+ LOGGER.error("Error fetching symbol and datatype table sizes");
+ } else {
+ context.fireConnected();
+ }
+ });
+ } catch (ParseException e) {
+ future.completeExceptionally(new PlcConnectionException("Error reading the symbol version of data type and symbol data.", e));
+ }
+ }));
+ } catch (ParseException e) {
+ future.completeExceptionally(new PlcConnectionException("Error reading the online version of data type and symbol data.", e));
+ }
+ }));
+ }));
+ /*} else {
+ context.fireConnected();
+ }*/
});
}
@@ -217,88 +312,146 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
protected CompletableFuture<Void> readSymbolTableAndDatatypeTable(ConversationContext<AmsTCPPacket> context) {
final CompletableFuture<Void> future = new CompletableFuture<>();
- // Initialize the request.
- AmsPacket amsPacket = new AdsReadRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
+ // Read the data-type and symbol table sizes
+ AmsPacket readDataAndSymbolTableSizesRequest = new AdsReadRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(), 0, getInvokeId(),
ReservedIndexGroups.ADSIGRP_SYMBOL_AND_DATA_TYPE_SIZES.getValue(), 0x00000000, 24);
- AmsTCPPacket amsTCPPacket = new AmsTCPPacket(amsPacket);
- // Start a new request-transaction (Is ended in the response-handler)
- RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
- transaction.submit(() -> context.sendRequest(amsTCPPacket)
+ RequestTransactionManager.RequestTransaction readDataAndSymbolTableSizesTx = tm.startRequest();
+ readDataAndSymbolTableSizesTx.submit(() -> context.sendRequest(new AmsTCPPacket(readDataAndSymbolTableSizesRequest))
.expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
.onTimeout(future::completeExceptionally)
.onError((p, e) -> future.completeExceptionally(e))
- .check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == amsPacket.getInvokeId())
+ .check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == readDataAndSymbolTableSizesRequest.getInvokeId())
.unwrap(response -> (AdsReadResponse) response.getUserdata())
- .handle(responseAdsData -> {
- transaction.endRequest();
- if (responseAdsData.getResult() == ReturnCode.OK) {
- ReadBuffer readBuffer = new ReadBufferByteBased(responseAdsData.getData());
- try {
- AdsTableSizes adsTableSizes = AdsTableSizes.staticParse(readBuffer);
- LOGGER.debug("PLC contains {} symbols and {} data-types", adsTableSizes.getSymbolCount(), adsTableSizes.getDataTypeCount());
-
- // Now we load the datatype definitions.
- AmsPacket amsReadTablePacket = new AdsReadRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
- configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(), 0, getInvokeId(),
- ReservedIndexGroups.ADSIGRP_DATA_TYPE_TABLE_UPLOAD.getValue(), 0x00000000, adsTableSizes.getDataTypeLength());
- RequestTransactionManager.RequestTransaction transaction2 = tm.startRequest();
- AmsTCPPacket amsReadTableTCPPacket = new AmsTCPPacket(amsReadTablePacket);
- transaction2.submit(() -> context.sendRequest(amsReadTableTCPPacket)
- .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
- .onTimeout(future::completeExceptionally)
- .onError((p, e) -> future.completeExceptionally(e))
- .check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == amsReadTablePacket.getInvokeId())
- .unwrap(response -> (AdsReadResponse) response.getUserdata())
- .handle(responseAdsReadTableData -> {
- transaction2.endRequest();
- if (responseAdsData.getResult() == ReturnCode.OK) {
- // Parse the result.
- ReadBuffer rb = new ReadBufferByteBased(responseAdsReadTableData.getData());
- for (int i = 0; i < adsTableSizes.getDataTypeCount(); i++) {
+ .handle(readDataAndSymbolTableSizesResponse -> {
+ readDataAndSymbolTableSizesTx.endRequest();
+ if (readDataAndSymbolTableSizesResponse.getResult() != ReturnCode.OK) {
+ // TODO: Handle this
+ future.completeExceptionally(new PlcException("Reading data type and symbol table sizes failed: " + readDataAndSymbolTableSizesResponse.getResult()));
+ return;
+ }
+ try {
+ ReadBuffer readBuffer = new ReadBufferByteBased(readDataAndSymbolTableSizesResponse.getData());
+ AdsTableSizes adsTableSizes = AdsTableSizes.staticParse(readBuffer);
+ LOGGER.debug("PLC contains {} symbols and {} data-types", adsTableSizes.getSymbolCount(), adsTableSizes.getDataTypeCount());
+
+ // Now we load the datatype definitions.
+ AmsPacket readDataTypeTableRequest = new AdsReadRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
+ configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(), 0, getInvokeId(),
+ ReservedIndexGroups.ADSIGRP_DATA_TYPE_TABLE_UPLOAD.getValue(), 0x00000000, adsTableSizes.getDataTypeLength());
+ RequestTransactionManager.RequestTransaction readDataTypeTableTx = tm.startRequest();
+ AmsTCPPacket amsReadTableTCPPacket = new AmsTCPPacket(readDataTypeTableRequest);
+ readDataTypeTableTx.submit(() -> context.sendRequest(amsReadTableTCPPacket)
+ .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
+ .onTimeout(future::completeExceptionally)
+ .onError((p, e) -> future.completeExceptionally(e))
+ .check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == readDataTypeTableRequest.getInvokeId())
+ .unwrap(response -> (AdsReadResponse) response.getUserdata())
+ .handle(readDataTypeTableResponse -> {
+ readDataTypeTableTx.endRequest();
+ if (readDataTypeTableResponse.getResult() != ReturnCode.OK) {
+ // TODO: Handle this
+ future.completeExceptionally(new PlcException("Reading data type table failed: " + readDataTypeTableResponse.getResult()));
+ return;
+ }
+ // Parse the result.
+ ReadBuffer rb = new ReadBufferByteBased(readDataTypeTableResponse.getData());
+ for (int i = 0; i < adsTableSizes.getDataTypeCount(); i++) {
+ try {
+ AdsDataTypeTableEntry adsDataTypeTableEntry = AdsDataTypeTableEntry.staticParse(rb);
+ dataTypeTable.put(adsDataTypeTableEntry.getDataTypeName(), adsDataTypeTableEntry);
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // Now we load the symbol definitions
+ AmsPacket readSymbolTableRequest = new AdsReadRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
+ configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(), 0, getInvokeId(),
+ ReservedIndexGroups.ADSIGRP_SYM_UPLOAD.getValue(), 0x00000000, adsTableSizes.getSymbolLength());
+ RequestTransactionManager.RequestTransaction readSymbolTableTx = tm.startRequest();
+ AmsTCPPacket amsReadSymbolTableTCPPacket = new AmsTCPPacket(readSymbolTableRequest);
+ readSymbolTableTx.submit(() -> context.sendRequest(amsReadSymbolTableTCPPacket)
+ .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
+ .onTimeout(future::completeExceptionally)
+ .onError((p, e) -> future.completeExceptionally(e))
+ .check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == readSymbolTableRequest.getInvokeId())
+ .unwrap(response -> (AdsReadResponse) response.getUserdata())
+ .handle(readSymbolTableResponse -> {
+ readSymbolTableTx.endRequest();
+ if (readSymbolTableResponse.getResult() != ReturnCode.OK) {
+ // TODO: Handle this
+ future.completeExceptionally(new PlcException("Reading symbol table failed: " + readSymbolTableResponse.getResult()));
+ return;
+ }
+ ReadBuffer rb2 = new ReadBufferByteBased(readSymbolTableResponse.getData());
+ for (int i = 0; i < adsTableSizes.getSymbolCount(); i++) {
try {
- AdsDataTypeTableEntry adsDataTypeTableEntry = AdsDataTypeTableEntry.staticParse(rb);
- dataTypeTable.put(adsDataTypeTableEntry.getDataTypeName(), adsDataTypeTableEntry);
+ AdsSymbolTableEntry adsSymbolTableEntry = AdsSymbolTableEntry.staticParse(rb2);
+ symbolTable.put(adsSymbolTableEntry.getName(), adsSymbolTableEntry);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
- AmsPacket amsReadSymbolTablePacket = new AdsReadRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
- configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(), 0, getInvokeId(),
- ReservedIndexGroups.ADSIGRP_SYM_UPLOAD.getValue(), 0x00000000, adsTableSizes.getSymbolLength());
- RequestTransactionManager.RequestTransaction transaction3 = tm.startRequest();
- AmsTCPPacket amsReadSymbolTableTCPPacket = new AmsTCPPacket(amsReadSymbolTablePacket);
- transaction3.submit(() -> context.sendRequest(amsReadSymbolTableTCPPacket)
- .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
- .onTimeout(future::completeExceptionally)
- .onError((p, e) -> future.completeExceptionally(e))
- .check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == amsReadSymbolTablePacket.getInvokeId())
- .unwrap(response -> (AdsReadResponse) response.getUserdata())
- .handle(responseAdsReadSymbolTableData -> {
- transaction3.endRequest();
- if (responseAdsData.getResult() == ReturnCode.OK) {
- ReadBuffer rb2 = new ReadBufferByteBased(responseAdsReadSymbolTableData.getData());
- for (int i = 0; i < adsTableSizes.getSymbolCount(); i++) {
- try {
- AdsSymbolTableEntry adsSymbolTableEntry = AdsSymbolTableEntry.staticParse(rb2);
- symbolTable.put(adsSymbolTableEntry.getName(), adsSymbolTableEntry);
- } catch (ParseException e) {
- throw new RuntimeException(e);
+ LinkedHashMap<String, PlcSubscriptionField> subscriptionFields = new LinkedHashMap<>();
+ // Subscribe to online-version changes (get the address from the collected data for symbol: "TwinCAT_SystemInfoVarList._AppInfo.OnlineChangeCnt")
+ subscriptionFields.put("onlineVersion", new DefaultPlcSubscriptionField(
+ PlcSubscriptionType.CHANGE_OF_STATE,
+ new SymbolicAdsField("TwinCAT_SystemInfoVarList._AppInfo.OnlineChangeCnt"),
+ Duration.ofMillis(1000)));
+ // Subscribe to symbol-version changes (Address: GroupID: 0xF008, Offset: 0, Read length: 1)
+ subscriptionFields.put("symbolVersion", new DefaultPlcSubscriptionField(
+ PlcSubscriptionType.CHANGE_OF_STATE,
+ new DirectAdsField(0xF008, 0x0000, "USINT", 1),
+ Duration.ofMillis(1000)));
+ LinkedHashMap<String, List<Consumer<PlcSubscriptionEvent>>> consumer = new LinkedHashMap<>();
+ consumer.put("onlineVersion", Collections.singletonList(plcSubscriptionEvent -> {
+ long oldVersion = onlineVersion;
+ long newVersion = plcSubscriptionEvent.getPlcValue("onlineVersion").getLong();
+ if(oldVersion != newVersion) {
+ if(invalidationLock.tryLock()) {
+ LOGGER.info("Detected change of the 'online-version', invalidating data type and symbol information.");
+ CompletableFuture<Void> reloadingFuture = readSymbolTableAndDatatypeTable(context);
+ reloadingFuture.whenComplete((unused, throwable) -> {
+ if(throwable != null) {
+ LOGGER.error("Error reloading data type and symbol data", throwable);
}
- }
- future.complete(null);
+ invalidationLock.unlock();
+ });
}
- }));
- }
- }));
+ }
+ }));
+ consumer.put("symbolVersion", Collections.singletonList(plcSubscriptionEvent -> {
+ int oldVersion = symbolVersion;
+ int newVersion = plcSubscriptionEvent.getPlcValue("symbolVersion").getInteger();
+ if(oldVersion != newVersion) {
+ if(invalidationLock.tryLock()) {
+ LOGGER.info("Detected change of the 'symbol-version', invalidating data type and symbol information.");
+ CompletableFuture<Void> reloadingFuture = readSymbolTableAndDatatypeTable(context);
+ reloadingFuture.whenComplete((unused, throwable) -> {
+ if(throwable != null) {
+ LOGGER.error("Error reloading data type and symbol data", throwable);
+ }
+ invalidationLock.unlock();
+ });
+ }
+ }
+ }));
+ PlcSubscriptionRequest subscriptionRequest = new DefaultPlcSubscriptionRequest(this, subscriptionFields, consumer);
+ CompletableFuture<PlcSubscriptionResponse> subscriptionResponseCompletableFuture = subscribe(subscriptionRequest);
+
+ // Wait for the subscription to be finished
+ subscriptionResponseCompletableFuture.whenComplete((plcSubscriptionResponse, throwable) -> {
+ if(throwable == null) {
+ future.complete(null);
+ }
+ });
+ }));
+ }));
} catch (ParseException e) {
future.completeExceptionally(new PlcException("Error loading the table sizes", e));
}
- } else {
- // TODO: Implement this correctly.
- future.completeExceptionally(new PlcException("Result is " + responseAdsData.getResult()));
- }
}));
return future;
}
@@ -404,14 +557,14 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
@Override
public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
// Get all ADS addresses in their resolved state.
- final CompletableFuture<List<DirectAdsField>> directAdsFieldsFuture =
+ final CompletableFuture<Map<AdsField, DirectAdsField>> directAdsFieldsFuture =
getDirectAddresses(readRequest.getFields());
// If all addresses were already resolved we can send the request immediately.
if (directAdsFieldsFuture.isDone()) {
- final List<DirectAdsField> fields = directAdsFieldsFuture.getNow(null);
- if (fields != null) {
- return executeRead(readRequest, fields);
+ final Map<AdsField, DirectAdsField> resolvedFields = directAdsFieldsFuture.getNow(null);
+ if (resolvedFields != null) {
+ return executeRead(readRequest, resolvedFields);
} else {
final CompletableFuture<PlcReadResponse> errorFuture = new CompletableFuture<>();
errorFuture.completeExceptionally(new PlcException("Fields are null"));
@@ -448,15 +601,15 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
}
protected CompletableFuture<PlcReadResponse> executeRead(PlcReadRequest readRequest,
- List<DirectAdsField> directAdsFields) {
+ Map<AdsField, DirectAdsField> resolvedFields) {
// Depending on the number of fields, use a single item request or a sum-request
- if (directAdsFields.size() == 1) {
+ if (resolvedFields.size() == 1) {
// Do a normal (single item) ADS Read Request
- return singleRead(readRequest, directAdsFields.get(0));
+ return singleRead(readRequest, resolvedFields.values().stream().findFirst().get());
} else {
// TODO: Check if the version of the remote station is at least TwinCAT v2.11 Build >= 1550 otherwise split up into single item requests.
// Do a ADS-Sum Read Request.
- return multiRead(readRequest, directAdsFields);
+ return multiRead(readRequest, resolvedFields);
}
}
@@ -495,12 +648,12 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
return future;
}
- protected CompletableFuture<PlcReadResponse> multiRead(PlcReadRequest readRequest, List<DirectAdsField> directAdsFields) {
+ protected CompletableFuture<PlcReadResponse> multiRead(PlcReadRequest readRequest, Map<AdsField, DirectAdsField> resolvedFields) {
CompletableFuture<PlcReadResponse> future = new CompletableFuture<>();
// Calculate the size of all fields together.
// Calculate the expected size of the response data.
- long expectedResponseDataSize = directAdsFields.stream().mapToLong(
+ long expectedResponseDataSize = resolvedFields.values().stream().mapToLong(
field -> {
String dataTypeName = field.getAdsDataTypeName();
AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(dataTypeName);
@@ -512,15 +665,17 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
// With multi-requests, the index-group is fixed and the index offset indicates the number of elements.
AmsPacket amsPacket = new AdsReadWriteRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(),
- 0, getInvokeId(), ReservedIndexGroups.ADSIGRP_MULTIPLE_READ.getValue(), directAdsFields.size(),
- expectedResponseDataSize, directAdsFields.stream().map(directAdsField -> {
- String dataTypeName = directAdsField.getAdsDataTypeName();
- AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(dataTypeName);
- long size = adsDataTypeTableEntry.getSize();
- return new AdsMultiRequestItemRead(
- directAdsField.getIndexGroup(), directAdsField.getIndexOffset(),
- (size * directAdsField.getNumberOfElements()));
- }).collect(Collectors.toList()), null);
+ 0, getInvokeId(), ReservedIndexGroups.ADSIGRP_MULTIPLE_READ.getValue(), resolvedFields.size(),
+ expectedResponseDataSize, readRequest.getFieldNames().stream().map(fieldName -> {
+ AdsField field = (AdsField) readRequest.getField(fieldName);
+ DirectAdsField directAdsField = resolvedFields.get(field);
+ String dataTypeName = directAdsField.getAdsDataTypeName();
+ AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(dataTypeName);
+ long size = adsDataTypeTableEntry.getSize();
+ return new AdsMultiRequestItemRead(
+ directAdsField.getIndexGroup(), directAdsField.getIndexOffset(),
+ (size * directAdsField.getNumberOfElements()));
+ }).collect(Collectors.toList()), null);
AmsTCPPacket amsTCPPacket = new AmsTCPPacket(amsPacket);
// Start a new request-transaction (Is ended in the response-handler)
@@ -561,7 +716,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
} else if (adsData instanceof AdsReadWriteResponse) {
AdsReadWriteResponse adsReadWriteResponse = (AdsReadWriteResponse) adsData;
readBuffer = new ReadBufferByteBased(adsReadWriteResponse.getData(), ByteOrder.LITTLE_ENDIAN);
- // When parsing a multi-item response, the error codes of each items come
+ // When parsing a multi-item response, the error codes of each item comes
// in sequence and then come the values.
for (String fieldName : readRequest.getFieldNames()) {
try {
@@ -613,7 +768,8 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
int strLen = 0;
if ((plcValueType == PlcValueType.STRING) || (plcValueType == PlcValueType.WSTRING)) {
- strLen = (field instanceof AdsStringField) ? ((AdsStringField) field).getStringLength() : 256;
+ // Extract the string length from the data type name.
+ strLen = Integer.parseInt(dataTypeName.substring(dataTypeName.indexOf("(") + 1, dataTypeName.indexOf(")")));
}
final int stringLength = strLen;
if (field.getNumberOfElements() == 1) {
@@ -693,14 +849,14 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
@Override
public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
// Get all ADS addresses in their resolved state.
- final CompletableFuture<List<DirectAdsField>> directAdsFieldsFuture =
+ final CompletableFuture<Map<AdsField, DirectAdsField>> directAdsFieldsFuture =
getDirectAddresses(writeRequest.getFields());
// If all addresses were already resolved we can send the request immediately.
if (directAdsFieldsFuture.isDone()) {
- final List<DirectAdsField> fields = directAdsFieldsFuture.getNow(null);
- if (fields != null) {
- return executeWrite(writeRequest, fields);
+ final Map<AdsField, DirectAdsField> resolvedFields = directAdsFieldsFuture.getNow(null);
+ if (resolvedFields != null) {
+ return executeWrite(writeRequest, resolvedFields);
} else {
final CompletableFuture<PlcWriteResponse> errorFuture = new CompletableFuture<>();
errorFuture.completeExceptionally(new PlcException("Fields are null"));
@@ -738,15 +894,15 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
}
protected CompletableFuture<PlcWriteResponse> executeWrite(PlcWriteRequest writeRequest,
- List<DirectAdsField> directAdsFields) {
+ Map<AdsField, DirectAdsField> resolvedFields) {
// Depending on the number of fields, use a single item request or a sum-request
- if (directAdsFields.size() == 1) {
+ if (resolvedFields.size() == 1) {
// Do a normal (single item) ADS Write Request
- return singleWrite(writeRequest, directAdsFields.get(0));
+ return singleWrite(writeRequest, resolvedFields.values().stream().findFirst().get());
} else {
// TODO: Check if the version of the remote station is at least TwinCAT v2.11 Build >= 1550 otherwise split up into single item requests.
// Do a ADS-Sum Read Request.
- return multiWrite(writeRequest, directAdsFields);
+ return multiWrite(writeRequest, resolvedFields);
}
}
@@ -801,7 +957,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
return future;
}
- protected CompletableFuture<PlcWriteResponse> multiWrite(PlcWriteRequest writeRequest, List<DirectAdsField> directAdsFields) {
+ protected CompletableFuture<PlcWriteResponse> multiWrite(PlcWriteRequest writeRequest, Map<AdsField, DirectAdsField> resolvedFields) {
CompletableFuture<PlcWriteResponse> future = new CompletableFuture<>();
// Calculate the size of all fields together.
@@ -896,7 +1052,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
@Override
public CompletableFuture<PlcSubscriptionResponse> subscribe(PlcSubscriptionRequest subscriptionRequest) {
// Get all ADS addresses in their resolved state.
- final CompletableFuture<List<DirectAdsField>> directAdsFieldsFuture =
+ final CompletableFuture<Map<AdsField, DirectAdsField>> directAdsFieldsFuture =
getDirectAddresses(subscriptionRequest.getFields()
.stream()
.map(field -> ((DefaultPlcSubscriptionField) field).getPlcField())
@@ -904,9 +1060,9 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
// If all addresses were already resolved we can send the request immediately.
if (directAdsFieldsFuture.isDone()) {
- final List<DirectAdsField> fields = directAdsFieldsFuture.getNow(null);
- if (fields != null) {
- return executeSubscribe(subscriptionRequest);
+ final Map<AdsField, DirectAdsField> resolvedFields = directAdsFieldsFuture.getNow(null);
+ if (resolvedFields != null) {
+ return executeSubscribe(subscriptionRequest, resolvedFields);
} else {
final CompletableFuture<PlcSubscriptionResponse> errorFuture = new CompletableFuture<>();
errorFuture.completeExceptionally(new PlcException("Fields are null"));
@@ -922,10 +1078,10 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
// we can complete the initial one.
else {
CompletableFuture<PlcSubscriptionResponse> delayedSubscribe = new CompletableFuture<>();
- directAdsFieldsFuture.handle((directAdsFields, throwable) -> {
- if (directAdsFields != null) {
+ directAdsFieldsFuture.handle((fieldMapping, throwable) -> {
+ if (fieldMapping != null) {
final CompletableFuture<PlcSubscriptionResponse> delayedResponse =
- executeSubscribe(subscriptionRequest);
+ executeSubscribe(subscriptionRequest, fieldMapping);
delayedResponse.handle((plcSubscribeResponse, throwable1) -> {
if (plcSubscribeResponse != null) {
delayedSubscribe.complete(plcSubscribeResponse);
@@ -943,14 +1099,14 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
}
}
- private CompletableFuture<PlcSubscriptionResponse> executeSubscribe(PlcSubscriptionRequest subscribeRequest) {
+ private CompletableFuture<PlcSubscriptionResponse> executeSubscribe(PlcSubscriptionRequest subscribeRequest, Map<AdsField, DirectAdsField> resolvedFields) {
CompletableFuture<PlcSubscriptionResponse> future = new CompletableFuture<>();
List<AmsTCPPacket> amsTCPPackets = subscribeRequest.getFields().stream()
.map(field -> (DefaultPlcSubscriptionField) field)
.map(field -> {
- AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(((DirectAdsField) field.getPlcField()).getAdsDataTypeName());
- DirectAdsField directAdsField = getDirectAdsFieldForSymbolicName(field);
+ AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(resolvedFields.get((AdsField) field.getPlcField()).getAdsDataTypeName());
+ DirectAdsField directAdsField = getDirectAdsFieldForSymbolicName(field.getPlcField());
return new AmsTCPPacket(new AdsAddDeviceNotificationRequest(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(),
configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(),
0, getInvokeId(),
@@ -970,6 +1126,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
transaction.submit(subscribeRecursively(
subscribeRequest,
subscribeRequest.getFieldNames().iterator(),
+ resolvedFields,
responses,
future,
amsTCPPackets.iterator(),
@@ -977,7 +1134,9 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
return future;
}
- private Runnable subscribeRecursively(PlcSubscriptionRequest subscriptionRequest, Iterator<String> fieldNames,
+ private Runnable subscribeRecursively(PlcSubscriptionRequest subscriptionRequest,
+ Iterator<String> fieldNames,
+ Map<AdsField, DirectAdsField> resolvedFields,
Map<String, ResponseItem<PlcSubscriptionHandle>> responses,
CompletableFuture<PlcSubscriptionResponse> future,
Iterator<AmsTCPPacket> amsTCPPackets,
@@ -995,7 +1154,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
.handle(response -> {
if (response.getResult() == ReturnCode.OK) {
DefaultPlcSubscriptionField subscriptionField = (DefaultPlcSubscriptionField) subscriptionRequest.getField(fieldName);
- AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(((DirectAdsField) subscriptionField.getPlcField()).getAdsDataTypeName());
+ AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get((resolvedFields.get((AdsField) subscriptionField.getPlcField())).getAdsDataTypeName());
// Collect notification handle from individual response.
responses.put(fieldName, new ResponseItem<>(
@@ -1025,7 +1184,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
if (hasMorePackets) {
RequestTransactionManager.RequestTransaction nextTransaction = tm.startRequest();
nextTransaction.submit(subscribeRecursively(
- subscriptionRequest, fieldNames, responses, future, amsTCPPackets, nextTransaction));
+ subscriptionRequest, fieldNames, resolvedFields, responses, future, amsTCPPackets, nextTransaction));
}
});
};
@@ -1150,8 +1309,8 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
consumers.remove(consumerRegistration);
}
- protected CompletableFuture<List<DirectAdsField>> getDirectAddresses(List<PlcField> fields) {
- CompletableFuture<List<DirectAdsField>> future = new CompletableFuture<>();
+ protected CompletableFuture<Map<AdsField, DirectAdsField>> getDirectAddresses(List<PlcField> fields) {
+ CompletableFuture<Map<AdsField, DirectAdsField>> future = new CompletableFuture<>();
// Get all symbolic fields from the current request.
// These potentially need to be resolved to direct addresses, if this has not been done before.
@@ -1202,26 +1361,28 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
if (throwable != null) {
return future.completeExceptionally(throwable.getCause());
} else {
- List<DirectAdsField> directAdsFields = new ArrayList<>(fields.size());
+ Map<AdsField, DirectAdsField> directAdsFieldMapping = new HashMap<>(fields.size());
for (PlcField field : fields) {
if (field instanceof SymbolicAdsField) {
- directAdsFields.add(getDirectAdsFieldForSymbolicName(field));
+ directAdsFieldMapping.put((AdsField) field, getDirectAdsFieldForSymbolicName(field));
} else {
- directAdsFields.add((DirectAdsField) field);
+ directAdsFieldMapping.put((AdsField) field, (DirectAdsField) field);
}
}
- return future.complete(directAdsFields);
+ return future.complete(directAdsFieldMapping);
}
});
} else {
// If all fields were resolved, we can continue instantly.
- future.complete(fields.stream().map(plcField -> {
- if (plcField instanceof SymbolicAdsField) {
- return getDirectAdsFieldForSymbolicName(plcField);
+ Map<AdsField, DirectAdsField> directAdsFieldMapping = new HashMap<>(fields.size());
+ for (PlcField field : fields) {
+ if (field instanceof SymbolicAdsField) {
+ directAdsFieldMapping.put((AdsField) field, getDirectAdsFieldForSymbolicName(field));
} else {
- return (DirectAdsField) plcField;
+ directAdsFieldMapping.put((AdsField) field, (DirectAdsField) field);
}
- }).collect(Collectors.toList()));
+ }
+ future.complete(directAdsFieldMapping);
}
return future;
}
@@ -1364,9 +1525,16 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
if (!symbolTable.containsKey(symbolicAddress)) {
return null;
}
-
AdsSymbolTableEntry adsSymbolTableEntry = symbolTable.get(symbolicAddress);
+ if(adsSymbolTableEntry == null) {
+ throw new PlcInvalidFieldException("Couldn't resolve symbolic address: " + symbolicAddress);
+ }
AdsDataTypeTableEntry dataTypeTableEntry = dataTypeTable.get(adsSymbolTableEntry.getDataTypeName());
+ if(dataTypeTableEntry == null) {
+ throw new PlcInvalidFieldException(
+ "Couldn't resolve datatype: '" + adsSymbolTableEntry.getDataTypeName() +
+ "' for address: '" + ((SymbolicAdsField) field).getSymbolicAddress() + "'");
+ }
return new DirectAdsField(adsSymbolTableEntry.getGroup(), adsSymbolTableEntry.getOffset(),
dataTypeTableEntry.getDataTypeName(), dataTypeTableEntry.getArrayDimensions());
}
@@ -1374,7 +1542,15 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
else {
String symbolName = addressParts[0] + "." + addressParts[1];
AdsSymbolTableEntry adsSymbolTableEntry = symbolTable.get(symbolName);
+ if(adsSymbolTableEntry == null) {
+ throw new PlcInvalidFieldException("Couldn't resolve symbolic address: " + symbolName);
+ }
AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get(adsSymbolTableEntry.getDataTypeName());
+ if(adsDataTypeTableEntry == null) {
+ throw new PlcInvalidFieldException(
+ "Couldn't resolve datatype: '" + adsSymbolTableEntry.getDataTypeName() +
+ "' for address: '" + ((SymbolicAdsField) field).getSymbolicAddress() + "'");
+ }
return resolveDirectAdsFieldForSymbolicNameFromDataType(
Arrays.asList(addressParts).subList(2, addressParts.length),
adsSymbolTableEntry.getGroup(), adsSymbolTableEntry.getOffset(), adsDataTypeTableEntry);
@@ -1384,7 +1560,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
protected DirectAdsField resolveDirectAdsFieldForSymbolicNameFromDataType(List<String> remainingAddressParts, long currentGroup, long currentOffset, AdsDataTypeTableEntry adsDataTypeTableEntry) {
if (remainingAddressParts.isEmpty()) {
// TODO: Implement the Array support
- return new DirectAdsField(currentGroup, currentOffset, adsDataTypeTableEntry.getDataTypeName(), null);
+ return new DirectAdsField(currentGroup, currentOffset, adsDataTypeTableEntry.getDataTypeName(), 1);
}
// Go through all children looking for a matching one.
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/readwrite/utils/StaticHelper.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/readwrite/utils/StaticHelper.java
deleted file mode 100644
index f0b874735..000000000
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/readwrite/utils/StaticHelper.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.plc4x.java.ads.readwrite.utils;
-
-import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
-import org.apache.plc4x.java.api.value.PlcValue;
-import org.apache.plc4x.java.spi.generation.ParseException;
-import org.apache.plc4x.java.spi.generation.ReadBuffer;
-import org.apache.plc4x.java.spi.generation.WriteBuffer;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-
-public class StaticHelper {
-
- public static String parseAmsString(ReadBuffer readBuffer, int stringLength, String encoding) {
- try {
- if ("UTF-8".equalsIgnoreCase(encoding)) {
- List<Byte> bytes = new ArrayList<>();
- for(int i = 0; (i < stringLength) && readBuffer.hasMore(8); i++) {
- final byte curByte = readBuffer.readByte();
- if (curByte != 0) {
- bytes.add(curByte);
- } else {
- // Gobble up the remaining data, which is not added to the string.
- i++;
- for(; (i < stringLength) && readBuffer.hasMore(8); i++) {
- readBuffer.readByte();
- }
- break;
- }
- }
- // Read the terminating byte.
- readBuffer.readByte();
- final byte[] byteArray = new byte[bytes.size()];
- for (int i = 0; i < bytes.size(); i++) {
- byteArray[i] = bytes.get(i);
- }
- return new String(byteArray, StandardCharsets.UTF_8);
- } else if ("UTF-16".equalsIgnoreCase(encoding)) {
- List<Byte> bytes = new ArrayList<>();
- for(int i = 0; (i < stringLength) && readBuffer.hasMore(16); i++) {
- final short curShort = readBuffer.readShort(16);
- if (curShort != 0) {
- bytes.add((byte) (curShort >>> 8));
- bytes.add((byte) (curShort & 0xFF));
- } else {
- // Gobble up the remaining data, which is not added to the string.
- i++;
- for(; (i < stringLength) && readBuffer.hasMore(16); i++) {
- readBuffer.readShort(16);
- }
- break;
- }
- }
- // Read the terminating byte.
- readBuffer.readByte();
- final byte[] byteArray = new byte[bytes.size()];
- for (int i = 0; i < bytes.size(); i++) {
- byteArray[i] = bytes.get(i);
- }
- return new String(byteArray, StandardCharsets.UTF_16);
- } else {
- throw new PlcRuntimeException("Unsupported string encoding " + encoding);
- }
- } catch (ParseException e) {
- throw new PlcRuntimeException("Error parsing string", e);
- }
- }
-
- public static void serializeAmsString(WriteBuffer writeBuffer, PlcValue value, int stringLength, Object encoding) {
- // TODO: Need to implement the serialization or we can't write strings
- throw new PlcRuntimeException("Not implemented yet");
- }
-
-}
diff --git a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java
index 8f9d25e64..d89a68d95 100644
--- a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java
+++ b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java
@@ -69,40 +69,36 @@ public class ManualAdsDriverTest extends ManualTest {
public static void main(String[] args) throws Exception {
String spsIp = "192.168.23.20";
- /////
- // TODO: adjust this to your ip address
String clientIp = "192.168.23.200";
- //
- ////
String sourceAmsNetId = clientIp + ".1.1";
int sourceAmsPort = 65534;
String targetAmsNetId = spsIp + ".1.1";
int targetAmsPort = 851;
String connectionString = String.format("ads:tcp://%s?sourceAmsNetId=%s&sourceAmsPort=%d&targetAmsNetId=%s&targetAmsPort=%d", spsIp, sourceAmsNetId, sourceAmsPort, targetAmsNetId, targetAmsPort);
ManualAdsDriverTest test = new ManualAdsDriverTest(connectionString);
- test.addTestCase("main.hurz_BOOL:BOOL", true);
- test.addTestCase("main.hurz_BYTE:BYTE", Arrays.asList(false, false, true, false, true, false, true, false));
- test.addTestCase("main.hurz_WORD:WORD", Arrays.asList(true, false, true, false, false, true, false, true, true, false, true, true, true, false, false, false));
- test.addTestCase("main.hurz_DWORD:DWORD", Arrays.asList(true, true, true, true, true, true, false, false, true, true, false, true, true, true, true, false, true, false, false, false, true, false, false, false, true, false, true, true, true, false, false, false));
- test.addTestCase("main.hurz_SINT:SINT", -42);
- test.addTestCase("main.hurz_USINT:USINT", 42);
- test.addTestCase("main.hurz_INT:INT", -2424);
- test.addTestCase("main.hurz_UINT:UINT", 42424);
- test.addTestCase("main.hurz_DINT:DINT", -242442424);
- test.addTestCase("main.hurz_UDINT:UDINT", 4242442424L);
- test.addTestCase("main.hurz_LINT:LINT", -4242442424242424242L);
- test.addTestCase("main.hurz_ULINT:ULINT", 4242442424242424242L);
- test.addTestCase("main.hurz_REAL:REAL", 3.14159265359F);
- test.addTestCase("main.hurz_LREAL:LREAL", 2.71828182846D);
- test.addTestCase("main.hurz_STRING:STRING", "hurz");
- test.addTestCase("main.hurz_WSTRING:WSTRING", "wolf");
- test.addTestCase("main.hurz_TIME:TIME", "PT1.234S");
- test.addTestCase("main.hurz_LTIME:LTIME", "PT24015H23M12.034002044S");
- test.addTestCase("main.hurz_DATE:DATE", "1978-03-28");
- test.addTestCase("main.hurz_TIME_OF_DAY:TIME_OF_DAY", "15:36:30.123");
- test.addTestCase("main.hurz_TOD:TOD", "16:17:18.123");
- test.addTestCase("main.hurz_DATE_AND_TIME:DATE_AND_TIME", "1996-05-06T15:36:30");
- test.addTestCase("main.hurz_DT:DT", "1972-03-29T00:00");
+ test.addTestCase("MAIN.hurz_BOOL", true);
+ test.addTestCase("MAIN.hurz_BYTE", Arrays.asList(false, false, true, false, true, false, true, false));
+ test.addTestCase("MAIN.hurz_WORD", Arrays.asList(true, false, true, false, false, true, false, true, true, false, true, true, true, false, false, false));
+ test.addTestCase("MAIN.hurz_DWORD", Arrays.asList(true, true, true, true, true, true, false, false, true, true, false, true, true, true, true, false, true, false, false, false, true, false, false, false, true, false, true, true, true, false, false, false));
+ test.addTestCase("MAIN.hurz_SINT", -42);
+ test.addTestCase("MAIN.hurz_USINT", 42);
+ test.addTestCase("MAIN.hurz_INT", -2424);
+ test.addTestCase("MAIN.hurz_UINT", 42424);
+ test.addTestCase("MAIN.hurz_DINT", -242442424);
+ test.addTestCase("MAIN.hurz_UDINT", 4242442424L);
+ test.addTestCase("MAIN.hurz_LINT", -4242442424242424242L);
+ test.addTestCase("MAIN.hurz_ULINT", 4242442424242424242L);
+ test.addTestCase("MAIN.hurz_REAL", 3.14159265359F);
+ test.addTestCase("MAIN.hurz_LREAL", 2.71828182846D);
+ test.addTestCase("MAIN.hurz_STRING", "hurz");
+ test.addTestCase("MAIN.hurz_WSTRING", "wolf");
+ test.addTestCase("MAIN.hurz_TIME", "PT1.234S");
+ test.addTestCase("MAIN.hurz_LTIME", "PT24015H23M12.034002044S");
+ test.addTestCase("MAIN.hurz_DATE", "1978-03-28");
+ test.addTestCase("MAIN.hurz_TIME_OF_DAY", "15:36:30.123");
+ test.addTestCase("MAIN.hurz_TOD", "16:17:18.123");
+ test.addTestCase("MAIN.hurz_DATE_AND_TIME", "1996-05-06T15:36:30");
+ test.addTestCase("MAIN.hurz_DT", "1972-03-29T00:00");
test.run();
}
diff --git a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/readwrite/utils/StaticHelper.java b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/readwrite/utils/StaticHelper.java
index 5aff2986d..87b016139 100644
--- a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/readwrite/utils/StaticHelper.java
+++ b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/readwrite/utils/StaticHelper.java
@@ -48,7 +48,7 @@ public class StaticHelper {
// NOOP - a placeholder to let mspec compile
}
- public static Object parseString(ReadBuffer io, int length, String charset) {
+ public static Object parseString(ReadBuffer io, int length, String charset) throws ParseException {
return io.readString(8 * length, charset);
}
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java
index 054e1c7b8..660aa7a4f 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java
@@ -1930,7 +1930,7 @@ public class StaticHelper {
throw new NotImplementedException("Serializing DATE_AND_TIME not implemented");
}
- public static String parseS7Char(ReadBuffer io, String encoding) {
+ public static String parseS7Char(ReadBuffer io, String encoding) throws ParseException {
if ("UTF-8".equalsIgnoreCase(encoding)) {
return io.readString(8, encoding);
} else if ("UTF-16".equalsIgnoreCase(encoding)) {
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
index 79ccaec5b..663a43c78 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
@@ -128,9 +128,9 @@ public interface ReadBuffer extends ByteOrderAware, PositionAware {
return readBigDecimal("", bitLength);
}
- String readString(String logicalName, int bitLength, String encoding, WithReaderArgs... readerArgs);
+ String readString(String logicalName, int bitLength, String encoding, WithReaderArgs... readerArgs) throws ParseException;
- default String readString(int bitLength, String encoding) {
+ default String readString(int bitLength, String encoding) throws ParseException {
return readString("", bitLength, encoding);
}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBufferByteBased.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBufferByteBased.java
index 8c90ac6e8..6afe32f14 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBufferByteBased.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBufferByteBased.java
@@ -26,6 +26,7 @@ import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.Objects;
public class ReadBufferByteBased implements ReadBuffer {
@@ -321,7 +322,7 @@ public class ReadBufferByteBased implements ReadBuffer {
if(sign) {
fraction = (short) (fraction | 0xF800);
}
- if ((exponent >= 1) && (exponent <= 15)) {
+ if ((exponent >= 1) && (exponent < 15)) {
return (float) (0.01 * fraction * Math.pow(2, exponent));
}
if (exponent == 0) {
@@ -388,17 +389,65 @@ public class ReadBufferByteBased implements ReadBuffer {
}
@Override
- public String readString(String logicalName, int bitLength, String encoding, WithReaderArgs... readerArgs) {
- byte[] strBytes = new byte[bitLength / 8];
- for (int i = 0; (i < (bitLength / 8)) && hasMore(8); i++) {
- try {
- strBytes[i] = readByte(logicalName);
- } catch (Exception e) {
- throw new PlcRuntimeException(e);
+ public String readString(String logicalName, int bitLength, String encoding, WithReaderArgs... readerArgs) throws ParseException {
+ encoding = encoding.replaceAll("[^a-zA-Z0-9]", "");
+ switch (encoding.toUpperCase()) {
+ case "UTF8": {
+ byte[] strBytes = new byte[bitLength / 8];
+ int realLength = 0;
+ boolean finishedReading = false;
+ for (int i = 0; (i < (bitLength / 8)) && hasMore(8); i++) {
+ try {
+ byte b = readByte(logicalName);
+ if (b == 0x00) {
+ finishedReading = true;
+ } else if (!finishedReading) {
+ strBytes[i] = b;
+ realLength++;
+ }
+ } catch (Exception e) {
+ throw new PlcRuntimeException(e);
+ }
+ }
+ return new String(strBytes, StandardCharsets.UTF_8).substring(0, realLength);
}
+ case "UTF16":
+ case "UTF16LE":
+ case "UTF16BE": {
+ byte[] strBytes = new byte[bitLength / 8];
+ int realLength = 0;
+ boolean finishedReading = false;
+ for (int i = 0; (i < (bitLength / 16)) && hasMore(16); i++) {
+ try {
+ byte b1 = readByte(logicalName);
+ byte b2 = readByte(logicalName);
+ if ((b1 == 0x00) && (b2 == 0x00)) {
+ finishedReading = true;
+ } else if (!finishedReading){
+ strBytes[(i * 2)] = b1;
+ strBytes[(i * 2) + 1] = b2;
+ realLength++;
+ }
+ } catch (Exception e) {
+ throw new PlcRuntimeException(e);
+ }
+ }
+ Charset charset;
+ switch (encoding) {
+ case "UTF16LE":
+ charset = StandardCharsets.UTF_16LE;
+ break;
+ case "UTF16BE":
+ charset = StandardCharsets.UTF_16BE;
+ break;
+ default:
+ charset = StandardCharsets.UTF_16;
+ }
+ return new String(strBytes, charset).substring(0, realLength);
+ }
+ default:
+ throw new ParseException("Unsupported encoding: " + encoding);
}
- //replaceAll function removes and leading ' char or hypens.
- return new String(strBytes, Charset.forName(encoding.replaceAll("[^a-zA-Z0-9]", "")));
}
diff --git a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/generation/ReadBufferTest.java b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/generation/ReadBufferTest.java
index 757a0b30d..aeb6d60a4 100644
--- a/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/generation/ReadBufferTest.java
+++ b/plc4j/spi/src/test/java/org/apache/plc4x/java/spi/generation/ReadBufferTest.java
@@ -30,7 +30,7 @@ class ReadBufferTest {
* Test which makes sure that PLC4X-256 is not happening.
*/
@Test
- void readString() {
+ void readString() throws ParseException {
String value = new String("abcdef");
final ReadBuffer buffer = new ReadBufferByteBased(value.getBytes(StandardCharsets.UTF_8));
String answer = buffer.readString("", value.length() * 8, "UTF-8");
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/java/s7/utils/StaticHelper.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/java/s7/utils/StaticHelper.java
index e74b5ed9c..5f70844b9 100644
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/java/s7/utils/StaticHelper.java
+++ b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/java/s7/utils/StaticHelper.java
@@ -137,7 +137,7 @@ public class StaticHelper {
throw new NotImplementedException("Serializing STRING not implemented");
}
- public static String parseS7Char(ReadBuffer io, Object encoding) {
+ public static String parseS7Char(ReadBuffer io, Object encoding) throws ParseException {
// Read the full size of the string.
return io.readString(8, (String) encoding);
}
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java
index b5ab8eb8a..92e4733c3 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java
@@ -91,7 +91,7 @@ public abstract class ManualTest {
for (TestCase testCase : shuffledTestcases) {
sb.append(testCase.address).append(", ");
}
- System.out.println(" using order: " + sb.toString());
+ System.out.println(" using order: " + sb);
final PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
for (TestCase testCase : shuffledTestcases) {
@@ -107,17 +107,20 @@ public abstract class ManualTest {
Assertions.assertEquals(shuffledTestcases.size(), readResponse.getFieldNames().size());
for (TestCase testCase : shuffledTestcases) {
String fieldName = testCase.address;
- Assertions.assertEquals(PlcResponseCode.OK, readResponse.getResponseCode(fieldName));
- Assertions.assertNotNull(readResponse.getPlcValue(fieldName));
+ Assertions.assertEquals(PlcResponseCode.OK, readResponse.getResponseCode(fieldName),
+ "Field: " + fieldName);
+ Assertions.assertNotNull(readResponse.getPlcValue(fieldName), "Field: " + fieldName);
if (readResponse.getPlcValue(fieldName) instanceof PlcList) {
PlcList plcList = (PlcList) readResponse.getPlcValue(fieldName);
List<Object> expectedValues = (List<Object>) testCase.expectedReadValue;
for (int j = 0; j < expectedValues.size(); j++) {
- Assertions.assertEquals(expectedValues.get(j), plcList.getIndex(j).getObject());
+ Assertions.assertEquals(expectedValues.get(j), plcList.getIndex(j).getObject(),
+ "Field: " + fieldName);
}
} else {
Assertions.assertEquals(
- testCase.expectedReadValue.toString(), readResponse.getPlcValue(fieldName).getObject().toString());
+ testCase.expectedReadValue.toString(), readResponse.getPlcValue(fieldName).getObject().toString(),
+ "Field: " + fieldName);
}
}
}
diff --git a/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/KnxManufacturer.cs b/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/KnxManufacturer.cs
index ae91c3575..59306feb1 100644
--- a/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/KnxManufacturer.cs
+++ b/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/KnxManufacturer.cs
@@ -623,8 +623,9 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
M_GUANGDONG_KANWAY = 596,
M_PHOENIX_CONTACT_2 = 597,
M_RAMIREZ_ENGINEERING_GMBH = 598,
- M_ABB___RESERVED = 599,
- M_BUSCH_JAEGER_ELEKTRO___RESERVED = 600,
+ M_ZHONGSHAN_TAIYANG_IMPANDEXP__CO_LTD = 599,
+ M_ABB___RESERVED = 600,
+ M_BUSCH_JAEGER_ELEKTRO___RESERVED = 601,
}
public static class KnxManufacturerInfo
@@ -2299,8 +2300,8 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
case KnxManufacturer.M_RAMIREZ_ENGINEERING_GMBH: { /* '598' */
return 656;
}
- case KnxManufacturer.M_ABB___RESERVED: { /* '599' */
- return 43954;
+ case KnxManufacturer.M_ZHONGSHAN_TAIYANG_IMPANDEXP__CO_LTD: { /* '599' */
+ return 657;
}
case KnxManufacturer.M_BUSCH_JAEGER_ELEKTRO: { /* '6' */
return 7;
@@ -2308,7 +2309,10 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
case KnxManufacturer.M_TECHEM: { /* '60' */
return 99;
}
- case KnxManufacturer.M_BUSCH_JAEGER_ELEKTRO___RESERVED: { /* '600' */
+ case KnxManufacturer.M_ABB___RESERVED: { /* '600' */
+ return 43954;
+ }
+ case KnxManufacturer.M_BUSCH_JAEGER_ELEKTRO___RESERVED: { /* '601' */
return 43959;
}
case KnxManufacturer.M_SCHNEIDER_ELECTRIC_INDUSTRIES_SAS: { /* '61' */
@@ -4112,8 +4116,8 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
case KnxManufacturer.M_RAMIREZ_ENGINEERING_GMBH: { /* '598' */
return "RAMIREZ Engineering GmbH";
}
- case KnxManufacturer.M_ABB___RESERVED: { /* '599' */
- return "ABB - reserved";
+ case KnxManufacturer.M_ZHONGSHAN_TAIYANG_IMPANDEXP__CO_LTD: { /* '599' */
+ return "Zhongshan Taiyang IMP&EXP. CO LTD";
}
case KnxManufacturer.M_BUSCH_JAEGER_ELEKTRO: { /* '6' */
return "Busch-Jaeger Elektro";
@@ -4121,7 +4125,10 @@ namespace org.apache.plc4net.drivers.knxnetip.readwrite.model
case KnxManufacturer.M_TECHEM: { /* '60' */
return "Techem";
}
- case KnxManufacturer.M_BUSCH_JAEGER_ELEKTRO___RESERVED: { /* '600' */
+ case KnxManufacturer.M_ABB___RESERVED: { /* '600' */
+ return "ABB - reserved";
+ }
+ case KnxManufacturer.M_BUSCH_JAEGER_ELEKTRO___RESERVED: { /* '601' */
return "Busch-Jaeger Elektro - reserved";
}
case KnxManufacturer.M_SCHNEIDER_ELECTRIC_INDUSTRIES_SAS: { /* '61' */
diff --git a/protocols/ads/src/main/resources/protocols/ads/ads.mspec b/protocols/ads/src/main/resources/protocols/ads/ads.mspec
index d1ce4bee6..284835ac0 100644
--- a/protocols/ads/src/main/resources/protocols/ads/ads.mspec
+++ b/protocols/ads/src/main/resources/protocols/ads/ads.mspec
@@ -458,15 +458,15 @@
[simple string 8 value]
]
['WCHAR' STRING
- [simple string 16 value encoding='"UTF-16"']
+ [simple string 16 value encoding='"UTF-16LE"']
]
['STRING' STRING
- // TODO: Fix this length
- [manual vstring value 'STATIC_CALL("parseAmsString", readBuffer, stringLength, _type.encoding)' 'STATIC_CALL("serializeAmsString", writeBuffer, _value, stringLength, _type.encoding)' 'stringLength + 1']
+ [simple vstring 'stringLength * 8' value ]
+ [reserved uint 8 '0x00']
]
['WSTRING' STRING
- // TODO: Fix this length
- [manual vstring value 'STATIC_CALL("parseAmsString", readBuffer, stringLength, _type.encoding)' 'STATIC_CALL("serializeAmsString", writeBuffer, _value, stringLength, _type.encoding)' '(stringLength * 2) + 2' encoding='"UTF-16"']
+ [simple vstring 'stringLength * 8 * 2' value encoding='"UTF-16LE"']
+ [reserved uint 16 '0x0000' ]
]
// -----------------------------------------