You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2019/02/07 21:30:08 UTC
[incubator-plc4x] 02/02: - Continued working on the dynamic s7
driver
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git
commit 6c49277e0af21ca24f803c14685d78f417244cdd
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Feb 7 22:30:00 2019 +0100
- Continued working on the dynamic s7 driver
(It's current state allows connecting to S7 devices, however no read/write/subscription functionality is enabled)
---
.../apache/plc4x/protocols/s7/protocol.scxml.xml | 17 ++-
.../pom.xml | 25 ++-
.../java/dynamic}/actions/BaseConnectedAction.java | 2 +-
.../java/dynamic}/actions/BaseDaffodilAction.java | 2 +-
.../java/dynamic}/actions/BasePlc4xAction.java | 2 +-
.../java/dynamic}/actions/ConnectAction.java | 2 +-
.../java/dynamic}/actions/InitContextAction.java | 2 +-
.../java/dynamic}/actions/ReceiveAction.java | 2 +-
.../sandbox/java/dynamic}/actions/SendAction.java | 4 +-
.../connection/DynamicDriverConnectionBase.java | 134 +++++++++++++++++
.../utils/W3CDOMTemplateInfosetInputter.scala | 2 +-
sandbox/dynamic-driver-s7/pom.xml | 36 ++---
.../sandbox/java/dynamic/s7/DynamicS7Driver.java | 77 ++++++++++
.../plc4x/sandbox/java/{ => dynamic}/s7/Poc.java | 20 ++-
.../s7/actions}/S7DecodeArticleNumber.java | 4 +-
.../dynamic/s7/connection/DynamicS7Connection.java | 167 +++++++++++++++++++++
.../s7/utils/S7TsapIdEncoder.java} | 25 ++-
.../services/org.apache.plc4x.java.spi.PlcDriver | 38 +++++
sandbox/pom.xml | 1 +
19 files changed, 492 insertions(+), 70 deletions(-)
diff --git a/protocols/s7/src/main/resources/org/apache/plc4x/protocols/s7/protocol.scxml.xml b/protocols/s7/src/main/resources/org/apache/plc4x/protocols/s7/protocol.scxml.xml
index bfab15c..eba7511 100644
--- a/protocols/s7/src/main/resources/org/apache/plc4x/protocols/s7/protocol.scxml.xml
+++ b/protocols/s7/src/main/resources/org/apache/plc4x/protocols/s7/protocol.scxml.xml
@@ -68,6 +68,7 @@
</sc:onentry>
<sc:transition event="success" target="sendCotpConnectionRequest"/>
<sc:transition event="failure" target="error"/>
+ <sc:transition event="disconnect" target="disconnect"/>
</sc:state>
<!--
@@ -126,6 +127,7 @@
</sc:onentry>
<sc:transition event="success" target="receiveCotpConnectionResponse"/>
<sc:transition event="failure" target="error"/>
+ <sc:transition event="disconnect" target="disconnect"/>
</sc:state>
<!--
@@ -145,6 +147,7 @@
</sc:onentry>
<sc:transition event="success" target="sendS7SetupCommunicationRequest"/>
<sc:transition event="failure" target="error"/>
+ <sc:transition event="disconnect" target="disconnect"/>
</sc:state>
<!--
@@ -198,6 +201,7 @@
</sc:onentry>
<sc:transition event="success" target="receiveS7SetupCommunicationResponse"/>
<sc:transition event="failure" target="error"/>
+ <sc:transition event="disconnect" target="disconnect"/>
</sc:state>
<!--
@@ -222,6 +226,7 @@
<sc:transition event="success" cond="plcType == null" target="sendS7IdentificationRequest"/>
<sc:transition event="success" cond="plcType != null" target="connected"/>
<sc:transition event="failure" target="error"/>
+ <sc:transition event="disconnect" target="disconnect"/>
</sc:state>
<!--
@@ -284,6 +289,7 @@
</sc:onentry>
<sc:transition event="success" target="receiveS7IdentificationRequest"/>
<sc:transition event="failure" target="error"/>
+ <sc:transition event="disconnect" target="disconnect"/>
</sc:state>
<!--
@@ -304,7 +310,8 @@
<plc4x:S7DecodeArticleNumber articleNumberParameterName="s7ArticleNumber" plcTypeParameterName="plcType"/>
</sc:transition>
<sc:transition event="failure" target="error"/>
- </sc:state>
+ <sc:transition event="disconnect" target="disconnect"/>
+ </sc:state>
<!--
Default state after connecting to a PLC.
@@ -313,6 +320,14 @@
<sc:onentry>
<sc:log expr="'Connected to PLC of type: ' + plcType"/>
</sc:onentry>
+ <sc:transition event="disconnect" target="disconnect"/>
+ </sc:state>
+
+ <!--
+ Initiate disconnecting.
+ -->
+ <sc:state id="disconnect">
+ <sc:transition event="disconnect" target="disconnected"/>
</sc:state>
<!--
diff --git a/sandbox/dynamic-driver-s7/pom.xml b/sandbox/dynamic-driver-base/pom.xml
similarity index 86%
copy from sandbox/dynamic-driver-s7/pom.xml
copy to sandbox/dynamic-driver-base/pom.xml
index f302333..8b0c9d0 100644
--- a/sandbox/dynamic-driver-s7/pom.xml
+++ b/sandbox/dynamic-driver-base/pom.xml
@@ -27,12 +27,18 @@
<version>0.4.0-SNAPSHOT</version>
</parent>
- <artifactId>plc4j-dynamic-driver-s7</artifactId>
- <name>Sandbox: Dynamic-Driver: S7</name>
- <description>Implementation of a S7 driver based on definitions provided by DFDL and SCXML.</description>
+ <artifactId>plc4j-dynamic-driver-base</artifactId>
+ <name>Sandbox: Dynamic-Driver: (Base)</name>
+ <description>Base Implementation of a driver based on definitions provided by DFDL and SCXML.</description>
<dependencies>
<dependency>
+ <groupId>org.apache.plc4x</groupId>
+ <artifactId>plc4j-api</artifactId>
+ <version>0.4.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-scxml2</artifactId>
<version>2.0-SNAPSHOT</version>
@@ -63,17 +69,6 @@
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
</dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4x-protocols-s7</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <scope>runtime</scope>
- </dependency>
</dependencies>
<build>
@@ -110,9 +105,7 @@
<artifactId>maven-dependency-plugin</artifactId>
<configuration>
<usedDependencies combine.children="append">
- <usedDependency>org.apache.plc4x:plc4x-protocols-s7</usedDependency>
<usedDependency>org.apache.commons:commons-jexl3</usedDependency>
- <usedDependency>org.slf4j:slf4j-simple</usedDependency>
</usedDependencies>
</configuration>
</plugin>
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BaseConnectedAction.java b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/BaseConnectedAction.java
similarity index 95%
copy from sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BaseConnectedAction.java
copy to sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/BaseConnectedAction.java
index cf37c81..bdc3cc5 100644
--- a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BaseConnectedAction.java
+++ b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/BaseConnectedAction.java
@@ -17,7 +17,7 @@
under the License.
*/
-package org.apache.plc4x.sandbox.java.s7.actions;
+package org.apache.plc4x.sandbox.java.dynamic.actions;
import org.apache.commons.scxml2.ActionExecutionContext;
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BaseDaffodilAction.java b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/BaseDaffodilAction.java
similarity index 97%
rename from sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BaseDaffodilAction.java
rename to sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/BaseDaffodilAction.java
index 4ed74ee..b3ef163 100644
--- a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BaseDaffodilAction.java
+++ b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/BaseDaffodilAction.java
@@ -17,7 +17,7 @@
under the License.
*/
-package org.apache.plc4x.sandbox.java.s7.actions;
+package org.apache.plc4x.sandbox.java.dynamic.actions;
import org.apache.commons.scxml2.ActionExecutionContext;
import org.apache.commons.scxml2.model.ParsedValue;
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BasePlc4xAction.java b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/BasePlc4xAction.java
similarity index 97%
rename from sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BasePlc4xAction.java
rename to sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/BasePlc4xAction.java
index 6a763b6..3693294 100644
--- a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BasePlc4xAction.java
+++ b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/BasePlc4xAction.java
@@ -17,7 +17,7 @@
under the License.
*/
-package org.apache.plc4x.sandbox.java.s7.actions;
+package org.apache.plc4x.sandbox.java.dynamic.actions;
import org.apache.commons.scxml2.ActionExecutionContext;
import org.apache.commons.scxml2.EventBuilder;
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/ConnectAction.java b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/ConnectAction.java
similarity index 97%
rename from sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/ConnectAction.java
rename to sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/ConnectAction.java
index bf374d1..e5df22e 100644
--- a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/ConnectAction.java
+++ b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/ConnectAction.java
@@ -17,7 +17,7 @@
under the License.
*/
-package org.apache.plc4x.sandbox.java.s7.actions;
+package org.apache.plc4x.sandbox.java.dynamic.actions;
import org.apache.commons.scxml2.ActionExecutionContext;
import org.slf4j.Logger;
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/InitContextAction.java b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/InitContextAction.java
similarity index 98%
rename from sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/InitContextAction.java
rename to sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/InitContextAction.java
index ed93053..bbc3b5d 100644
--- a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/InitContextAction.java
+++ b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/InitContextAction.java
@@ -17,7 +17,7 @@
under the License.
*/
-package org.apache.plc4x.sandbox.java.s7.actions;
+package org.apache.plc4x.sandbox.java.dynamic.actions;
import org.apache.commons.scxml2.ActionExecutionContext;
import org.apache.commons.scxml2.EventBuilder;
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/ReceiveAction.java b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/ReceiveAction.java
similarity index 99%
rename from sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/ReceiveAction.java
rename to sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/ReceiveAction.java
index 39ab99f..4db3fd9 100644
--- a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/ReceiveAction.java
+++ b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/ReceiveAction.java
@@ -17,7 +17,7 @@
under the License.
*/
-package org.apache.plc4x.sandbox.java.s7.actions;
+package org.apache.plc4x.sandbox.java.dynamic.actions;
import org.apache.commons.scxml2.ActionExecutionContext;
import org.apache.commons.scxml2.EventBuilder;
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/SendAction.java b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/SendAction.java
similarity index 96%
rename from sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/SendAction.java
rename to sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/SendAction.java
index bd4a467..6421cf6 100644
--- a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/SendAction.java
+++ b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/actions/SendAction.java
@@ -17,14 +17,14 @@
under the License.
*/
-package org.apache.plc4x.sandbox.java.s7.actions;
+package org.apache.plc4x.sandbox.java.dynamic.actions;
import org.apache.commons.scxml2.ActionExecutionContext;
import org.apache.commons.scxml2.model.ParsedValue;
import org.apache.daffodil.japi.DataProcessor;
import org.apache.daffodil.japi.UnparseResult;
import org.apache.daffodil.japi.infoset.InfosetInputter;
-import org.apache.plc4x.sandbox.java.s7.utils.W3CDOMTemplateInfosetInputter;
+import org.apache.plc4x.sandbox.java.dynamic.utils.W3CDOMTemplateInfosetInputter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
diff --git a/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/connection/DynamicDriverConnectionBase.java b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/connection/DynamicDriverConnectionBase.java
new file mode 100644
index 0000000..d27510d
--- /dev/null
+++ b/sandbox/dynamic-driver-base/src/main/java/org/apache/plc4x/sandbox/java/dynamic/connection/DynamicDriverConnectionBase.java
@@ -0,0 +1,134 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package org.apache.plc4x.sandbox.java.dynamic.connection;
+
+import org.apache.commons.scxml2.EventBuilder;
+import org.apache.commons.scxml2.SCXMLExecutor;
+import org.apache.commons.scxml2.TriggerEvent;
+import org.apache.commons.scxml2.env.SimpleDispatcher;
+import org.apache.commons.scxml2.env.SimpleErrorReporter;
+import org.apache.commons.scxml2.invoke.SimpleSCXMLInvoker;
+import org.apache.commons.scxml2.io.SCXMLReader;
+import org.apache.commons.scxml2.model.CustomAction;
+import org.apache.commons.scxml2.model.ModelException;
+import org.apache.commons.scxml2.model.SCXML;
+import org.apache.plc4x.java.api.PlcConnection;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata;
+import org.apache.plc4x.sandbox.java.dynamic.actions.ConnectAction;
+import org.apache.plc4x.sandbox.java.dynamic.actions.InitContextAction;
+import org.apache.plc4x.sandbox.java.dynamic.actions.ReceiveAction;
+import org.apache.plc4x.sandbox.java.dynamic.actions.SendAction;
+
+import javax.xml.stream.XMLStreamException;
+import java.io.IOException;
+import java.util.*;
+
+public abstract class DynamicDriverConnectionBase implements PlcConnection {
+
+ private String stateMachineURI;
+ private String dataFormatURI;
+ private SCXMLExecutor executor;
+
+ protected DynamicDriverConnectionBase(String stateMachineURI, String dataFormatURI) {
+ this.stateMachineURI = stateMachineURI;
+ this.dataFormatURI = dataFormatURI;
+ }
+
+ private void init() throws PlcConnectionException {
+ // Initialize our PLC4X specific actions.
+ List<CustomAction> customActions = new LinkedList<>();
+ customActions.add(
+ new CustomAction("https://plc4x.apache.org/scxml-extension", "initContext", InitContextAction.class));
+ customActions.add(
+ new CustomAction("https://plc4x.apache.org/scxml-extension", "connect", ConnectAction.class));
+ customActions.add(
+ new CustomAction("https://plc4x.apache.org/scxml-extension", "send", SendAction.class));
+ customActions.add(
+ new CustomAction("https://plc4x.apache.org/scxml-extension", "receive", ReceiveAction.class));
+ customActions.addAll(getAdditionalCustomActions());
+
+ try {
+ // Initialize the state-machine with the definition from the protocol module.
+ SCXML scxml = SCXMLReader.read(
+ DynamicDriverConnectionBase.class.getClassLoader().getResource(stateMachineURI),
+ new SCXMLReader.Configuration(null, null, customActions));
+
+ // Create an executor for running the state-machine.
+ executor = new SCXMLExecutor(null, new SimpleDispatcher(), new SimpleErrorReporter());
+ executor.setStateMachine(scxml);
+ executor.registerInvokerClass("scxml", SimpleSCXMLInvoker.class);
+ } catch (XMLStreamException | IOException | ModelException e) {
+ throw new PlcConnectionException("Error initializing driver state-machine", e);
+ }
+ }
+
+ protected Collection<CustomAction> getAdditionalCustomActions() {
+ return Collections.emptyList();
+ }
+
+ protected Map<String, Object> getAdditionalContextDataItems() {
+ return Collections.emptyMap();
+ }
+
+ protected abstract String getConnectedStateName();
+
+ protected abstract String getDisconnectTransitionName();
+
+ @Override
+ public void connect() throws PlcConnectionException {
+ // Setup the driver.
+ init();
+
+ // Initialize the drivers state.
+ Map<String, Object> context = new HashMap<>();
+ context.put("protocolDaffodilSchema", dataFormatURI);
+ getAdditionalContextDataItems().forEach(context::put);
+
+ try {
+ // Run the state-machine.
+ executor.go(context);
+ } catch (ModelException e) {
+ throw new PlcConnectionException("Error initializing driver state-machine", e);
+ }
+ }
+
+ @Override
+ public boolean isConnected() {
+ if(executor == null) {
+ return false;
+ }
+ return executor.getStatus().isInState(getConnectedStateName());
+ }
+
+ @Override
+ public void close() throws Exception {
+ if(executor == null) {
+ return;
+ }
+ executor.triggerEvent(new EventBuilder(getDisconnectTransitionName(), TriggerEvent.SIGNAL_EVENT).build());
+ }
+
+ @Override
+ public PlcConnectionMetadata getMetadata() {
+ return null;
+ }
+
+}
diff --git a/sandbox/dynamic-driver-s7/src/main/scala/org/apache/plc4x/sandbox/java/s7/utils/W3CDOMTemplateInfosetInputter.scala b/sandbox/dynamic-driver-base/src/main/scala/org/apache/plc4x/sandbox/java/dynamic/utils/W3CDOMTemplateInfosetInputter.scala
similarity index 96%
rename from sandbox/dynamic-driver-s7/src/main/scala/org/apache/plc4x/sandbox/java/s7/utils/W3CDOMTemplateInfosetInputter.scala
rename to sandbox/dynamic-driver-base/src/main/scala/org/apache/plc4x/sandbox/java/dynamic/utils/W3CDOMTemplateInfosetInputter.scala
index 04a83fd..d2c517f 100644
--- a/sandbox/dynamic-driver-s7/src/main/scala/org/apache/plc4x/sandbox/java/s7/utils/W3CDOMTemplateInfosetInputter.scala
+++ b/sandbox/dynamic-driver-base/src/main/scala/org/apache/plc4x/sandbox/java/dynamic/utils/W3CDOMTemplateInfosetInputter.scala
@@ -17,7 +17,7 @@
under the License.
*/
-package org.apache.plc4x.sandbox.java.s7.utils
+package org.apache.plc4x.sandbox.java.dynamic.utils
import org.apache.commons.scxml2.Context
import org.apache.daffodil.dpath.NodeInfo
diff --git a/sandbox/dynamic-driver-s7/pom.xml b/sandbox/dynamic-driver-s7/pom.xml
index f302333..06dd27d 100644
--- a/sandbox/dynamic-driver-s7/pom.xml
+++ b/sandbox/dynamic-driver-s7/pom.xml
@@ -33,6 +33,11 @@
<dependencies>
<dependency>
+ <groupId>org.apache.plc4x.sandbox</groupId>
+ <artifactId>plc4j-dynamic-driver-base</artifactId>
+ <version>0.4.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-scxml2</artifactId>
<version>2.0-SNAPSHOT</version>
@@ -47,6 +52,10 @@
<artifactId>commons-jexl3</artifactId>
<version>3.1</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
<dependency>
<groupId>commons-logging</groupId>
@@ -79,33 +88,6 @@
<build>
<plugins>
<plugin>
- <groupId>net.alchim31.maven</groupId>
- <artifactId>scala-maven-plugin</artifactId>
- <version>3.4.6</version>
- <executions>
- <execution>
- <id>add-scala-sources</id>
- <phase>validate</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sourceDir>src/main/scala</sourceDir>
- </configuration>
- </execution>
- <execution>
- <id>compile-scala</id>
- <phase>compile</phase>
- <goals>
- <goal>compile</goal>
- </goals>
- <configuration>
- <outputDir>${project.build.outputDirectory}</outputDir>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<configuration>
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/DynamicS7Driver.java b/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/DynamicS7Driver.java
new file mode 100644
index 0000000..a5b1eb5
--- /dev/null
+++ b/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/DynamicS7Driver.java
@@ -0,0 +1,77 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package org.apache.plc4x.sandbox.java.dynamic.s7;
+
+import org.apache.plc4x.java.api.PlcConnection;
+import org.apache.plc4x.java.api.authentication.PlcAuthentication;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.apache.plc4x.java.spi.PlcDriver;
+import org.apache.plc4x.sandbox.java.dynamic.s7.connection.DynamicS7Connection;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DynamicS7Driver implements PlcDriver {
+
+ private static final Pattern S7_URI_PATTERN = Pattern.compile("^s7d://(?<host>.*)/(?<rack>\\d{1,4})/(?<slot>\\d{1,4})(?<params>\\?.*)?");
+
+ @Override
+ public String getProtocolCode() {
+ return "s7d";
+ }
+
+ @Override
+ public String getProtocolName() {
+ return "Siemens S7 (Basic - Dynamic)";
+ }
+
+ @Override
+ public PlcConnection connect(String url) throws PlcConnectionException {
+ Matcher matcher = S7_URI_PATTERN.matcher(url);
+ if (!matcher.matches()) {
+ throw new PlcConnectionException(
+ "Connection url doesn't match the format 's7://{host|ip}/{rack}/{slot}'");
+ }
+ String host = matcher.group("host");
+
+ int rack = Integer.parseInt(matcher.group("rack"));
+ int slot = Integer.parseInt(matcher.group("slot"));
+ String params = matcher.group("params") != null ? matcher.group("params").substring(1) : null;
+
+ try {
+ InetAddress serverInetAddress = InetAddress.getByName(host);
+ DynamicS7Connection connection = new DynamicS7Connection(serverInetAddress, rack, slot, params);
+ connection.connect();
+ return connection;
+ } catch (UnknownHostException e) {
+ throw new PlcConnectionException("Error parsing address", e);
+ } catch (Exception e) {
+ throw new PlcConnectionException("Error connecting to host", e);
+ }
+ }
+
+ @Override
+ public PlcConnection connect(String url, PlcAuthentication authentication) throws PlcConnectionException {
+ throw new PlcConnectionException("Basic S7 connections don't support authentication.");
+ }
+
+}
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/Poc.java b/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/Poc.java
similarity index 85%
rename from sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/Poc.java
rename to sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/Poc.java
index 04faee4..fe3d771 100644
--- a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/Poc.java
+++ b/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/Poc.java
@@ -17,7 +17,7 @@
under the License.
*/
-package org.apache.plc4x.sandbox.java.s7;
+package org.apache.plc4x.sandbox.java.dynamic.s7;
import org.apache.commons.scxml2.SCXMLExecutor;
import org.apache.commons.scxml2.env.SimpleDispatcher;
@@ -26,11 +26,12 @@ import org.apache.commons.scxml2.invoke.SimpleSCXMLInvoker;
import org.apache.commons.scxml2.io.SCXMLReader;
import org.apache.commons.scxml2.model.CustomAction;
import org.apache.commons.scxml2.model.SCXML;
-import org.apache.plc4x.sandbox.java.s7.actions.ConnectAction;
-import org.apache.plc4x.sandbox.java.s7.actions.InitContextAction;
-import org.apache.plc4x.sandbox.java.s7.actions.ReceiveAction;
-import org.apache.plc4x.sandbox.java.s7.actions.SendAction;
-import org.apache.plc4x.sandbox.java.s7.actions.s7.S7DecodeArticleNumber;
+import org.apache.plc4x.java.api.PlcConnection;
+import org.apache.plc4x.sandbox.java.dynamic.actions.ConnectAction;
+import org.apache.plc4x.sandbox.java.dynamic.actions.InitContextAction;
+import org.apache.plc4x.sandbox.java.dynamic.actions.ReceiveAction;
+import org.apache.plc4x.sandbox.java.dynamic.actions.SendAction;
+import org.apache.plc4x.sandbox.java.dynamic.s7.actions.S7DecodeArticleNumber;
import java.util.HashMap;
import java.util.LinkedList;
@@ -89,10 +90,13 @@ public class Poc {
}
public static void main(String[] args) throws Exception {
- Poc poc = new Poc(
+ /*Poc poc = new Poc(
"org/apache/plc4x/protocols/s7/protocol.scxml.xml",
"org/apache/plc4x/protocols/s7/protocol.dfdl.xsd");
- poc.run();
+ poc.run();*/
+
+ PlcConnection connection = new DynamicS7Driver().connect("s7://10.10.64.20/1/1");
+ connection.isConnected();
}
}
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/s7/S7DecodeArticleNumber.java b/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/actions/S7DecodeArticleNumber.java
similarity index 95%
rename from sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/s7/S7DecodeArticleNumber.java
rename to sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/actions/S7DecodeArticleNumber.java
index 46e897b..8ced6eb 100644
--- a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/s7/S7DecodeArticleNumber.java
+++ b/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/actions/S7DecodeArticleNumber.java
@@ -17,11 +17,11 @@
under the License.
*/
-package org.apache.plc4x.sandbox.java.s7.actions.s7;
+package org.apache.plc4x.sandbox.java.dynamic.s7.actions;
import org.apache.commons.scxml2.ActionExecutionContext;
import org.apache.commons.scxml2.model.ActionExecutionError;
-import org.apache.plc4x.sandbox.java.s7.actions.BasePlc4xAction;
+import org.apache.plc4x.sandbox.java.dynamic.actions.BasePlc4xAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/connection/DynamicS7Connection.java b/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/connection/DynamicS7Connection.java
new file mode 100644
index 0000000..a70564a
--- /dev/null
+++ b/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/connection/DynamicS7Connection.java
@@ -0,0 +1,167 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package org.apache.plc4x.sandbox.java.dynamic.s7.connection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.scxml2.model.CustomAction;
+import org.apache.plc4x.java.api.exceptions.PlcUnsupportedOperationException;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest;
+import org.apache.plc4x.java.api.messages.PlcUnsubscriptionRequest;
+import org.apache.plc4x.java.api.messages.PlcWriteRequest;
+import org.apache.plc4x.sandbox.java.dynamic.connection.DynamicDriverConnectionBase;
+import org.apache.plc4x.sandbox.java.dynamic.s7.actions.S7DecodeArticleNumber;
+import org.apache.plc4x.sandbox.java.dynamic.s7.utils.S7TsapIdEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class DynamicS7Connection extends DynamicDriverConnectionBase {
+
+ private static final Logger logger = LoggerFactory.getLogger(DynamicS7Connection.class);
+
+ private final InetAddress address;
+ private final short calledTsapId;
+ private final short callingTsapId;
+
+ private short paramPduSize;
+ private short paramMaxAmqCaller;
+ private short paramMaxAmqCallee;
+ private String paramControllerType;
+
+ public DynamicS7Connection(InetAddress address, int rack, int slot, String params) {
+ super("org/apache/plc4x/protocols/s7/protocol.scxml.xml",
+ "org/apache/plc4x/protocols/s7/protocol.dfdl.xsd");
+
+ this.address = address;
+ this.calledTsapId = S7TsapIdEncoder.encodeS7TsapId((byte) 0x02, 0, 0);
+ this.callingTsapId = S7TsapIdEncoder.encodeS7TsapId((byte) 0x01, rack, slot);
+
+ short curParamPduSize = 1024;
+ short curParamMaxAmqCaller = 8;
+ short curParamMaxAmqCallee = 8;
+ String curParamControllerType = null;
+
+ if (!StringUtils.isEmpty(params)) {
+ for (String param : params.split("&")) {
+ String[] paramElements = param.split("=");
+ String paramName = paramElements[0];
+ if (paramElements.length == 2) {
+ String paramValue = paramElements[1];
+ switch (paramName) {
+ case "pdu-size":
+ curParamPduSize = Short.parseShort(paramValue);
+ break;
+ case "max-amq-caller":
+ curParamMaxAmqCaller = Short.parseShort(paramValue);
+ break;
+ case "max-amq-callee":
+ curParamMaxAmqCallee = Short.parseShort(paramValue);
+ break;
+ case "controller-type":
+ curParamControllerType = paramValue;
+ break;
+ default:
+ logger.debug("Unknown parameter {} with value {}", paramName, paramValue);
+ }
+ } else {
+ logger.debug("Unknown no-value parameter {}", paramName);
+ }
+ }
+ }
+
+ // It seems that the LOGO devices are a little picky about the pdu-size.
+ // Instead of handling this out, they just hang up without any error message.
+ // So in case of a LOGO controller, set this to a known working value.
+ if((curParamControllerType != null) && curParamControllerType.equalsIgnoreCase("logo") && curParamPduSize == 1024) {
+ curParamPduSize = 480;
+ }
+
+ // IsoTP uses pre defined sizes. Find the smallest box,
+ // that would be able to contain the requested pdu size.
+ this.paramPduSize = curParamPduSize;
+ this.paramMaxAmqCaller = curParamMaxAmqCaller;
+ this.paramMaxAmqCallee = curParamMaxAmqCallee;
+ this.paramControllerType = curParamControllerType;
+ }
+
+ @Override
+ protected String getConnectedStateName() {
+ return "connected";
+ }
+
+ @Override
+ protected String getDisconnectTransitionName() {
+ return "disconnect";
+ }
+
+ @Override
+ protected Collection<CustomAction> getAdditionalCustomActions() {
+ return Collections.singleton(
+ new CustomAction("https://plc4x.apache.org/scxml-extension", "S7DecodeArticleNumber",
+ S7DecodeArticleNumber.class));
+ }
+
+ @Override
+ protected Map<String, Object> getAdditionalContextDataItems() {
+ Map<String, Object> dataItems = new HashMap<>();
+
+ dataItems.put("hostname", address.getHostAddress());
+ dataItems.put("port", "102");
+ dataItems.put("plcType", paramControllerType);
+
+ dataItems.put("cotpLocalReference", "15");
+ dataItems.put("cotpCalledTsap", Short.toString(calledTsapId));
+ dataItems.put("cotpCallingTsap", Short.toString(callingTsapId));
+ dataItems.put("cotpTpduSize", "10");
+
+ dataItems.put("s7PduLength", Short.toString(paramPduSize));
+ dataItems.put("s7MaxAmqCaller", Short.toString(paramMaxAmqCaller));
+ dataItems.put("s7MaxAmqCallee", Short.toString(paramMaxAmqCallee));
+
+ return dataItems;
+ }
+
+ @Override
+ public PlcReadRequest.Builder readRequestBuilder() {
+ throw new PlcUnsupportedOperationException("The connection does not support reading");
+ }
+
+ @Override
+ public PlcWriteRequest.Builder writeRequestBuilder() {
+ throw new PlcUnsupportedOperationException("The connection does not support writing");
+ }
+
+ @Override
+ public PlcSubscriptionRequest.Builder subscriptionRequestBuilder() {
+ throw new PlcUnsupportedOperationException("The connection does not support subscription");
+ }
+
+ @Override
+ public PlcUnsubscriptionRequest.Builder unsubscriptionRequestBuilder() {
+ throw new PlcUnsupportedOperationException("The connection does not support subscription");
+ }
+
+}
diff --git a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BaseConnectedAction.java b/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/utils/S7TsapIdEncoder.java
similarity index 52%
rename from sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BaseConnectedAction.java
rename to sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/utils/S7TsapIdEncoder.java
index cf37c81..9e87c51 100644
--- a/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/s7/actions/BaseConnectedAction.java
+++ b/sandbox/dynamic-driver-s7/src/main/java/org/apache/plc4x/sandbox/java/dynamic/s7/utils/S7TsapIdEncoder.java
@@ -16,19 +16,30 @@
specific language governing permissions and limitations
under the License.
*/
+package org.apache.plc4x.sandbox.java.dynamic.s7.utils;
-package org.apache.plc4x.sandbox.java.s7.actions;
+public class S7TsapIdEncoder {
-import org.apache.commons.scxml2.ActionExecutionContext;
+ private S7TsapIdEncoder() {
+ // Prevent this from being instantiated.
+ }
-import java.net.Socket;
+ public static short encodeS7TsapId(byte deviceGroup, int rack, int slot) {
+ short firstByte = (short) (deviceGroup << 8);
+ short secondByte = (short) ((rack << 4) | (slot & 0x0F));
+ return (short) (firstByte | secondByte);
+ }
-public abstract class BaseConnectedAction extends BasePlc4xAction {
+ public static byte decodeDeviceGroup(short tsapId) {
+ return (byte) ((tsapId >> 8) & (0xFF));
+ }
- public static final String SOCKET_PARAMETER_NAME="connection";
+ public static int decodeRack(short tsapId) {
+ return (tsapId >> 4) & 0xF;
+ }
- protected Socket getSocket(ActionExecutionContext ctx) {
- return (Socket) ctx.getGlobalContext().get(SOCKET_PARAMETER_NAME);
+ public static int decodeSlot(short tsapId) {
+ return tsapId & 0xF;
}
}
diff --git a/sandbox/dynamic-driver-s7/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver b/sandbox/dynamic-driver-s7/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver
new file mode 100644
index 0000000..8609dd7
--- /dev/null
+++ b/sandbox/dynamic-driver-s7/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.PlcDriver
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+#
+# 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.
+#
+org.apache.plc4x.sandbox.java.dynamic.s7.DynamicS7Driver
diff --git a/sandbox/pom.xml b/sandbox/pom.xml
index f5301bf..bf2effd 100644
--- a/sandbox/pom.xml
+++ b/sandbox/pom.xml
@@ -35,6 +35,7 @@
<description>Place where new stuff is located before it is regarded production-quality.</description>
<modules>
+ <module>dynamic-driver-base</module>
<module>dynamic-driver-s7</module>
</modules>