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 f423f0a  Working on CreateSessionResponse Parsing.
f423f0a is described below

commit f423f0a26e1ece7f073c931f25c205589a2f3cf4
Author: hutcheb <[email protected]>
AuthorDate: Wed Dec 30 20:24:54 2020 -0500

    Working on CreateSessionResponse Parsing.
    
    Almost finished with the connection messages.
---
 .../language/java/JavaLanguageTemplateHelper.java  |   2 +-
 .../resources/templates/java/pojo-template.ftlh    |   8 +-
 .../mspec/parser/MessageFormatListener.java        |   4 +-
 .../apache/plc4x/java/opcua/OpcuaPlcDriver.java    |   8 +-
 .../java/opcua/config/OpcuaConfiguration.java      |   3 +-
 .../java/opcua/protocol/OpcuaProtocolLogic.java    | 229 ++++++++-
 .../plc4x/java/spi/generation/ReadBuffer.java      |  72 ++-
 .../plc4x/java/spi/generation/WriteBuffer.java     |   5 +-
 protocols/opcua/pom.xml                            |  29 +-
 .../src/main/resources/protocols/opcua/opcua.mspec |  74 ++-
 protocols/opcua/src/main/xslt/opc-types.xsl        | 569 +++++++++++++++++++--
 11 files changed, 881 insertions(+), 122 deletions(-)

diff --git 
a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
 
b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
index 81081da..fa7e36f 100644
--- 
a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
+++ 
b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
@@ -412,7 +412,7 @@ public class JavaLanguageTemplateHelper extends 
BaseFreemarkerLanguageTemplateHe
             }
             case STRING: {
                 StringTypeReference stringTypeReference = 
(StringTypeReference) simpleTypeReference;
-                return "io.writeString(" + stringTypeReference.getSizeInBits() 
+ ", \"" +
+                return "io.writeString(" + stringTypeReference.getLength() + 
", \"" +
                     stringTypeReference.getEncoding() + "\", (String) " + 
fieldName + ")";
             }
         }
diff --git 
a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
 
b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
index 822c7f8..7772377 100644
--- 
a/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
+++ 
b/build-utils/language-java/src/main/resources/templates/java/pojo-template.ftlh
@@ -204,8 +204,14 @@ public<#if helper.isDiscriminatedParentTypeDefinition()> 
abstract</#if> class ${
         <#assign discriminatorField = field>
         <#assign simpleTypeReference = discriminatorField.type>
 
-        // Discriminator Field (${discriminatorField.name})
+        // Discriminator Field (${discriminatorField.name})        
+        <#if 
helper.getLanguageTypeNameForTypeReference(discriminatorField.type) = "String">
+            <#assign simpleTypeReference = discriminatorField.type>
+        lengthInBits += ${simpleTypeReference.getLength()};
+        <#else>
+            <#assign simpleTypeReference = discriminatorField.type>
         lengthInBits += ${simpleTypeReference.sizeInBits};
+        </#if>
         <#break>
     <#case "enum">
         <#assign enumField = field>
diff --git 
a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
 
