You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2021/01/08 10:31:36 UTC
[plc4x] branch feature/native_opua_client updated: Add enum types
and close request logic
This is an automated email from the ASF dual-hosted git repository.
hutcheb pushed a commit to branch feature/native_opua_client
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/feature/native_opua_client by this push:
new 597deaf Add enum types and close request logic
597deaf is described below
commit 597deaf080806c775ca40189f6f29e24aa0eccf9
Author: hutcheb <be...@gmail.com>
AuthorDate: Fri Jan 8 05:30:57 2021 -0500
Add enum types and close request logic
---
.../java/opcua/protocol/OpcuaProtocolLogic.java | 197 +++++++++++++++++++--
protocols/opcua/pom.xml | 62 ++++++-
.../apache/plc4x/protocol/opcua/OpcuaProtocol.java | 2 +-
.../src/main/resources/protocols/opcua/opcua.mspec | 55 +++---
protocols/opcua/src/main/xslt/opc-types.xsl | 56 ++++--
5 files changed, 307 insertions(+), 65 deletions(-)
diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
index 6e7aba7..db8c5d7 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
@@ -24,9 +24,7 @@ import io.netty.buffer.Unpooled;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.authentication.PlcAuthentication;
-import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
-import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
-import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
+import org.apache.plc4x.java.api.exceptions.*;
import org.apache.plc4x.java.api.messages.PlcReadRequest;
import org.apache.plc4x.java.api.messages.PlcReadResponse;
import org.apache.plc4x.java.api.messages.PlcResponse;
@@ -60,11 +58,13 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse;
import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
import org.apache.plc4x.java.spi.values.*;
+import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.time.Duration;
+import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
@@ -82,7 +82,8 @@ import static org.apache.plc4x.java.spi.configuration.ConfigurationFactory.confi
public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements HasConfiguration<OpcuaConfiguration> {
private static final Logger LOGGER = LoggerFactory.getLogger(OpcuaProtocolLogic.class);
- public static final Duration REQUEST_TIMEOUT = Duration.ofMillis(10000);
+ public static final Duration REQUEST_TIMEOUT = Duration.ofMillis(1000000);
+ public static final long REQUEST_TIMEOUT_LONG = 10000L;
private static final String CHUNK = "F";
private static final int VERSION = 0;
private static final int DEFAULT_RECEIVE_BUFFER_SIZE = 65535;
@@ -125,7 +126,49 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
@Override
public void close(ConversationContext<OpcuaAPU> context) {
- // Nothing to do here ...
+ int transactionId = transactionIdentifierGenerator.getAndIncrement();
+ if(transactionIdentifierGenerator.get() == 0xFFFF) {
+ transactionIdentifierGenerator.set(1);
+ }
+
+ int requestHandle = requestHandleGenerator.getAndIncrement();
+ if(requestHandleGenerator.get() == 0xFFFF) {
+ requestHandleGenerator.set(1);
+ }
+
+ ExpandedNodeId expandedNodeId = new ExpandedNodeIdFourByte(false, //Namespace Uri Specified
+ false, //Server Index Specified
+ NULL_STRING, //Namespace Uri
+ 1L, //Server Index
+ new FourByteNodeId((short) 0, 473)); //Identifier for OpenSecureChannel
+
+ RequestHeader requestHeader = new RequestHeader(authenticationToken,
+ getCurrentDateTime(),
+ requestHandle, //RequestHandle
+ 0L,
+ NULL_STRING,
+ 5000L,
+ NULL_EXTENSION_OBJECT);
+
+ CloseSessionRequest closeSessionRequest = new CloseSessionRequest((byte) 1,
+ (byte) 0,
+ requestHeader,
+ true);
+
+ OpcuaMessageRequest messageRequest = new OpcuaMessageRequest(CHUNK,
+ channelId.get(),
+ tokenId.get(),
+ transactionId,
+ transactionId,
+ closeSessionRequest);
+
+ context.sendRequest(new OpcuaAPU(messageRequest))
+ .expectResponse(OpcuaAPU.class, REQUEST_TIMEOUT)
+ .check(p -> p.getMessage() instanceof OpcuaMessageResponse)
+ .unwrap(p -> (OpcuaMessageResponse) p.getMessage())
+ .handle(opcuaMessageResponse -> {
+ LOGGER.debug("Got Close Session Response Connection Response");
+ });
}
@Override
@@ -182,7 +225,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
0L, //RequestHandle
0L,
NULL_STRING,
- 10000L,
+ REQUEST_TIMEOUT_LONG,
NULL_EXTENSION_OBJECT);
OpenSecureChannelRequest openSecureChannelRequest = new OpenSecureChannelRequest((byte) 1,
@@ -241,7 +284,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
0L,
0L,
NULL_STRING,
- 10000L,
+ REQUEST_TIMEOUT_LONG,
NULL_EXTENSION_OBJECT);
LocalizedText applicationName = new LocalizedText((short) 0,
@@ -330,7 +373,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
requestHandle,
0L,
NULL_STRING,
- 10000L,
+ REQUEST_TIMEOUT_LONG,
NULL_EXTENSION_OBJECT);
SignatureData clientSignature = new SignatureData(NULL_STRING, NULL_STRING);
@@ -415,7 +458,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
requestHandle,
0L,
NULL_STRING,
- 10000L,
+ REQUEST_TIMEOUT_LONG,
NULL_EXTENSION_OBJECT);
ReadValueId[] readValueArray = new ReadValueId[1];
@@ -459,21 +502,137 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
// Try to decode the response data based on the corresponding request.
ReadResponse readResponse = (ReadResponse) opcuaResponse.getMessage();
- //TODO;- Fix this
DataValue[] results = readResponse.getResults();
- Integer value = null;
+ PlcValue value = null;
+ PlcResponseCode responseCode = PlcResponseCode.OK;
if (results.length > 0) {
- Variant variant = results[0].getValue();
- LOGGER.info("Repsponse Include Variant of type " + variant.getClass().toString());
- if (variant instanceof VariantInt32) {
- value = ((VariantInt32) variant).getValue()[0];
+ if (results[0].getStatusCode() == null) {
+ Variant variant = results[0].getValue();
+ LOGGER.info("Repsponse includes Variant of type " + variant.getClass().toString());
+ if (variant instanceof VariantBoolean) {
+ boolean[] array = ((VariantBoolean) variant).getValue();
+ int length = array.length;
+ Boolean[] tmpValue = new Boolean[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = array[i];
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantSByte) {
+ byte[] array = ((VariantSByte) variant).getValue();
+ int length = array.length;
+ Byte[] tmpValue = new Byte[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = array[i];
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantByte) {
+ short[] array = ((VariantByte) variant).getValue();
+ int length = array.length;
+ Short[] tmpValue = new Short[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = array[i];
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantInt16) {
+ short[] array = ((VariantInt16) variant).getValue();
+ int length = array.length;
+ Short[] tmpValue = new Short[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = array[i];
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantUInt16) {
+ int[] array = ((VariantUInt16) variant).getValue();
+ int length = array.length;
+ Integer[] tmpValue = new Integer[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = array[i];
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantInt32) {
+ int[] array = ((VariantInt32) variant).getValue();
+ int length = array.length;
+ Integer[] tmpValue = new Integer[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = array[i];
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantUInt32) {
+ long[] array = ((VariantUInt32) variant).getValue();
+ int length = array.length;
+ Long[] tmpValue = new Long[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = array[i];
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantInt64) {
+ long[] array = ((VariantInt64) variant).getValue();
+ int length = array.length;
+ Long[] tmpValue = new Long[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = array[i];
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantUInt64) {
+ value = IEC61131ValueHandler.of(((VariantUInt64) variant).getValue());
+ } else if (variant instanceof VariantFloat) {
+ float[] array = ((VariantFloat) variant).getValue();
+ int length = array.length;
+ Float[] tmpValue = new Float[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = array[i];
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantDouble) {
+ double[] array = ((VariantDouble) variant).getValue();
+ int length = array.length;
+ Double[] tmpValue = new Double[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = array[i];
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantString) {
+ int length = ((VariantString) variant).getValue().length;
+ PascalString[] stringArray = ((VariantString) variant).getValue();
+ String[] tmpValue = new String[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = stringArray[i].getStringValue();
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantDateTime) {
+ long[] array = ((VariantDateTime) variant).getValue();
+ int length = array.length;
+ DateTime[] tmpValue = new DateTime[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = new DateTime(array[i]);
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else if (variant instanceof VariantGuid) {
+ int length = ((VariantGuid) variant).getValue().length;
+ String[] stringArray = ((VariantGuid) variant).getValue();
+ value = IEC61131ValueHandler.of(stringArray);
+ } else if (variant instanceof VariantXmlElement) {
+ int length = ((VariantXmlElement) variant).getValue().length;
+ PascalString[] stringArray = ((VariantXmlElement) variant).getValue();
+ String[] tmpValue = new String[length];
+ for (int i = 0; i < length; i++) {
+ tmpValue[i] = stringArray[i].getStringValue();
+ }
+ value = IEC61131ValueHandler.of(tmpValue);
+ } else {
+ responseCode = PlcResponseCode.UNSUPPORTED;
+ LOGGER.error("Data type - " + variant.getClass() + " is not supported ");
+ }
+ } else {
+ responseCode = PlcResponseCode.UNSUPPORTED;
+ LOGGER.error("Error while reading value from OPC UA server error code:- " + results[0].getStatusCode().toString());
}
+
}
- PlcValue plcValue = new PlcDINT(value);
// Prepare the response.
PlcReadResponse response = new DefaultPlcReadResponse(request,
- Collections.singletonMap(fieldName, new ResponseItem<>(PlcResponseCode.OK, plcValue)));
+ Collections.singletonMap(fieldName, new ResponseItem<>(responseCode, value)));
// Pass the response back to the application.
future.complete(response);
@@ -496,4 +655,8 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
private long getCurrentDateTime() {
return (System.currentTimeMillis() * 10000) + epochOffset;
}
+
+ private long getDateTime(long dateTime) {
+ return (dateTime - epochOffset) / 10000;
+ }
}
diff --git a/protocols/opcua/pom.xml b/protocols/opcua/pom.xml
index aeb3acb..8b24b88 100644
--- a/protocols/opcua/pom.xml
+++ b/protocols/opcua/pom.xml
@@ -49,11 +49,31 @@
<url>https://opcfoundation.org/UA/schemas/1.04/Opc.Ua.Types.bsd</url>
<unpack>false</unpack>
<outputDirectory>${project.build.directory}/downloads</outputDirectory>
- <outputFileName>opc-datatypes.xml</outputFileName>
+ <outputFileName>Opc.Ua.Types.bsd</outputFileName>
</configuration>
</execution>
</executions>
</plugin>
+ <!-- Fetch the master-data which will be used to translate manufacturer ids to readable names -->
+ <plugin>
+ <groupId>com.googlecode.maven-download-plugin</groupId>
+ <artifactId>download-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>fetch-opc-statuscodes</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>wget</goal>
+ </goals>
+ <configuration>
+ <url>https://opcfoundation.org/UA/schemas/1.04/StatusCode.csv</url>
+ <unpack>false</unpack>
+ <outputDirectory>${project.build.directory}/downloads</outputDirectory>
+ <outputFileName>StatusCode.csv</outputFileName>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
@@ -68,7 +88,26 @@
<url>https://opcfoundation.org/UA/schemas/1.04/Opc.Ua.NodeSet2.Services.xml</url>
<unpack>false</unpack>
<outputDirectory>${project.build.directory}/downloads</outputDirectory>
- <outputFileName>opc-discriminators.xml</outputFileName>
+ <outputFileName>Opc.Ua.NodeSet2.Services.xml</outputFileName>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>com.googlecode.maven-download-plugin</groupId>
+ <artifactId>download-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>fetch-opc-services-enum</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>wget</goal>
+ </goals>
+ <configuration>
+ <url>https://opcfoundation.org/UA/schemas/1.04/Opc.Ua.NodeIds.Services.csv</url>
+ <unpack>false</unpack>
+ <outputDirectory>${project.build.directory}/downloads</outputDirectory>
+ <outputFileName>Opc.Ua.NodeIds.Services.csv</outputFileName>
</configuration>
</execution>
</executions>
@@ -89,7 +128,7 @@
<transformationSets>
<transformationSet>
<dir>${project.build.directory}/downloads</dir>
- <includes>opc-datatypes.xml</includes>
+ <includes>Opc.Ua.Types.bsd</includes>
<stylesheet>src/main/xslt/opc-types.xsl</stylesheet>
<outputDir>${project.build.outputDirectory}/protocols/opcua</outputDir>
<fileMappers>
@@ -100,7 +139,15 @@
<parameters>
<parameter>
<name>services</name>
- <value>${project.build.directory}/downloads/opc-discriminators.xml</value>
+ <value>${project.build.directory}/downloads/Opc.Ua.NodeSet2.Services.xml</value>
+ </parameter>
+ <parameter>
+ <name>servicesEnum</name>
+ <value>${project.build.directory}/downloads/Opc.Ua.NodeIds.Services.csv</value>
+ </parameter>
+ <parameter>
+ <name>statusCodes</name>
+ <value>${project.build.directory}/downloads/StatusCode.csv</value>
</parameter>
</parameters>
<outputProperties>
@@ -112,6 +159,13 @@
</transformationSet>
</transformationSets>
</configuration>
+ <dependencies>
+ <dependency>
+ <groupId>net.sf.saxon</groupId>
+ <artifactId>saxon</artifactId>
+ <version>8.7</version>
+ </dependency>
+ </dependencies>
</plugin>
</plugins>
</build>
diff --git a/protocols/opcua/src/main/java/org/apache/plc4x/protocol/opcua/OpcuaProtocol.java b/protocols/opcua/src/main/java/org/apache/plc4x/protocol/opcua/OpcuaProtocol.java
index dbafedd..1985acc 100644
--- a/protocols/opcua/src/main/java/org/apache/plc4x/protocol/opcua/OpcuaProtocol.java
+++ b/protocols/opcua/src/main/java/org/apache/plc4x/protocol/opcua/OpcuaProtocol.java
@@ -47,7 +47,7 @@ public class OpcuaProtocol implements Protocol {
new LinkedHashMap<>(new MessageFormatParser().parse(schemaInputStream));
InputStream masterDataInputStream = OpcuaProtocol.class.getResourceAsStream(
- "/protocols/opcua/opc-datatypes.mspec");
+ "/protocols/opcua/Opc.Ua.Types.mspec");
if(masterDataInputStream == null) {
throw new GenerationException("Error loading message-format schema for protocol '" + getName() + "'");
}
diff --git a/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec b/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec
index c50a140..e2c8743 100644
--- a/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec
+++ b/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec
@@ -105,38 +105,33 @@
]
-[enum string '-1' 'OpcuaDataType'
- ['IEC61131_NULL' NULL ]
- ['IEC61131_BOOL' BOOL ]
- ['IEC61131_BYTE' BYTE ]
- ['IEC61131_WORD' WORD ]
- ['IEC61131_DWORD' DWORD ]
- ['IEC61131_LWORD' LWORD ]
- ['IEC61131_SINT' SINT ]
- ['IEC61131_INT' INT ]
- ['IEC61131_DINT' DINT ]
- ['IEC61131_LINT' LINT ]
- ['IEC61131_USINT' USINT ]
- ['IEC61131_UINT' UINT ]
- ['IEC61131_UDINT' UDINT ]
- ['IEC61131_ULINT' ULINT ]
- ['IEC61131_REAL' REAL ]
- ['IEC61131_LREAL' LREAL ]
- ['IEC61131_TIME' TIME ]
- ['IEC61131_LTIME' LTIME ]
- ['IEC61131_DATE' DATE ]
- ['IEC61131_LDATE' LDATE ]
- ['IEC61131_TIME_OF_DAY' TIME_OF_DAY ]
- ['IEC61131_LTIME_OF_DAY' LTIME_OF_DAY ]
- ['IEC61131_DATE_AND_TIME' DATE_AND_TIME ]
- ['IEC61131_LDATE_AND_TIME' LDATE_AND_TIME ]
- ['IEC61131_CHAR' CHAR ]
- ['IEC61131_WCHAR' WCHAR ]
- ['IEC61131_STRING' STRING ]
- ['IEC61131_WSTRING' WSTRING ]
+[enum string '-1' 'OpcuaDataType' [uint 8 'variantType']
+ ['IEC61131_NULL' NULL ['0']]
+ ['IEC61131_BOOL' BOOL ['1']]
+ ['IEC61131_BYTE' BYTE ['3']]
+ ['IEC61131_SINT' SINT ['2']]
+ ['IEC61131_INT' INT ['4']]
+ ['IEC61131_DINT' DINT ['6']]
+ ['IEC61131_LINT' LINT ['8']]
+ ['IEC61131_USINT' USINT ['3']]
+ ['IEC61131_UINT' UINT ['5']]
+ ['IEC61131_UDINT' UDINT ['7']]
+ ['IEC61131_ULINT' ULINT ['9']]
+ ['IEC61131_REAL' REAL ['10']]
+ ['IEC61131_LREAL' LREAL ['11']]
+ ['IEC61131_TIME' TIME ['1']]
+ ['IEC61131_LTIME' LTIME ['1']]
+ ['IEC61131_DATE' DATE ['1']]
+ ['IEC61131_LDATE' LDATE ['1']]
+ ['IEC61131_TIME_OF_DAY' TIME_OF_DAY ['1']]
+ ['IEC61131_LTIME_OF_DAY' LTIME_OF_DAY ['1']]
+ ['IEC61131_DATE_AND_TIME' DATE_AND_TIME ['13']]
+ ['IEC61131_LDATE_AND_TIME' LDATE_AND_TIME ['1']]
+ ['IEC61131_CHAR' CHAR ['1']]
+ ['IEC61131_WCHAR' WCHAR ['1']]
+ ['IEC61131_STRING' STRING ['12']]
]
-
[enum string '-1' 'OpcuaIdentifierType'
['s' STRING_IDENTIFIER]
['i' NUMBER_IDENTIFIER]
diff --git a/protocols/opcua/src/main/xslt/opc-types.xsl b/protocols/opcua/src/main/xslt/opc-types.xsl
index 4a74ae2..7402f87 100644
--- a/protocols/opcua/src/main/xslt/opc-types.xsl
+++ b/protocols/opcua/src/main/xslt/opc-types.xsl
@@ -17,7 +17,7 @@
specific language governing permissions and limitations
under the License.
-->
-<xsl:stylesheet version="1.0"
+<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:opc="http://opcfoundation.org/BinarySchema/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -32,9 +32,14 @@
/>
<xsl:param name="services"></xsl:param>
+ <xsl:param name="statusCodes"></xsl:param>
+ <xsl:param name="servicesEnum"></xsl:param>
+ <xsl:variable name="originaldoc" select="/"/>
<xsl:param name="file" select="document($services)"/>
+ <xsl:param name="statusCodeFile" select="unparsed-text($statusCodes)"/>
+ <xsl:param name="servicesEnumFile" select="unparsed-text($servicesEnum)"/>
<xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
@@ -55,7 +60,11 @@
<xsl:apply-templates select="$file/node:UANodeSet/node:UADataType[@BrowseName='ReadResponse']"/>
<xsl:apply-templates select="$file/node:UANodeSet/node:UADataType[@BrowseName='WriteRequest']"/>
<xsl:apply-templates select="$file/node:UANodeSet/node:UADataType[@BrowseName='WriteResponse']"/>
- <xsl:apply-templates select="$file/node:UANodeSet/node:UADataType[@BrowseName='CloseSessionRequest']"/>
+ ['473' CloseSessionRequest
+ [simple RequestHeader 'requestHeader']
+ [reserved uint 7 '0x00']
+ [simple bit 'deleteSubscriptions']
+ ]
<xsl:apply-templates select="$file/node:UANodeSet/node:UADataType[@BrowseName='CloseSessionResponse']"/>
<xsl:apply-templates select="$file/node:UANodeSet/node:UADataType[@BrowseName='CloseSecureChannelRequest']"/>
<xsl:apply-templates select="$file/node:UANodeSet/node:UADataType[@BrowseName='CloseSecureChannelResponse']"/>
@@ -223,7 +232,7 @@
]
['16' VariantXmlElement [bit 'arrayLengthSpecified']
[optional int 32 'arrayLength' 'arrayLengthSpecified']
- [array XmlElement 'value' count 'arrayLength == null ? 1 : arrayLength']
+ [array PascalString 'value' count 'arrayLength == null ? 1 : arrayLength']
]
['17' VariantNodeId [bit 'arrayLengthSpecified']
[optional int 32 'arrayLength' 'arrayLengthSpecified']
@@ -393,7 +402,8 @@
<xsl:apply-templates select="/opc:TypeDictionary/opc:StructuredType[@Name='WriteValue']"/>
]
-
+ <xsl:call-template name="statusCodeParsing"/>
+ <xsl:call-template name="servicesEnumParsing"/>
</xsl:template>
@@ -402,12 +412,11 @@
<xsl:value-of select='@BrowseName'/>
</xsl:variable>
<xsl:choose>
- <xsl:when test="/opc:TypeDictionary/opc:StructuredType[@Name=$browseName]">
+ <xsl:when test="$originaldoc/opc:TypeDictionary/opc:StructuredType[@Name=$browseName]">
<xsl:choose>
<xsl:when test="not(@BrowseName='Vector') and not(substring(@BrowseName,1,1) = '<') and not(number(substring(@BrowseName,1,1)))">
- [type '<xsl:value-of select='@BrowseName'/>'
- <xsl:apply-templates select="/opc:TypeDictionary/opc:StructuredType[@Name=$browseName]"/>
- ]
+ [type '<xsl:value-of select='@BrowseName'/>'
+ <xsl:apply-templates select="$originaldoc/opc:TypeDictionary/opc:StructuredType[@Name=$browseName]"/>]
</xsl:when>
</xsl:choose>
</xsl:when>
@@ -419,13 +428,12 @@
<xsl:value-of select='@BrowseName'/>
</xsl:variable>
<xsl:choose>
- <xsl:when test="/opc:TypeDictionary/opc:StructuredType[@Name=$browseName]">
+ <xsl:when test="$originaldoc/opc:TypeDictionary/opc:StructuredType[@Name=$browseName]">
<xsl:choose>
<xsl:when test="not(Definition) and not(@BrowseName = 'Duration') and not(number(substring(@BrowseName,1,1))) and not(@IsAbstract) and number(substring(@NodeId,3)) > 29">
- ['<xsl:value-of select="number(substring(@NodeId,3)) + 2"/><xsl:text>' </xsl:text><xsl:value-of select='@BrowseName'/><xsl:text>
+ ['<xsl:value-of select="number(substring(@NodeId,3)) + 2"/><xsl:text>' </xsl:text><xsl:value-of select='@BrowseName'/><xsl:text>
</xsl:text>
- <xsl:apply-templates select="/opc:TypeDictionary/opc:StructuredType[@Name=$browseName]"/>
- ]
+ <xsl:apply-templates select="$originaldoc/opc:TypeDictionary/opc:StructuredType[@Name=$browseName]"/>]
</xsl:when>
</xsl:choose>
</xsl:when>
@@ -503,7 +511,7 @@
<xsl:when test="@LengthField">[array <xsl:value-of select="$dataType"/> '<xsl:value-of select="$lowerCaseName"/>' count '<xsl:value-of select="$lowerCaseLengthField"/>']
</xsl:when>
<xsl:otherwise>[<xsl:value-of select="$mspecType"/><xsl:text> </xsl:text><xsl:value-of select="$dataType"/> '<xsl:value-of select="$lowerCaseName"/>']
- </xsl:otherwise>
+ </xsl:otherwise>
</xsl:choose>
</xsl:template>
@@ -556,4 +564,26 @@
</xsl:choose>
</xsl:template>
+ <xsl:template name="statusCodeParsing" >
+ <xsl:variable name="tokenizedLine" select="tokenize($statusCodeFile, '\r\n|\r|\n')" />
+[enum int 32 'OpcuaStatusCodes'
+<xsl:for-each select="$tokenizedLine">
+ <xsl:variable select="tokenize(., ',')" name="values" /> ['<xsl:value-of select="$values[2]"/>' <xsl:value-of select="$values[1]"/>]
+</xsl:for-each>
+]
+</xsl:template>
+
+ <xsl:template name="servicesEnumParsing" >
+ <xsl:variable name="tokenizedLine" select="tokenize($servicesEnumFile, '\r\n|\r|\n')" />
+[enum int 32 'OpcuaNodeIdServices'
+ <xsl:for-each select="$tokenizedLine">
+ <xsl:variable select="tokenize(., ',')" name="values" />
+ <xsl:choose>
+ <xsl:when test="$values[2]">['<xsl:value-of select="$values[2]"/>' <xsl:value-of select="$values[1]"/>]
+ </xsl:when>
+ </xsl:choose>
+ </xsl:for-each>
+]
+ </xsl:template>
+
</xsl:stylesheet>