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 2020/10/28 20:32:50 UTC
[plc4x] branch feature/plc4go updated: - Continued working on the
go integration-testsuite
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch feature/plc4go
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/feature/plc4go by this push:
new 7d8c4bb - Continued working on the go integration-testsuite
7d8c4bb is described below
commit 7d8c4bb60a5d74ce6311bc9961ecb060c5837b62
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Oct 28 21:32:42 2020 +0100
- Continued working on the go integration-testsuite
---
.../apache/plc4x/language/go/GoLanguageOutput.java | 5 +-
.../resources/templates/go/model-template.ftlh | 14 +-
.../templates/go/xml-parser-factory-template.ftlh | 88 +++++
.../plc4x/java/modbus/field/ModbusField.java | 4 +-
.../java/modbus/protocol/ModbusProtocolLogic.java | 3 +-
.../plc4x/test/driver/DriverTestsuiteRunner.java | 9 +-
.../resources/protocols/modbus/DriverTestsuite.xml | 84 +++-
.../testing}/protocols/modbus/DriverTestsuite.xml | 84 +++-
.../cmd/main/drivers/tests/modbus_driver_test.go | 29 ++
...firmedServiceRequestConfirmedCOVNotification.go | 11 +-
.../BACnetConfirmedServiceRequestReadProperty.go | 11 +-
.../BACnetConfirmedServiceRequestSubscribeCOV.go | 11 +-
.../BACnetConfirmedServiceRequestWriteProperty.go | 11 +-
.../readwrite/model/BACnetErrorReadProperty.go | 22 +-
.../model/BACnetServiceAckReadProperty.go | 11 +-
.../model/BACnetTagApplicationBitString.go | 11 +-
.../model/BACnetTagApplicationEnumerated.go | 11 +-
.../model/BACnetTagApplicationSignedInteger.go | 11 +-
.../model/BACnetTagApplicationUnsignedInteger.go | 11 +-
.../bacnetip/readwrite/model/BACnetTagContext.go | 11 +-
.../model/BACnetUnconfirmedServiceRequestIAm.go | 11 +-
...rmedServiceRequestUnconfirmedPrivateTransfer.go | 11 +-
.../model/BACnetUnconfirmedServiceRequestWhoHas.go | 11 +-
.../model/BACnetUnconfirmedServiceRequestWhoIs.go | 22 +-
.../bacnetip/readwrite/model/XmlParserHelper.go | 118 ++++++
.../knxnetip/readwrite/model/CEMIDataFrame.go | 22 +-
.../knxnetip/readwrite/model/CEMIFrameData.go | 22 +-
.../knxnetip/readwrite/model/CEMIFrameDataExt.go | 22 +-
.../knxnetip/readwrite/model/DIBDeviceInfo.go | 22 +-
.../plc4go/knxnetip/readwrite/model/IPAddress.go | 11 +-
.../plc4go/knxnetip/readwrite/model/MACAddress.go | 11 +-
.../knxnetip/readwrite/model/UnknownMessage.go | 11 +-
.../knxnetip/readwrite/model/XmlParserHelper.go | 202 ++++++++++
.../internal/plc4go/modbus/ModbusConnection.go | 9 +
.../plc4go/internal/plc4go/modbus/ModbusDriver.go | 2 +-
.../plc4go/internal/plc4go/modbus/ModbusField.go | 6 +-
.../internal/plc4go/modbus/ModbusMessageCodec.go | 4 +-
.../model/ModbusPDUGetComEventLogResponse.go | 11 +-
.../readwrite/model/ModbusPDUReadCoilsResponse.go | 11 +-
.../model/ModbusPDUReadDiscreteInputsResponse.go | 11 +-
.../model/ModbusPDUReadFileRecordResponseItem.go | 11 +-
.../model/ModbusPDUReadHoldingRegistersResponse.go | 11 +-
.../model/ModbusPDUReadInputRegistersResponse.go | 11 +-
...sPDUReadWriteMultipleHoldingRegistersRequest.go | 11 +-
...PDUReadWriteMultipleHoldingRegistersResponse.go | 11 +-
.../model/ModbusPDUReportServerIdResponse.go | 11 +-
.../model/ModbusPDUWriteFileRecordRequestItem.go | 11 +-
.../model/ModbusPDUWriteFileRecordResponseItem.go | 11 +-
.../model/ModbusPDUWriteMultipleCoilsRequest.go | 11 +-
...odbusPDUWriteMultipleHoldingRegistersRequest.go | 11 +-
.../modbus/readwrite/model/XmlParserHelper.go | 90 +++++
.../s7/readwrite/model/S7VarPayloadDataItem.go | 11 +-
.../plc4go/s7/readwrite/model/SzlDataTreeItem.go | 11 +-
.../plc4go/s7/readwrite/model/XmlParserHelper.go | 132 +++++++
.../plc4go/spi/TransportInstanceExposer.go | 25 ++
.../internal/plc4go/testutils/DriverTestRunner.go | 433 +++++++++++++++++++++
.../internal/plc4go/transports/tcp/TcpTransport.go | 4 -
.../plc4go/transports/test/TestTransport.go | 92 +++++
sandbox/plc4go/internal/plc4go/utils/CastUtils.go | 8 +
59 files changed, 1767 insertions(+), 151 deletions(-)
diff --git a/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageOutput.java b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageOutput.java
index a0f91a6..435a470 100644
--- a/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageOutput.java
+++ b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageOutput.java
@@ -41,8 +41,9 @@ public class GoLanguageOutput extends FreemarkerLanguageOutput {
@Override
protected List<Template> getSpecTemplates(Configuration freemarkerConfiguration) throws IOException {
- return Collections.singletonList(
- freemarkerConfiguration.getTemplate("templates/go/parser-factory-template.ftlh"));
+ return Arrays.asList(
+ freemarkerConfiguration.getTemplate("templates/go/parser-factory-template.ftlh"),
+ freemarkerConfiguration.getTemplate("templates/go/xml-parser-factory-template.ftlh"));
}
@Override
diff --git a/build-utils/language-go/src/main/resources/templates/go/model-template.ftlh b/build-utils/language-go/src/main/resources/templates/go/model-template.ftlh
index cbb5ea7..e20ef9b 100644
--- a/build-utils/language-go/src/main/resources/templates/go/model-template.ftlh
+++ b/build-utils/language-go/src/main/resources/templates/go/model-template.ftlh
@@ -896,7 +896,19 @@ func (m *${type.name}) UnmarshalXML(d *xml.Decoder, start xml.StartElement) erro
<#if type.propertyFields?has_content>
<#list type.propertyFields as field>
case "${field.name}":
- <#if helper.isComplexTypeReference(field.type) && helper.isDiscriminatedParentTypeDefinition(helper.getTypeDefinitionForTypeReference(field.type))>
+ <#-- int8 arrays are serialized in Base64 encoding -->
+ <#if helper.isArrayField(field) && (helper.getLanguageTypeNameForField(field) == 'int8')>
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.${field.name?cap_first} = utils.ByteToInt8(_decoded[0:_len])
+ <#elseif helper.isComplexTypeReference(field.type) && helper.isDiscriminatedParentTypeDefinition(helper.getTypeDefinitionForTypeReference(field.type))>
<#if helper.isArrayField(field)>
var _values []<#if helper.isComplexTypeReference(field.type)>I</#if>${helper.getLanguageTypeNameForTypeReference(field.type)}
</#if>
diff --git a/build-utils/language-go/src/main/resources/templates/go/xml-parser-factory-template.ftlh b/build-utils/language-go/src/main/resources/templates/go/xml-parser-factory-template.ftlh
new file mode 100644
index 0000000..cd3ef7e
--- /dev/null
+++ b/build-utils/language-go/src/main/resources/templates/go/xml-parser-factory-template.ftlh
@@ -0,0 +1,88 @@
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.go.GoLanguageTemplateHelper" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
+<#-- Declare the name and type of variables declared locally inside the template -->
+<#-- @ftlvariable name="arrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField" -->
+<#-- @ftlvariable name="checksumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ChecksumField" -->
+<#-- @ftlvariable name="constField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ConstField" -->
+<#-- @ftlvariable name="discriminatorField" type="org.apache.plc4x.plugins.codegenerator.types.fields.DiscriminatorField" -->
+<#-- @ftlvariable name="enumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.EnumField" -->
+<#-- @ftlvariable name="implicitField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ImplicitField" -->
+<#-- @ftlvariable name="manualArrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualArrayField" -->
+<#-- @ftlvariable name="manualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualField" -->
+<#-- @ftlvariable name="optionalField" type="org.apache.plc4x.plugins.codegenerator.types.fields.OptionalField" -->
+<#-- @ftlvariable name="paddingField" type="org.apache.plc4x.plugins.codegenerator.types.fields.PaddingField" -->
+<#-- @ftlvariable name="reservedField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ReservedField" -->
+<#-- @ftlvariable name="simpleField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SimpleField" -->
+<#-- @ftlvariable name="switchField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField" -->
+<#-- @ftlvariable name="virtualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.VirtualField" -->
+<#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" -->
+<#-- @ftlvariable name="complexTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference" -->
+${helper.fileName(protocolName, languageName, outputFlavor)?replace(".", "/")}/model/XmlParserHelper.go
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+ "encoding/xml"
+ "errors"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+)
+
+type ${protocolName?cap_first}XmlParserHelper struct {
+}
+
+func (m ${protocolName?cap_first}XmlParserHelper) Parse(typeName string, xmlString string) (spi.Message, error) {
+ switch typeName {
+<#list helper.getComplexTypeRootDefinitions() as typeDefinition>
+ case "${typeDefinition.name}":
+ var obj ${helper.getLanguageTypeNameForTypeReference(typeDefinition.typeReference)}
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+</#list>
+ }
+ return nil, errors.New("Unsupported type " + typeName)
+}
+</#outputformat>
\ No newline at end of file
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/field/ModbusField.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/field/ModbusField.java
index a50e402..9e92901 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/field/ModbusField.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/field/ModbusField.java
@@ -60,11 +60,11 @@ public abstract class ModbusField implements PlcField {
protected ModbusField(int address, Integer quantity, String dataType) {
this.address = address;
if ((this.address + PROTOCOL_ADDRESS_OFFSET) <= 0) {
- throw new IllegalArgumentException("address must be greater then zero. Was " + (this.address + PROTOCOL_ADDRESS_OFFSET));
+ throw new IllegalArgumentException("address must be greater than zero. Was " + (this.address + PROTOCOL_ADDRESS_OFFSET));
}
this.quantity = quantity != null ? quantity : 1;
if (this.quantity <= 0) {
- throw new IllegalArgumentException("quantity must be greater then zero. Was " + this.quantity);
+ throw new IllegalArgumentException("quantity must be greater than zero. Was " + this.quantity);
}
this.dataType = dataType != null ? dataType : "INT";
ModbusDataTypeSizes.enumForValue(this.dataType);
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
index 45ad0c9..df04f38 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
@@ -61,7 +61,7 @@ public class ModbusProtocolLogic extends Plc4xProtocolBase<ModbusTcpADU> impleme
private Duration requestTimeout;
private short unitIdentifier;
private RequestTransactionManager tm;
- private AtomicInteger transactionIdentifierGenerator = new AtomicInteger(10);
+ private AtomicInteger transactionIdentifierGenerator = new AtomicInteger(1);
private final static int FC_EXTENDED_REGISTERS_GROUP_HEADER_LENGTH = 2;
private final static int FC_EXTENDED_REGISTERS_FILE_RECORD_LENGTH = 10000;
@@ -70,7 +70,6 @@ public class ModbusProtocolLogic extends Plc4xProtocolBase<ModbusTcpADU> impleme
this.requestTimeout = Duration.ofMillis(configuration.getRequestTimeout());
this.unitIdentifier = (short) configuration.getUnitIdentifier();
this.tm = new RequestTransactionManager(1);
- this.transactionIdentifierGenerator = new AtomicInteger(10);
}
@Override
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/DriverTestsuiteRunner.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/DriverTestsuiteRunner.java
index c47bf77..a591515 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/DriverTestsuiteRunner.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/driver/DriverTestsuiteRunner.java
@@ -406,7 +406,9 @@ public class DriverTestsuiteRunner {
final Object parsedOutput = messageIO.parse(readBuffer, parserArguments.toArray(new String[0]));
final String xmlString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(parsedOutput);
final String referenceXmlString = referenceXml.asXML();
- final Diff diff = DiffBuilder.compare(referenceXmlString).withTest(xmlString).ignoreComments().ignoreWhitespace().build();
+ final Diff diff = DiffBuilder.compare(referenceXmlString)
+ .withTest(xmlString).checkForSimilar().ignoreComments().ignoreWhitespace()
+ .build();
if (diff.hasDifferences()) {
LOGGER.warn(xmlString);
LOGGER.warn(diff.toString());
@@ -419,9 +421,12 @@ public class DriverTestsuiteRunner {
private void validateApiMessage(Element referenceXml, String apiMessage) throws DriverTestsuiteException {
final String referenceXmlString = referenceXml.asXML();
- final Diff diff = DiffBuilder.compare(referenceXmlString).withTest(apiMessage).ignoreComments().ignoreWhitespace().build();
+ final Diff diff = DiffBuilder.compare(referenceXmlString)
+ .withTest(apiMessage).checkForSimilar().ignoreComments().ignoreWhitespace()
+ .build();
if (diff.hasDifferences()) {
LOGGER.warn(apiMessage);
+ LOGGER.warn(diff.toString());
throw new DriverTestsuiteException("Differences were found after parsing.\n" + diff.toString());
}
}
diff --git a/protocols/modbus/src/test/resources/protocols/modbus/DriverTestsuite.xml b/protocols/modbus/src/test/resources/protocols/modbus/DriverTestsuite.xml
index 429997d..befd271 100644
--- a/protocols/modbus/src/test/resources/protocols/modbus/DriverTestsuite.xml
+++ b/protocols/modbus/src/test/resources/protocols/modbus/DriverTestsuite.xml
@@ -20,19 +20,24 @@
<test:driver-testsuite xmlns:test="https://plc4x.apache.org/schemas/driver-testsuite.xsd"
bigEndian="true">
+ <!-- https://base64.guru/converter/encode/hex -->
+
<name>Modbus</name>
<driver-name>modbus</driver-name>
- <testcase>
- <name>Single element read request</name>
+ <!-- Single element read BOOL (Coil) -->
+
+
+ <!--testcase>
+ <name>Single element read BOOL</name>
<steps>
<api-request name="Receive Read Request from application">
<TestReadRequest className="org.apache.plc4x.test.driver.model.api.TestReadRequest">
<fields>
<field className="org.apache.plc4x.test.driver.model.api.TestField">
<name>hurz</name>
- <address>holding-register:1:REAL[2]</address>
+ <address>holding-register:1:BOOL</address>
</field>
</fields>
</TestReadRequest>
@@ -92,6 +97,79 @@
</DefaultPlcReadResponse>
</api-response>
</steps>
+ </testcase-->
+
+
+ <testcase>
+ <name>Single element read request</name>
+ <steps>
+ <api-request name="Receive Read Request from application">
+ <TestReadRequest className="org.apache.plc4x.test.driver.model.api.TestReadRequest">
+ <fields>
+ <field className="org.apache.plc4x.test.driver.model.api.TestField">
+ <name>hurz</name>
+ <address>holding-register:1:REAL[2]</address>
+ </field>
+ </fields>
+ </TestReadRequest>
+ </api-request>
+ <outgoing-plc-message name="Send Modbus Input-Register Read Request">
+ <!-- 000a00000006010300000004 -->
+ <parser-arguments>
+ <response>false</response>
+ </parser-arguments>
+ <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
+ <transactionIdentifier>1</transactionIdentifier>
+ <unitIdentifier>1</unitIdentifier>
+ <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersRequest">
+ <startingAddress>0</startingAddress>
+ <quantity>4</quantity>
+ </pdu>
+ </ModbusTcpADU>
+ </outgoing-plc-message>
+ <incoming-plc-message name="Receive Modbus Input-Register Read Response">
+ <!-- 000b0000000b0103080000000000000000 -->
+ <parser-arguments>
+ <response>true</response>
+ </parser-arguments>
+ <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
+ <transactionIdentifier>1</transactionIdentifier>
+ <unitIdentifier>1</unitIdentifier>
+ <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersResponse">
+ <value>QEkP20BJD9s=</value>
+ </pdu>
+ </ModbusTcpADU>
+ </incoming-plc-message>
+ <api-response name="Report Read Response to application">
+ <DefaultPlcReadResponse className="org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse">
+ <request className="org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest">
+ <hurz className="org.apache.plc4x.java.modbus.field.ModbusFieldHoldingRegister">
+ <address>0</address>
+ <dataType>IEC61131_REAL</dataType>
+ <lengthWords>4</lengthWords>
+ <dataTypeSize>4</dataTypeSize>
+ <lengthBytes>8</lengthBytes>
+ </hurz>
+ </request>
+ <hurz>
+ <code>OK</code>
+ <value className="org.apache.plc4x.java.api.value.PlcList">
+ <object>java.util.Collections..UnmodifiableRandomAccessList</object>
+ <object>org.apache.plc4x.java.api.value.PlcREAL</object>
+ <object>
+ <object>java.lang.Float</object>
+ <object>3.1415927</object>
+ </object>
+ <object>org.apache.plc4x.java.api.value.PlcREAL</object>
+ <object>
+ <object>java.lang.Float</object>
+ <object>3.1415927</object>
+ </object>
+ </value>
+ </hurz>
+ </DefaultPlcReadResponse>
+ </api-response>
+ </steps>
</testcase>
</test:driver-testsuite>
diff --git a/protocols/modbus/src/test/resources/protocols/modbus/DriverTestsuite.xml b/sandbox/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml
similarity index 55%
copy from protocols/modbus/src/test/resources/protocols/modbus/DriverTestsuite.xml
copy to sandbox/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml
index 429997d..befd271 100644
--- a/protocols/modbus/src/test/resources/protocols/modbus/DriverTestsuite.xml
+++ b/sandbox/plc4go/assets/testing/protocols/modbus/DriverTestsuite.xml
@@ -20,19 +20,24 @@
<test:driver-testsuite xmlns:test="https://plc4x.apache.org/schemas/driver-testsuite.xsd"
bigEndian="true">
+ <!-- https://base64.guru/converter/encode/hex -->
+
<name>Modbus</name>
<driver-name>modbus</driver-name>
- <testcase>
- <name>Single element read request</name>
+ <!-- Single element read BOOL (Coil) -->
+
+
+ <!--testcase>
+ <name>Single element read BOOL</name>
<steps>
<api-request name="Receive Read Request from application">
<TestReadRequest className="org.apache.plc4x.test.driver.model.api.TestReadRequest">
<fields>
<field className="org.apache.plc4x.test.driver.model.api.TestField">
<name>hurz</name>
- <address>holding-register:1:REAL[2]</address>
+ <address>holding-register:1:BOOL</address>
</field>
</fields>
</TestReadRequest>
@@ -92,6 +97,79 @@
</DefaultPlcReadResponse>
</api-response>
</steps>
+ </testcase-->
+
+
+ <testcase>
+ <name>Single element read request</name>
+ <steps>
+ <api-request name="Receive Read Request from application">
+ <TestReadRequest className="org.apache.plc4x.test.driver.model.api.TestReadRequest">
+ <fields>
+ <field className="org.apache.plc4x.test.driver.model.api.TestField">
+ <name>hurz</name>
+ <address>holding-register:1:REAL[2]</address>
+ </field>
+ </fields>
+ </TestReadRequest>
+ </api-request>
+ <outgoing-plc-message name="Send Modbus Input-Register Read Request">
+ <!-- 000a00000006010300000004 -->
+ <parser-arguments>
+ <response>false</response>
+ </parser-arguments>
+ <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
+ <transactionIdentifier>1</transactionIdentifier>
+ <unitIdentifier>1</unitIdentifier>
+ <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersRequest">
+ <startingAddress>0</startingAddress>
+ <quantity>4</quantity>
+ </pdu>
+ </ModbusTcpADU>
+ </outgoing-plc-message>
+ <incoming-plc-message name="Receive Modbus Input-Register Read Response">
+ <!-- 000b0000000b0103080000000000000000 -->
+ <parser-arguments>
+ <response>true</response>
+ </parser-arguments>
+ <ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
+ <transactionIdentifier>1</transactionIdentifier>
+ <unitIdentifier>1</unitIdentifier>
+ <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadHoldingRegistersResponse">
+ <value>QEkP20BJD9s=</value>
+ </pdu>
+ </ModbusTcpADU>
+ </incoming-plc-message>
+ <api-response name="Report Read Response to application">
+ <DefaultPlcReadResponse className="org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse">
+ <request className="org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest">
+ <hurz className="org.apache.plc4x.java.modbus.field.ModbusFieldHoldingRegister">
+ <address>0</address>
+ <dataType>IEC61131_REAL</dataType>
+ <lengthWords>4</lengthWords>
+ <dataTypeSize>4</dataTypeSize>
+ <lengthBytes>8</lengthBytes>
+ </hurz>
+ </request>
+ <hurz>
+ <code>OK</code>
+ <value className="org.apache.plc4x.java.api.value.PlcList">
+ <object>java.util.Collections..UnmodifiableRandomAccessList</object>
+ <object>org.apache.plc4x.java.api.value.PlcREAL</object>
+ <object>
+ <object>java.lang.Float</object>
+ <object>3.1415927</object>
+ </object>
+ <object>org.apache.plc4x.java.api.value.PlcREAL</object>
+ <object>
+ <object>java.lang.Float</object>
+ <object>3.1415927</object>
+ </object>
+ </value>
+ </hurz>
+ </DefaultPlcReadResponse>
+ </api-response>
+ </steps>
</testcase>
</test:driver-testsuite>
diff --git a/sandbox/plc4go/cmd/main/drivers/tests/modbus_driver_test.go b/sandbox/plc4go/cmd/main/drivers/tests/modbus_driver_test.go
new file mode 100644
index 0000000..0cc07db
--- /dev/null
+++ b/sandbox/plc4go/cmd/main/drivers/tests/modbus_driver_test.go
@@ -0,0 +1,29 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package tests
+
+import (
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/modbus"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/testutils"
+ "testing"
+)
+
+func TestModbusDriver(t *testing.T) {
+ testutils.RunDriverTestsuite(t, modbus.NewModbusDriver(), "assets/testing/protocols/modbus/DriverTestsuite.xml")
+}
\ No newline at end of file
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotification.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotification.go
index 448203a..ae854c4 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotification.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestConfirmedCOVNotification.go
@@ -432,11 +432,16 @@ func (m *BACnetConfirmedServiceRequestConfirmedCOVNotification) UnmarshalXML(d *
}
m.LifetimeLength = data
case "lifetimeSeconds":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.LifetimeSeconds = data
+ m.LifetimeSeconds = utils.ByteToInt8(_decoded[0:_len])
case "notifications":
var data []IBACnetTagWithContent
if err := d.DecodeElement(&data, &tok); err != nil {
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadProperty.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadProperty.go
index b9de9ac..4cdb3d3 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadProperty.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestReadProperty.go
@@ -250,11 +250,16 @@ func (m *BACnetConfirmedServiceRequestReadProperty) UnmarshalXML(d *xml.Decoder,
}
m.PropertyIdentifierLength = data
case "propertyIdentifier":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.PropertyIdentifier = data
+ m.PropertyIdentifier = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOV.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOV.go
index bc59d30..e910164 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOV.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestSubscribeCOV.go
@@ -353,11 +353,16 @@ func (m *BACnetConfirmedServiceRequestSubscribeCOV) UnmarshalXML(d *xml.Decoder,
}
m.LifetimeLength = data
case "lifetimeSeconds":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.LifetimeSeconds = data
+ m.LifetimeSeconds = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWriteProperty.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWriteProperty.go
index 51e5139..e4331c3 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWriteProperty.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetConfirmedServiceRequestWriteProperty.go
@@ -345,11 +345,16 @@ func (m *BACnetConfirmedServiceRequestWriteProperty) UnmarshalXML(d *xml.Decoder
}
m.PropertyIdentifierLength = data
case "propertyIdentifier":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.PropertyIdentifier = data
+ m.PropertyIdentifier = utils.ByteToInt8(_decoded[0:_len])
case "value":
switch tok.Attr[0].Value {
case "org.apache.plc4x.java.bacnetip.readwrite.BACnetTagApplicationNull":
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go
index 865cf8f..574c590 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetErrorReadProperty.go
@@ -249,11 +249,16 @@ func (m *BACnetErrorReadProperty) UnmarshalXML(d *xml.Decoder, start xml.StartEl
}
m.ErrorClassLength = data
case "errorClass":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.ErrorClass = data
+ m.ErrorClass = utils.ByteToInt8(_decoded[0:_len])
case "errorCodeLength":
var data uint8
if err := d.DecodeElement(&data, &tok); err != nil {
@@ -261,11 +266,16 @@ func (m *BACnetErrorReadProperty) UnmarshalXML(d *xml.Decoder, start xml.StartEl
}
m.ErrorCodeLength = data
case "errorCode":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.ErrorCode = data
+ m.ErrorCode = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadProperty.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadProperty.go
index 43ec5de..62e56d7 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadProperty.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetServiceAckReadProperty.go
@@ -311,11 +311,16 @@ func (m *BACnetServiceAckReadProperty) UnmarshalXML(d *xml.Decoder, start xml.St
}
m.PropertyIdentifierLength = data
case "propertyIdentifier":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.PropertyIdentifier = data
+ m.PropertyIdentifier = utils.ByteToInt8(_decoded[0:_len])
case "value":
switch tok.Attr[0].Value {
case "org.apache.plc4x.java.bacnetip.readwrite.BACnetTagApplicationNull":
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBitString.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBitString.go
index f99d948..ccba29f 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBitString.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationBitString.go
@@ -168,11 +168,16 @@ func (m *BACnetTagApplicationBitString) UnmarshalXML(d *xml.Decoder, start xml.S
}
m.UnusedBits = data
case "data":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Data = data
+ m.Data = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationEnumerated.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationEnumerated.go
index 124aede..d5ce739 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationEnumerated.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationEnumerated.go
@@ -145,11 +145,16 @@ func (m *BACnetTagApplicationEnumerated) UnmarshalXML(d *xml.Decoder, start xml.
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "data":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Data = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Data = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationSignedInteger.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationSignedInteger.go
index 99e39e5..4fcc3c4 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationSignedInteger.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationSignedInteger.go
@@ -145,11 +145,16 @@ func (m *BACnetTagApplicationSignedInteger) UnmarshalXML(d *xml.Decoder, start x
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "data":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Data = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Data = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationUnsignedInteger.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationUnsignedInteger.go
index d1e2314..c2fdb76 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationUnsignedInteger.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagApplicationUnsignedInteger.go
@@ -145,11 +145,16 @@ func (m *BACnetTagApplicationUnsignedInteger) UnmarshalXML(d *xml.Decoder, start
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "data":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Data = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Data = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagContext.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagContext.go
index bdc8184..2f5cb00 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagContext.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetTagContext.go
@@ -145,11 +145,16 @@ func (m *BACnetTagContext) UnmarshalXML(d *xml.Decoder, start xml.StartElement)
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "data":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Data = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Data = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIAm.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIAm.go
index b952446..c22bba3 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIAm.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestIAm.go
@@ -322,11 +322,16 @@ func (m *BACnetUnconfirmedServiceRequestIAm) UnmarshalXML(d *xml.Decoder, start
}
m.MaximumApduLengthAcceptedLength = data
case "maximumApduLengthAccepted":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.MaximumApduLengthAccepted = data
+ m.MaximumApduLengthAccepted = utils.ByteToInt8(_decoded[0:_len])
case "segmentationSupported":
var data uint8
if err := d.DecodeElement(&data, &tok); err != nil {
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedPrivateTransfer.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedPrivateTransfer.go
index c8b3736..0c03161 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedPrivateTransfer.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestUnconfirmedPrivateTransfer.go
@@ -266,11 +266,16 @@ func (m *BACnetUnconfirmedServiceRequestUnconfirmedPrivateTransfer) UnmarshalXML
}
m.ServiceNumber = data
case "values":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Values = data
+ m.Values = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoHas.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoHas.go
index cdae776..2293b79 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoHas.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoHas.go
@@ -286,11 +286,16 @@ func (m *BACnetUnconfirmedServiceRequestWhoHas) UnmarshalXML(d *xml.Decoder, sta
}
m.ObjectNameCharacterSet = data
case "objectName":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.ObjectName = data
+ m.ObjectName = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoIs.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoIs.go
index 1f8a8b2..ea36252 100644
--- a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoIs.go
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/BACnetUnconfirmedServiceRequestWhoIs.go
@@ -249,11 +249,16 @@ func (m *BACnetUnconfirmedServiceRequestWhoIs) UnmarshalXML(d *xml.Decoder, star
}
m.DeviceInstanceRangeLowLimitLength = data
case "deviceInstanceRangeLowLimit":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.DeviceInstanceRangeLowLimit = data
+ m.DeviceInstanceRangeLowLimit = utils.ByteToInt8(_decoded[0:_len])
case "deviceInstanceRangeHighLimitLength":
var data uint8
if err := d.DecodeElement(&data, &tok); err != nil {
@@ -261,11 +266,16 @@ func (m *BACnetUnconfirmedServiceRequestWhoIs) UnmarshalXML(d *xml.Decoder, star
}
m.DeviceInstanceRangeHighLimitLength = data
case "deviceInstanceRangeHighLimit":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.DeviceInstanceRangeHighLimit = data
+ m.DeviceInstanceRangeHighLimit = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/XmlParserHelper.go b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/XmlParserHelper.go
new file mode 100644
index 0000000..135dc59
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/bacnetip/readwrite/model/XmlParserHelper.go
@@ -0,0 +1,118 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+ "encoding/xml"
+ "errors"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+)
+
+type BacnetipXmlParserHelper struct {
+}
+
+func (m BacnetipXmlParserHelper) Parse(typeName string, xmlString string) (spi.Message, error) {
+ switch typeName {
+ case "APDU":
+ var obj APDU
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "BACnetTag":
+ var obj BACnetTag
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "BACnetTagWithContent":
+ var obj BACnetTagWithContent
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "BACnetError":
+ var obj BACnetError
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "NLM":
+ var obj NLM
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "BACnetConfirmedServiceRequest":
+ var obj BACnetConfirmedServiceRequest
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "BACnetAddress":
+ var obj BACnetAddress
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "BACnetConfirmedServiceACK":
+ var obj BACnetConfirmedServiceACK
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "BACnetUnconfirmedServiceRequest":
+ var obj BACnetUnconfirmedServiceRequest
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "BACnetServiceAck":
+ var obj BACnetServiceAck
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "BVLC":
+ var obj BVLC
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "NPDU":
+ var obj NPDU
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ }
+ return nil, errors.New("Unsupported type " + typeName)
+}
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataFrame.go b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataFrame.go
index 4250bfe..b1ab309 100644
--- a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataFrame.go
+++ b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIDataFrame.go
@@ -501,11 +501,16 @@ func (m *CEMIDataFrame) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err
}
m.SourceAddress = CastIKNXAddress(data)
case "destinationAddress":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.DestinationAddress = data
+ m.DestinationAddress = utils.ByteToInt8(_decoded[0:_len])
case "dataLength":
var data uint8
if err := d.DecodeElement(&data, &tok); err != nil {
@@ -537,11 +542,16 @@ func (m *CEMIDataFrame) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err
}
m.DataFirstByte = data
case "data":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Data = data
+ m.Data = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameData.go b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameData.go
index 29b702d..fb6b6a7 100644
--- a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameData.go
+++ b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameData.go
@@ -345,11 +345,16 @@ func (m *CEMIFrameData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err
}
m.SourceAddress = CastIKNXAddress(data)
case "destinationAddress":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.DestinationAddress = data
+ m.DestinationAddress = utils.ByteToInt8(_decoded[0:_len])
case "groupAddress":
var data bool
if err := d.DecodeElement(&data, &tok); err != nil {
@@ -393,11 +398,16 @@ func (m *CEMIFrameData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err
}
m.DataFirstByte = data
case "data":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Data = data
+ m.Data = utils.ByteToInt8(_decoded[0:_len])
case "crc":
var data uint8
if err := d.DecodeElement(&data, &tok); err != nil {
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameDataExt.go b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameDataExt.go
index 7464eb8..58200a2 100644
--- a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameDataExt.go
+++ b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/CEMIFrameDataExt.go
@@ -380,11 +380,16 @@ func (m *CEMIFrameDataExt) UnmarshalXML(d *xml.Decoder, start xml.StartElement)
}
m.SourceAddress = CastIKNXAddress(data)
case "destinationAddress":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.DestinationAddress = data
+ m.DestinationAddress = utils.ByteToInt8(_decoded[0:_len])
case "dataLength":
var data uint8
if err := d.DecodeElement(&data, &tok); err != nil {
@@ -416,11 +421,16 @@ func (m *CEMIFrameDataExt) UnmarshalXML(d *xml.Decoder, start xml.StartElement)
}
m.DataFirstByte = data
case "data":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Data = data
+ m.Data = utils.ByteToInt8(_decoded[0:_len])
case "crc":
var data uint8
if err := d.DecodeElement(&data, &tok); err != nil {
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DIBDeviceInfo.go b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DIBDeviceInfo.go
index 9140222..72405e0 100644
--- a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DIBDeviceInfo.go
+++ b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/DIBDeviceInfo.go
@@ -348,11 +348,16 @@ func (m *DIBDeviceInfo) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err
}
m.ProjectInstallationIdentifier = CastIProjectInstallationIdentifier(data)
case "knxNetIpDeviceSerialNumber":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.KnxNetIpDeviceSerialNumber = data
+ m.KnxNetIpDeviceSerialNumber = utils.ByteToInt8(_decoded[0:_len])
case "knxNetIpDeviceMulticastAddress":
var data *IPAddress
if err := d.DecodeElement(&data, &tok); err != nil {
@@ -366,11 +371,16 @@ func (m *DIBDeviceInfo) UnmarshalXML(d *xml.Decoder, start xml.StartElement) err
}
m.KnxNetIpDeviceMacAddress = CastIMACAddress(data)
case "deviceFriendlyName":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.DeviceFriendlyName = data
+ m.DeviceFriendlyName = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/IPAddress.go b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/IPAddress.go
index c984ccd..5d70098 100644
--- a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/IPAddress.go
+++ b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/IPAddress.go
@@ -129,11 +129,16 @@ func (m *IPAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "addr":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Addr = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Addr = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/MACAddress.go b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/MACAddress.go
index b5afd36..c2fb589 100644
--- a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/MACAddress.go
+++ b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/MACAddress.go
@@ -129,11 +129,16 @@ func (m *MACAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "addr":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Addr = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Addr = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/UnknownMessage.go b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/UnknownMessage.go
index 622a252..85e386b 100644
--- a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/UnknownMessage.go
+++ b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/UnknownMessage.go
@@ -140,11 +140,16 @@ func (m *UnknownMessage) UnmarshalXML(d *xml.Decoder, start xml.StartElement) er
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "unknownData":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.UnknownData = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.UnknownData = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/XmlParserHelper.go b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/XmlParserHelper.go
new file mode 100644
index 0000000..085a048
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/knxnetip/readwrite/model/XmlParserHelper.go
@@ -0,0 +1,202 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+ "encoding/xml"
+ "errors"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+)
+
+type KnxnetipXmlParserHelper struct {
+}
+
+func (m KnxnetipXmlParserHelper) Parse(typeName string, xmlString string) (spi.Message, error) {
+ switch typeName {
+ case "CEMIAdditionalInformation":
+ var obj CEMIAdditionalInformation
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "HPAIControlEndpoint":
+ var obj HPAIControlEndpoint
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "TunnelingResponseDataBlock":
+ var obj TunnelingResponseDataBlock
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "ConnectionResponseDataBlock":
+ var obj ConnectionResponseDataBlock
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "TunnelingRequestDataBlock":
+ var obj TunnelingRequestDataBlock
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "KNXGroupAddress":
+ var obj KNXGroupAddress
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "DIBDeviceInfo":
+ var obj DIBDeviceInfo
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "DeviceConfigurationRequestDataBlock":
+ var obj DeviceConfigurationRequestDataBlock
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "DeviceConfigurationAckDataBlock":
+ var obj DeviceConfigurationAckDataBlock
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "DIBSuppSvcFamilies":
+ var obj DIBSuppSvcFamilies
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "ConnectionRequestInformation":
+ var obj ConnectionRequestInformation
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "HPAIDiscoveryEndpoint":
+ var obj HPAIDiscoveryEndpoint
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "ProjectInstallationIdentifier":
+ var obj ProjectInstallationIdentifier
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "KNXAddress":
+ var obj KNXAddress
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "CEMIDataFrame":
+ var obj CEMIDataFrame
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "ServiceId":
+ var obj ServiceId
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "KNXNetIPMessage":
+ var obj KNXNetIPMessage
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "HPAIDataEndpoint":
+ var obj HPAIDataEndpoint
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "RelativeTimestamp":
+ var obj RelativeTimestamp
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "CEMI":
+ var obj CEMI
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "MACAddress":
+ var obj MACAddress
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "CEMIFrame":
+ var obj CEMIFrame
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "DeviceStatus":
+ var obj DeviceStatus
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "IPAddress":
+ var obj IPAddress
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ }
+ return nil, errors.New("Unsupported type " + typeName)
+}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusConnection.go b/sandbox/plc4go/internal/plc4go/modbus/ModbusConnection.go
index bf35b92..90c474c 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/ModbusConnection.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/ModbusConnection.go
@@ -21,6 +21,7 @@ package modbus
import (
internalModel "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/model"
"plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/transports"
"plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go"
"plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/model"
)
@@ -106,3 +107,11 @@ func (m ModbusConnection) SubscriptionRequestBuilder() model.PlcSubscriptionRequ
func (m ModbusConnection) UnsubscriptionRequestBuilder() model.PlcUnsubscriptionRequestBuilder {
panic("implement me")
}
+
+func (m ModbusConnection) GetTransportInstance() transports.TransportInstance {
+ if mc, ok := m.messageCodec.(spi.TransportInstanceExposer); ok {
+ return mc.GetTransportInstance()
+ }
+ return nil
+}
+
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusDriver.go b/sandbox/plc4go/internal/plc4go/modbus/ModbusDriver.go
index a7f3ab8..bb68052 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/ModbusDriver.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/ModbusDriver.go
@@ -40,7 +40,7 @@ type ModbusDriver struct {
func NewModbusDriver() *ModbusDriver {
return &ModbusDriver{
- transactionIdCounter: 1,
+ transactionIdCounter: 0,
fieldHandler: NewFieldHandler(),
valueHandler: NewValueHandler(),
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusField.go b/sandbox/plc4go/internal/plc4go/modbus/ModbusField.go
index 9f214f3..65a31df 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/ModbusField.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/ModbusField.go
@@ -24,6 +24,10 @@ import (
"strconv"
)
+const (
+ MODBUS_PROTOCOL_ADDRESS_OFFSET = 1
+)
+
type ModbusPlcField struct {
FieldType uint8
Address uint16
@@ -34,7 +38,7 @@ type ModbusPlcField struct {
func NewModbusPlcField(fieldType uint8, address uint16, quantity uint16, datatype string) ModbusPlcField {
return ModbusPlcField{
FieldType: fieldType,
- Address: address,
+ Address: address - MODBUS_PROTOCOL_ADDRESS_OFFSET,
Quantity: quantity,
Datatype: datatype,
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/ModbusMessageCodec.go b/sandbox/plc4go/internal/plc4go/modbus/ModbusMessageCodec.go
index 1bb1f4e..d274349 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/ModbusMessageCodec.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/ModbusMessageCodec.go
@@ -153,4 +153,6 @@ func work(codec *ModbusMessageCodec) {
}
}
-
+func (m ModbusMessageCodec) GetTransportInstance() transports.TransportInstance {
+ return m.transportInstance
+}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogResponse.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogResponse.go
index 4dcbec4..3dc9096 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogResponse.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUGetComEventLogResponse.go
@@ -233,11 +233,16 @@ func (m *ModbusPDUGetComEventLogResponse) UnmarshalXML(d *xml.Decoder, start xml
}
m.MessageCount = data
case "events":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Events = data
+ m.Events = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsResponse.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsResponse.go
index 1e76525..03a4d9c 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsResponse.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadCoilsResponse.go
@@ -164,11 +164,16 @@ func (m *ModbusPDUReadCoilsResponse) UnmarshalXML(d *xml.Decoder, start xml.Star
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "value":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Value = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Value = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsResponse.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsResponse.go
index 4e8309a..2d9d983 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsResponse.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadDiscreteInputsResponse.go
@@ -164,11 +164,16 @@ func (m *ModbusPDUReadDiscreteInputsResponse) UnmarshalXML(d *xml.Decoder, start
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "value":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Value = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Value = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponseItem.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponseItem.go
index 1e0768b..0e3e93c 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponseItem.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadFileRecordResponseItem.go
@@ -169,11 +169,16 @@ func (m *ModbusPDUReadFileRecordResponseItem) UnmarshalXML(d *xml.Decoder, start
}
m.ReferenceType = data
case "data":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Data = data
+ m.Data = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersResponse.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersResponse.go
index 76d913a..7ebf373 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersResponse.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadHoldingRegistersResponse.go
@@ -164,11 +164,16 @@ func (m *ModbusPDUReadHoldingRegistersResponse) UnmarshalXML(d *xml.Decoder, sta
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "value":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Value = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Value = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersResponse.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersResponse.go
index 6894b75..e71a767 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersResponse.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadInputRegistersResponse.go
@@ -164,11 +164,16 @@ func (m *ModbusPDUReadInputRegistersResponse) UnmarshalXML(d *xml.Decoder, start
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "value":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Value = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Value = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersRequest.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersRequest.go
index baf19c3..d9a954a 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersRequest.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersRequest.go
@@ -256,11 +256,16 @@ func (m *ModbusPDUReadWriteMultipleHoldingRegistersRequest) UnmarshalXML(d *xml.
}
m.WriteQuantity = data
case "value":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Value = data
+ m.Value = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersResponse.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersResponse.go
index 78d214d..eddfada 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersResponse.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReadWriteMultipleHoldingRegistersResponse.go
@@ -164,11 +164,16 @@ func (m *ModbusPDUReadWriteMultipleHoldingRegistersResponse) UnmarshalXML(d *xml
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "value":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Value = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Value = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdResponse.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdResponse.go
index 95c35a5..0d2970a 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdResponse.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUReportServerIdResponse.go
@@ -164,11 +164,16 @@ func (m *ModbusPDUReportServerIdResponse) UnmarshalXML(d *xml.Decoder, start xml
tok := token.(xml.StartElement)
switch tok.Name.Local {
case "value":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
return err
}
- m.Value = data
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
+ return err
+ }
+ m.Value = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequestItem.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequestItem.go
index 0e3a3a6..f647fc2 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequestItem.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordRequestItem.go
@@ -215,11 +215,16 @@ func (m *ModbusPDUWriteFileRecordRequestItem) UnmarshalXML(d *xml.Decoder, start
}
m.RecordNumber = data
case "recordData":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.RecordData = data
+ m.RecordData = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponseItem.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponseItem.go
index 7c84ae7..8332092 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponseItem.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteFileRecordResponseItem.go
@@ -215,11 +215,16 @@ func (m *ModbusPDUWriteFileRecordResponseItem) UnmarshalXML(d *xml.Decoder, star
}
m.RecordNumber = data
case "recordData":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.RecordData = data
+ m.RecordData = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsRequest.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsRequest.go
index 76dd4ca..bdc8116 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsRequest.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleCoilsRequest.go
@@ -210,11 +210,16 @@ func (m *ModbusPDUWriteMultipleCoilsRequest) UnmarshalXML(d *xml.Decoder, start
}
m.Quantity = data
case "value":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Value = data
+ m.Value = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersRequest.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersRequest.go
index 995b4df..1b5d031 100644
--- a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersRequest.go
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/ModbusPDUWriteMultipleHoldingRegistersRequest.go
@@ -210,11 +210,16 @@ func (m *ModbusPDUWriteMultipleHoldingRegistersRequest) UnmarshalXML(d *xml.Deco
}
m.Quantity = data
case "value":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Value = data
+ m.Value = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/XmlParserHelper.go b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/XmlParserHelper.go
new file mode 100644
index 0000000..932c6a4
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/modbus/readwrite/model/XmlParserHelper.go
@@ -0,0 +1,90 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+ "encoding/xml"
+ "errors"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+)
+
+type ModbusXmlParserHelper struct {
+}
+
+func (m ModbusXmlParserHelper) Parse(typeName string, xmlString string) (spi.Message, error) {
+ switch typeName {
+ case "ModbusPDUWriteFileRecordRequestItem":
+ var obj ModbusPDUWriteFileRecordRequestItem
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "ModbusPDUReadFileRecordResponseItem":
+ var obj ModbusPDUReadFileRecordResponseItem
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "ModbusConstants":
+ var obj ModbusConstants
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "ModbusTcpADU":
+ var obj ModbusTcpADU
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "ModbusPDUWriteFileRecordResponseItem":
+ var obj ModbusPDUWriteFileRecordResponseItem
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "ModbusPDU":
+ var obj ModbusPDU
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "ModbusPDUReadFileRecordRequestItem":
+ var obj ModbusPDUReadFileRecordRequestItem
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "ModbusSerialADU":
+ var obj ModbusSerialADU
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ }
+ return nil, errors.New("Unsupported type " + typeName)
+}
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadDataItem.go b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadDataItem.go
index ac14d8e..503daa7 100644
--- a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadDataItem.go
+++ b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/S7VarPayloadDataItem.go
@@ -222,11 +222,16 @@ func (m *S7VarPayloadDataItem) UnmarshalXML(d *xml.Decoder, start xml.StartEleme
}
m.TransportSize = data
case "data":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Data = data
+ m.Data = utils.ByteToInt8(_decoded[0:_len])
}
}
}
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlDataTreeItem.go b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlDataTreeItem.go
index bc2d3b0..9678979 100644
--- a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlDataTreeItem.go
+++ b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/SzlDataTreeItem.go
@@ -203,11 +203,16 @@ func (m *SzlDataTreeItem) UnmarshalXML(d *xml.Decoder, start xml.StartElement) e
}
m.ItemIndex = data
case "mlfb":
- var data []int8
- if err := d.DecodeElement(&data, &tok); err != nil {
+ var _encoded string
+ if err := d.DecodeElement(&_encoded, &tok); err != nil {
+ return err
+ }
+ _decoded := make([]byte, base64.StdEncoding.DecodedLen(len(_encoded)))
+ _len, err := base64.StdEncoding.Decode(_decoded, []byte(_encoded))
+ if err != nil {
return err
}
- m.Mlfb = data
+ m.Mlfb = utils.ByteToInt8(_decoded[0:_len])
case "moduleTypeId":
var data uint16
if err := d.DecodeElement(&data, &tok); err != nil {
diff --git a/sandbox/plc4go/internal/plc4go/s7/readwrite/model/XmlParserHelper.go b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/XmlParserHelper.go
new file mode 100644
index 0000000..228fe97
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/s7/readwrite/model/XmlParserHelper.go
@@ -0,0 +1,132 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package model
+
+import (
+ "encoding/xml"
+ "errors"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+)
+
+type S7XmlParserHelper struct {
+}
+
+func (m S7XmlParserHelper) Parse(typeName string, xmlString string) (spi.Message, error) {
+ switch typeName {
+ case "SzlId":
+ var obj SzlId
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "S7Message":
+ var obj S7Message
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "S7VarPayloadStatusItem":
+ var obj S7VarPayloadStatusItem
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "S7Parameter":
+ var obj S7Parameter
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "SzlDataTreeItem":
+ var obj SzlDataTreeItem
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "COTPPacket":
+ var obj COTPPacket
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "S7PayloadUserDataItem":
+ var obj S7PayloadUserDataItem
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "COTPParameter":
+ var obj COTPParameter
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "TPKTPacket":
+ var obj TPKTPacket
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "S7Payload":
+ var obj S7Payload
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "S7VarRequestParameterItem":
+ var obj S7VarRequestParameterItem
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "S7VarPayloadDataItem":
+ var obj S7VarPayloadDataItem
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "S7Address":
+ var obj S7Address
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ case "S7ParameterUserDataItem":
+ var obj S7ParameterUserDataItem
+ err := xml.Unmarshal([]byte(xmlString), &obj)
+ if err != nil {
+ return nil, errors.New("error unmarshalling xml: " + err.Error())
+ }
+ return obj, nil
+ }
+ return nil, errors.New("Unsupported type " + typeName)
+}
diff --git a/sandbox/plc4go/internal/plc4go/spi/TransportInstanceExposer.go b/sandbox/plc4go/internal/plc4go/spi/TransportInstanceExposer.go
new file mode 100644
index 0000000..1a60698
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/spi/TransportInstanceExposer.go
@@ -0,0 +1,25 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package spi
+
+import "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/transports"
+
+type TransportInstanceExposer interface {
+ GetTransportInstance() transports.TransportInstance
+}
diff --git a/sandbox/plc4go/internal/plc4go/testutils/DriverTestRunner.go b/sandbox/plc4go/internal/plc4go/testutils/DriverTestRunner.go
new file mode 100644
index 0000000..5528bb5
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/testutils/DriverTestRunner.go
@@ -0,0 +1,433 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package testutils
+
+import (
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "github.com/subchen/go-xmldom"
+ "os"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/modbus/readwrite/model"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/spi"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/transports/test"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/utils"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go"
+ api "plc4x.apache.org/plc4go-modbus-driver/v0/pkg/plc4go/model"
+ "strconv"
+ "testing"
+ "time"
+)
+
+type DriverTestsuite struct {
+ name string
+ driverName string
+ driverParameters map[string]string
+ setupSteps []TestStep
+ teardownSteps []TestStep
+ testcases []Testcase
+}
+
+func (m DriverTestsuite) Run(driverManager plc4go.PlcDriverManager, testcase Testcase) error {
+ // Get a connection
+ connectionChan := driverManager.GetConnection(m.driverName + ":test://hurz")
+ connectionResult := <-connectionChan
+
+ if connectionResult.Err != nil {
+ return errors.New("error getting a connection: " + connectionResult.Err.Error())
+ }
+
+ // Run the setup steps
+ for _, testStep := range m.setupSteps {
+ m.ExecuteStep(connectionResult.Connection, &testcase, testStep)
+ }
+
+ // Run the actual scenario steps
+ for _, testStep := range testcase.steps {
+ m.ExecuteStep(connectionResult.Connection, &testcase, testStep)
+ }
+
+ // Run the teardown steps
+ for _, testStep := range m.teardownSteps {
+ m.ExecuteStep(connectionResult.Connection, &testcase, testStep)
+ }
+
+ return nil
+}
+
+func (m DriverTestsuite) ExecuteStep(connection plc4go.PlcConnection, testcase *Testcase, step TestStep) error {
+ mc, ok := connection.(spi.TransportInstanceExposer)
+ if !ok {
+ return errors.New("couldn't access connections transport instance")
+ }
+ transportInstance := mc.GetTransportInstance()
+
+ switch step.stepType {
+ case StepType_API_REQUEST:
+ switch step.payload.Name {
+ case "TestReadRequest":
+ // Assemble a read-request according to the information in the test xml
+ rrb := connection.ReadRequestBuilder()
+ for _, fieldNode := range step.payload.GetChild("fields").GetChildren("field") {
+ fieldName := fieldNode.GetChild("name").Text
+ fieldAddress := fieldNode.GetChild("address").Text
+ rrb.AddItem(fieldName, fieldAddress)
+ }
+ readRequest, err := rrb.Build()
+ if err != nil {
+ return errors.New("Error creating read-request: " + err.Error())
+ }
+
+ // Execute the read-request and store the response-channel in the testcase.
+ if testcase.readRequestResultChannel != nil {
+ return errors.New("testcase read-request result channel already occupied")
+ }
+ testcase.readRequestResultChannel = readRequest.Execute()
+ case "TestWriteRequest":
+ wrb := connection.WriteRequestBuilder()
+ for _, fieldNode := range step.payload.GetChild("fields").GetChildren("field") {
+ fieldName := fieldNode.GetChild("name").Text
+ fieldAddress := fieldNode.GetChild("address").Text
+ fieldValue := fieldNode.GetChild("value").Text
+ wrb.AddItem(fieldName, fieldAddress, fieldValue)
+ }
+ writeRequest, err := wrb.Build()
+ if err != nil {
+ return errors.New("Error creating write-request: " + err.Error())
+ }
+ if testcase.writeRequestResultChannel != nil {
+ return errors.New("testcase write-request result channel already occupied")
+ }
+ testcase.writeRequestResultChannel = writeRequest.Execute()
+ }
+ case StepType_API_RESPONSE:
+ switch step.payload.Name {
+ case "DefaultPlcReadResponse":
+ if testcase.readRequestResultChannel == nil {
+ return errors.New("no read response expected")
+ }
+ readResponse := <- testcase.readRequestResultChannel
+ // TODO: Implement this ...
+ fmt.Println(readResponse)
+ case "DefaultPlcWriteResponse":
+ if testcase.writeRequestResultChannel == nil {
+ return errors.New("no write response expected")
+ }
+ writeResponse := <- testcase.writeRequestResultChannel
+ // TODO: Implement this ...
+ fmt.Println(writeResponse)
+ }
+ case StepType_OUTGOING_PLC_MESSAGE:
+ typeName := step.payload.Name
+ payloadString := step.payload.XML()
+
+ // Parse the xml into a real model
+ message, err := model.ModbusXmlParserHelper{}.Parse(typeName, payloadString)
+ if err != nil {
+ return errors.New("error parsing xml: " + err.Error())
+ }
+
+ // Serialize the model into bytes
+ ser, ok := message.(utils.Serializable)
+ if !ok {
+ return errors.New("error converting type into Serializable type: " + err.Error())
+ }
+ wb := utils.WriteBufferNew()
+ err = ser.Serialize(*wb)
+ if err != nil {
+ return errors.New("error serializing message: " + err.Error())
+ }
+ expectedRawOutput := wb.GetBytes()
+
+ // Read exactly this amount of bytes from the transport
+ rawOutput, err := transportInstance.Read(uint32(len(expectedRawOutput)))
+ if err != nil {
+ return errors.New("error getting bytes from transport: " + err.Error())
+ }
+
+ // Compare the bytes read with the ones we expect
+ for i := range expectedRawOutput {
+ if expectedRawOutput[i] != rawOutput[i] {
+ return errors.New("actual output doesn't match expected output")
+ }
+ }
+ // If there's a difference, parse the input and display it to simplify debugging
+ case StepType_OUTGOING_PLC_BYTES:
+ // Read exactly this amount of bytes from the transport
+ expectedRawInput, err := hex.DecodeString(step.payload.Text)
+ if err != nil {
+ return errors.New("error decoding hex-encoded byte data: " + err.Error())
+ }
+ rawInput, err := transportInstance.Read(uint32(len(expectedRawInput)))
+ if err != nil {
+ return errors.New("error getting bytes from transport: " + err.Error())
+ }
+
+ // Compare the bytes read with the ones we expect
+ for i := range expectedRawInput {
+ if expectedRawInput[i] != rawInput[i] {
+ return errors.New("actual output doesn't match expected output")
+ }
+ }
+ // If there's a difference, parse the input and display it to simplify debugging
+ case StepType_INCOMING_PLC_MESSAGE:
+ typeName := step.payload.Name
+ payloadString := step.payload.XML()
+
+ // Parse the xml into a real model
+ message, err := model.ModbusXmlParserHelper{}.Parse(typeName, payloadString)
+ if err != nil {
+ return errors.New("error parsing xml: " + err.Error())
+ }
+
+ // Serialize the model into bytes
+ ser, ok := message.(utils.Serializable)
+ if !ok {
+ return errors.New("error converting type into Serializable type: " + err.Error())
+ }
+ wb := utils.WriteBufferNew()
+ err = ser.Serialize(*wb)
+ if err != nil {
+ return errors.New("error serializing message: " + err.Error())
+ }
+
+ // Send these bytes to the transport
+ err = transportInstance.Write(wb.GetBytes())
+ if err != nil {
+ return errors.New("error writing data to transport: " + err.Error())
+ }
+ case StepType_INCOMING_PLC_BYTES:
+ // Get the raw hex-data.
+ rawInput, err := hex.DecodeString(step.payload.Text)
+ if err != nil {
+ return errors.New("error decoding hex-encoded byte data: " + err.Error())
+ }
+
+ // Send these bytes to the transport
+ err = transportInstance.Write(rawInput)
+ if err != nil {
+ return errors.New("error writing data to transport: " + err.Error())
+ }
+ case StepType_DELAY:
+ // Get the number of milliseconds
+ delay, err := strconv.Atoi(step.payload.Text)
+ if err != nil {
+ return errors.New("invalid delay format: " + err.Error())
+ }
+ // Sleep for that long
+ time.Sleep(time.Duration(delay))
+ case StepType_TERMINATE:
+ // Simply close the transport connection
+ err := transportInstance.Close()
+ if err != nil {
+ return errors.New("error closing transport: " + err.Error())
+ }
+ }
+ return nil
+}
+
+func (m DriverTestsuite) ParseXml(referenceXml *xmldom.Node, parserArguments []string) {
+ normalizeXml(referenceXml)
+ //referenceSerialized := referenceXml.FirstChild().XML()
+}
+
+type Testcase struct {
+ name string
+ steps []TestStep
+ readRequestResultChannel <-chan api.PlcReadRequestResult
+ writeRequestResultChannel <-chan api.PlcWriteRequestResult
+}
+
+type TestStep struct {
+ name string
+ stepType StepType
+ parserArguments []string
+ payload xmldom.Node
+}
+
+type StepType uint8
+
+const (
+ StepType_OUTGOING_PLC_MESSAGE StepType = 0x01
+ StepType_OUTGOING_PLC_BYTES StepType = 0x02
+ StepType_INCOMING_PLC_MESSAGE StepType = 0x03
+ StepType_INCOMING_PLC_BYTES StepType = 0x04
+ StepType_API_REQUEST StepType = 0x05
+ StepType_API_RESPONSE StepType = 0x06
+ StepType_DELAY StepType = 0x07
+ StepType_TERMINATE StepType = 0x08
+)
+
+func RunDriverTestsuite(t *testing.T, driver plc4go.PlcDriver, testPath string) {
+ // Read the test-specification as XML file
+ rootNode, err := ParseDriverTestsuiteXml(testPath)
+ if err != nil {
+ t.Error(err.Error())
+ t.Fail()
+ return
+ }
+
+ // Parse the contents of the test-specification
+ testsuite, err := ParseDriverTestsuite(*rootNode)
+ if err != nil {
+ t.Error(err.Error())
+ t.Fail()
+ return
+ }
+
+ // Initialize the driver manager
+ driverManager := plc4go.NewPlcDriverManager()
+ driverManager.RegisterTransport(test.NewTestTransport())
+ driverManager.RegisterDriver(driver)
+
+ for _, testcase := range testsuite.testcases {
+ testsuite.Run(driverManager, testcase)
+ }
+ // Execute the tests in the testsuite
+ fmt.Printf(testsuite.name)
+}
+
+func ParseDriverTestsuiteXml(testPath string) (*xmldom.Node, error) {
+ // Get the current working directory
+ path, err := os.Getwd()
+ if err != nil {
+ return nil, err
+ }
+
+ // Check if the test-file is available
+ info, err := os.Stat(path + "/../../../../" + testPath)
+ if os.IsNotExist(err) {
+ return nil, errors.New("test-File doesn't exist")
+ }
+ if info.IsDir() {
+ return nil, errors.New("test-file refers to a directory")
+ }
+
+ // Open a reader for this file
+ dat, err := os.Open(path + "/../../../../" + testPath)
+ if err != nil {
+ return nil, errors.New("error opening file")
+ }
+
+ // Read the xml
+ node := xmldom.Must(xmldom.Parse(dat)).Root
+ return node, nil
+}
+
+func ParseDriverTestsuite(node xmldom.Node) (*DriverTestsuite, error) {
+ if node.Name != "driver-testsuite" {
+ return nil, errors.New("invalid document structure")
+ }
+ var testsuiteName string
+ var driverName string
+ var setupSteps []TestStep
+ var teardownSteps []TestStep
+ var testcases []Testcase
+ for _, childPtr := range node.Children {
+ child := *childPtr
+ if child.Name == "name" {
+ testsuiteName = child.Text
+ } else if child.Name == "driver-name" {
+ driverName = child.Text
+ } else if child.Name == "setup" {
+ steps, err := ParseDriverTestsuiteSteps(child)
+ if err != nil {
+ return nil, errors.New("error parsing setup steps")
+ }
+ setupSteps = steps
+ } else if child.Name == "teardown" {
+ steps, err := ParseDriverTestsuiteSteps(child)
+ if err != nil {
+ return nil, errors.New("error teardown setup steps")
+ }
+ teardownSteps = steps
+ } else if child.Name == "testcase" {
+ testcaseName := child.FindOneByName("name").Text
+ stepsNode := child.FindOneByName("steps")
+ steps, err := ParseDriverTestsuiteSteps(*stepsNode)
+ if err != nil {
+ return nil, errors.New("error parsing testcase " + testcaseName + ": " + err.Error())
+ }
+ testcase := Testcase{
+ name: testcaseName,
+ steps: steps,
+ }
+ testcases = append(testcases, testcase)
+ } else {
+ return nil, errors.New("invalid document structure")
+ }
+ }
+
+ return &DriverTestsuite{
+ name: testsuiteName,
+ driverName: driverName,
+ setupSteps: setupSteps,
+ teardownSteps: teardownSteps,
+ testcases: testcases,
+ }, nil
+}
+
+func ParseDriverTestsuiteSteps(node xmldom.Node) ([]TestStep, error) {
+ var testSteps []TestStep
+ for _, step := range node.Children {
+ name := step.GetAttributeValue("name")
+ var stepType StepType
+ switch step.Name {
+ case "api-request":
+ stepType = StepType_API_REQUEST
+ case "api-response":
+ stepType = StepType_API_RESPONSE
+ case "outgoing-plc-message":
+ stepType = StepType_OUTGOING_PLC_MESSAGE
+ case "incoming-plc-message":
+ stepType = StepType_INCOMING_PLC_MESSAGE
+ case "outgoing-plc-bytes":
+ stepType = StepType_OUTGOING_PLC_BYTES
+ case "incoming-plc-bytes":
+ stepType = StepType_INCOMING_PLC_BYTES
+ case "delay":
+ stepType = StepType_DELAY
+ case "terminate":
+ stepType = StepType_TERMINATE
+ }
+ var parserArguments []string
+ var payload *xmldom.Node
+ for _, childNode := range step.Children {
+ if childNode.Name == "parser-arguments" {
+ for _, parserArgumentNode := range childNode.Children {
+ parserArguments = append(parserArguments, parserArgumentNode.Text)
+ }
+ } else if payload == nil {
+ payload = childNode
+ } else {
+ return nil, errors.New("test step can only contain a single payload element")
+ }
+ }
+ if payload == nil {
+ return nil, errors.New("missing payload element")
+ }
+ testSteps = append(testSteps, TestStep{
+ name: name,
+ stepType: stepType,
+ parserArguments: parserArguments,
+ payload: *payload,
+ })
+ }
+ return testSteps, nil
+}
diff --git a/sandbox/plc4go/internal/plc4go/transports/tcp/TcpTransport.go b/sandbox/plc4go/internal/plc4go/transports/tcp/TcpTransport.go
index 637145d..09cd9dc 100644
--- a/sandbox/plc4go/internal/plc4go/transports/tcp/TcpTransport.go
+++ b/sandbox/plc4go/internal/plc4go/transports/tcp/TcpTransport.go
@@ -194,7 +194,3 @@ func (m *TcpTransportInstance) Write(data []uint8) error {
}
return errors.New("error writing to transport. No writer available")
}
-
-
-
-
diff --git a/sandbox/plc4go/internal/plc4go/transports/test/TestTransport.go b/sandbox/plc4go/internal/plc4go/transports/test/TestTransport.go
new file mode 100644
index 0000000..d8eb716
--- /dev/null
+++ b/sandbox/plc4go/internal/plc4go/transports/test/TestTransport.go
@@ -0,0 +1,92 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package test
+
+import (
+ "errors"
+ "net/url"
+ "plc4x.apache.org/plc4go-modbus-driver/v0/internal/plc4go/transports"
+)
+
+type TestTransport struct {
+ transports.Transport
+}
+
+func NewTestTransport() *TestTransport {
+ return &TestTransport{}
+}
+
+func (m TestTransport) GetTransportCode() string {
+ return "test"
+}
+
+func (m TestTransport) GetTransportName() string {
+ return "Test Transport"
+}
+
+func (m TestTransport) CreateTransportInstance(transportUrl url.URL, options map[string][]string) (transports.TransportInstance, error) {
+ transportInstance := NewTestTransportInstance(&m)
+
+ castFunc := func(typ interface{}) (transports.TransportInstance, error) {
+ if transportInstance, ok := typ.(transports.TransportInstance); ok {
+ return transportInstance, nil
+ }
+ return nil, errors.New("couldn't cast to TransportInstance")
+ }
+ return castFunc(transportInstance)
+}
+
+type TestTransportInstance struct {
+ buffer []byte
+ transport *TestTransport
+}
+
+func NewTestTransportInstance(transport *TestTransport) *TestTransportInstance {
+ return &TestTransportInstance {
+ buffer: []byte{},
+ transport: transport,
+ }
+}
+
+func (m *TestTransportInstance) Connect() error {
+ return nil
+}
+
+func (m *TestTransportInstance) Close() error {
+ return nil
+}
+
+func (m *TestTransportInstance) GetNumReadableBytes() (uint32, error) {
+ return uint32(len(m.buffer)), nil
+}
+
+func (m *TestTransportInstance) PeekReadableBytes(numBytes uint32) ([]uint8, error) {
+ return m.buffer[0:numBytes], nil
+}
+
+func (m *TestTransportInstance) Read(numBytes uint32) ([]uint8, error) {
+ data := m.buffer[0:int(numBytes)]
+ m.buffer = m.buffer[int(numBytes):]
+ return data, nil
+}
+
+func (m *TestTransportInstance) Write(data []uint8) error {
+ m.buffer = append(m.buffer, data...)
+ return nil
+}
diff --git a/sandbox/plc4go/internal/plc4go/utils/CastUtils.go b/sandbox/plc4go/internal/plc4go/utils/CastUtils.go
index 46c15a0..03bbce5 100644
--- a/sandbox/plc4go/internal/plc4go/utils/CastUtils.go
+++ b/sandbox/plc4go/internal/plc4go/utils/CastUtils.go
@@ -36,6 +36,14 @@ func Int8ToByte(input []int8) []byte {
return output
}
+func ByteToInt8(input []byte) []int8 {
+ output := make([]int8, len(input))
+ for i, _val := range input {
+ output[i] = int8(_val)
+ }
+ return output
+}
+
func StrToBool(str string) (bool, error) {
boolVal, err := strconv.ParseBool(str)
if err != nil {