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/14 11:19:53 UTC
[plc4x] branch feature/native_opua_client updated: Add support for
wrtiing.
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 2893f3d Add support for wrtiing.
2893f3d is described below
commit 2893f3d91340e9861b0b4af9d81e8034ba21e49b
Author: hutcheb <be...@gmail.com>
AuthorDate: Thu Jan 14 06:18:40 2021 -0500
Add support for wrtiing.
Initial support for UsernameIdentityToken, stuck on encrypting the password :(
---
.../apache/plc4x/java/opcua/OpcuaPlcDriver.java | 19 +-
.../java/opcua/config/OpcuaConfiguration.java | 104 +++++-
.../java/opcua/protocol/OpcuaProtocolLogic.java | 382 ++++++++++++++++++---
.../plc4x/java/opcua/OpcuaPlcDriverTest.java | 82 ++++-
.../apache/plc4x/java/spi/Plc4xNettyWrapper.java | 2 -
.../plc4x/java/spi/generation/ReadBuffer.java | 16 -
.../plc4x/java/spi/generation/WriteBuffer.java | 12 -
.../spi/internal/DefaultExpectRequestContext.java | 1 -
protocols/opcua/src/main/xslt/opc-types.xsl | 16 +-
9 files changed, 532 insertions(+), 102 deletions(-)
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 a005cb3..b100a00 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
@@ -26,6 +26,7 @@ import org.apache.plc4x.java.opcua.protocol.*;
import org.apache.plc4x.java.opcua.config.*;
import org.apache.plc4x.java.opcua.readwrite.*;
import org.apache.plc4x.java.opcua.readwrite.io.*;
+import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
import org.apache.plc4x.java.spi.connection.*;
import org.apache.plc4x.java.spi.transport.Transport;
import org.apache.plc4x.java.spi.values.IEC61131ValueHandler;
@@ -63,8 +64,8 @@ public class OpcuaPlcDriver extends GeneratedDriverBase<OpcuaAPU> {
public static final Pattern URI_PATTERN = Pattern.compile("^(?<protocolCode>opcua)" +
INET_ADDRESS_PATTERN +
- "(?<transportEndpoint>[\\w/=]+)" +
- "(?<paramString>[(\\?|\\&)\\w=]+\\=[\\w&]+)*"
+ "(?<transportEndpoint>[\\w/=]+)[\\?]?" +
+ "(?<paramString>[\\&\\w=]+\\=[\\w&]+)*"
);
@@ -163,15 +164,15 @@ public class OpcuaPlcDriver extends GeneratedDriverBase<OpcuaAPU> {
}
// Create the configuration object.
- OpcuaConfiguration configuration = new OpcuaConfiguration( transportCode,
- transportHost,
- transportPort,
- transportEndpoint,
- paramString);
-
+ OpcuaConfiguration configuration = (OpcuaConfiguration) new ConfigurationFactory().createConfiguration(
+ getConfigurationType(), paramString);
if(configuration == null) {
throw new PlcConnectionException("Unsupported configuration");
}
+ configuration.setTransportCode(transportCode);
+ configuration.setHost(transportHost);
+ configuration.setPort(transportPort);
+ configuration.setEndpoint("opc." + transportCode + "://" + transportHost + ":" + transportPort + "" + transportEndpoint);
// Try to find a transport in order to create a communication channel.
Transport transport = null;
@@ -226,9 +227,7 @@ public class OpcuaPlcDriver extends GeneratedDriverBase<OpcuaAPU> {
public static class ByteLengthEstimator implements ToIntFunction<ByteBuf> {
@Override
public int applyAsInt(ByteBuf byteBuf) {
- System.out.println("Estimate:- ");
if (byteBuf.readableBytes() >= 8) {
- System.out.println("Estimate:- " + Integer.reverseBytes(byteBuf.getInt(byteBuf.readerIndex() + 4)));
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 99f43a3..94ae1d5 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
@@ -21,23 +21,83 @@ package org.apache.plc4x.java.opcua.config;
import org.apache.plc4x.java.spi.configuration.Configuration;
import org.apache.plc4x.java.spi.configuration.annotations.ConfigurationParameter;
+import org.apache.plc4x.java.spi.configuration.annotations.defaults.BooleanDefaultValue;
import org.apache.plc4x.java.spi.configuration.annotations.defaults.IntDefaultValue;
import org.apache.plc4x.java.transport.tcp.TcpTransportConfiguration;
public class OpcuaConfiguration implements Configuration, TcpTransportConfiguration {
- private final String code;
- private final String host;
- private final String port;
- private final String endpoint;
- private final String params;
+ private String code;
+ private String host;
+ private String port;
+ private String endpoint;
+ private String params;
- public OpcuaConfiguration(String transportCode, String transportHost, String transportPort, String transportEndpoint, String paramString) {
- this.code = transportCode;
- this.host = transportHost;
- this.port = transportPort;
- this.endpoint = "opc." + transportCode + "://" + transportHost + ":" + transportPort + "" + transportEndpoint;
- this.params = paramString;
+ @ConfigurationParameter("discovery")
+ @BooleanDefaultValue(true)
+ private boolean discovery;
+
+ @ConfigurationParameter("username")
+ private String username;
+
+ @ConfigurationParameter("password")
+ private String password;
+
+ @ConfigurationParameter("certFile")
+ private String certFile;
+
+ @ConfigurationParameter("securityPolicy")
+ private String securityPolicy;
+
+ @ConfigurationParameter("keyStoreFile")
+ private String keyStoreFile;
+
+ public boolean isDiscovery() {
+ return discovery;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String getCertFile() {
+ return certFile;
+ }
+
+ public String getSecurityPolicy() {
+ return securityPolicy;
+ }
+
+ public String getKeyStoreFile() {
+ return keyStoreFile;
+ }
+
+ public void setDiscovery(boolean discovery) {
+ this.discovery = discovery;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public void setCertFile(String certFile) {
+ this.certFile = certFile;
+ }
+
+ public void setSecurityPolicy(String securityPolicy) {
+ this.securityPolicy = securityPolicy;
+ }
+
+ public void setKeyStoreFile(String keyStoreFile) {
+ this.keyStoreFile = keyStoreFile;
}
public String getTransportCode() {
@@ -56,15 +116,24 @@ public class OpcuaConfiguration implements Configuration, TcpTransportConfigurat
return endpoint;
}
- public String getParams() {
- return params;
+ public void setTransportCode(String code) {
+ this.code = code;
}
-
- @Override
- public int getDefaultPort() {
- return 12687;
+
+ public void setHost(String host) {
+ this.host = host;
}
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+ public void setEndpoint(String endpoint) {
+ this.endpoint = endpoint;
+ }
+
+
+
@Override
public String toString() {
return "Configuration{" +
@@ -72,3 +141,4 @@ public class OpcuaConfiguration implements Configuration, TcpTransportConfigurat
}
}
+
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 06896f6..a8d0972 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
@@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.RandomUtils;
import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.authentication.PlcAuthentication;
import org.apache.plc4x.java.api.exceptions.*;
@@ -61,7 +62,11 @@ import org.apache.plc4x.java.spi.values.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
import java.time.*;
import java.math.BigInteger;
import java.util.*;
@@ -75,6 +80,15 @@ import java.util.regex.Matcher;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.nio.charset.StandardCharsets;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import java.security.*;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
/**
@@ -95,9 +109,11 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
private static final int DEFAULT_RECEIVE_BUFFER_SIZE = 65535;
private static final int DEFAULT_SEND_BUFFER_SIZE = 65535;
private static final int VERSION = 0;
+ private static final String PASSWORD_ENCRYPTION_ALGORITHM = "http://www.w3.org/2001/04/xmlenc#rsa-oaep";
private NodeId authenticationToken = new NodeIdTwoByte(NodeIdType.nodeIdTypeTwoByte, new TwoByteNodeId((short) 0));
private static final PascalString NULL_STRING = new PascalString(-1,null);
+ private static final PascalByteString NULL_BYTE_STRING = new PascalByteString(-1, new byte[0]);
private static ExpandedNodeId NULL_EXPANDED_NODEID = new ExpandedNodeIdTwoByte(false,
false,
null,
@@ -111,25 +127,42 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
private static final String CHUNK = "F";
private static final String nameSpaceSecurityPolicyNone = "http://opcfoundation.org/UA/SecurityPolicy#None";
+ private static final String nameSpaceSecurityPolicyUserName = "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256";
private static final String applicationUri = "urn:apache:plc4x:client";
private static final String productUri = "urn:apache:plc4x:client";
private static final String applicationText = "OPCUA client for the Apache PLC4X:PLC4J project";
+
private final String sessionName = "UaSession:" + applicationText + ":" + RandomStringUtils.random(20, true, true);
- private final String clientNonce = RandomStringUtils.random(40, true, true);
+ private final byte[] clientNonce = RandomUtils.nextBytes(40);
private RequestTransactionManager tm;
private String endpoint;
+ private boolean discovery;
+ private String username;
+ private String password;
+ private String certFile;
+ private String securityPolicy;
+ private String keyStoreFile;
private AtomicInteger transactionIdentifierGenerator = new AtomicInteger(1);
private AtomicInteger requestHandleGenerator = new AtomicInteger(1);
private AtomicInteger tokenId = new AtomicInteger(1);
private AtomicInteger channelId = new AtomicInteger(1);
+ private byte[] senderCertificate = null;
+ private String certificateThumbprint = null;
private AtomicBoolean securedConnection = new AtomicBoolean(false);
@Override
public void setConfiguration(OpcuaConfiguration configuration) {
this.endpoint = configuration.getEndpoint();
+ this.discovery = configuration.isDiscovery();
+ this.username = configuration.getUsername();
+ this.password = configuration.getPassword();
+ this.certFile = configuration.getCertFile();
+ this.securityPolicy = configuration.getSecurityPolicy();
+ this.keyStoreFile = configuration.getKeyStoreFile();
+
this.tm = new RequestTransactionManager(1);
}
@@ -279,7 +312,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
VERSION,
SecurityTokenRequestType.securityTokenRequestTypeIssue,
MessageSecurityMode.messageSecurityModeNone,
- NULL_STRING,
+ NULL_BYTE_STRING,
DEFAULT_CONNECTION_LIFETIME);
OpcuaOpenRequest openRequest = new OpcuaOpenRequest(CHUNK,
@@ -309,10 +342,13 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
}
public void onConnectCreateSessionRequest(ConversationContext<OpcuaAPU> context, OpcuaOpenResponse opcuaOpenResponse) throws PlcConnectionException {
+
+ certificateThumbprint = opcuaOpenResponse.getReceiverCertificateThumbprint();
OpenSecureChannelResponse openSecureChannelResponse = (OpenSecureChannelResponse) opcuaOpenResponse.getMessage();
tokenId.set((int) openSecureChannelResponse.getSecurityToken().getTokenId());
channelId.set((int) openSecureChannelResponse.getSecurityToken().getChannelId());
+
int transactionId = getTransactionIdentifier(securedConnection.get());
Integer nextSequenceNumber = opcuaOpenResponse.getSequenceNumber() + 1;
@@ -358,8 +394,8 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
NULL_STRING,
new PascalString(endpoint.length(), endpoint),
new PascalString(sessionName.length(), sessionName),
- new PascalString(clientNonce.length(), clientNonce),
- NULL_STRING,
+ new PascalByteString(clientNonce.length, clientNonce),
+ NULL_BYTE_STRING,
120000L,
0L);
@@ -387,7 +423,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
private void onConnectActivateSessionRequest(ConversationContext<OpcuaAPU> context, OpcuaMessageResponse opcuaMessageResponse) throws PlcConnectionException {
CreateSessionResponse createSessionResponse = (CreateSessionResponse) opcuaMessageResponse.getMessage();
-
+ senderCertificate = createSessionResponse.getServerCertificate().getStringValue();
authenticationToken = (NodeIdByteString) createSessionResponse.getAuthenticationToken();
tokenId.set((int) opcuaMessageResponse.getSecureTokenId());
channelId.set((int) opcuaMessageResponse.getSecureChannelId());
@@ -398,7 +434,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
Integer nextRequestId = opcuaMessageResponse.getRequestId() + 1;
if (!(transactionId == nextSequenceNumber)) {
- LOGGER.error("Sequence number isn't as expected, we might have missed a packet. - " + transactionId + " != " + nextSequenceNumber);
+ LOGGER.error("Sequence number isn't as expected, we might have missed a packet. - {} != {}" , transactionId, nextSequenceNumber);
throw new PlcConnectionException("Sequence number isn't as expected, we might have missed a packet. - " + transactionId + " != " + nextSequenceNumber);
}
@@ -412,29 +448,54 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
REQUEST_TIMEOUT_LONG,
NULL_EXTENSION_OBJECT);
- SignatureData clientSignature = new SignatureData(NULL_STRING, NULL_STRING);
+ SignatureData clientSignature = new SignatureData(NULL_STRING, NULL_BYTE_STRING);
SignedSoftwareCertificate[] signedSoftwareCertificate = new SignedSoftwareCertificate[1];
- signedSoftwareCertificate[0] = new SignedSoftwareCertificate(NULL_STRING, NULL_STRING);
-
- //Manually serialize this object
- PascalString anonymousIdentityToken = new PascalString("anonymous".length(), "anonymous");
- WriteBuffer buffer = new WriteBuffer(anonymousIdentityToken.getLengthInBytes(), true);
- try{
- PascalStringIO.staticSerialize(buffer, anonymousIdentityToken);
- } catch (ParseException e) {
- LOGGER.error("Failed to serialize the user identity token - " + anonymousIdentityToken.getStringValue());
- throw new PlcConnectionException("Failed to serialize the user identity token - " + anonymousIdentityToken.getStringValue());
- }
+ signedSoftwareCertificate[0] = new SignedSoftwareCertificate(NULL_BYTE_STRING, NULL_BYTE_STRING);
- ExpandedNodeId extExpandedNodeId4 = new ExpandedNodeIdFourByte(false,
- false,
- null,
- null,
- new FourByteNodeId((short) 0, 321));
- ExtensionObject userIdentityToken = new ExtensionObject(extExpandedNodeId4, (short) 1, buffer.getData().length, buffer.getData());
+ ExpandedNodeId extExpandedNodeId = null;
+ ExtensionObject userIdentityToken = null;
+ if (this.username == null) {
+ //Manually serialize this object
+ PascalString anonymousIdentityToken = new PascalString("anonymous".length(), "anonymous");
+ WriteBuffer buffer = new WriteBuffer(anonymousIdentityToken.getLengthInBytes(), true);
+ try{
+ PascalStringIO.staticSerialize(buffer, anonymousIdentityToken);
+ } catch (ParseException e) {
+ LOGGER.error("Failed to serialize the user identity token - {}", anonymousIdentityToken.getStringValue());
+ throw new PlcConnectionException("Failed to serialize the user identity token - " + anonymousIdentityToken.getStringValue());
+ }
+ extExpandedNodeId = new ExpandedNodeIdFourByte(false,
+ false,
+ null,
+ null,
+ new FourByteNodeId((short) 0, OpcuaNodeIdServices.AnonymousIdentityToken_Encoding_DefaultBinary.getValue()));
+ userIdentityToken = new ExtensionObject(extExpandedNodeId, (short) 1, buffer.getData().length, buffer.getData());
+ } else {
+ //Manually serialize this object
+ byte[] encryptedPassword = encrypt(this.password, senderCertificate);
+ UserNameIdentityToken userNameIdentityToken = new UserNameIdentityToken(
+ new PascalString("username".length(), "username"),
+ new PascalString(this.username.length(), this.username),
+ new PascalByteString(encryptedPassword.length, encryptedPassword),
+ new PascalString(PASSWORD_ENCRYPTION_ALGORITHM.length(), PASSWORD_ENCRYPTION_ALGORITHM)
+ );
+ WriteBuffer buffer = new WriteBuffer(userNameIdentityToken.getLengthInBytes(), true);
+ try{
+ UserNameIdentityTokenIO.staticSerialize(buffer, userNameIdentityToken);
+ } catch (ParseException e) {
+ LOGGER.error("Failed to serialize the user identity token - {}", userNameIdentityToken);
+ throw new PlcConnectionException("Failed to serialize the user identity token - " + userNameIdentityToken);
+ }
+ extExpandedNodeId = new ExpandedNodeIdFourByte(false,
+ false,
+ null,
+ null,
+ new FourByteNodeId((short) 0, OpcuaNodeIdServices.UserNameIdentityToken_Encoding_DefaultBinary.getValue()));
+ userIdentityToken = new ExtensionObject(extExpandedNodeId, (short) 1, buffer.getData().length, buffer.getData());
+ }
ActivateSessionRequest activateSessionRequest = new ActivateSessionRequest((byte) 1,
(byte) 0,
@@ -465,7 +526,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
long returnedRequestHandle = activateMessageResponse.getResponseHeader().getRequestHandle();
if (!(requestHandle == returnedRequestHandle)) {
- LOGGER.error("Request handle isn't as expected, we might have missed a packet. - " + requestHandle + " != " + returnedRequestHandle);
+ LOGGER.error("Request handle isn't as expected, we might have missed a packet. {} != {}" ,requestHandle, returnedRequestHandle);
}
// Send an event that connection setup is complete.
@@ -561,7 +622,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
PlcValue value = null;
if (results[count].getStatusCode() == null) {
Variant variant = results[count].getValue();
- LOGGER.info("Repsponse includes Variant of type " + variant.getClass().toString());
+ LOGGER.info("Response of type {}", variant.getClass().toString());
if (variant instanceof VariantBoolean) {
byte[] array = ((VariantBoolean) variant).getValue();
int length = array.length;
@@ -761,14 +822,215 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
return response;
}
- private Variant fromPlcValue(OpcuaField field, PlcWriteRequest request) {
- return new VariantInt32(false,
- null,
- null,
- request.getFieldNames().size(),
- new int[] {request.getPlcValue("value-0").getInt()});
+ private Variant fromPlcValue(String fieldName, OpcuaField field, PlcWriteRequest request) {
+
+ PlcList valueObject;
+ if (request.getPlcValue(fieldName).getObject() instanceof ArrayList) {
+ valueObject = (PlcList) request.getPlcValue(fieldName);
+ } else {
+ ArrayList<PlcValue> list = new ArrayList<>();
+ list.add(request.getPlcValue(fieldName));
+ valueObject = new PlcList(list);
+ }
+
+ List<PlcValue> plcValueList = valueObject.getList();
+ String dataType = field.getPlcDataType();
+ if (dataType.equals("IEC61131_NULL")) {
+ if (plcValueList.get(0).getObject() instanceof Boolean) {
+ dataType = "IEC61131_BOOL";
+ } else if (plcValueList.get(0).getObject() instanceof Byte) {
+ dataType = "IEC61131_SINT";
+ } else if (plcValueList.get(0).getObject() instanceof Short) {
+ dataType = "IEC61131_INT";
+ } else if (plcValueList.get(0).getObject() instanceof Integer) {
+ dataType = "IEC61131_DINT";
+ } else if (plcValueList.get(0).getObject() instanceof Long) {
+ dataType = "IEC61131_LINT";
+ } else if (plcValueList.get(0).getObject() instanceof Float) {
+ dataType = "IEC61131_REAL";
+ } else if (plcValueList.get(0).getObject() instanceof Double) {
+ dataType = "IEC61131_LREAL";
+ } else if (plcValueList.get(0).getObject() instanceof String) {
+ dataType = "IEC61131_STRING";
+ }
+ }
+ int length = valueObject.getLength();
+ switch (dataType) {
+ case "IEC61131_BOOL":
+ case "IEC61131_BIT":
+ byte[] tmpBOOL = new byte[length];
+ for (int i = 0; i < length; i++) {
+ tmpBOOL[i] = valueObject.getIndex(i).getByte();
+ }
+ return new VariantBoolean(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpBOOL);
+ case "IEC61131_BYTE":
+ case "IEC61131_BITARR8":
+ case "IEC61131_USINT":
+ case "IEC61131_UINT8":
+ case "IEC61131_BIT8":
+ short[] tmpBYTE = new short[length];
+ for (int i = 0; i < length; i++) {
+ tmpBYTE[i] = valueObject.getIndex(i).getByte();
+ }
+ return new VariantByte(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpBYTE);
+ case "IEC61131_SINT":
+ case "IEC61131_INT8":
+ byte[] tmpSINT = new byte[length];
+ for (int i = 0; i < length; i++) {
+ tmpSINT[i] = valueObject.getIndex(i).getByte();
+ }
+ return new VariantSByte(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpSINT);
+ case "IEC61131_INT":
+ case "IEC61131_INT16":
+ short[] tmpINT16 = new short[length];
+ for (int i = 0; i < length; i++) {
+ tmpINT16[i] = valueObject.getIndex(i).getShort();
+ }
+ return new VariantInt16(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpINT16);
+ case "IEC61131_UINT":
+ case "IEC61131_UINT16":
+ case "IEC61131_WORD":
+ case "IEC61131_BITARR16":
+ int[] tmpUINT = new int[length];
+ for (int i = 0; i < length; i++) {
+ tmpUINT[i] = valueObject.getIndex(i).getInt();
+ }
+ return new VariantUInt16(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpUINT);
+ case "IEC61131_DINT":
+ case "IEC61131_INT32":
+ int[] tmpDINT = new int[length];
+ for (int i = 0; i < length; i++) {
+ tmpDINT[i] = valueObject.getIndex(i).getInt();
+ }
+ return new VariantInt32(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpDINT);
+ case "IEC61131_UDINT":
+ case "IEC61131_UINT32":
+ case "IEC61131_DWORD":
+ case "IEC61131_BITARR32":
+ long[] tmpUDINT = new long[length];
+ for (int i = 0; i < length; i++) {
+ tmpUDINT[i] = valueObject.getIndex(i).getLong();
+ }
+ return new VariantUInt32(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpUDINT);
+ case "IEC61131_LINT":
+ case "IEC61131_INT64":
+ long[] tmpLINT = new long[length];
+ for (int i = 0; i < length; i++) {
+ tmpLINT[i] = valueObject.getIndex(i).getLong();
+ }
+ return new VariantInt64(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpLINT);
+ case "IEC61131_ULINT":
+ case "IEC61131_UINT64":
+ case "IEC61131_LWORD":
+ case "IEC61131_BITARR64":
+ BigInteger[] tmpULINT = new BigInteger[length];
+ for (int i = 0; i < length; i++) {
+ tmpULINT[i] = valueObject.getIndex(i).getBigInteger();
+ }
+ return new VariantUInt64(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpULINT);
+ case "IEC61131_REAL":
+ case "IEC61131_FLOAT":
+ float[] tmpREAL = new float[length];
+ for (int i = 0; i < length; i++) {
+ tmpREAL[i] = valueObject.getIndex(i).getFloat();
+ }
+ return new VariantFloat(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpREAL);
+ case "IEC61131_LREAL":
+ case "IEC61131_DOUBLE":
+ double[] tmpLREAL = new double[length];
+ for (int i = 0; i < length; i++) {
+ tmpLREAL[i] = valueObject.getIndex(i).getDouble();
+ }
+ return new VariantDouble(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpLREAL);
+ case "IEC61131_CHAR":
+ case "IEC61131_WCHAR":
+ case "IEC61131_STRING":
+ case "IEC61131_WSTRING":
+ case "IEC61131_STRING16":
+ PascalString[] tmpString = new PascalString[length];
+ for (int i = 0; i < length; i++) {
+ String s = valueObject.getIndex(i).getString();
+ tmpString[i] = new PascalString(s.length(), s);
+ }
+ return new VariantString(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpString);
+ case "IEC61131_DATE_AND_TIME":
+ long[] tmpDateTime = new long[length];
+ for (int i = 0; i < length; i++) {
+ tmpDateTime[i] = valueObject.getIndex(i).getDateTime().toEpochSecond(ZoneOffset.UTC);
+ }
+ return new VariantDateTime(length == 1 ? false : true,
+ false,
+ null,
+ null,
+ length == 1 ? null : length,
+ tmpDateTime);
+ default:
+ throw new PlcRuntimeException("Unsupported write field type " + dataType);
+ }
+
}
+
@Override
public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
LOGGER.info("Writing Value");
@@ -811,8 +1073,8 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
false,
false,
false,
- false,
- fromPlcValue(field, writeRequest),
+ true,
+ fromPlcValue(fieldName, field, writeRequest),
null,
null,
null,
@@ -843,12 +1105,8 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
.check(p -> p.getMessage() instanceof OpcuaMessageResponse)
.unwrap(p -> (OpcuaMessageResponse) p.getMessage())
.handle(opcuaResponse -> {
-
- Map<String, PlcResponseCode> responseMap = new HashMap<>();
- responseMap.put("value-0", PlcResponseCode.OK);
-
- // Prepare the response.
- PlcWriteResponse response = new DefaultPlcWriteResponse(request, responseMap);
+ WriteResponse responseMessage = (WriteResponse) opcuaResponse.getMessage();
+ PlcWriteResponse response = writeResponse(request, responseMessage);
// Pass the response back to the application.
future.complete(response);
@@ -860,6 +1118,29 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
return future;
}
+ private PlcWriteResponse writeResponse(DefaultPlcWriteRequest request, WriteResponse writeResponse) {
+ Map<String, PlcResponseCode> responseMap = new HashMap<>();
+
+ StatusCode[] results = writeResponse.getResults();
+ Iterator<String> responseIterator = request.getFieldNames().iterator();
+ for (int i = 0; i < request.getFieldNames().size(); i++ ) {
+ String fieldName = responseIterator.next();
+ OpcuaStatusCodes statusCode = OpcuaStatusCodes.enumForValue(results[i].getStatusCode());
+ switch (statusCode) {
+ case Good:
+ responseMap.put(fieldName, PlcResponseCode.OK);
+ break;
+ case BadNodeIdUnknown:
+ responseMap.put(fieldName, PlcResponseCode.NOT_FOUND);
+ break;
+ default:
+ responseMap.put(fieldName, PlcResponseCode.REMOTE_ERROR);
+ }
+ }
+
+ return new DefaultPlcWriteResponse(request, responseMap);
+ }
+
/**
* Returns the next transaction identifier, for a secured connection we should return a random number.
* @param random - Select if we return a random number or the next value
@@ -901,4 +1182,25 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
private long getDateTime(long dateTime) {
return (dateTime - epochOffset) / 10000;
}
+
+ public byte[] encrypt(String data, byte[] publicKey) {
+ try {
+ Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, getCertificateX509().getPublicKey());
+ return cipher.doFinal(data.getBytes());
+ } catch (Exception e) {
+ LOGGER.error("Unable to encrypt Data");
+ return null;
+ }
+ }
+
+ public X509Certificate getCertificateX509() {
+ try {
+ CertificateFactory factory = CertificateFactory.getInstance("X.509");
+ return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(this.senderCertificate));
+ } catch (Exception e) {
+ LOGGER.error("Unable to get certificate from String {}", this.senderCertificate);
+ return null;
+ }
+ }
}
diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java
index e41954d..525cda7 100644
--- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java
+++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java
@@ -24,6 +24,8 @@ import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
import org.apache.plc4x.java.api.messages.PlcReadRequest;
import org.apache.plc4x.java.api.messages.PlcReadResponse;
+import org.apache.plc4x.java.api.messages.PlcWriteRequest;
+import org.apache.plc4x.java.api.messages.PlcWriteResponse;
import org.apache.plc4x.java.api.types.PlcResponseCode;
import org.eclipse.milo.examples.server.ExampleServer;
import org.junit.jupiter.api.*;
@@ -36,6 +38,8 @@ import static org.assertj.core.api.Assertions.fail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.math.BigInteger;
+
/**
*/
public class OpcuaPlcDriverTest {
@@ -269,6 +273,82 @@ public class OpcuaPlcDriverTest {
}
@Test
+ public void writeVariables() throws Exception {
+ PlcConnection opcuaConnection = new PlcDriverManager().getConnection(tcpConnectionAddress);
+ assert opcuaConnection.isConnected();
+
+ PlcWriteRequest.Builder builder = opcuaConnection.writeRequestBuilder();
+ builder.addItem("Bool", BOOL_IDENTIFIER_READ_WRITE, true);
+ builder.addItem("Byte", BYTE_IDENTIFIER_READ_WRITE + ":BYTE", 3);
+ builder.addItem("Double", DOUBLE_IDENTIFIER_READ_WRITE, 0.5d);
+ builder.addItem("Float", FLOAT_IDENTIFIER_READ_WRITE, 0.5f);
+ builder.addItem("Int16", INT16_IDENTIFIER_READ_WRITE + ":INT", 1);
+ builder.addItem("Int32", INT32_IDENTIFIER_READ_WRITE, 42);
+ builder.addItem("Int64", INT64_IDENTIFIER_READ_WRITE, 42L);
+ builder.addItem("Integer", INTEGER_IDENTIFIER_READ_WRITE, 42);
+ builder.addItem("SByte", SBYTE_IDENTIFIER_READ_WRITE + ":SINT", -127);
+ builder.addItem("String", STRING_IDENTIFIER_READ_WRITE, "Helllo Toddy!");
+ builder.addItem("UInt16", UINT16_IDENTIFIER_READ_WRITE + ":UINT", 65535);
+ builder.addItem("UInt32", UINT32_IDENTIFIER_READ_WRITE + ":UDINT", 101010101L);
+ builder.addItem("UInt64", UINT64_IDENTIFIER_READ_WRITE + ":ULINT", new BigInteger("1337"));
+ builder.addItem("UInteger", UINTEGER_IDENTIFIER_READ_WRITE + ":UDINT", 102020202L);
+
+
+ builder.addItem("BooleanArray", BOOL_ARRAY_IDENTIFIER, new Boolean[] {true, true, true, true, true});
+ builder.addItem("ByteArray", BYTE_ARRAY_IDENTIFIER + ":BYTE", new Short[] {1, 100, 100, 255, 123});
+ builder.addItem("DoubleArray", DOUBLE_ARRAY_IDENTIFIER, new Double[] {1.0,2.0,3.0,4.0,5.0});
+ builder.addItem("FloatArray", FLOAT_ARRAY_IDENTIFIER, new Float[] {1.0F,2.0F,3.0F,4.0F,5.0F});
+ builder.addItem("Int16Array", INT16_ARRAY_IDENTIFIER, new Short[] {1,2,3,4,5});
+ builder.addItem("Int32Array", INT32_ARRAY_IDENTIFIER, new Integer[] {1,2,3,4,5});
+ builder.addItem("Int64Array", INT64_ARRAY_IDENTIFIER, new Long[] {1L,2L,3L,4L,5L});
+ builder.addItem("IntegerArray", INT32_ARRAY_IDENTIFIER, new Integer[] {1,2,3,4,5});
+ builder.addItem("SByteArray", SBYTE_ARRAY_IDENTIFIER, new Byte[] {1,2,3,4,5});
+ builder.addItem("StringArray", STRING_ARRAY_IDENTIFIER, new String[] {"1","2","3","4","5"});
+ builder.addItem("UInt16Array", UINT16_ARRAY_IDENTIFIER + ":UINT", new Short[] {1,2,3,4,5});
+ builder.addItem("UInt32Array", UINT32_ARRAY_IDENTIFIER + ":UDINT", new Integer[] {1,2,3,4,5});
+ builder.addItem("UInt64Array", UINT64_ARRAY_IDENTIFIER + ":ULINT", new Long[] {1L,2L,3L,4L,5L});
+
+ builder.addItem("DoesNotExists", DOES_NOT_EXIST_IDENTIFIER_READ_WRITE, "11");
+
+ PlcWriteRequest request = builder.build();
+ PlcWriteResponse response = request.execute().get();
+
+ assert response.getResponseCode("Bool").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("Byte").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("Double").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("Float").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("Int16").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("Int32").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("Int64").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("Integer").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("SByte").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("String").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("UInt16").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("UInt32").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("UInt64").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("UInteger").equals(PlcResponseCode.OK);
+
+ assert response.getResponseCode("BooleanArray").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("ByteArray").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("DoubleArray").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("FloatArray").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("Int16Array").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("Int32Array").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("Int64Array").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("IntegerArray").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("SByteArray").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("StringArray").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("UInt16Array").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("UInt32Array").equals(PlcResponseCode.OK);
+ assert response.getResponseCode("UInt64Array").equals(PlcResponseCode.OK);
+
+ assert response.getResponseCode("DoesNotExists").equals(PlcResponseCode.NOT_FOUND);
+
+ opcuaConnection.close();
+ assert !opcuaConnection.isConnected();
+ }
+
+ @Test
public void testOpcuaAddressPattern() {
assertMatching(INET_ADDRESS_PATTERN, ":tcp://localhost");
@@ -290,7 +370,7 @@ public class OpcuaPlcDriverTest {
assertMatching(URI_PATTERN, "opcua:tcp://254.254.254.254:1337");
assertMatching(URI_PATTERN, "opcua:tcp://254.254.254.254");
- assertMatching(URI_PATTERN, "opcua:tcp://127.0.0.1&discovery=false");
+ assertMatching(URI_PATTERN, "opcua:tcp://127.0.0.1?discovery=false");
assertMatching(URI_PATTERN, "opcua:tcp://opcua.demo-this.com:51210/UA/SampleServer?discovery=false");
}
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java
index 9aba597..ea5c894 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java
@@ -98,7 +98,6 @@ public class Plc4xNettyWrapper<T> extends MessageToMessageCodec<T, Object> {
@Override
public ExpectRequestContext<T> expectRequest(Class<T> clazz, Duration timeout) {
- System.out.println("Testing BH ---");
return new DefaultExpectRequestContext<>(handler -> {
logger.trace("Adding Request Handler ...");
registeredHandlers.add(handler);
@@ -236,7 +235,6 @@ public class Plc4xNettyWrapper<T> extends MessageToMessageCodec<T, Object> {
@Override
public SendRequestContext<T1> sendRequest(T1 packet) {
- System.out.println("Testing BH ---&&");
return new DefaultSendRequestContext<>(handler -> {
logger.trace("Adding Response Handler ...");
registeredHandlers.add(handler);
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 4fcfe44..3e77df0 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
@@ -89,7 +89,6 @@ public class ReadBuffer {
public boolean readBit() throws ParseException {
try {
boolean ret = bi.readBoolean();
- LOGGER.info("Reading Bit:- " + ret);
return ret;
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -105,7 +104,6 @@ public class ReadBuffer {
}
try {
byte ret = bi.readByte(true, bitLength);
- LOGGER.info("Reading Unsigned Byte:- " + ret);
return ret;
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -122,7 +120,6 @@ public class ReadBuffer {
try {
// No need to flip here as we're only reading one byte.
short ret = bi.readShort(true, bitLength);
- LOGGER.info("Reading Unsigned Short:- " + ret);
return ret;
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -140,11 +137,9 @@ public class ReadBuffer {
if (littleEndian) {
int intValue = bi.readInt(true, bitLength);
int ret = Integer.reverseBytes(intValue) >>> 16;
- LOGGER.info("Reading Unsigned Int:- " + ret);
return ret;
}
int ret = bi.readInt(true, bitLength);
- LOGGER.info("Reading Unsigned Int:- " + ret);
return ret;
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -162,11 +157,9 @@ public class ReadBuffer {
if (littleEndian) {
final long longValue = bi.readLong(true, bitLength);
long ret = Long.reverseBytes(longValue) >>> 32;
- LOGGER.info("Reading Unsigned Long:- " + ret);
return ret;
}
long ret = bi.readLong(true, bitLength);
- LOGGER.info("Reading Unsigned Long:- " + ret);
return ret;
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -207,7 +200,6 @@ public class ReadBuffer {
}
try {
byte ret = bi.readByte(false, bitLength);
- LOGGER.info("Reading Byte:- " + ret);
return ret;
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -224,11 +216,9 @@ public class ReadBuffer {
try {
if (littleEndian) {
short ret = Short.reverseBytes(bi.readShort(false, bitLength));
- LOGGER.info("Reading Short:- " + ret);
return ret;
}
short ret = bi.readShort(false, bitLength);
- LOGGER.info("Reading Short:- " + ret);
return ret;
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -245,11 +235,9 @@ public class ReadBuffer {
try {
if (littleEndian) {
int ret = Integer.reverseBytes(bi.readInt(false, bitLength));
- LOGGER.info("Reading Integer:- " + ret);
return ret;
}
int ret = bi.readInt(false, bitLength);
- LOGGER.info("Reading Int:- " + ret);
return ret;
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -266,11 +254,9 @@ public class ReadBuffer {
try {
if (littleEndian) {
long ret = Long.reverseBytes(bi.readLong(false, bitLength));
- LOGGER.info("Reading Read Long:- " + ret);
return ret;
}
long ret = bi.readLong(false, bitLength);
- LOGGER.info("Reading Read Long:- " + ret);
return ret;
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -320,7 +306,6 @@ public class ReadBuffer {
if(bitLength == 64) {
long longValue = readLong(64);
double ret = Double.longBitsToDouble(longValue);
- LOGGER.info("Reading Double:- " + ret);
return ret;
} else {
throw new UnsupportedOperationException("unsupported bit length (only 64 supported)");
@@ -342,7 +327,6 @@ public class ReadBuffer {
}
//replaceAll function removes and leading ' char or hypens.
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 d05eb8e..a0b6aeb 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
@@ -69,7 +69,6 @@ public class WriteBuffer {
public void writeBit(boolean value) throws ParseException {
try {
- LOGGER.info("Writing Bit:- " + value);
bo.writeBoolean(value);
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -84,7 +83,6 @@ public class WriteBuffer {
throw new ParseException("unsigned byte can only contain max 8 bits");
}
try {
- LOGGER.info("Writing Usigned Byte:- " + value + ", " + bitLength + ", " + getPos());
bo.writeByte(true, bitLength, value);
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -99,7 +97,6 @@ public class WriteBuffer {
throw new ParseException("unsigned short can only contain max 16 bits");
}
try {
- LOGGER.info("Writing Unsigned Short:- " + value + ", " + bitLength + ", " + getPos());
bo.writeShort(true, bitLength, value);
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -114,7 +111,6 @@ public class WriteBuffer {
throw new ParseException("unsigned int can only contain max 32 bits");
}
try {
- LOGGER.info("Writing Unisgned Int:- " + value + ", " + bitLength + ", " + getPos());
if(littleEndian) {
value = Integer.reverseBytes(value) >> 16;
}
@@ -132,7 +128,6 @@ public class WriteBuffer {
throw new ParseException("unsigned long can only contain max 63 bits");
}
try {
- LOGGER.info("Writing Unsigned Long:- " + value + ", " + bitLength + ", " + getPos());
if(littleEndian) {
value = Long.reverseBytes(value) >> 32;
}
@@ -178,7 +173,6 @@ public class WriteBuffer {
throw new ParseException("byte can only contain max 8 bits");
}
try {
- LOGGER.info("Writing Byte:- " + value + ", " + bitLength + ", " + getPos());
bo.writeByte(false, bitLength, value);
} catch (IOException e) {
throw new ParseException("Error reading", e);
@@ -193,7 +187,6 @@ public class WriteBuffer {
throw new ParseException("short can only contain max 16 bits");
}
try {
- LOGGER.info("Writing Short:- " + value + ", " + bitLength + ", " + getPos());
if(littleEndian) {
value = Short.reverseBytes(value);
}
@@ -211,7 +204,6 @@ public class WriteBuffer {
throw new ParseException("int can only contain max 32 bits");
}
try {
- LOGGER.info("Writing int:- " + value + ", " + bitLength + ", " + getPos());
if(littleEndian) {
value = Integer.reverseBytes(value);
}
@@ -229,7 +221,6 @@ public class WriteBuffer {
throw new ParseException("long can only contain max 64 bits");
}
try {
- LOGGER.info("Writing long:- " + value + ", " + bitLength + ", " + getPos());
if(littleEndian) {
value = Long.reverseBytes(value);
}
@@ -254,7 +245,6 @@ public class WriteBuffer {
if (bitsExponent != 8 || bitsMantissa != 23) {
throw new UnsupportedOperationException("Exponent and/or Mantissa non standard size");
}
- LOGGER.info("Writing float:- " + value);
writeInt(1 + bitsExponent + bitsMantissa, Float.floatToRawIntBits(value));
}
@@ -262,7 +252,6 @@ public class WriteBuffer {
if (bitsExponent != 11 || bitsMantissa != 52) {
throw new UnsupportedOperationException("Exponent and/or Mantissa non standard size");
}
- LOGGER.info("Writing double:- " + value);
writeLong(1 + bitsExponent + bitsMantissa, Double.doubleToRawLongBits(value));
}
@@ -271,7 +260,6 @@ public class WriteBuffer {
}
public void writeString(int bitLength, String encoding, String value) throws ParseException {
- LOGGER.info("Writing String:- " + value + ", " + bitLength + ", " + getPos());
final byte[] bytes = value.getBytes(Charset.forName(encoding.replaceAll("[^a-zA-Z0-9]","")));
try {
int count = 0;
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultExpectRequestContext.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultExpectRequestContext.java
index 8b43f39..64c54f6 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultExpectRequestContext.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultExpectRequestContext.java
@@ -51,7 +51,6 @@ public class DefaultExpectRequestContext<T> implements ConversationContext.Expec
private HandlerRegistration registration;
public DefaultExpectRequestContext(Consumer<HandlerRegistration> finisher, Class<T> expectClazz, Duration timeout, ConversationContext context) {
- System.out.println("Testing BH");
this.finisher = finisher;
this.expectClazz = expectClazz;
this.timeout = timeout;
diff --git a/protocols/opcua/src/main/xslt/opc-types.xsl b/protocols/opcua/src/main/xslt/opc-types.xsl
index e3f2ac8..f34db8f 100644
--- a/protocols/opcua/src/main/xslt/opc-types.xsl
+++ b/protocols/opcua/src/main/xslt/opc-types.xsl
@@ -67,6 +67,7 @@
<xsl:apply-templates select="$file/node:UANodeSet/node:UADataType[@BrowseName='WriteResponse']"/>
<xsl:apply-templates select="$file/node:UANodeSet/node:UADataType[@BrowseName='BrowseRequest']"/>
<xsl:apply-templates select="$file/node:UANodeSet/node:UADataType[@BrowseName='BrowseResponse']"/>
+ <xsl:apply-templates select="$file/node:UANodeSet/node:UADataType[@BrowseName='ServiceFault']"/>
['473' CloseSessionRequest
[simple RequestHeader 'requestHeader']
@@ -132,7 +133,11 @@
]
[enum int 32 'NodeClass'
-<xsl:apply-templates select="/opc:TypeDictionary/opc:EnumeratedType[@Name='NodeClass']"/>
+ <xsl:apply-templates select="/opc:TypeDictionary/opc:EnumeratedType[@Name='NodeClass']"/>
+]
+
+[type 'UserNameIdentityToken'
+ <xsl:apply-templates select="/opc:TypeDictionary/opc:StructuredType[@Name='UserNameIdentityToken']"/>
]
[type 'DiagnosticInfo'
@@ -227,7 +232,7 @@
]
[discriminatedType 'Variant'
- [discriminator bit 'arrayLengthSpecified']
+ [simple bit 'arrayLengthSpecified']
[simple bit 'arrayDimensionsSpecified']
[discriminator uint 6 'VariantType']
[typeSwitch 'VariantType','arrayLengthSpecified'
@@ -404,6 +409,11 @@
[optional string 'stringLength == -1 ? 0 : stringLength * 8' 'UTF-8' 'stringValue' 'stringLength >= 0']
]
+[type 'PascalByteString'
+ [simple int 32 'stringLength']
+ [array int 8 'stringValue' count 'stringLength == -1 ? 0 : stringLength']
+]
+
[type 'LocalizedText'
[simple uint 6 'reserved1']
[simple bit 'localeSpecified']
@@ -620,7 +630,7 @@
<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'">PascalString</xsl:when>
+ <xsl:when test="$datatype = 'opc:ByteString'">PascalByteString</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>