b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
index 0759877..d0b80c1 100644
--- 
a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
+++ 
b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/parser/MessageFormatListener.java
@@ -436,8 +436,8 @@ public class MessageFormatListener extends 
MSpecBaseListener {
         SimpleTypeReference.SimpleBaseType simpleBaseType =
             
SimpleTypeReference.SimpleBaseType.valueOf(ctx.base.getText().toUpperCase());
         // String types need an additional "encoding" field and an optional 
size.
-        if(simpleBaseType == SimpleTypeReference.SimpleBaseType.STRING) {
-            String size = (ctx.length != null) ? 
ctx.length.getText().substring( 1, ctx.length.getText().length() - 1 ) : "-1";
+        if(simpleBaseType == SimpleTypeReference.SimpleBaseType.STRING) {      
      
+            String size = ctx.length.getText().substring( 1, 
ctx.length.getText().length() - 1 );
             String encoding = (ctx.encoding != null) ? ctx.encoding.getText() 
: "UTF-8";
             return new DefaultStringTypeReference(simpleBaseType, size, 
encoding);
         }
diff --git 
a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java
 
b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java
index cb1e8ef..b2c7d1f 100644
--- 
a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java
+++ 
b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java
@@ -121,7 +121,7 @@ public class OpcuaPlcDriver extends 
GeneratedDriverBase<OpcuaAPU> {
     protected ProtocolStackConfigurer<OpcuaAPU> getStackConfigurer() {
         return SingleProtocolStackConfigurer.builder(OpcuaAPU.class, 
OpcuaAPUIO.class)
             .withProtocol(OpcuaProtocolLogic.class)
-            //.withPacketSizeEstimator(ByteLengthEstimator.class)
+            .withPacketSizeEstimator(ByteLengthEstimator.class)
             // Every incoming message is to be treated as a response.
             .withParserArgs(true)
             .littleEndian()
@@ -131,9 +131,9 @@ public class OpcuaPlcDriver extends 
GeneratedDriverBase<OpcuaAPU> {
     /** Estimate the Length of a Packet */
     public static class ByteLengthEstimator implements ToIntFunction<ByteBuf> {
         @Override
-        public int applyAsInt(ByteBuf byteBuf) {
-            if (byteBuf.readableBytes() >= 6) {
-                return byteBuf.getUnsignedShort(byteBuf.readerIndex() + 256) + 
6;
+        public int applyAsInt(ByteBuf byteBuf) {            
+            if (byteBuf.readableBytes() >= 8) {
+                return 
Integer.reverseBytes(byteBuf.getInt(byteBuf.readerIndex() + 4));
             }
             return -1;
         }
diff --git 
a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/config/OpcuaConfiguration.java
 
b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/config/OpcuaConfiguration.java
index bff0452..07f1b47 100644
--- 
a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/config/OpcuaConfiguration.java
+++ 
b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/config/OpcuaConfiguration.java
@@ -25,8 +25,7 @@ import 
org.apache.plc4x.java.spi.configuration.annotations.defaults.IntDefaultVa
 import org.apache.plc4x.java.transport.tcp.TcpTransportConfiguration;
 
 public class OpcuaConfiguration implements Configuration, 
TcpTransportConfiguration {
-
-
+        
     @Override
     public int getDefaultPort() {
         return 12687;
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 cc8be66..4b5593d 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
@@ -32,11 +32,13 @@ import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.spi.values.PlcNull;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
+import org.apache.plc4x.java.opcua.config.OpcuaConfiguration;
 import org.apache.plc4x.java.opcua.readwrite.*;
 import org.apache.plc4x.java.opcua.readwrite.io.*;
 import org.apache.plc4x.java.opcua.readwrite.types.*;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
+import org.apache.plc4x.java.spi.configuration.HasConfiguration;
 import org.apache.plc4x.java.spi.context.DriverContext;
 import org.apache.plc4x.java.spi.generation.ParseException;
 import org.apache.plc4x.java.spi.generation.ReadBuffer;
@@ -66,7 +68,7 @@ import java.nio.charset.StandardCharsets;
  * So we need to limit those.
  * Thus, each request goes to a Work Queue and this Queue ensures, that only 3 
are open at the same time.
  */
-public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> {
+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);
@@ -75,6 +77,10 @@ public class OpcuaProtocolLogic extends 
Plc4xProtocolBase<OpcuaAPU> {
     private RequestTransactionManager tm;
 
     @Override
+    public void setConfiguration(OpcuaConfiguration configuration) {
+    }
+
+    @Override
     public void close(ConversationContext<OpcuaAPU> context) {
         // Nothing to do here ...
     }
@@ -84,7 +90,15 @@ public class OpcuaProtocolLogic extends 
Plc4xProtocolBase<OpcuaAPU> {
         // Only the TCP transport supports login.
         LOGGER.info("Opcua Driver running in ACTIVE mode.");
 
-        OpcuaHelloRequest hello = new OpcuaHelloRequest("F", 63, 0, 65535, 
65535, 2097152, 64, 31, new String("opc.tcp://127.0.0.1:12687/plc4x"));
+        final String endpoint = "opc.tcp://127.0.0.1:12687/plc4x";
+        OpcuaHelloRequest hello = new OpcuaHelloRequest("F",
+                                                        0,
+                                                        65535,
+                                                        65535,
+                                                        2097152,
+                                                        64,
+                                                        endpoint.length(),
+                                                        endpoint);
 
         context.sendRequest(new OpcuaAPU(hello))
             .expectResponse(OpcuaAPU.class, REQUEST_TIMEOUT)
@@ -93,16 +107,213 @@ public class OpcuaProtocolLogic extends 
Plc4xProtocolBase<OpcuaAPU> {
             .handle(opcuaAcknowledgeResponse -> {
                 LOGGER.debug("Got Hello Response Connection Response");
 
-                OpcuaMessage openMessage = new OpcuaMessage("F", 63, 0, 65535, 
65535, 2097152, 64, 31, new String("opc.tcp://127.0.0.1:12687/plc4x"));
-                OpcuaOpenRequest openrequest = new OpcuaOpenRequest("F", 63, 
0, 65535, 65535, 2097152, 64, 31, new 
String("opc.tcp://127.0.0.1:12687/plc4x"));
+                NodeIdTwoByte authenticationToken = new 
NodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte,
+                                                                    new 
TwoByteNodeId((short) 0));
+
+                ExpandedNodeId expandedNodeId = new 
ExpandedNodeIdFourByte(NodeIdType.nodeIdTypeFourByte,
+                                                                    false,
+                                                                    false,
+                                                                    new 
FourByteNodeId((short) 0, 466),
+                                                                    new 
PascalString(-1,""),
+                                                                    1L);
+
+                ExpandedNodeId extExpandedNodeId = new 
ExpandedNodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte,
+                                                                    false,
+                                                                    false,
+                                                                    new 
TwoByteNodeId((short) 0),
+                                                                    null,
+                                                                    null);
+
+                ExtensionObject extObject = new 
ExtensionObject(extExpandedNodeId, (short) 0);
+
+                RequestHeader requestHeader = new 
RequestHeader(authenticationToken,
+                                                                
System.currentTimeMillis() * 10000L,
+                                                                0L,
+                                                                0L,
+                                                                new 
PascalString(-1, ""),
+                                                                10000L,
+                                                                extObject);
+
+
+
+                OpenSecureChannelRequest openrequest = new 
OpenSecureChannelRequest((byte) 1,
+                                                                (byte) 0,
+                                                                requestHeader,
+                                                                0L,
+                                                                
SecurityTokenRequestType.securityTokenRequestTypeIssue,
+                                                                
MessageSecurityMode.messageSecurityModeNone,
+                                                                new 
PascalString(-1, ""),
+                                                                36000000);
 
 
-                context.sendRequest(new OpcuaAPU(hello))
+                String nameSpace = 
"http://opcfoundation.org/UA/SecurityPolicy#None";;
+                OpcuaOpenRequest openRequest = new OpcuaOpenRequest("F",
+                                                                0,
+                                                                
nameSpace.length(),
+                                                                nameSpace,
+                                                                -1,
+                                                                "",
+                                                                -1,
+                                                                "",
+                                                                1,
+                                                                1,
+                                                                openrequest);
+
+                context.sendRequest(new OpcuaAPU(openRequest))
                     .expectResponse(OpcuaAPU.class, REQUEST_TIMEOUT)
-                    .check(p -> p.getMessage() instanceof 
OpcuaAcknowledgeResponse)
-                    .unwrap(p -> (OpcuaAcknowledgeResponse) p.getMessage())
-                    .handle(opcuaAcknowledgeResponse -> {
-                        LOGGER.debug("Got Hello Response Connection Response");
+                    .check(p -> p.getMessage() instanceof OpcuaOpenResponse)
+                    .unwrap(p -> (OpcuaOpenResponse) p.getMessage())
+                    .handle(opcuaOpenResponse -> {
+                        LOGGER.debug("Got Secure Response Connection 
Response");
+                        OpenSecureChannelResponse openSecureChannelResponse = 
(OpenSecureChannelResponse) opcuaOpenResponse.getMessage();
+                        Integer tokenId = (int) 
openSecureChannelResponse.getSecurityToken().getTokenId();
+                        Integer channelId = (int) 
openSecureChannelResponse.getSecurityToken().getChannelId();
+                        Integer nextSequenceNumber = 
opcuaOpenResponse.getSequenceNumber() + 1;
+                        Integer nextRequestId = 
opcuaOpenResponse.getRequestId() + 1;
+
+                        NodeIdTwoByte authenticationToken2 = new 
NodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte,                                     
                                       
+                                                                            
new TwoByteNodeId((short) 0));
+
+                        ExpandedNodeId extExpandedNodeId2 = new 
ExpandedNodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte,
+                                                                            
false,
+                                                                            
false,
+                                                                            
new TwoByteNodeId((short) 0),
+                                                                            
null,
+                                                                            
null);
+
+                        ExtensionObject extObject2 = new 
ExtensionObject(extExpandedNodeId2, (short) 0);
+
+                        RequestHeader requestHeader2 = new 
RequestHeader(authenticationToken2,
+                                                                        
System.currentTimeMillis() * 10000L,
+                                                                        0L,
+                                                                        0L,
+                                                                        new 
PascalString(-1, ""),
+                                                                        10000L,
+                                                                        
extObject2);
+
+                        String applicationUri = 
"urn:eclipse:milo:plc4x:client";
+                        String productUri = "urn:eclipse:milo:plc4x:client";
+                        String text = "eclipse milo opc-ua client of the 
apache PLC4X:PLC4J project";
+                        LocalizedText applicationName = new 
LocalizedText((short) 0,
+                                                                          true,
+                                                                          true,
+                                                                          new 
PascalString(2, "en"),
+                                                                          new 
PascalString(text.length(), text));
+                        PascalString gatewayServerUri = new PascalString(-1, 
"");
+                        PascalString discoveryProfileUri = new 
PascalString(-1, "");
+                        int noOfDiscoveryUrls = -1;
+                        PascalString discoveryUrls = null;
+
+                        ApplicationDescription clientDescription = new 
ApplicationDescription(new PascalString(applicationUri.length(), 
applicationUri),
+                                                                               
     new PascalString(productUri.length(), productUri),
+                                                                               
     applicationName,
+                                                                               
     ApplicationType.applicationTypeClient,
+                                                                               
     gatewayServerUri,
+                                                                               
     discoveryProfileUri,
+                                                                               
     noOfDiscoveryUrls,
+                                                                               
     discoveryUrls);
+
+                        String endpoint2 = "opc.tcp://127.0.0.1:12687/plc4x";
+                        String sessionName = "UaSession:eclipse milo opc-ua 
client of the apache PLC4X:PLC4J project:" + System.currentTimeMillis();
+                        String clientNonce = "764287368237654873259869867";
+
+                        CreateSessionRequest createSessionRequest = new 
CreateSessionRequest((byte) 1,
+                                                                        (byte) 
0,
+                                                                        
requestHeader2,
+                                                                        
clientDescription,
+                                                                        new 
PascalString(-1, ""),
+                                                                        new 
PascalString(endpoint2.length(), endpoint2),
+                                                                        new 
PascalString(sessionName.length(), sessionName),
+                                                                        new 
PascalString(clientNonce.length(), clientNonce),
+                                                                        new 
PascalString(-1, ""),
+                                                                        
120000L,
+                                                                        0L);
+
+                        OpcuaMessageRequest messageRequest = new 
OpcuaMessageRequest("F",
+                                                                        
channelId,
+                                                                        
tokenId,
+                                                                        
nextSequenceNumber,
+                                                                        
nextRequestId,
+                                                                        
createSessionRequest);
+
+                        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 Create Session Response 
Connection Response");
+                                CreateSessionResponse createSessionResponse = 
(CreateSessionResponse) opcuaMessageResponse.getMessage();
+
+                                NodeIdTwoByte authenticationToken3 = 
(NodeIdTwoByte) createSessionResponse.getAuthenticationToken();
+                                Integer tokenId2 = (int) 
opcuaMessageResponse.getSecureTokenId();
+                                Integer channelId2 = (int) 
opcuaMessageResponse.getSecureChannelId();
+                                Integer nextSequenceNumber2 = 
opcuaMessageResponse.getSequenceNumber() + 1;
+                                Integer nextRequestId2 = 
opcuaMessageResponse.getRequestId() + 1;
+
+
+                                ExpandedNodeId extExpandedNodeId3 = new 
ExpandedNodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte,
+                                                                               
     false,
+                                                                               
     false,
+                                                                               
     new TwoByteNodeId((short) 0),
+                                                                               
     null,
+                                                                               
     null);
+
+                                ExtensionObject extObject3 = new 
ExtensionObject(extExpandedNodeId3, (short) 0);
+
+                                RequestHeader requestHeader3 = new 
RequestHeader(authenticationToken3,
+                                                                               
 System.currentTimeMillis() * 10000L,
+                                                                               
 1L,
+                                                                               
 0L,
+                                                                               
 new PascalString(-1, ""),
+                                                                               
 10000L,
+                                                                               
 extObject3);
+
+                                SignatureData clientSignature = new 
SignatureData(new PascalString(-1, ""), new PascalString(-1, ""));
+
+                                SignedSoftwareCertificate[] 
signedSoftwareCertificate = null;
+
+                                ExpandedNodeId extExpandedNodeId4 = new 
ExpandedNodeIdFourByte(NodeIdType.nodeIdTypeFourByte,
+                                                                               
     false,
+                                                                               
     false,
+                                                                               
     new FourByteNodeId((short) 0,  321),
+                                                                               
     null,
+                                                                               
     null);
+
+
+                                ExtensionObject useridentityToken = new 
ExtensionObject(extExpandedNodeId4, (short) 0);
+
+                                String endpoint3 = 
"opc.tcp://127.0.0.1:12687/plc4x";
+
+                                ActivateSessionRequest activateSessionRequest 
= new ActivateSessionRequest((byte) 1,
+                                                                               
 (byte) 0,
+                                                                               
 requestHeader3,
+                                                                               
 clientSignature,
+                                                                               
 0,
+                                                                               
 signedSoftwareCertificate,
+                                                                               
 0,
+                                                                               
 null,
+                                                                               
 useridentityToken,
+                                                                               
 clientSignature);
+
+                                OpcuaMessageRequest activateMessageRequest = 
new OpcuaMessageRequest("F",
+                                                                               
 channelId2,
+                                                                               
 tokenId2,
+                                                                               
 nextSequenceNumber2,
+                                                                               
 nextRequestId2,
+                                                                               
 activateSessionRequest);
+
+                                context.sendRequest(new 
OpcuaAPU(activateMessageRequest))
+                                    .expectResponse(OpcuaAPU.class, 
REQUEST_TIMEOUT)
+                                    .check(p -> p.getMessage() instanceof 
OpcuaMessageResponse)
+                                    .unwrap(p -> (OpcuaMessageResponse) 
p.getMessage())
+                                    .handle(opcuaActivateResponse -> {
+                                        LOGGER.debug("Got Activate Session 
Response Connection Response");
+
+                                    });
+
+
+                            });
+
                     });
             });
     }
diff --git 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
index 9635c3a..b534ec2 100644
--- 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
+++ 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBuffer.java
@@ -28,8 +28,13 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.nio.charset.Charset;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class ReadBuffer {
 
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(ReadBuffer.class);
+
     private final MyDefaultBitInput bi;
     private final boolean littleEndian;
     private final long totalBytes;
@@ -39,6 +44,7 @@ public class ReadBuffer {
     }
 
     public ReadBuffer(byte[] input, boolean littleEndian) {
+        LOGGER.info("Creating read buffer " + input.length)
         ArrayByteInput abi = new ArrayByteInput(input);
         this.bi = new MyDefaultBitInput(abi);
         this.littleEndian = littleEndian;
@@ -82,7 +88,9 @@ public class ReadBuffer {
 
     public boolean readBit() throws ParseException {
         try {
-            return bi.readBoolean();
+            boolean ret = bi.readBoolean();
+            LOGGER.info("Reading Bit:- " + ret);
+            return ret;
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
         }
@@ -96,7 +104,9 @@ public class ReadBuffer {
             throw new ParseException("unsigned byte can only contain max 4 
bits");
         }
         try {
-            return bi.readByte(true, bitLength);
+            byte ret = bi.readByte(true, bitLength);
+            LOGGER.info("Reading Unsigned Byte:- " + ret);
+            return ret;
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
         }
@@ -111,7 +121,9 @@ public class ReadBuffer {
         }
         try {
             // No need to flip here as we're only reading one byte.
-            return bi.readShort(true, bitLength);
+            short ret =  bi.readShort(true, bitLength);
+            LOGGER.info("Reading Unsigned Short:- " + ret);
+            return ret;
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
         }
@@ -127,9 +139,13 @@ public class ReadBuffer {
         try {
             if (littleEndian) {
                 int intValue = bi.readInt(true, bitLength);
-                return Integer.reverseBytes(intValue) >>> 16;
+                int ret =  Integer.reverseBytes(intValue) >>> 16;
+                LOGGER.info("Reading Unsigned Int:- " + ret);
+                return ret;
             }
-            return bi.readInt(true, bitLength);
+            int ret =  bi.readInt(true, bitLength);
+            LOGGER.info("Reading Unsigned Int:- " + ret);
+            return ret;
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
         }
@@ -145,9 +161,13 @@ public class ReadBuffer {
         try {
             if (littleEndian) {
                 final long longValue = bi.readLong(true, bitLength);
-                return Long.reverseBytes(longValue) >>> 32;
+                long ret = Long.reverseBytes(longValue) >>> 32;
+                LOGGER.info("Reading Unsigned Long:- " + ret);
+                return ret;
             }
-            return bi.readLong(true, bitLength);
+            long ret =  bi.readLong(true, bitLength);
+            LOGGER.info("Reading Unsigned Long:- " + ret);
+            return ret;
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
         }
@@ -186,7 +206,9 @@ public class ReadBuffer {
             throw new ParseException("byte can only contain max 8 bits");
         }
         try {
-            return bi.readByte(false, bitLength);
+            byte ret = bi.readByte(false, bitLength);
+            LOGGER.info("Reading Byte:- " + ret);
+            return ret;
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
         }
@@ -201,9 +223,13 @@ public class ReadBuffer {
         }
         try {
             if (littleEndian) {
-                return Short.reverseBytes(bi.readShort(false, bitLength));
+                short ret =  Short.reverseBytes(bi.readShort(false, 
bitLength));
+                LOGGER.info("Reading Short:- " + ret);
+                return ret;
             }
-            return bi.readShort(false, bitLength);
+            short ret = bi.readShort(false, bitLength);
+            LOGGER.info("Reading Short:- " + ret);
+            return ret;
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
         }
@@ -218,9 +244,13 @@ public class ReadBuffer {
         }
         try {
             if (littleEndian) {
-                return Integer.reverseBytes(bi.readInt(false, bitLength));
+                int ret =  Integer.reverseBytes(bi.readInt(false, bitLength));
+                LOGGER.info("Reading Integer:- " + ret);
+                return ret;
             }
-            return bi.readInt(false, bitLength);
+            int ret = bi.readInt(false, bitLength);
+            LOGGER.info("Reading Int:- " + ret);
+            return ret;
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
         }
@@ -235,9 +265,13 @@ public class ReadBuffer {
         }
         try {
             if (littleEndian) {
-                return Long.reverseBytes(bi.readLong(false, bitLength));
+                long ret = Long.reverseBytes(bi.readLong(false, bitLength));
+                LOGGER.info("Reading Read Long:- " + ret);
+                return ret;
             }
-            return bi.readLong(false, bitLength);
+            long ret = bi.readLong(false, bitLength);
+            LOGGER.info("Reading Read Long:- " + ret);
+            return ret;
         } catch (IOException e) {
             throw new ParseException("Error reading", e);
         }
@@ -285,7 +319,9 @@ public class ReadBuffer {
     public double readDouble(int bitLength) throws ParseException {
         if(bitLength == 64) {
             long longValue = readLong(64);
-            return Double.longBitsToDouble(longValue);
+            double ret = Double.longBitsToDouble(longValue);
+            LOGGER.info("Reading Double:- " + ret);
+            return ret;
         } else {
             throw new UnsupportedOperationException("unsupported bit length 
(only 64 supported)");
         }
@@ -298,14 +334,16 @@ public class ReadBuffer {
     public String readString(int bitLength, String encoding) {
         byte[] strBytes = new byte[bitLength / 8];
         for (int i = 0; (i < (bitLength / 8)) && hasMore(8); i++) {
-            try {                
+            try {
                 strBytes[i] = readByte(8);
             } catch (Exception e) {
                 throw new PlcRuntimeException(e);
             }
         }
         //replaceAll function removes and leading ' char or hypens.
-        return new String(strBytes, 
Charset.forName(encoding.replaceAll("[^a-zA-Z0-9]","")));
+        String ret =  new String(strBytes, 
Charset.forName(encoding.replaceAll("[^a-zA-Z0-9]","")));
+        LOGGER.info("Reading String:- " + ret);
+        return ret;
     }
 
 }
diff --git 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
index a4424cf..1f6fa85 100644
--- 
a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
+++ 
b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBuffer.java
@@ -190,7 +190,7 @@ public class WriteBuffer {
         }
     }
 
-    public void writeInt(int bitLength, int value) throws ParseException {     
   
+    public void writeInt(int bitLength, int value) throws ParseException {
         if(bitLength <= 0) {
             throw new ParseException("int must contain at least 1 bit");
         }
@@ -257,8 +257,7 @@ public class WriteBuffer {
         final byte[] bytes = value.getBytes(Charset.forName(encoding));
         try {
             int count = 0;
-            for (byte aByte : bytes) {
-                System.out.println(count);
+            for (byte aByte : bytes) {                
                 count += 1;
                 bo.writeByte(false, 8, aByte);
             }
diff --git a/protocols/opcua/pom.xml b/protocols/opcua/pom.xml
index ecfa277..aeb3acb 100644
--- a/protocols/opcua/pom.xml
+++ b/protocols/opcua/pom.xml
@@ -55,6 +55,25 @@
             </executions>
           </plugin>
           <plugin>
+            <groupId>com.googlecode.maven-download-plugin</groupId>
+            <artifactId>download-maven-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>fetch-opc-discriminators</id>
+                <phase>generate-resources</phase>
+                <goals>
+                  <goal>wget</goal>
+                </goals>
+                <configuration>
+                  
<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>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
             <groupId>org.codehaus.mojo</groupId>
             <artifactId>xml-maven-plugin</artifactId>
             <version>1.0.2</version>
@@ -70,7 +89,7 @@
               <transformationSets>
                 <transformationSet>
                   <dir>${project.build.directory}/downloads</dir>
-                  <includes>*.xml</includes>
+                  <includes>opc-datatypes.xml</includes>
                   <stylesheet>src/main/xslt/opc-types.xsl</stylesheet>
                   
<outputDir>${project.build.outputDirectory}/protocols/opcua</outputDir>
                   <fileMappers>
@@ -78,6 +97,12 @@
                       <targetExtension>.mspec</targetExtension>
                     </fileMapper>
                   </fileMappers>
+                  <parameters>
+                    <parameter>
+                      <name>services</name>
+                      
<value>${project.build.directory}/downloads/opc-discriminators.xml</value>
+                    </parameter>
+                  </parameters>                  
                   <outputProperties>
                     <outputProperty>
                       <name>indent</name>
@@ -86,7 +111,7 @@
                   </outputProperties>
                 </transformationSet>
               </transformationSets>
-            </configuration>                      
+            </configuration>
           </plugin>
       </plugins>
   </build>
diff --git a/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec 
b/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec
index 85cc054..d4406bf 100644
--- a/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec
+++ b/protocols/opcua/src/main/resources/protocols/opcua/opcua.mspec
@@ -27,15 +27,15 @@
     [discriminator string '24'          'messageType']
     [typeSwitch 'messageType','response'
         ['HEL','false'     OpcuaHelloRequest
-            [simple          string '8'            'chunk']
-            [simple          int 32              'messageSize']
+            [simple          string '1 * 8'            'chunk']
+            [implicit          int 32             'messageSize' 
'lengthInBytes']
             [simple          int 32             'version']
             [simple          int 32             'receiveBufferSize']
             [simple          int 32             'sendBufferSize']
             [simple          int 32             'maxMessageSize']
             [simple          int 32             'maxChunkCount']
             [simple          int 32             'stringLength']
-            [simple          string 'stringLength'         'endpoint']
+            [simple          string 'stringLength * 8' 'endpoint']
         ]
         ['HEL','true'     OpcuaHelloResponse
         ]
@@ -43,7 +43,7 @@
         ]
         ['ACK','true'     OpcuaAcknowledgeResponse
             [simple          string '8'            'chunk']
-            [simple          int 32             'messageSize']
+            [implicit          int 32             'messageSize' 
'lengthInBytes']
             [simple          int 32             'version']
             [simple          int 32             'receiveBufferSize']
             [simple          int 32             'sendBufferSize']
@@ -56,63 +56,57 @@
         ]
         ['OPN','false'     OpcuaOpenRequest
             [simple          string '8'         'chunk']
-            [simple          int 32             'messageSize']
+            [implicit          int 32             'messageSize' 
'lengthInBytes']
             [simple          int 32             'secureChannelId']
             [simple          int 32             'securityPolicyUriSize']
-            [simple          string 'securityPolicyUriSize == -1 ? 0 : 
securityPolicyUriSize'          'endpoint']
+            [simple          string 'securityPolicyUriSize == -1 ? 0 : 
securityPolicyUriSize * 8'          'endpoint']
             [simple          int 32             'senderCertificateSize']
-            [simple          string 'senderCertificateSize == -1 ? 0 : 
senderCertificateSize'             'senderCertificate']
+            [simple          string 'senderCertificateSize == -1 ? 0 : 
senderCertificateSize * 8'             'senderCertificate']
             [simple          int 32             
'receiverCertificateThumbprintSize']
-            [simple          string 'receiverCertificateThumbprintSize == -1 ? 
0 : receiverCertificateThumbprintSize'             
'receiverCertificateThumbprint']
+            [simple          string 'receiverCertificateThumbprintSize == -1 ? 
0 : receiverCertificateThumbprintSize * 8'             
'receiverCertificateThumbprint']
             [simple          int 32             'sequenceNumber']
             [simple          int 32             'requestId']
             [simple          OpcuaMessage       'message']
        ]
        ['OPN','true'     OpcuaOpenResponse
+           [simple          string '8'         'chunk']
+           [implicit          int 32             'messageSize' 'lengthInBytes']
+           [simple          int 32             'secureChannelId']
+           [simple          int 32             'securityPolicyUriSize']
+           [simple          string 'securityPolicyUriSize == -1 ? 0 : 
securityPolicyUriSize * 8'          'endpoint']
+           [simple          int 32             'senderCertificateSize']
+           [simple          string 'senderCertificateSize == -1 ? 0 : 
senderCertificateSize * 8'             'senderCertificate']
+           [simple          int 32             
'receiverCertificateThumbprintSize']
+           [simple          string 'receiverCertificateThumbprintSize == -1 ? 
0 : receiverCertificateThumbprintSize * 8'             
'receiverCertificateThumbprint']
+           [simple          int 32             'sequenceNumber']
+           [simple          int 32             'requestId']
+           [simple          OpcuaMessage       'message']
        ]
        ['CLO','false'     OpcuaCloseRequest
        ]
        ['CLO','true'     OpcuaCloseResponse
        ]
        ['MSG','false'     OpcuaMessageRequest
+           [simple          string '8'         'chunk']
+           [implicit        int 32             'messageSize' 'lengthInBytes']
+           [simple          int 32             'secureChannelId']
+           [simple          int 32             'secureTokenId']
+           [simple          int 32             'sequenceNumber']
+           [simple          int 32             'requestId']
+           [simple          OpcuaMessage       'message']
        ]
        ['MSG','true'     OpcuaMessageResponse
+           [simple          string '8'         'chunk']
+           [implicit        int 32             'messageSize' 'lengthInBytes']
+           [simple          int 32             'secureChannelId']
+           [simple          int 32             'secureTokenId']
+           [simple          int 32             'sequenceNumber']
+           [simple          int 32             'requestId']
+           [simple          OpcuaMessage       'message']
        ]
     ]
 ]
 
-[discriminatedType 'OpcuaMessage'
-    [simple         int 8   'nodeIdEncodingMask' ]
-    [simple         int 8   'nodeIdNamespaceIndex' ]
-    [discriminator  int 16   'nodeId' ]
-    [typeSwitch 'nodeId'
-        ['0x01BE'    OpcuaOpenSecureChannelRequest
-            [simple         int 8   'authenticationToken' ]
-            [simple         int 64   'timestamp' ]
-            [simple         int 32   'requestHandle' ]
-            [simple         bit   'serviceLevelSymbolicId' ]
-            [simple         bit   'serviceLevelLocalizedText' ]
-            [simple         bit   'serviceLevelAdditionalInfo' ]
-            [simple         bit   'serviceLevelStatusCode' ]
-            [simple         bit   'serviceLevelDiagnostics' ]
-            [simple         bit   'operationLevelSymbolcId' ]
-            [simple         bit   'operationLevelLocalizedText' ]
-            [simple         bit   'operationLevelAdditionalInfo' ]
-            [simple         bit   'operationLevelStatusCode' ]
-            [simple         bit   'operationLevelDiagnostics' ]
-            [reserved       int 22 '0x000000'] // padding
-            [simple         int 32   'auditEntryId' ]
-            [simple         int 32   'timeoutHint' ]
-            [simple         int 24   'additionalHeader' ]
-            [simple         int 32   'clientProtocolVersion' ]
-            [simple         int 32   'seecurityTokenRequestType' ]
-            [simple         int 32   'messageSecurityMode' ]
-            [simple         int 32   'clientNonceSize' ]
-            [simple         string 'clientNonceSize == -1 ? 0 : 
clientNonceSize'          'clientNonce']
-            [simple         int 32   'requestedLifetime' ]
-        ]
-    ]
-]
 
 [enum string '-1' 'OpcuaDataType'
     ['IEC61131_NULL' NULL ]
diff --git a/protocols/opcua/src/main/xslt/opc-types.xsl 
b/protocols/opcua/src/main/xslt/opc-types.xsl
index 8ec49e4..a36a514 100644
--- a/protocols/opcua/src/main/xslt/opc-types.xsl
+++ b/protocols/opcua/src/main/xslt/opc-types.xsl
@@ -22,7 +22,8 @@
                 xmlns:opc="http://opcfoundation.org/BinarySchema/";
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
                 xmlns:ua="http://opcfoundation.org/UA/";
-                xmlns:tns="http://opcfoundation.org/UA/";>
+                xmlns:tns="http://opcfoundation.org/UA/";
+                xmlns:node="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd";>
 
     <xsl:output
         method="text"
@@ -30,36 +31,532 @@
         encoding="utf-8"
     />
 
-    <xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'" />
-    <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
+    <xsl:param name="services"></xsl:param>
+
+
+    <xsl:param name="file" select="document($services)"/>
+
+    <xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'"/>
+    <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
 
     <xsl:template match="/">
-//
-// 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.
-//
-        <xsl:apply-templates select="opc:TypeDictionary"/>
+[discriminatedType 'OpcuaMessage'
+    [simple         int 8   'OPCUAnodeIdEncodingMask' ]
+    [simple         int 8   'OPCUAnodeIdNamespaceIndex' ]
+    [discriminator  int 16   'OPCUAnodeId' ]
+    [typeSwitch 'OPCUAnodeId'
+        <xsl:apply-templates 
select="$file/node:UANodeSet/node:UADataType[@BrowseName='OpenSecureChannelRequest']"/>
+        <xsl:apply-templates 
select="$file/node:UANodeSet/node:UADataType[@BrowseName='OpenSecureChannelResponse']"/>
+        <xsl:apply-templates 
select="$file/node:UANodeSet/node:UADataType[@BrowseName='CreateSessionRequest']"/>
+        <xsl:apply-templates 
select="$file/node:UANodeSet/node:UADataType[@BrowseName='CreateSessionResponse']"/>
+        <xsl:apply-templates 
select="$file/node:UANodeSet/node:UADataType[@BrowseName='ActivateSessionRequest']"/>
+        <xsl:apply-templates 
select="$file/node:UANodeSet/node:UADataType[@BrowseName='ActivateSessionResponse']"/>
+        <xsl:apply-templates 
select="$file/node:UANodeSet/node:UADataType[@BrowseName='ReadRequest']"/>
+        <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']"/>
+        <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']"/>
+    ]
+]
+
+[type 'RequestHeader'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='RequestHeader']"/>
+]
+[enum int 32 'SecurityTokenRequestType'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:EnumeratedType[@Name='SecurityTokenRequestType']"/>
+]
+[enum int 32 'MessageSecurityMode'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:EnumeratedType[@Name='MessageSecurityMode']"/>
+]
+[type 'ResponseHeader'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='ResponseHeader']"/>
+]
+[type 'ChannelSecurityToken'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='ChannelSecurityToken']"/>
+]
+
+[type 'DiagnosticInfo'
+    [simple bit 'symbolicIdSpecified']
+    [simple bit 'namespaceURISpecified']
+    [simple bit 'localizedTextSpecified']
+    [simple bit 'localeSpecified']
+    [simple bit 'additionalInfoSpecified']
+    [simple bit 'innerStatusCodeSpecified']
+    [simple bit 'innerDiagnosticInfoSpecified']
+    [simple bit 'reserved1']
+    [optional int 32 'symbolicId' 'symbolicIdSpecified']
+    [optional int 32 'namespaceURI' 'namespaceURISpecified']
+    [optional int 32 'locale' 'localizedTextSpecified']
+    [optional int 32 'localizedText' 'localeSpecified']
+    [optional PascalString 'additionalInfo' 'additionalInfoSpecified']
+    [optional StatusCode 'innerStatusCode' 'innerStatusCodeSpecified']
+    [optional DiagnosticInfo 'innerDiagnosticInfo' 
'innerDiagnosticInfoSpecified']
+]
+
+[type 'StatusCode'
+    [simple int 32 'statusCode']
+]
+
+[type 'XmlElement'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='XmlElement']"/>
+]
+
+[type 'DataValue'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='DataValue']"/>
+]
+
+[enum int 6 'NodeIdType'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:EnumeratedType[@Name='NodeIdType']"/>
+]
+
+[type 'TwoByteNodeId'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='TwoByteNodeId']"/>
+]
+
+[type 'FourByteNodeId'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='FourByteNodeId']"/>
+]
+
+[type 'NumericNodeId'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='NumericNodeId']"/>
+]
+
+[type 'StringNodeId'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='StringNodeId']"/>
+]
+
+[type 'GuidNodeId'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='GuidNodeId']"/>
+]
+
+[type 'ByteStringNodeId'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='ByteStringNodeId']"/>
+]
+
+[type 'DataValue'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='DataValue']"/>
+]
+
+[discriminatedType 'Variant'
+    [discriminator uint 6 'VariantType']
+    [typeSwitch 'VariantType'
+        ['1' VariantBoolean
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array bit 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['2' VariantSByte
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array int 8 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['3' VariantByte
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array uint 8 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['4' VariantInt16
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array int 16 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['5' VariantUInt16
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array uint 16 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['6' VariantInt32
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array int 32 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['7' VariantUInt32
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array uint 32 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['8' VariantInt64
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array int 64 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['9' VariantUInt64
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array uint 64 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['10' VariantFloat
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array float 8.23 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['11' VariantDouble
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array float 11.52 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['12' VariantString
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array PascalString  'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['13' VariantDateTime
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array int 64 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['14' VariantGuid
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array string '-1' 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['15' VariantByteString
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array PascalString 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['16' VariantXmlElement
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array XmlElement 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['17' VariantNodeId
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array NodeId 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['18' VariantExpandedNodeId
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array ExpandedNodeId 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['19' VariantStatusCode
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array StatusCode 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['20' VariantQualifiedName
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array QualifiedName 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['21' VariantLocalizedText
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array LocalizedText 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['22' VariantExtensionObject
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array ExtensionObject 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['23' VariantDataValue
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array DataValue 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['24' VariantVariant
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array Variant 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+        ['25' VariantDiagnosticInfo
+
+            [simple bit 'ArrayDimensionsSpecified']
+            [simple bit 'ArrayLengthSpecified']
+            [simple int 32 'arrayLength']
+            [array DiagnosticInfo 'value' count 'arrayLength']
+            [simple int 32 'noOfArrayDimensions']
+            [array bit 'arrayDimensions' count 'noOfArrayDimensions']
+        ]
+    ]
+]
+
+[discriminatedType 'NodeId'
+    [reserved int 2 '0x00']
+    [simple NodeIdType 'nodeIdType']
+    [typeSwitch 'nodeIdType'
+        ['NodeIdType.nodeIdTypeTwoByte' NodeIdTwoByte
+            [simple TwoByteNodeId 'id']
+        ]
+        ['NodeIdType.nodeIdTypeFourByte' NodeIdFourByte
+            [simple FourByteNodeId 'id']
+        ]
+        ['NodeIdType.nodeIdTypeNumeric' NodeIdNumeric
+            [simple NumericNodeId 'id']
+        ]
+        ['NodeIdType.nodeIdTypeString' NodeIdString
+            [simple StringNodeId 'id']
+        ]
+        ['NodeIdType.nodeIdTypeGuid' NodeIdGuid
+            [simple GuidNodeId 'id']
+        ]
+        ['NodeIdType.nodeIdTypeByteString' NodeIdByteString
+            [simple ByteStringNodeId 'id']
+        ]
+    ]
+]
+
+[discriminatedType 'ExpandedNodeId'
+    [simple NodeIdType 'nodeIdType']
+    [typeSwitch 'nodeIdType'
+        ['NodeIdType.nodeIdTypeTwoByte' ExpandedNodeIdTwoByte
+            [simple bit 'serverIndexSpecified']
+            [simple bit 'namespaceURISpecified']
+            [simple TwoByteNodeId 'id']
+            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
+            [optional uint 32 'serverIndex' 'serverIndexSpecified']
+        ]
+        ['NodeIdType.nodeIdTypeFourByte' ExpandedNodeIdFourByte
+            [simple bit 'serverIndexSpecified']
+            [simple bit 'namespaceURISpecified']
+            [simple FourByteNodeId 'id']
+            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
+            [optional uint 32 'serverIndex' 'serverIndexSpecified']
+        ]
+        ['NodeIdType.nodeIdTypeNumeric' ExpandedNodeIdNumeric
+            [simple bit 'serverIndexSpecified']
+            [simple bit 'namespaceURISpecified']
+            [simple NumericNodeId 'id']
+            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
+            [optional uint 32 'serverIndex' 'serverIndexSpecified']
+        ]
+        ['NodeIdType.nodeIdTypeString' ExpandedNodeIdString
+            [simple bit 'serverIndexSpecified']
+            [simple bit 'namespaceURISpecified']
+            [reserved uint 6 '0x00']
+            [simple StringNodeId 'id']
+            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
+            [optional uint 32 'serverIndex' 'serverIndexSpecified']
+        ]
+        ['NodeIdType.nodeIdTypeGuid' ExpandedNodeIdGuid
+            [simple bit 'serverIndexSpecified']
+            [simple bit 'namespaceURISpecified']
+            [simple GuidNodeId 'id']
+            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
+            [optional uint 32 'serverIndex' 'serverIndexSpecified']
+        ]
+        ['NodeIdType.nodeIdTypeByteString' ExpandedNodeIdByteString
+            [simple bit 'serverIndexSpecified']
+            [simple bit 'namespaceURISpecified']
+            [simple ByteStringNodeId 'id']
+            [optional PascalString 'namespaceURI' 'namespaceURISpecified']
+            [optional uint 32 'serverIndex' 'serverIndexSpecified']
+        ]
+    ]
+]
+
+[type 'ExtensionObject'
+    [simple ExpandedNodeId 'nodeId']
+    [simple uint 8 'encodingMask']
+]
+
+[type 'PascalString'
+    [simple int 32 'stringLength']
+    [simple string 'stringLength == -1 ? 0 : stringLength * 8' 'stringValue']
+]
+
+[type 'LocalizedText'
+    [simple uint 6 'reserved1']
+    [simple bit 'localeSpecified']
+    [simple bit 'textSpecified']
+    [optional PascalString 'Locale' 'localeSpecified']
+    [optional PascalString 'Text' 'textSpecified']
+]
+
+[type 'QualifiedName'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='QualifiedName']"/>
+]
+
+[type 'ApplicationDescription'
+    [simple PascalString 'applicationUri']
+    [simple PascalString 'productUri']
+    [simple LocalizedText 'applicationName']
+    [simple ApplicationType 'applicationType']
+    [simple PascalString 'gatewayServerUri']
+    [simple PascalString 'discoveryProfileUri']
+    [simple int 32 'noOfDiscoveryUrls']
+    [optional PascalString 'discoveryUrls' 'noOfDiscoveryUrls > 0']
+]
+
+[type 'EndpointDescription'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='EndpointDescription']"/>
+]
+
+[type 'SignedSoftwareCertificate'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='SignedSoftwareCertificate']"/>
+]
+
+
+[type 'SignatureData'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='SignatureData']"/>
+]
+
+
+[enum int 32 'ApplicationType'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:EnumeratedType[@Name='ApplicationType']"/>
+]
+
+[type 'UserTokenPolicy'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='UserTokenPolicy']"/>
+]
+
+[enum int 32 'UserTokenType'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:EnumeratedType[@Name='UserTokenType']"/>
+]
+
+[enum int 32 'TimestampsToReturn'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:EnumeratedType[@Name='TimestampsToReturn']"/>
+]
+
+[type 'ReadValueId'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='ReadValueId']"/>
+]
+
+[type 'WriteValue'
+    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name='WriteValue']"/>
+]
+
+
+
+    </xsl:template>
+
+    <xsl:template match="node:UAVariable">
+        <xsl:variable name="browseName">
+            <xsl:value-of select='@BrowseName'/>
+        </xsl:variable>
+        <xsl:choose>
+            <xsl:when 
test="/opc:TypeDictionary/opc:StructuredType[@Name=$browseName]">
+                <xsl:choose>
+                    <xsl:when test="not(@BrowseName='Vector') and 
not(substring(@BrowseName,1,1) = '&lt;') and 
not(number(substring(@BrowseName,1,1)))">
+                [type '<xsl:value-of select='@BrowseName'/>'
+                    <xsl:apply-templates 
select="/opc:TypeDictionary/opc:StructuredType[@Name=$browseName]"/>
+                ]
+                    </xsl:when>
+                </xsl:choose>
+            </xsl:when>
+        </xsl:choose>
+    </xsl:template>
+
+    <xsl:template match="node:UADataType[not(Definition)]">
+        <xsl:variable name="browseName">
+            <xsl:value-of select='@BrowseName'/>
+        </xsl:variable>
+        <xsl:choose>
+            <xsl:when 
test="/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)) &gt; 29">
+                    ['<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:when>
+                </xsl:choose>
+            </xsl:when>
+        </xsl:choose>
     </xsl:template>
 
     <xsl:template match="opc:EnumeratedType">
-        [enum int 32 '<xsl:value-of select="@Name"/>'
         <xsl:apply-templates select="opc:Documentation"/>
         <xsl:apply-templates select="opc:EnumeratedValue"/>
-  ]
     </xsl:template>
 
     <xsl:template match="opc:Documentation">
@@ -96,13 +593,8 @@
                 <xsl:with-param name="switchValue" select="@SwitchValue"/>
             </xsl:call-template>
         </xsl:variable>
-        <xsl:choose>
-            <xsl:when test="*[@SwitchField]">[discriminatedType '<xsl:value-of 
select="@Name"/>'</xsl:when>
-            <xsl:when test="not(*[@SwitchField])">[type '<xsl:value-of 
select="@Name"/>'</xsl:when>
-        </xsl:choose>
-    <xsl:apply-templates select="opc:Documentation"/>
-    <xsl:apply-templates select="opc:Field"/>
-  ]
+        <xsl:apply-templates select="opc:Documentation"/>
+        <xsl:apply-templates select="opc:Field"/>
     </xsl:template>
 
     <xsl:template match="opc:Field">
@@ -130,13 +622,8 @@
         </xsl:variable>
 
         <xsl:choose>
-            <xsl:when test="@LengthField and @TypeName = 'opc:String'">[array 
<xsl:value-of select="$dataType"/> '-1' '<xsl:value-of 
select="$lowerCaseName"/>' count '<xsl:value-of 
select="$lowerCaseLengthField"/>']
-            </xsl:when>
             <xsl:when test="@LengthField">[array <xsl:value-of 
select="$dataType"/>  '<xsl:value-of select="$lowerCaseName"/>' count 
'<xsl:value-of select="$lowerCaseLengthField"/>']
             </xsl:when>
-            <xsl:when test="@TypeName = 'opc:String'">[simple int 32 
'<xsl:value-of select="$lowerCaseName"/>Size']
-            [simple <xsl:value-of select="$dataType"/> '<xsl:value-of 
select="$lowerCaseName"/>Size' '<xsl:value-of select="@Name"/>']
-            </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:choose>
@@ -181,12 +668,12 @@
             <xsl:when test="$datatype = 'opc:UInt64'">uint 64</xsl:when>
             <xsl:when test="$datatype = 'opc:Float'">float 8.23</xsl:when>
             <xsl:when test="$datatype = 'opc:Double'">float 11.52</xsl:when>
-            <xsl:when test="$datatype = 'opc:Char'">string '-1'</xsl:when>
-            <xsl:when test="$datatype = 'opc:CharArray'">string '-1'</xsl:when>
+            <xsl:when test="$datatype = 'opc:Char'">string '1'</xsl:when>
+            <xsl:when test="$datatype = 
'opc:CharArray'">PascalString</xsl:when>
             <xsl:when test="$datatype = 'opc:Guid'">string '-1'</xsl:when>
-            <xsl:when test="$datatype = 'opc:ByteString'">string 
'-1'</xsl:when>
-            <xsl:when test="$datatype = 'opc:DateTime'">string '-1'</xsl:when>
-            <xsl:when test="$datatype = 'opc:String'">string</xsl:when>
+            <xsl:when test="$datatype = 
'opc:ByteString'">PascalString</xsl:when>
+            <xsl:when test="$datatype = 'opc:DateTime'">int 64</xsl:when>
+            <xsl:when test="$datatype = 'opc:String'">PascalString</xsl:when>
             <xsl:otherwise><xsl:value-of 
select="substring-after($datatype,':')"/></xsl:otherwise>
         </xsl:choose>
     </xsl:template>

Reply via email to