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 2026/08/11 12:30:32 UTC
(plc4x) branch chore/cleanup created (now 977b5a6d84)
This is an automated email from the ASF dual-hosted git repository.
chrisdutz pushed a change to branch chore/cleanup
in repository https://gitbox.apache.org/repos/asf/plc4x.git
at 977b5a6d84 chore: Major cleanup of the dependencies chore: removed now replaced modules socketcan, virtualcan refactor: Made the OPC-UA server build inside Docker chore: Removed most of the obsolete code from the pcap-replay modules chore: Removed the plc-simulator
This branch includes the following new commits:
new 977b5a6d84 chore: Major cleanup of the dependencies chore: removed now replaced modules socketcan, virtualcan refactor: Made the OPC-UA server build inside Docker chore: Removed most of the obsolete code from the pcap-replay modules chore: Removed the plc-simulator
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(plc4x) 01/01: chore: Major cleanup of the dependencies chore: removed now replaced modules socketcan, virtualcan refactor: Made the OPC-UA server build inside Docker chore: Removed most of the obsolete code from the pcap-replay modules chore: Removed the plc-simulator
Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
chrisdutz pushed a commit to branch chore/cleanup
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 977b5a6d84099b010c6ea50d4bbdbb17c87645a2
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Tue Aug 11 14:30:05 2026 +0200
chore: Major cleanup of the dependencies
chore: removed now replaced modules socketcan, virtualcan
refactor: Made the OPC-UA server build inside Docker
chore: Removed most of the obsolete code from the pcap-replay modules
chore: Removed the plc-simulator
---
LICENSE | 5 -
NOTICE | 5 -
.../bacnetip/readwrite/model/BACnetVendorId.go | 96 +++
.../java/bacnetip/readwrite/BACnetVendorId.java | 12 +
plc4j/drivers/can/pom.xml | 13 -
plc4j/drivers/canopen/pom.xml | 13 -
plc4j/drivers/opcua/Dockerfile.test | 21 -
plc4j/drivers/opcua/pom.xml | 89 ---
.../apache/plc4x/java/opcua/KeystoreGenerator.java | 78 ++-
.../apache/plc4x/java/opcua/MiloTestContainer.java | 33 +-
.../src/test/resources/opcua/server/Dockerfile | 48 ++
.../milo/examples/server/EventNotifierTask.java | 0
.../milo/examples/server/Plc4xTestNamespace.java | 0
.../milo/examples/server/Plc4xTestStruct.java | 0
.../milo/examples/server/TestMiloServer.java | 0
plc4j/drivers/simulated/pom.xml | 1 +
plc4j/tools/opm/pom.xml | 13 -
plc4j/transports/socketcan/pom.xml | 141 ----
.../java/socketcan/readwrite/SocketCANFrame.java | 211 ------
.../socketcan/readwrite/utils/StaticHelper.java | 59 --
.../socketcan/SocketCANChannelFactory.java | 71 --
.../transport/socketcan/SocketCANFrameBuilder.java | 47 --
.../transport/socketcan/SocketCANTransport.java | 115 ----
.../socketcan/netty/SocketCANChannel.java | 283 --------
.../socketcan/netty/SocketCANChannelConfig.java | 31 -
.../socketcan/netty/address/SocketCANAddress.java | 40 --
....apache.plc4x.java.spi.transports.api.Transport | 19 -
plc4j/transports/virtualcan/pom.xml | 87 ---
.../java/transport/virtualcan/VirtualCANFrame.java | 90 ---
.../transport/virtualcan/VirtualCANTransport.java | 123 ----
....apache.plc4x.java.spi.transports.api.Transport | 20 -
plc4j/utils/pcap-replay/pom.xml | 104 ---
.../utils/pcapreplay/netty/PcapReplayChannel.java | 277 --------
.../netty/address/PcapReplayAddress.java | 39 --
.../netty/config/PcapReplayChannelConfig.java | 95 ---
.../netty/config/PcapReplayChannelOption.java | 46 --
plc4j/utils/pcap-shared/pom.xml | 87 ---
.../pcap/netty/address/PcapSocketAddress.java | 25 -
.../utils/pcap/netty/config/PcapChannelConfig.java | 185 ------
.../utils/pcap/netty/config/PcapChannelOption.java | 59 --
.../utils/pcap/netty/exception/PcapException.java | 35 -
.../utils/pcap/netty/handlers/PacketHandler.java | 27 -
.../pcap/netty/handlers/TcpIpPacketHandler.java | 41 --
.../pcap/netty/handlers/UdpIpPacketHandler.java | 41 --
.../src/main/remote-resources/META-INF/LICENSE | 6 -
.../src/main/remote-resources/META-INF/NOTICE | 4 -
plc4j/utils/plc-simulator/pom.xml | 131 ----
.../apache/plc4x/java/s7/utils/StaticHelper.java | 151 -----
.../org/apache/plc4x/simulator/PlcSimulator.java | 172 -----
.../apache/plc4x/simulator/PlcSimulatorConfig.java | 44 --
.../simulator/exceptions/SimulatorException.java | 35 -
.../org/apache/plc4x/simulator/model/Context.java | 112 ----
.../plc4x/simulator/server/ServerModule.java | 39 --
.../server/bacnet/BacnetServerModule.java | 138 ----
.../bacnet/protocol/BacnetServerAdapter.java | 191 ------
.../simulator/server/cbus/CBusServerModule.java | 122 ----
.../server/cbus/protocol/CBusServerAdapter.java | 715 ---------------------
.../plc4x/simulator/server/s7/S7ServerModule.java | 116 ----
.../server/s7/protocol/S7Step7ServerAdapter.java | 341 ----------
.../simulator/simulation/SimulationModule.java | 42 --
.../watertank/WaterTankSimulationModule.java | 109 ----
.../org.apache.plc4x.simulator.server.ServerModule | 21 -
...che.plc4x.simulator.simulation.SimulationModule | 19 -
.../plc-simulator/src/main/resources/logback.xml | 32 -
plc4j/utils/pom.xml | 7 -
plc4j/utils/raw-sockets/pom.xml | 33 -
.../utils/rawsockets/netty/RawSocketChannel.java | 411 ------------
.../rawsockets/netty/address/RawSocketAddress.java | 36 --
.../netty/address/RawSocketPassiveAddress.java | 37 --
.../netty/config/RawSocketChannelConfig.java | 30 -
.../utils/rawsockets/netty/utils/ArpUtils.java | 4 +-
.../src/remote-resources/META-INF/LICENSE | 9 -
.../src/remote-resources/META-INF/NOTICE | 4 -
.../java/utils/rawsockets/netty/ManualArpTest.java | 41 --
.../rawsockets/netty/RawSocketChannelTest.java | 97 ---
.../src/test/resources/logback-test.xml | 36 --
plc4j/utils/test-generator/pom.xml | 7 -
pom.xml | 95 +--
protocols/bacnetip/pom.xml | 9 +
.../protocols/bacnetip/bacnet-vendorids.mspec | 6 +
protocols/c-bus/pom.xml | 4 +
protocols/cotp/pom.xml | 11 -
protocols/knxnetip/pom.xml | 10 +
protocols/opcua/pom.xml | 4 +
protocols/plc4x-api/pom.xml | 4 +
protocols/plc4x/pom.xml | 4 +
protocols/pom.xml | 46 ++
protocols/profinet/pom.xml | 4 +
88 files changed, 345 insertions(+), 5969 deletions(-)
diff --git a/LICENSE b/LICENSE
index 711f75f3ed..7e649d5c79 100644
--- a/LICENSE
+++ b/LICENSE
@@ -203,11 +203,6 @@
===============================================================
-The files:
-plc4j/transports/test/src/main/java/io/netty/channel/embedded/Plc4xEmbeddedChannel.java
-plc4j/transports/test/src/main/java/io/netty/channel/embedded/Plc4xEmbeddedEventLoop.java
-Are copyrighted by the The Netty Project which is distributed under the Apache 2.0 license.
-
The files:
plc4go/spi/transports/serial/serialport/apply_linux.go
plc4go/spi/transports/serial/serialport/apply_darwin.go
diff --git a/NOTICE b/NOTICE
index 7f56f7ce93..9fa88a2dbc 100644
--- a/NOTICE
+++ b/NOTICE
@@ -6,8 +6,3 @@ The Apache Software Foundation (http://www.apache.org/).
----------------------------------------------
-This product includes software developed at
-The Netty project (https://netty.io/).
-
-----------------------------------------------
-
diff --git a/plc4go/protocols/bacnetip/readwrite/model/BACnetVendorId.go b/plc4go/protocols/bacnetip/readwrite/model/BACnetVendorId.go
index 62f4516174..329dc8f6a7 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/BACnetVendorId.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/BACnetVendorId.go
@@ -1673,6 +1673,12 @@ const (
BACnetVendorId_SPEC_PROM_DIZAJNOOO BACnetVendorId = 1638
BACnetVendorId_FACTS_ENGINEERINGLLC BACnetVendorId = 1639
BACnetVendorId_G_ASERV_GMBH BACnetVendorId = 1640
+ BACnetVendorId_LEEDS_ELECTRONICS_ENGINEERING_LIMITED BACnetVendorId = 1641
+ BACnetVendorId_MITO_CONTRACTING_GROUP_INC BACnetVendorId = 1642
+ BACnetVendorId_CALECTROAB BACnetVendorId = 1643
+ BACnetVendorId_BMSOS_TECHNOLOGY_INC BACnetVendorId = 1644
+ BACnetVendorId_VOSSLOH_SCHWABE_DEUTSCHAND_GMBH BACnetVendorId = 1645
+ BACnetVendorId_IVIVA_PTE_LTD BACnetVendorId = 1646
BACnetVendorId_UNKNOWN_VENDOR BACnetVendorId = 0xFFFF
)
@@ -3311,6 +3317,12 @@ func init() {
BACnetVendorId_SPEC_PROM_DIZAJNOOO,
BACnetVendorId_FACTS_ENGINEERINGLLC,
BACnetVendorId_G_ASERV_GMBH,
+ BACnetVendorId_LEEDS_ELECTRONICS_ENGINEERING_LIMITED,
+ BACnetVendorId_MITO_CONTRACTING_GROUP_INC,
+ BACnetVendorId_CALECTROAB,
+ BACnetVendorId_BMSOS_TECHNOLOGY_INC,
+ BACnetVendorId_VOSSLOH_SCHWABE_DEUTSCHAND_GMBH,
+ BACnetVendorId_IVIVA_PTE_LTD,
BACnetVendorId_UNKNOWN_VENDOR,
}
}
@@ -6161,6 +6173,30 @@ func (e BACnetVendorId) VendorId() uint16 {
{ /* '1640' */
return 1640
}
+ case 1641:
+ { /* '1641' */
+ return 1641
+ }
+ case 1642:
+ { /* '1642' */
+ return 1642
+ }
+ case 1643:
+ { /* '1643' */
+ return 1643
+ }
+ case 1644:
+ { /* '1644' */
+ return 1644
+ }
+ case 1645:
+ { /* '1645' */
+ return 1645
+ }
+ case 1646:
+ { /* '1646' */
+ return 1646
+ }
case 165:
{ /* '165' */
return 165
@@ -12703,6 +12739,30 @@ func (e BACnetVendorId) VendorName() string {
{ /* '1640' */
return "GAserv GmbH"
}
+ case 1641:
+ { /* '1641' */
+ return "Leeds Electronics Engineering Limited"
+ }
+ case 1642:
+ { /* '1642' */
+ return "MITO Contracting Group Inc."
+ }
+ case 1643:
+ { /* '1643' */
+ return "Calectro AB"
+ }
+ case 1644:
+ { /* '1644' */
+ return "bmsOS Technology Inc."
+ }
+ case 1645:
+ { /* '1645' */
+ return "Vossloh-Schwabe Deutschand GmbH"
+ }
+ case 1646:
+ { /* '1646' */
+ return "Iviva Pte Ltd"
+ }
case 165:
{ /* '165' */
return "Smart Temp Australia Pty. Ltd."
@@ -17822,6 +17882,18 @@ func BACnetVendorIdByValue(value uint16) (enum BACnetVendorId, ok bool) {
return BACnetVendorId_HSC_REGELUNGSTECHNIK_GMBH, true
case 1640:
return BACnetVendorId_G_ASERV_GMBH, true
+ case 1641:
+ return BACnetVendorId_LEEDS_ELECTRONICS_ENGINEERING_LIMITED, true
+ case 1642:
+ return BACnetVendorId_MITO_CONTRACTING_GROUP_INC, true
+ case 1643:
+ return BACnetVendorId_CALECTROAB, true
+ case 1644:
+ return BACnetVendorId_BMSOS_TECHNOLOGY_INC, true
+ case 1645:
+ return BACnetVendorId_VOSSLOH_SCHWABE_DEUTSCHAND_GMBH, true
+ case 1646:
+ return BACnetVendorId_IVIVA_PTE_LTD, true
case 165:
return BACnetVendorId_SMART_TEMP_AUSTRALIA_PTY_LTD, true
case 166:
@@ -21090,6 +21162,18 @@ func BACnetVendorIdByName(value string) (enum BACnetVendorId, ok bool) {
return BACnetVendorId_HSC_REGELUNGSTECHNIK_GMBH, true
case "G_ASERV_GMBH":
return BACnetVendorId_G_ASERV_GMBH, true
+ case "LEEDS_ELECTRONICS_ENGINEERING_LIMITED":
+ return BACnetVendorId_LEEDS_ELECTRONICS_ENGINEERING_LIMITED, true
+ case "MITO_CONTRACTING_GROUP_INC":
+ return BACnetVendorId_MITO_CONTRACTING_GROUP_INC, true
+ case "CALECTROAB":
+ return BACnetVendorId_CALECTROAB, true
+ case "BMSOS_TECHNOLOGY_INC":
+ return BACnetVendorId_BMSOS_TECHNOLOGY_INC, true
+ case "VOSSLOH_SCHWABE_DEUTSCHAND_GMBH":
+ return BACnetVendorId_VOSSLOH_SCHWABE_DEUTSCHAND_GMBH, true
+ case "IVIVA_PTE_LTD":
+ return BACnetVendorId_IVIVA_PTE_LTD, true
case "SMART_TEMP_AUSTRALIA_PTY_LTD":
return BACnetVendorId_SMART_TEMP_AUSTRALIA_PTY_LTD, true
case "COOPER_CONTROLS":
@@ -24430,6 +24514,18 @@ func (e BACnetVendorId) PLC4XEnumName() string {
return "HSC_REGELUNGSTECHNIK_GMBH"
case BACnetVendorId_G_ASERV_GMBH:
return "G_ASERV_GMBH"
+ case BACnetVendorId_LEEDS_ELECTRONICS_ENGINEERING_LIMITED:
+ return "LEEDS_ELECTRONICS_ENGINEERING_LIMITED"
+ case BACnetVendorId_MITO_CONTRACTING_GROUP_INC:
+ return "MITO_CONTRACTING_GROUP_INC"
+ case BACnetVendorId_CALECTROAB:
+ return "CALECTROAB"
+ case BACnetVendorId_BMSOS_TECHNOLOGY_INC:
+ return "BMSOS_TECHNOLOGY_INC"
+ case BACnetVendorId_VOSSLOH_SCHWABE_DEUTSCHAND_GMBH:
+ return "VOSSLOH_SCHWABE_DEUTSCHAND_GMBH"
+ case BACnetVendorId_IVIVA_PTE_LTD:
+ return "IVIVA_PTE_LTD"
case BACnetVendorId_SMART_TEMP_AUSTRALIA_PTY_LTD:
return "SMART_TEMP_AUSTRALIA_PTY_LTD"
case BACnetVendorId_COOPER_CONTROLS:
diff --git a/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java b/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java
index b15fb9acc2..e57aa77889 100644
--- a/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java
+++ b/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java
@@ -3285,6 +3285,18 @@ public enum BACnetVendorId {
G_ASERV_GMBH((int) 1640, (int) 1640, "GAserv GmbH"),
+ LEEDS_ELECTRONICS_ENGINEERING_LIMITED((int) 1641, (int) 1641, "Leeds Electronics Engineering Limited"),
+
+ MITO_CONTRACTING_GROUP_INC((int) 1642, (int) 1642, "MITO Contracting Group Inc."),
+
+ CALECTROAB((int) 1643, (int) 1643, "Calectro AB"),
+
+ BMSOS_TECHNOLOGY_INC((int) 1644, (int) 1644, "bmsOS Technology Inc."),
+
+ VOSSLOH_SCHWABE_DEUTSCHAND_GMBH((int) 1645, (int) 1645, "Vossloh-Schwabe Deutschand GmbH"),
+
+ IVIVA_PTE_LTD((int) 1646, (int) 1646, "Iviva Pte Ltd"),
+
UNKNOWN_VENDOR((int) 0xFFFF, (int) 0xFFFF, "Unknown");
private static final Map<Integer, BACnetVendorId> map;
diff --git a/plc4j/drivers/can/pom.xml b/plc4j/drivers/can/pom.xml
index 3839149c09..e227e19616 100644
--- a/plc4j/drivers/can/pom.xml
+++ b/plc4j/drivers/can/pom.xml
@@ -121,19 +121,6 @@
</instructions>
</configuration>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <configuration>
- <ignoredDependencies combine.children="append">
- <!--
- For some reason we need to do this. The compiler needs it in order to compile,
- but the plugin doesn't detect this.
- -->
- <ignoredDependency>io.netty:netty-buffer</ignoredDependency>
- </ignoredDependencies>
- </configuration>
- </plugin>
</plugins>
</build>
diff --git a/plc4j/drivers/canopen/pom.xml b/plc4j/drivers/canopen/pom.xml
index 1108a0fb2f..f967761e56 100644
--- a/plc4j/drivers/canopen/pom.xml
+++ b/plc4j/drivers/canopen/pom.xml
@@ -125,19 +125,6 @@
</instructions>
</configuration>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <configuration>
- <ignoredDependencies combine.children="append">
- <!--
- For some reason we need to do this. The compiler needs it in order to compile,
- but the plugin doesn't detect this.
- -->
- <ignoredDependency>io.netty:netty-buffer</ignoredDependency>
- </ignoredDependencies>
- </configuration>
- </plugin>
</plugins>
</build>
diff --git a/plc4j/drivers/opcua/Dockerfile.test b/plc4j/drivers/opcua/Dockerfile.test
deleted file mode 100644
index 4dbdd0a1ef..0000000000
--- a/plc4j/drivers/opcua/Dockerfile.test
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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
-#
-# https://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.
-
-FROM eclipse-temurin:21
-
-ADD "target/milo-testcontainer/*.jar" "/opt/milo/"
-ADD "target/test-classes/org/eclipse/milo" "/opt/milo/org/eclipse/milo"
-
-CMD java -cp '/opt/milo/*:/opt/milo/' org.eclipse.milo.examples.server.TestMiloServer
\ No newline at end of file
diff --git a/plc4j/drivers/opcua/pom.xml b/plc4j/drivers/opcua/pom.xml
index a2bcccecbc..795c9e7b3e 100644
--- a/plc4j/drivers/opcua/pom.xml
+++ b/plc4j/drivers/opcua/pom.xml
@@ -67,23 +67,6 @@
</execution>
</executions>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>copy-milo-dependencies</id>
- <goals>
- <goal>copy-dependencies</goal>
- </goals>
- <phase>test-compile</phase>
- <configuration>
- <includeArtifactIds>server-examples</includeArtifactIds>
- <outputDirectory>${project.build.directory}/milo-testcontainer</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
@@ -226,42 +209,12 @@
<version>1.0.0-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.apache.plc4x</groupId>
<artifactId>plc4j-utils-test-utils</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>sdk-client</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>sdk-core</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>stack-core</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>stack-client</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>server-examples</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.apache.plc4x</groupId>
@@ -271,12 +224,6 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>com.github.docker-java</groupId>
- <artifactId>docker-java-api</artifactId>
- <version>3.7.1</version>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
@@ -289,44 +236,8 @@
<version>1.21.4</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>com.google.cloud.tools</groupId>
- <artifactId>jib-core</artifactId>
- <version>0.28.1</version>
- <scope>test</scope>
- </dependency>
</dependencies>
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>sdk-client</artifactId>
- <version>${milo.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>sdk-core</artifactId>
- <version>${milo.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>stack-core</artifactId>
- <version>${milo.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>stack-client</artifactId>
- <version>${milo.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>server-examples</artifactId>
- <version>${milo.version}</version>
- </dependency>
- </dependencies>
- </dependencyManagement>
-
<profiles>
<profile>
<id>update-generated-code</id>
diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/KeystoreGenerator.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/KeystoreGenerator.java
index c16f0b80e0..081a879000 100644
--- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/KeystoreGenerator.java
+++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/KeystoreGenerator.java
@@ -21,20 +21,42 @@ package org.apache.plc4x.java.opcua;
import java.io.IOException;
import java.io.OutputStream;
+import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyPair;
+import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
+import java.security.SecureRandom;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
+import java.time.Duration;
+import java.time.Instant;
import java.util.Base64;
+import java.util.Date;
import java.util.Set;
-import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateBuilder;
-import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateGenerator;
+import org.bouncycastle.asn1.x500.X500NameBuilder;
+import org.bouncycastle.asn1.x500.style.BCStyle;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
+import org.bouncycastle.asn1.x509.KeyPurposeId;
+import org.bouncycastle.asn1.x509.KeyUsage;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
/**
- * Utility to generate server certificate - based on Eclipse Milo stuff.
+ * Utility to generate the client / server keystores used by the OPC UA integration test.
+ *
+ * <p>The certificates mirror what Milo's {@code SelfSignedCertificateBuilder} produced before:
+ * a self-signed RSA certificate valid for a year, carrying the OPC UA application URI as a
+ * SAN URI entry - the test server refuses to start without one - plus the usual key usages an
+ * OPC UA stack expects. It is built with BouncyCastle here so that the test classpath does not
+ * need Milo (see {@code src/test/resources/opcua/server/Dockerfile}).
*/
public class KeystoreGenerator {
@@ -65,27 +87,45 @@ public class KeystoreGenerator {
private KeyStore generate(String password, int length, String applicationUri, String entryName, String commonName) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(null, password.toCharArray());
- KeyPair keyPair = SelfSignedCertificateGenerator.generateRsaKeyPair(length);
- SelfSignedCertificateBuilder builder = (new SelfSignedCertificateBuilder(
- keyPair)).setCommonName(commonName)
- .setOrganization("Apache Software Foundation")
- .setOrganizationalUnit("PLC4X")
- .setLocalityName("PLC4J")
- .setStateName("CA")
- .setCountryCode("US")
- .setApplicationUri(applicationUri);
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ keyPairGenerator.initialize(length, new SecureRandom());
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+
+ X500NameBuilder nameBuilder = new X500NameBuilder(BCStyle.INSTANCE)
+ .addRDN(BCStyle.CN, commonName)
+ .addRDN(BCStyle.O, "Apache Software Foundation")
+ .addRDN(BCStyle.OU, "PLC4X")
+ .addRDN(BCStyle.L, "PLC4J")
+ .addRDN(BCStyle.ST, "CA")
+ .addRDN(BCStyle.C, "US");
Set<String> hostnames = Set.of("127.0.0.1");
-
+ GeneralName[] subjectAltNames = new GeneralName[hostnames.size() + 1];
+ subjectAltNames[0] = new GeneralName(GeneralName.uniformResourceIdentifier, applicationUri);
+ int index = 1;
for (String hostname : hostnames) {
- if (hostname.startsWith("\\d+\\.")) {
- builder.addIpAddress(hostname);
- } else {
- builder.addDnsName(hostname);
- }
+ subjectAltNames[index++] = new GeneralName(GeneralName.dNSName, hostname);
}
- X509Certificate certificate = builder.build();
+ Instant notBefore = Instant.now();
+ JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(
+ nameBuilder.build(),
+ new BigInteger(64, new SecureRandom()),
+ Date.from(notBefore),
+ Date.from(notBefore.plus(Duration.ofDays(365))),
+ nameBuilder.build(),
+ keyPair.getPublic()
+ );
+ builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(false));
+ builder.addExtension(Extension.keyUsage, false, new KeyUsage(
+ KeyUsage.digitalSignature | KeyUsage.nonRepudiation | KeyUsage.keyEncipherment
+ | KeyUsage.dataEncipherment | KeyUsage.keyCertSign));
+ builder.addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(
+ new KeyPurposeId[]{KeyPurposeId.id_kp_clientAuth, KeyPurposeId.id_kp_serverAuth}));
+ builder.addExtension(Extension.subjectAlternativeName, false, new GeneralNames(subjectAltNames));
+
+ X509Certificate certificate = new JcaX509CertificateConverter().getCertificate(
+ builder.build(new JcaContentSignerBuilder("SHA256withRSA").build(keyPair.getPrivate())));
keyStore.setKeyEntry(entryName, keyPair.getPrivate(), password.toCharArray(), new X509Certificate[]{ certificate });
return keyStore;
}
diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/MiloTestContainer.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/MiloTestContainer.java
index 817813fd54..b700b54873 100644
--- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/MiloTestContainer.java
+++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/MiloTestContainer.java
@@ -19,17 +19,20 @@
package org.apache.plc4x.java.opcua;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.images.builder.ImageFromDockerfile;
public class MiloTestContainer extends GenericContainer<MiloTestContainer> {
- private final static Logger logger = LoggerFactory.getLogger(MiloTestContainer.class);
+ private final static String SERVER_RESOURCES = "opcua/server";
+
+ private final static String[] SERVER_SOURCES = {
+ "org/eclipse/milo/examples/server/EventNotifierTask.java",
+ "org/eclipse/milo/examples/server/Plc4xTestNamespace.java",
+ "org/eclipse/milo/examples/server/Plc4xTestStruct.java",
+ "org/eclipse/milo/examples/server/TestMiloServer.java"
+ };
private final static ImageFromDockerfile IMAGE = inlineImage();
@@ -52,13 +55,19 @@ public class MiloTestContainer extends GenericContainer<MiloTestContainer> {
}
private static ImageFromDockerfile inlineImage() {
- Path absolutePath = Paths.get(".").toAbsolutePath();
- logger.info("Building milo server image from {}", absolutePath);
- // Reuse the Docker layer cache across runs; the build context only changes when
- // the milo jar or the compiled TestMiloServer classes change, so a cached build
- // stays correct while turning a multi-minute rebuild into a near-instant one.
- return new ImageFromDockerfile("plc4x-milo-test", false)
- .withDockerfile(absolutePath.resolve("Dockerfile.test"));
+ // The build context is assembled from the test resources: the Dockerfile plus the
+ // sources of the test server, which are compiled inside the image against the Milo
+ // uber jar it downloads (see the Dockerfile for why Milo is not a Maven dependency).
+ //
+ // Keeping the named image around reuses the Docker layer cache across runs; the
+ // context only changes when the Dockerfile or those sources change, so a cached
+ // build stays correct while turning a multi-minute rebuild into a near-instant one.
+ ImageFromDockerfile image = new ImageFromDockerfile("plc4x-milo-test", false)
+ .withFileFromClasspath("Dockerfile", SERVER_RESOURCES + "/Dockerfile");
+ for (String source : SERVER_SOURCES) {
+ image.withFileFromClasspath("src/" + source, SERVER_RESOURCES + "/src/" + source);
+ }
+ return image;
}
}
diff --git a/plc4j/drivers/opcua/src/test/resources/opcua/server/Dockerfile b/plc4j/drivers/opcua/src/test/resources/opcua/server/Dockerfile
new file mode 100644
index 0000000000..85a1496678
--- /dev/null
+++ b/plc4j/drivers/opcua/src/test/resources/opcua/server/Dockerfile
@@ -0,0 +1,48 @@
+#
+# 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
+#
+# https://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.
+#
+
+# OPC UA test server used by OpcuaPlcDriverTest.
+#
+# Eclipse Milo is deliberately NOT a Maven dependency of this module: it would drag its
+# whole transitive tree (netty, jackson, guava, bouncycastle, ...) onto the test classpath,
+# where every one of them shows up as a dependency-update / vulnerability alert for a jar
+# that never leaves this container. Instead the server-examples uber jar - which already
+# bundles the complete Milo stack plus its dependencies - is fetched here and the handful
+# of PLC4X test-server classes under src/ are compiled against it inside the image.
+#
+# Consequence: the sources in src/ are not compiled by Maven, so the IDE will not flag
+# breakage in them. Bumping MILO_VERSION is a manual step; a compile error surfaces as a
+# failed image build when the integration test runs.
+
+ARG MILO_VERSION=0.6.16
+
+FROM eclipse-temurin:21-jdk AS build
+ARG MILO_VERSION
+ADD "https://repo1.maven.org/maven2/org/eclipse/milo/server-examples/${MILO_VERSION}/server-examples-${MILO_VERSION}.jar" /opt/milo/server-examples.jar
+COPY src /src
+RUN javac -nowarn -cp /opt/milo/server-examples.jar -d /opt/milo/classes $(find /src -name '*.java')
+
+FROM eclipse-temurin:21-jre
+COPY --from=build /opt/milo /opt/milo
+
+# The server binds this port and also advertises its endpoints on it, so the test container
+# maps it 1:1 onto the host (see MiloTestContainer).
+EXPOSE 12686
+
+CMD ["java", "-cp", "/opt/milo/server-examples.jar:/opt/milo/classes", "org.eclipse.milo.examples.server.TestMiloServer"]
diff --git a/plc4j/drivers/opcua/src/test/java/org/eclipse/milo/examples/server/EventNotifierTask.java b/plc4j/drivers/opcua/src/test/resources/opcua/server/src/org/eclipse/milo/examples/server/EventNotifierTask.java
similarity index 100%
rename from plc4j/drivers/opcua/src/test/java/org/eclipse/milo/examples/server/EventNotifierTask.java
rename to plc4j/drivers/opcua/src/test/resources/opcua/server/src/org/eclipse/milo/examples/server/EventNotifierTask.java
diff --git a/plc4j/drivers/opcua/src/test/java/org/eclipse/milo/examples/server/Plc4xTestNamespace.java b/plc4j/drivers/opcua/src/test/resources/opcua/server/src/org/eclipse/milo/examples/server/Plc4xTestNamespace.java
similarity index 100%
rename from plc4j/drivers/opcua/src/test/java/org/eclipse/milo/examples/server/Plc4xTestNamespace.java
rename to plc4j/drivers/opcua/src/test/resources/opcua/server/src/org/eclipse/milo/examples/server/Plc4xTestNamespace.java
diff --git a/plc4j/drivers/opcua/src/test/java/org/eclipse/milo/examples/server/Plc4xTestStruct.java b/plc4j/drivers/opcua/src/test/resources/opcua/server/src/org/eclipse/milo/examples/server/Plc4xTestStruct.java
similarity index 100%
rename from plc4j/drivers/opcua/src/test/java/org/eclipse/milo/examples/server/Plc4xTestStruct.java
rename to plc4j/drivers/opcua/src/test/resources/opcua/server/src/org/eclipse/milo/examples/server/Plc4xTestStruct.java
diff --git a/plc4j/drivers/opcua/src/test/java/org/eclipse/milo/examples/server/TestMiloServer.java b/plc4j/drivers/opcua/src/test/resources/opcua/server/src/org/eclipse/milo/examples/server/TestMiloServer.java
similarity index 100%
rename from plc4j/drivers/opcua/src/test/java/org/eclipse/milo/examples/server/TestMiloServer.java
rename to plc4j/drivers/opcua/src/test/resources/opcua/server/src/org/eclipse/milo/examples/server/TestMiloServer.java
diff --git a/plc4j/drivers/simulated/pom.xml b/plc4j/drivers/simulated/pom.xml
index a51a58426b..e0b935df81 100644
--- a/plc4j/drivers/simulated/pom.xml
+++ b/plc4j/drivers/simulated/pom.xml
@@ -142,6 +142,7 @@
<artifactId>logback-classic</artifactId>
</dependency>
+ <!-- TODO: Only needed for SimulatedTagTest -->
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
diff --git a/plc4j/tools/opm/pom.xml b/plc4j/tools/opm/pom.xml
index 330171d21a..0a6377b7c5 100644
--- a/plc4j/tools/opm/pom.xml
+++ b/plc4j/tools/opm/pom.xml
@@ -79,17 +79,4 @@
</dependency>
</dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <configuration>
- <usedDependencies combine.children="append">
- </usedDependencies>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
</project>
\ No newline at end of file
diff --git a/plc4j/transports/socketcan/pom.xml b/plc4j/transports/socketcan/pom.xml
deleted file mode 100644
index 44cfe6f26f..0000000000
--- a/plc4j/transports/socketcan/pom.xml
+++ /dev/null
@@ -1,141 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- https://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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsd">
-
- <modelVersion>4.1.0</modelVersion>
-
- <parent>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-transports</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>plc4j-transports-socketcan</artifactId>
- <name>PLC4J: Transports: SocketCAN</name>
- <description>Base classes needed to implement plc4x drivers based on SocketCAN connections. Powered by javacan library.</description>
-
- <properties>
- <project.build.outputTimestamp>2025-08-02T13:55:11Z</project.build.outputTimestamp>
- </properties>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
- <Bundle-Activator>org.apache.plc4x.java.osgi.TransportActivator</Bundle-Activator>
- <Export-Service>org.apache.plc4x.java.spi.transports.api.Transport,org.apache.plc4x.java.transport.socketcan.SocketCANTransport</Export-Service>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-spi-buffers-api</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-spi-buffers-byte</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-spi-config</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-spi-fields</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-transports-api</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-utils-audit-log-api</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>tel.schich</groupId>
- <artifactId>javacan-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <id>update-generated-code</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.plc4x.plugins</groupId>
- <artifactId>plc4x-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>socketcan</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>generate-driver</goal>
- </goals>
- <configuration>
- <protocolName>socketcan</protocolName>
- <languageName>java</languageName>
- <outputFlavor>read-write</outputFlavor>
- <outputDir>src/main/generated</outputDir>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4x-protocols-socketcan</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4x-code-generation-language-java</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
- </profile>
- </profiles>
-
-</project>
diff --git a/plc4j/transports/socketcan/src/main/generated/org/apache/plc4x/java/socketcan/readwrite/SocketCANFrame.java b/plc4j/transports/socketcan/src/main/generated/org/apache/plc4x/java/socketcan/readwrite/SocketCANFrame.java
deleted file mode 100644
index 1e9b1a7138..0000000000
--- a/plc4j/transports/socketcan/src/main/generated/org/apache/plc4x/java/socketcan/readwrite/SocketCANFrame.java
+++ /dev/null
@@ -1,211 +0,0 @@
-// 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
-//
-// https://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.java.socketcan.readwrite;
-
-import org.apache.plc4x.java.socketcan.readwrite.utils.StaticHelper;
-import org.apache.plc4x.java.spi.buffers.api.Message;
-import org.apache.plc4x.java.spi.buffers.api.ReadBuffer;
-import org.apache.plc4x.java.spi.buffers.api.WithOption;
-import org.apache.plc4x.java.spi.buffers.api.WriteBuffer;
-import org.apache.plc4x.java.spi.buffers.api.exceptions.BufferException;
-import org.apache.plc4x.java.spi.buffers.bytebased.WithByteBasedOption;
-import org.apache.plc4x.java.spi.fields.data.reader.DataReaderFactory;
-import org.apache.plc4x.java.spi.fields.data.writer.DataWriterFactory;
-import org.apache.plc4x.java.spi.fields.fields.reader.FieldReaderFactory;
-import org.apache.plc4x.java.spi.fields.fields.writer.FieldWriterFactory;
-import org.apache.plc4x.java.spi.fields.utils.ThreadLocalHelper;
-
-/**
- * Code generated by code-generation. DO NOT EDIT.
- */
-public class SocketCANFrame implements Message {
- protected final int rawId;
-
- protected final byte[] data;
-
- public SocketCANFrame(Integer rawId, byte[] data) {
- this.rawId = rawId;
- this.data = data;
- }
-
- /**
- * Property field rawId
- */
- public int getRawId() {
- return rawId;
- }
-
- /**
- * Property field data
- */
- public byte[] getData() {
- return data;
- }
-
- /**
- * Virtual field identifier
- */
- public int getIdentifier() {
- return (int) (StaticHelper.readIdentifier(rawId));
- }
-
- /**
- * Virtual field extended
- */
- public boolean getExtended() {
- return (boolean) (StaticHelper.isExtended(rawId));
- }
-
- /**
- * Virtual field remote
- */
- public boolean getRemote() {
- return (boolean) (StaticHelper.isRemote(rawId));
- }
-
- /**
- * Virtual field error
- */
- public boolean getError() {
- return (boolean) (StaticHelper.isError(rawId));
- }
-
- public static SocketCANFrame staticParse(ReadBuffer readBuffer) throws BufferException {
- readBuffer.pushContext(WithOption.WithName("SocketCANFrame"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
- int startPos = readBuffer.getPositionInBits();
- boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
- // Simple Field: rawId
- int rawId = FieldReaderFactory.readSimpleField(DataReaderFactory.readSignedInt(readBuffer, 32), WithOption.WithName("rawId"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
-
- // Virtual Field: identifier (doesn't parse anything, just makes the value available)
- int identifier = FieldReaderFactory.readVirtualField(int.class, StaticHelper.readIdentifier(rawId), WithOption.WithName("identifier"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
-
- // Virtual Field: extended (doesn't parse anything, just makes the value available)
- boolean extended = FieldReaderFactory.readVirtualField(boolean.class, StaticHelper.isExtended(rawId), WithOption.WithName("extended"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
-
- // Virtual Field: remote (doesn't parse anything, just makes the value available)
- boolean remote = FieldReaderFactory.readVirtualField(boolean.class, StaticHelper.isRemote(rawId), WithOption.WithName("remote"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
-
- // Virtual Field: error (doesn't parse anything, just makes the value available)
- boolean error = FieldReaderFactory.readVirtualField(boolean.class, StaticHelper.isError(rawId), WithOption.WithName("error"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
-
- // Implicit Field: size
- short size = FieldReaderFactory.readImplicitField(DataReaderFactory.readUnsignedShort(readBuffer, 8), WithOption.WithName("size"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
-
- // Reserved Field
- FieldReaderFactory.readReservedField(DataReaderFactory.readUnsignedShort(readBuffer, 8), (short) 0x0, WithOption.WithName("SocketCANFrame.reserved6"));
-
- // Reserved Field
- FieldReaderFactory.readReservedField(DataReaderFactory.readUnsignedShort(readBuffer, 8), (short) 0x0, WithOption.WithName("SocketCANFrame.reserved7"));
-
- // Reserved Field
- FieldReaderFactory.readReservedField(DataReaderFactory.readUnsignedShort(readBuffer, 8), (short) 0x0, WithOption.WithName("SocketCANFrame.reserved8"));
-
- // Array Field: data
- byte[] data = readBuffer.readBits(Math.toIntExact((size) * 8), WithOption.WithName("data"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
-
- // Padding Field: padding10
- FieldReaderFactory.readPaddingField(DataReaderFactory.readUnsignedShort(readBuffer, 8), (int) (8) - ((org.apache.plc4x.java.spi.utils.StaticHelper.COUNT(data))));
-
- readBuffer.popContext();
- return new SocketCANFrame(rawId, data);
- }
-
- @Override
- public void serialize(WriteBuffer writeBuffer) throws BufferException {
- writeBuffer.pushContext(WithOption.WithName("SocketCANFrame"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
- int startPos = writeBuffer.getPositionInBits();
- boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
- // Simple Field: rawId
- FieldWriterFactory.writeSimpleField((int) rawId, DataWriterFactory.writeSignedInt(writeBuffer, 32), WithOption.WithName("rawId"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
-
- // Virtual Field: identifier (doesn't serialize anything, just makes the value available)
- int identifier = (int) getIdentifier();
-
- // Virtual Field: extended (doesn't serialize anything, just makes the value available)
- boolean extended = (boolean) getExtended();
-
- // Virtual Field: remote (doesn't serialize anything, just makes the value available)
- boolean remote = (boolean) getRemote();
-
- // Virtual Field: error (doesn't serialize anything, just makes the value available)
- boolean error = (boolean) getError();
-
- // Implicit Field: size
- short size = (short) (org.apache.plc4x.java.spi.utils.StaticHelper.COUNT(data));
- FieldWriterFactory.writeImplicitField((short) size, DataWriterFactory.writeUnsignedShort(writeBuffer, 8), WithOption.WithName("size"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
-
- // Reserved Field
- FieldWriterFactory.writeReservedField((short) 0x0, DataWriterFactory.writeUnsignedShort(writeBuffer, 8));
-
- // Reserved Field
- FieldWriterFactory.writeReservedField((short) 0x0, DataWriterFactory.writeUnsignedShort(writeBuffer, 8));
-
- // Reserved Field
- FieldWriterFactory.writeReservedField((short) 0x0, DataWriterFactory.writeUnsignedShort(writeBuffer, 8));
-
- // Array Field: data
- FieldWriterFactory.writeByteArrayField(data, DataWriterFactory.writeByteArray(writeBuffer, (int) ((data != null) ? data.length : 0)), WithOption.WithName("data"), WithOption.WithFloatEncoding("IEEE754"), WithOption.WithSignedIntegerEncoding("twos-complement"), WithOption.WithUnsignedIntegerEncoding("unsigned-binary"), WithByteBasedOption.WithByteOrder("LITTLE_ENDIAN"), WithOption.WithStringEncoding("UTF8"));
-
- // Padding Field: padding10
- FieldWriterFactory.writePaddingField((int) (8) - ((org.apache.plc4x.java.spi.utils.StaticHelper.COUNT(data))), (short) 0x00, DataWriterFactory.writeUnsignedShort(writeBuffer, 8));
-
- writeBuffer.popContext();
- }
-
- @Override
- public int getLengthInBytes() {
- return (int) Math.ceil((float) getLengthInBits() / 8.0);
- }
-
- @Override
- public int getLengthInBits() {
- int lengthInBits = 0;
- SocketCANFrame _value = this;
- boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
- // Simple Field: rawId
- lengthInBits += 32;
-
- // Virtual Field: identifier (doesn't produce any output, just makes the value available)
-
- // Virtual Field: extended (doesn't produce any output, just makes the value available)
-
- // Virtual Field: remote (doesn't produce any output, just makes the value available)
-
- // Virtual Field: error (doesn't produce any output, just makes the value available)
-
- // Implicit Field: size
- lengthInBits += 8;
-
- // Reserved Field
- lengthInBits += 8;
-
- // Reserved Field
- lengthInBits += 8;
-
- // Reserved Field
- lengthInBits += 8;
-
- // Array Field: data
- lengthInBits += 8 * ((data != null) ? data.length : 0);
-
- // Padding Field: padding10
- lengthInBits += 8 * ((int) (8) - ((org.apache.plc4x.java.spi.utils.StaticHelper.COUNT(data))));
-
- return lengthInBits;
- }
-}
diff --git a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/socketcan/readwrite/utils/StaticHelper.java b/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/socketcan/readwrite/utils/StaticHelper.java
deleted file mode 100644
index 42a7d61ec0..0000000000
--- a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/socketcan/readwrite/utils/StaticHelper.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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
- *
- * https://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.java.socketcan.readwrite.utils;
-
-public class StaticHelper {
-
- public static final int EFF_FLAG = 0b10000000_00000000_00000000_00000000;
- public static final int RTR_FLAG = 0b01000000_00000000_00000000_00000000;
- public static final int ERR_FLAG = 0b00100000_00000000_00000000_00000000;
- public static final int SFF_MASK = 0b00000000_00000000_00000111_11111111;
- public static final int EFF_MASK = 0b00011111_11111111_11111111_11111111;
- public static final int ERR_MASK = EFF_MASK;
-
- public static final int EXTENDED_FRAME_FORMAT_FLAG = 0x80000000;
-
- public static final int REMOTE_TRANSMISSION_FLAG = 0x40000000;
-
- public static final int ERROR_FRAME_FLAG = 0x20000000;
-
- public static final int STANDARD_FORMAT_IDENTIFIER_MASK = 0x7ff;
-
- public static final int EXTENDED_FORMAT_IDENTIFIER_MASK = 0x1fffffff;
-
- public static int readIdentifier(int identifier) {
- if ((isExtended(identifier))) {
- return identifier & EXTENDED_FORMAT_IDENTIFIER_MASK;
- }
- return identifier & STANDARD_FORMAT_IDENTIFIER_MASK;
- }
-
- public static boolean isExtended(int identifier) {
- return (identifier & EXTENDED_FRAME_FORMAT_FLAG) != 0;
- }
-
- public static boolean isRemote(int identifier) {
- return (identifier & REMOTE_TRANSMISSION_FLAG) != 0;
- }
-
- public static boolean isError(int identifier) {
- return (identifier & ERROR_FRAME_FLAG) != 0;
- }
-
-}
diff --git a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/SocketCANChannelFactory.java b/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/SocketCANChannelFactory.java
deleted file mode 100644
index eb18abf640..0000000000
--- a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/SocketCANChannelFactory.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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
- *
- * https://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.java.transport.socketcan;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.ThreadPerChannelEventLoop;
-import io.netty.channel.oio.OioEventLoopGroup;
-import org.apache.plc4x.java.spi.configuration.HasConfiguration;
-import org.apache.plc4x.java.spi.connection.NettyChannelFactory;
-import org.apache.plc4x.java.transport.can.CANTransportConfiguration;
-import org.apache.plc4x.java.transport.socketcan.netty.SocketCANChannel;
-import org.apache.plc4x.java.transport.socketcan.netty.address.SocketCANAddress;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SocketCANChannelFactory extends NettyChannelFactory implements HasConfiguration<CANTransportConfiguration> {
-
- private static final Logger logger = LoggerFactory.getLogger(SocketCANChannelFactory.class);
-
- private CANTransportConfiguration configuration;
-
- public SocketCANChannelFactory(SocketCANAddress address) {
- super(address);
- }
-
- @Override
- public void setConfiguration(CANTransportConfiguration configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public Class<? extends Channel> getChannel() {
- return SocketCANChannel.class;
- }
-
- @Override
- public boolean isPassive() {
- return true;
- }
-
- @Override
- public EventLoopGroup getEventLoopGroup() {
- return new ThreadPerChannelEventLoop(new OioEventLoopGroup());
- }
-
- @Override
- public void configureBootstrap(Bootstrap bootstrap) {
- if(configuration != null) {
- logger.info("Configuring Bootstrap with {}", configuration);
- }
- }
-
-}
diff --git a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/SocketCANFrameBuilder.java b/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/SocketCANFrameBuilder.java
deleted file mode 100644
index f2445b072f..0000000000
--- a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/SocketCANFrameBuilder.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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
- *
- * https://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.java.transport.socketcan;
-
-import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
-import org.apache.plc4x.java.socketcan.readwrite.SocketCANFrame;
-import org.apache.plc4x.java.transport.can.CANFrameBuilder;
-
-public class SocketCANFrameBuilder implements CANFrameBuilder<SocketCANFrame> {
-
- private int nodeId;
- private byte[] data;
-
- @Override
- public CANFrameBuilder<SocketCANFrame> withId(int nodeId) {
- this.nodeId = nodeId;
- return this;
- }
-
- @Override
- public CANFrameBuilder<SocketCANFrame> withData(byte[] data) {
- this.data = data;
- return this;
- }
-
- @Override
- public SocketCANFrame create() throws PlcRuntimeException {
- return new SocketCANFrame(nodeId, data);
- }
-
-}
diff --git a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/SocketCANTransport.java b/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/SocketCANTransport.java
deleted file mode 100644
index 382bcfad2a..0000000000
--- a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/SocketCANTransport.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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
- *
- * https://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.java.transport.socketcan;
-
-import io.netty.buffer.ByteBuf;
-
-import java.util.function.Function;
-import java.util.function.ToIntFunction;
-
-import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
-import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
-import org.apache.plc4x.java.socketcan.readwrite.SocketCANFrame;
-import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration;
-import org.apache.plc4x.java.spi.connection.ChannelFactory;
-import org.apache.plc4x.java.spi.generation.*;
-import org.apache.plc4x.java.transport.can.CANFrameBuilder;
-import org.apache.plc4x.java.transport.can.CANTransport;
-import org.apache.plc4x.java.transport.can.FrameData;
-import org.apache.plc4x.java.transport.socketcan.netty.address.SocketCANAddress;
-
-/**
- * CAN specific transport which rely on JavaCAN library.
- */
-public class SocketCANTransport implements CANTransport<SocketCANFrame> {
-
- @Override
- public String getTransportCode() {
- return "socketcan";
- }
-
- @Override
- public String getTransportName() {
- return "SocketCAN Transport (based on JavaCAN)";
- }
-
- @Override
- public ChannelFactory createChannelFactory(String transportConfig) {
- SocketCANAddress address = new SocketCANAddress(transportConfig);
- return new SocketCANChannelFactory(address);
- }
-
- @Override
- public ToIntFunction<ByteBuf> getEstimator() {
- return (buff) -> 16;
- }
-
- public static class EmptyConfiguration implements PlcTransportConfiguration {}
-
- @Override
- public Class<? extends PlcTransportConfiguration> getTransportConfigType() {
- return EmptyConfiguration.class;
- }
-
-
- @Override
- public MessageInput<SocketCANFrame> getMessageInput(PlcConnectionConfiguration cfg) {
- return SocketCANFrame::staticParse;
- }
-
- @Override
- public Class<SocketCANFrame> getMessageType() {
- return SocketCANFrame.class;
- }
-
- @Override
- public CANFrameBuilder<SocketCANFrame> getTransportFrameBuilder() {
- return new SocketCANFrameBuilder();
- }
-
- @Override
- public Function<SocketCANFrame, FrameData> adapter() {
- return frame -> new FrameData() {
- @Override
- public int getNodeId() {
- return frame.getIdentifier();
- }
-
- @Override
- public int getDataLength() {
- return frame.getData().length;
- }
-
- @Override
- public byte[] getData() {
- return frame.getData();
- }
-
- @Override
- public <T extends Message> T read(MessageInput<T> input) {
- try {
- return input.parse(new ReadBufferByteBased(frame.getData(), ByteOrder.LITTLE_ENDIAN));
- } catch (ParseException e) {
- throw new PlcRuntimeException(e);
- }
- }
- };
- }
-
-}
diff --git a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/netty/SocketCANChannel.java b/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/netty/SocketCANChannel.java
deleted file mode 100644
index 9633f322c4..0000000000
--- a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/netty/SocketCANChannel.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * 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
- *
- * https://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.java.transport.socketcan.netty;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelConfig;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelPromise;
-import io.netty.channel.EventLoop;
-import io.netty.channel.oio.OioByteStreamChannel;
-import org.apache.plc4x.java.transport.socketcan.netty.address.SocketCANAddress;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import tel.schich.javacan.CanChannels;
-import tel.schich.javacan.NetworkDevice;
-import tel.schich.javacan.RawCanChannel;
-import tel.schich.javacan.platform.linux.LinuxNetworkDevice;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.SocketAddress;
-import java.net.SocketTimeoutException;
-import java.nio.ByteBuffer;
-
-/**
- * A naive copy of pcap channel implementation which allows to pass over data to PLC4X as well as drop it back to JavaCAN.
- * Sadly all this involves double parsing.
- */
-public class SocketCANChannel extends OioByteStreamChannel {
-
- private final Logger logger = LoggerFactory.getLogger(SocketCANChannel.class);
-
- private final SocketCANChannelConfig config;
-
- private SocketCANAddress remoteRawSocketAddress;
- private SocketAddress localAddress;
- private RawCanChannel handle;
- private Thread loopThread;
-
- public SocketCANChannel() {
- super(null);
- config = new SocketCANChannelConfig(this);
- }
-
- @Override
- protected boolean isInputShutdown() {
- return false;
- }
-
- @Override
- protected ChannelFuture shutdownInput() {
- throw new UnsupportedOperationException("");
- }
-
- @Override
- protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
- if (!(remoteAddress instanceof SocketCANAddress)) {
- logger.error("Expecting remote address of type SocketCANAddress");
- pipeline().fireExceptionCaught(new IllegalArgumentException("Expecting remote address of type SocketCANAddress"));
- return;
- }
- this.localAddress = localAddress;
- remoteRawSocketAddress = (SocketCANAddress) remoteAddress;
-
- // Try to get the device name of the network interface that we want to open.
- String interfaceName = getInterfaceName(remoteRawSocketAddress);
- if(interfaceName == null) {
- logger.error("Interface name is not specified and couldn't detect it automatically");
- pipeline().fireExceptionCaught(new IllegalArgumentException("Interface name is not specified and couldn't detect it automatically"));
- return;
- }
-
- NetworkDevice device = LinuxNetworkDevice.lookup(interfaceName);
- // Get a handle to the network-device and open it.
- handle = CanChannels.newRawChannel(device);
-
- if(logger.isDebugEnabled()) {
- logger.debug(String.format("Listening on device %s", interfaceName));
- }
-
- // TODO If the address allows fine tuning which packets to process, set a filter to reduce the load.
-// String filter =
-// if(filter.length() > 0) {
-// handle.setFilter(filter, BpfProgram.BpfCompileMode.OPTIMIZE);
-// }
-
- // Create a buffer where the raw socket worker can send data to.
- ByteBuf buffer = Unpooled.buffer();
-
- // Start a thread that processes the callbacks from the raw socket and simply
- // forwards the bytes read to the buffer.
- loopThread = new Thread(() -> {
- try {
- ByteBuffer byteBuffer = ByteBuffer.allocateDirect(16);
- while (!isInputShutdown()) {
- handle.readUnsafe(byteBuffer);
- buffer.writeBytes(byteBuffer);
- byteBuffer.rewind();
- }
- } catch (Exception e) {
- logger.warn("Could not read data", e);
- pipeline().fireExceptionCaught(e);
- } catch (Throwable e) {
- logger.warn("Fatal error while handling CAN communication", e);
- pipeline().fireExceptionCaught(e);
- }
- }, "javacan-reader");
- loopThread.start();
-
- activate(new CANInputStream(buffer), new CANOutputStream(handle));
- }
-
- @Override
- protected SocketAddress localAddress0() {
- return localAddress;
- }
-
- @Override
- protected SocketAddress remoteAddress0() {
- return remoteRawSocketAddress;
- }
-
- @Override
- protected void doBind(SocketAddress localAddress) {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- @Override
- protected void doDisconnect() {
- this.loopThread.interrupt();
- if (this.handle != null) {
- try {
- this.handle.close();
- } catch (IOException e) {
- logger.error("Failed to close CAN socket!");
- }
- }
- }
-
- @Override
- protected int doReadBytes(ByteBuf buf) throws Exception {
- if (handle == null || !handle.isOpen()) {
- return -1;
- }
- try {
- return super.doReadBytes(buf);
- } catch (SocketTimeoutException ignored) {
- return 0;
- }
- }
-
- @Override
- protected boolean isCompatible(EventLoop loop) {
- return super.isCompatible(loop);
- }
-
- @Override
- public ChannelConfig config() {
- return this.config;
- }
-
- @Override
- public boolean isOpen() {
- return true;
- }
-
- @Override
- protected AbstractUnsafe newUnsafe() {
- return new RawSocketUnsafe();
- }
-
- private String getInterfaceName(SocketCANAddress address) {
- // If the device name is provided, simply use this.
- if(address.getInterfaceName() != null) {
- return address.getInterfaceName();
- }
-
- // TODO: Implement this ...
- return null;
- }
-
- /**
- * InputStream that fulfills the contract of Netty for read operations to timeout.
- * Without this the InputStream would simply block indefinitely which would block
- * the entire IO module.
- */
- private static class CANInputStream extends InputStream {
- final ByteBuf buf;
-
- private CANInputStream(ByteBuf buf) {
- this.buf = buf;
- }
-
- @Override
- public int available() {
- return buf.readableBytes();
- }
-
- @Override
- public int read() throws IOException {
- // Timeout 10 ms
- final long timeout = System.nanoTime() + 10_000;
- // Yes, this could make the thread go nuts in case of no data,
- // but the Netty guys are doing it the same way and there probably
- // is a reason for it ;-)
- while (System.nanoTime() < timeout) {
- if (buf.readableBytes() > 0) {
- return buf.readByte() & 0xFF;
- }
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- throw new IOException(e);
- }
- }
- throw new SocketTimeoutException();
- }
-
- }
-
-
- private static class CANOutputStream extends OutputStream {
-
- private final RawCanChannel rawCanChannel;
- private final ByteBuffer buffer = ByteBuffer.allocateDirect(16);
-
- public CANOutputStream(RawCanChannel rawCanChannel) {
- this.rawCanChannel = rawCanChannel;
- }
-
- @Override
- public void write(int b) throws IOException {
- throw new IOException("Appending single bytes is not permitted. Use write(byte[], int, int)");
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- buffer.put(b, off, len);
- buffer.flip();
- rawCanChannel.writeUnsafe(buffer);
- // the NIO clear call does clear positions and limits, but does not erase contents of buffer.
- // since we write a complete frame with length any remaining data at the end of memory block
- // should be ignored. When we get payload of full length it will eventually override earlier data
- // which was not used
- buffer.clear();
- }
- }
-
- /**
- * Internal helper to wrap access to unsafe operations (Only used internally by netty)
- */
- private class RawSocketUnsafe extends AbstractUnsafe {
- @Override
- public void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
- try {
- doConnect(remoteAddress, localAddress);
- pipeline().fireChannelActive();
- promise.setSuccess();
- } catch (Exception e) {
- promise.setFailure(e);
- }
- }
- }
-
-}
diff --git a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/netty/SocketCANChannelConfig.java b/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/netty/SocketCANChannelConfig.java
deleted file mode 100644
index 0430116799..0000000000
--- a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/netty/SocketCANChannelConfig.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
- *
- * https://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.java.transport.socketcan.netty;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelConfig;
-import io.netty.channel.DefaultChannelConfig;
-
-public class SocketCANChannelConfig extends DefaultChannelConfig implements ChannelConfig {
-
- public SocketCANChannelConfig(Channel channel) {
- super(channel);
- }
-
-}
diff --git a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/netty/address/SocketCANAddress.java b/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/netty/address/SocketCANAddress.java
deleted file mode 100644
index 7d3cf45f55..0000000000
--- a/plc4j/transports/socketcan/src/main/java/org/apache/plc4x/java/transport/socketcan/netty/address/SocketCANAddress.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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
- *
- * https://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.java.transport.socketcan.netty.address;
-
-import java.net.SocketAddress;
-
-/**
- * Simple address implementation which covers only interface name.
- */
-public class SocketCANAddress extends SocketAddress {
-
- private static final long serialVersionUID = 1L;
-
- private final String interfaceName;
-
- public SocketCANAddress(String interfaceName) {
- this.interfaceName = interfaceName;
- }
-
- public String getInterfaceName() {
- return interfaceName;
- }
-
-}
diff --git a/plc4j/transports/socketcan/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.transports.api.Transport b/plc4j/transports/socketcan/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.transports.api.Transport
deleted file mode 100644
index 41e97c1060..0000000000
--- a/plc4j/transports/socketcan/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.transports.api.Transport
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# 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
-#
-# https://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.java.transport.socketcan.SocketCANTransport
\ No newline at end of file
diff --git a/plc4j/transports/virtualcan/pom.xml b/plc4j/transports/virtualcan/pom.xml
deleted file mode 100644
index daf1f9dcee..0000000000
--- a/plc4j/transports/virtualcan/pom.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- https://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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsd">
-
- <modelVersion>4.1.0</modelVersion>
-
- <parent>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-transports</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>plc4j-transports-virtualcan</artifactId>
- <name>PLC4J: Transports: VirtualCAN</name>
- <description>Virtual CAN transport which does work without any real CAN interface.</description>
-
- <properties>
- <project.build.outputTimestamp>2025-08-02T13:55:11Z</project.build.outputTimestamp>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-api</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-spi</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-transports-can</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-transports-test</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
- <Bundle-Activator>org.apache.plc4x.java.osgi.TransportActivator</Bundle-Activator>
- <Export-Service>org.apache.plc4x.java.spi.transport.Transport,org.apache.plc4x.java.transport.virtualcan.VirtualCANTransport</Export-Service>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
diff --git a/plc4j/transports/virtualcan/src/main/java/org/apache/plc4x/java/transport/virtualcan/VirtualCANFrame.java b/plc4j/transports/virtualcan/src/main/java/org/apache/plc4x/java/transport/virtualcan/VirtualCANFrame.java
deleted file mode 100644
index f1992fba20..0000000000
--- a/plc4j/transports/virtualcan/src/main/java/org/apache/plc4x/java/transport/virtualcan/VirtualCANFrame.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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
- *
- * https://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.java.transport.virtualcan;
-
-import static org.apache.plc4x.java.spi.codegen.fields.FieldWriterFactory.*;
-import static org.apache.plc4x.java.spi.codegen.fields.FieldReaderFactory.*;
-import static org.apache.plc4x.java.spi.codegen.io.DataWriterFactory.*;
-
-import org.apache.commons.codec.binary.Hex;
-import org.apache.plc4x.java.spi.codegen.WithOption;
-import org.apache.plc4x.java.spi.generation.ByteOrder;
-import org.apache.plc4x.java.spi.generation.Message;
-import org.apache.plc4x.java.spi.generation.MessageInput;
-import org.apache.plc4x.java.spi.generation.ParseException;
-import org.apache.plc4x.java.spi.generation.ReadBuffer;
-import org.apache.plc4x.java.spi.generation.SerializationException;
-import org.apache.plc4x.java.spi.generation.WriteBuffer;
-
-public class VirtualCANFrame implements Message {
-
- public final static MessageInput<VirtualCANFrame> PARSER = new MessageInput<VirtualCANFrame>() {
-
- @Override
- public VirtualCANFrame parse(ReadBuffer io) throws ParseException {
- WithOption withOption = WithOption.WithByteOrder(ByteOrder.LITTLE_ENDIAN);
-
- short length = io.readUnsignedShort("length", 8, withOption);
- int nodeId = io.readInt("nodeId", 32, withOption);
- byte[] data = io.readByteArray("data", length, withOption);
-
- return new VirtualCANFrame(nodeId, data);
- }
- };
-
- private final int nodeId;
- private final byte[] data;
-
- public VirtualCANFrame(int nodeId, byte[] data) {
- this.nodeId = nodeId;
- this.data = data;
- }
-
- public int getNodeId() {
- return nodeId;
- }
-
- public byte[] getData() {
- return data;
- }
-
- @Override
- public void serialize(WriteBuffer writeBuffer) throws SerializationException {
- WithOption withOption = WithOption.WithByteOrder(ByteOrder.LITTLE_ENDIAN);
-
- writeSimpleField("length", (short) data.length, writeUnsignedShort(writeBuffer, 8), withOption);
- writeSimpleField("nodeId", nodeId, writeSignedInt(writeBuffer, 32), withOption);
- writeByteArrayField("data", data, writeByteArray(writeBuffer, 8), withOption);
- }
-
-
- @Override
- public int getLengthInBytes() {
- return 1 + 4 + data.length;
- }
-
- @Override
- public int getLengthInBits() {
- return getLengthInBytes() * 8;
- }
-
- public String toString() {
- return "VirtualCANFrame " + nodeId + "[" + data.length + "]" + Hex.encodeHexString(data);
- }
-}
diff --git a/plc4j/transports/virtualcan/src/main/java/org/apache/plc4x/java/transport/virtualcan/VirtualCANTransport.java b/plc4j/transports/virtualcan/src/main/java/org/apache/plc4x/java/transport/virtualcan/VirtualCANTransport.java
deleted file mode 100644
index 18322c98a2..0000000000
--- a/plc4j/transports/virtualcan/src/main/java/org/apache/plc4x/java/transport/virtualcan/VirtualCANTransport.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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
- *
- * https://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.java.transport.virtualcan;
-
-import io.netty.buffer.ByteBuf;
-import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
-import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
-import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration;
-import org.apache.plc4x.java.spi.generation.*;
-import org.apache.plc4x.java.transport.can.CANFrameBuilder;
-import org.apache.plc4x.java.transport.can.CANTransport;
-import org.apache.plc4x.java.transport.can.FrameData;
-import org.apache.plc4x.java.transport.test.TestTransport;
-
-import java.util.function.Function;
-import java.util.function.ToIntFunction;
-
-public class VirtualCANTransport extends TestTransport implements CANTransport<VirtualCANFrame> {
-
- @Override
- public String getTransportCode() {
- return "virtualcan"; // vcan is used by socketcan, using virtualcan to avoid mismatches
- }
-
- @Override
- public String getTransportName() {
- return "Virtual CAN";
- }
-
- @Override
- public ToIntFunction<ByteBuf> getEstimator() {
- return ByteBuf::readableBytes;
- }
-
- @Override
- public Class<VirtualCANFrame> getMessageType() {
- return VirtualCANFrame.class;
- }
-
- public static class EmptyConfiguration implements PlcTransportConfiguration {}
-
- @Override
- public Class<? extends PlcTransportConfiguration> getTransportConfigType() {
- return EmptyConfiguration.class;
- }
-
- @Override
- public CANFrameBuilder<VirtualCANFrame> getTransportFrameBuilder() {
- return new CANFrameBuilder<>() {
-
- private byte[] data;
- private int nodeId;
-
- @Override
- public CANFrameBuilder<VirtualCANFrame> withId(int nodeId) {
- this.nodeId = nodeId;
- return this;
- }
-
- @Override
- public CANFrameBuilder<VirtualCANFrame> withData(byte[] data) {
- this.data = data;
- return this;
- }
-
- @Override
- public VirtualCANFrame create() {
- return new VirtualCANFrame(nodeId, data);
- }
- };
- }
-
- @Override
- public Function<VirtualCANFrame, FrameData> adapter() {
- return frame -> new FrameData() {
- @Override
- public int getNodeId() {
- return frame.getNodeId();
- }
-
- @Override
- public <T extends Message> T read(MessageInput<T> input) {
- try {
- return input.parse(new ReadBufferByteBased(getData(), ByteOrder.LITTLE_ENDIAN));
- } catch (ParseException e) {
- throw new PlcRuntimeException(e);
- }
- }
-
- @Override
- public int getDataLength() {
- return frame.getData().length;
- }
-
- @Override
- public byte[] getData() {
- return frame.getData();
- }
- };
- }
-
- @Override
- public MessageInput<VirtualCANFrame> getMessageInput(PlcConnectionConfiguration configuration) {
- return VirtualCANFrame.PARSER;
- }
-
-}
diff --git a/plc4j/transports/virtualcan/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.transports.api.Transport b/plc4j/transports/virtualcan/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.transports.api.Transport
deleted file mode 100644
index 93b1f846ec..0000000000
--- a/plc4j/transports/virtualcan/src/main/resources/META-INF/services/org.apache.plc4x.java.spi.transports.api.Transport
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# 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
-#
-# https://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.java.transport.virtualcan.VirtualCANTransport
\ No newline at end of file
diff --git a/plc4j/utils/pcap-replay/pom.xml b/plc4j/utils/pcap-replay/pom.xml
deleted file mode 100644
index 587ef84104..0000000000
--- a/plc4j/utils/pcap-replay/pom.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- https://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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsd">
-
- <parent>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-utils</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>plc4j-utils-pcap-replay</artifactId>
-
- <name>PLC4J: Utils: Pcap-Replay</name>
- <description>An implementation of a Netty Channel that uses a PCAP packet dump as input and simulates a raw socket
- device by replaying the recorded traffic.
- </description>
-
- <properties>
- <project.build.outputTimestamp>2025-08-02T13:55:11Z</project.build.outputTimestamp>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-utils-pcap-shared</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.pcap4j</groupId>
- <artifactId>pcap4j-core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.pcap4j</groupId>
- <artifactId>pcap4j-packetfactory-static</artifactId>
- <scope>runtime</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <configuration>
- <usedDependencies>
- <usedDependency>org.pcap4j:pcap4j-packetfactory-static</usedDependency>
- </usedDependencies>
- </configuration>
- </plugin>
-
- <!-- This is currently a work in progress ... skip this till it reaches a slightly more mature state -->
- <plugin>
- <groupId>org.sonarsource.scanner.maven</groupId>
- <artifactId>sonar-maven-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
diff --git a/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/PcapReplayChannel.java b/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/PcapReplayChannel.java
deleted file mode 100644
index ec0be02d1e..0000000000
--- a/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/PcapReplayChannel.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.pcapreplay.netty;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelConfig;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelPromise;
-import io.netty.channel.oio.OioByteStreamChannel;
-import org.apache.commons.lang3.NotImplementedException;
-import org.apache.plc4x.java.utils.pcap.netty.exception.PcapException;
-import org.apache.plc4x.java.utils.pcapreplay.netty.address.PcapReplayAddress;
-import org.apache.plc4x.java.utils.pcapreplay.netty.config.PcapReplayChannelConfig;
-import org.pcap4j.core.*;
-import org.pcap4j.packet.Packet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.SocketAddress;
-import java.net.SocketTimeoutException;
-import java.sql.Timestamp;
-import java.util.concurrent.TimeUnit;
-
-public class PcapReplayChannel extends OioByteStreamChannel {
-
- private static final Logger logger = LoggerFactory.getLogger(PcapReplayChannel.class);
-
- private final PcapReplayChannelConfig config;
-
- private PcapReplayAddress remoteRawSocketAddress;
- private SocketAddress localAddress;
- private PcapHandle handle;
- private Thread loopThread;
-
- public PcapReplayChannel() {
- super(null);
- config = new PcapReplayChannelConfig(this);
- }
-
- @Override
- protected boolean isInputShutdown() {
- return false;
- }
-
- @Override
- protected ChannelFuture shutdownInput() {
- throw new NotImplementedException("");
- }
-
- @Override
- protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
- this.localAddress = localAddress;
-
- if (!(remoteAddress instanceof PcapReplayAddress)) {
- logger.error("Expecting remote address of type PcapSocketAddress");
- pipeline().fireExceptionCaught(new PcapException("Expecting remote address of type PcapSocketAddress"));
- return;
- }
- remoteRawSocketAddress = (PcapReplayAddress) remoteAddress;
-
- // Get a handle to the network-device and open it.
- File pcapFile = remoteRawSocketAddress.getPcapFile();
- if (!pcapFile.exists()) {
- logger.error("Couldn't find PCAP capture file at: {}", pcapFile.getAbsolutePath());
- PcapException exception = new PcapException(String.format("Couldn't find PCAP capture file at: %s", pcapFile.getAbsolutePath()));
- pipeline().fireExceptionCaught(exception);
- return;
- }
- logger.debug("Opening PCAP capture file at: {}", pcapFile.getAbsolutePath());
-
- handle = Pcaps.openOffline(remoteRawSocketAddress.getPcapFile().getAbsolutePath(),
- PcapHandle.TimestampPrecision.NANO);
-
- // If the address allows fine tuning which packets to process, set a filter to reduce the load.
- String filter = config.getFilter();
- if (filter.length() > 0) {
- handle.setFilter(filter, BpfProgram.BpfCompileMode.OPTIMIZE);
- }
-
- // Create a buffer where the raw socket worker can send data to.
- ByteBuf buffer = Unpooled.buffer();
-
- // Start a thread that processes the callbacks from the raw socket and simply
- // forwards the bytes read to the buffer.
- loopThread = new Thread(() -> {
- try {
- handle.loop(-1, new PacketListener() {
- private Timestamp lastPacketTime = null;
-
- @Override
- public void gotPacket(Packet packet) {
- Timestamp curPacketTime = handle.getTimestamp();
-
- // Only enable the throttling if it is not disabled.
- if (config.getSpeedFactor() != PcapReplayChannelConfig.SPEED_FAST_FULL) {
- // If last-time is not null, wait for the given number of nano-seconds.
- if (lastPacketTime != null) {
- int numMicrosecondsSleep = (int)
- ((curPacketTime.getNanos() - lastPacketTime.getNanos()) / config.getSpeedFactor());
- nanoSecondSleep(numMicrosecondsSleep);
- }
- }
-
- // Send the bytes to the netty pipeline.
- byte[] data = config.getPacketHandler().getData(packet);
- if (data != null) {
- buffer.writeBytes(data);
- }
-
- // Remember the timestamp of the current packet.
- lastPacketTime = curPacketTime;
- }
- });
- } catch (PcapNativeException | NotOpenException e) {
- logger.error("PCAP loop thread died!", e);
- pipeline().fireExceptionCaught(e);
- } catch (InterruptedException e) {
- logger.warn("PCAP loop thread was interrupted (hopefully intentionally)", e);
- Thread.currentThread().interrupt();
- }
- });
- loopThread.start();
-
- // Right now we're using an output stream that simply discards everything.
- // This is ok while implementing passive drivers for protocols, however as
- // soon as we start implementing ethernet layer protocols, we'll have to also
- // be able to actually send data. The PcapInputStream simply acts as a
- // breaking point if no packets are coming in and the read operation would
- // simply block indefinitely.
- activate(new PcapInputStream(buffer), new DiscardingOutputStream());
- }
-
- @Override
- protected SocketAddress localAddress0() {
- return localAddress;
- }
-
- @Override
- protected SocketAddress remoteAddress0() {
- return remoteRawSocketAddress;
- }
-
- @Override
- protected void doBind(SocketAddress localAddress) {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- @Override
- protected void doDisconnect() {
- this.loopThread.interrupt();
- if (this.handle != null) {
- this.handle.close();
- }
- }
-
- @Override
- protected int doReadBytes(ByteBuf buf) throws Exception {
- if (handle == null || !handle.isOpen()) {
- return -1;
- }
- try {
- return super.doReadBytes(buf);
- } catch (SocketTimeoutException ignored) {
- return 0;
- }
- }
-
- @Override
- public ChannelConfig config() {
- return this.config;
- }
-
- @Override
- public boolean isOpen() {
- return true;
- }
-
- @Override
- protected AbstractUnsafe newUnsafe() {
- return new RawSocketUnsafe();
- }
-
- private void nanoSecondSleep(long numNanos) {
- try {
- TimeUnit.NANOSECONDS.sleep(numNanos);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
-
- /**
- * This output stream simply discards anything it should send.
- */
- private static class DiscardingOutputStream extends OutputStream {
- @Override
- public void write(int b) throws IOException {
- // discard
- logger.debug("Discarding {}", b);
- }
-
- @Override
- public void write(byte[] b, int off, int len) {
- logger.debug("Discarding {}", b);
- }
- }
-
- /**
- * InputStream that fulfills the contract of Netty for read operations to timeout.
- * Without this the InputStream would simply block indefinitely which would block
- * the entire IO module.
- */
- private static class PcapInputStream extends InputStream {
- final ByteBuf buf;
-
- private PcapInputStream(ByteBuf buf) {
- this.buf = buf;
- }
-
- @Override
- public int available() {
- return buf.readableBytes();
- }
-
- @Override
- public int read() throws IOException {
- // Timeout 10 ms
- final long timeout = System.nanoTime() + 10_000;
- // Yes, this could make the thread go nuts in case of no data,
- // but the Netty guys are doing it the same way and there probably
- // is a reason for it ;-)
- while (System.nanoTime() < timeout) {
- if (buf.readableBytes() > 0) {
- return buf.readByte() & 0xFF;
- }
- }
- throw new SocketTimeoutException();
- }
- }
-
- /**
- * Internal helper to wrap access to unsafe operations (Only used internally by netty)
- */
- private class RawSocketUnsafe extends AbstractUnsafe {
- @Override
- public void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
- try {
- doConnect(remoteAddress, localAddress);
- pipeline().fireChannelActive();
- promise.setSuccess();
- } catch (Exception e) {
- promise.setFailure(e);
- }
- }
- }
-
-}
diff --git a/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/address/PcapReplayAddress.java b/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/address/PcapReplayAddress.java
deleted file mode 100644
index 28bcd1edd8..0000000000
--- a/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/address/PcapReplayAddress.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.pcapreplay.netty.address;
-
-import org.apache.plc4x.java.utils.pcap.netty.address.PcapSocketAddress;
-
-import java.io.File;
-
-public class PcapReplayAddress extends PcapSocketAddress {
-
- private static final long serialVersionUID = 1L;
-
- private final File pcapFile;
-
- public PcapReplayAddress(File pcapFile) {
- this.pcapFile = pcapFile;
- }
-
- public File getPcapFile() {
- return pcapFile;
- }
-
-}
diff --git a/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/config/PcapReplayChannelConfig.java b/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/config/PcapReplayChannelConfig.java
deleted file mode 100644
index 08ec928ba6..0000000000
--- a/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/config/PcapReplayChannelConfig.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.pcapreplay.netty.config;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelOption;
-import org.apache.plc4x.java.utils.pcap.netty.config.PcapChannelConfig;
-
-import java.util.Map;
-
-public class PcapReplayChannelConfig extends PcapChannelConfig {
-
- public static final float SPEED_SLOW_HALF = 0.5f;
- public static final float SPEED_REALTIME = 1f;
- public static final float SPEED_FAST_DOUBLE = 2f;
- public static final float SPEED_FAST_FULL = 0f;
-
- private float speedFactor = SPEED_REALTIME;
- private boolean loop = false;
- private String filter = "";
-
- public PcapReplayChannelConfig(Channel channel) {
- super(channel);
- }
-
- @Override
- public Map<ChannelOption<?>, Object> getOptions() {
- return getOptions(super.getOptions(), PcapReplayChannelOption.SPEED_FACTOR);
- }
-
- @Override
- public <T> boolean setOption(ChannelOption<T> option, T value) {
- if (option == PcapReplayChannelOption.SPEED_FACTOR) {
- if (value instanceof Float) {
- speedFactor = (Float) value;
- return speedFactor >= 0;
- }
- return false;
- } else if (option == PcapReplayChannelOption.LOOP) {
- if (value instanceof Boolean) {
- loop = (Boolean) value;
- return true;
- }
- return false;
- } else if (option == PcapReplayChannelOption.FILTER) {
- if (value instanceof String) {
- filter = (String) value;
- return true;
- }
- return false;
- } else {
- return super.setOption(option, value);
- }
- }
-
- public float getSpeedFactor() {
- return speedFactor;
- }
-
- public void setSpeedFactor(float speedFactor) {
- this.speedFactor = speedFactor;
- }
-
- public boolean isLoop() {
- return loop;
- }
-
- public void setLoop(boolean loop) {
- this.loop = loop;
- }
-
- public String getFilter() {
- return filter;
- }
-
- public void setFilter(String filter) {
- this.filter = filter;
- }
-}
diff --git a/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/config/PcapReplayChannelOption.java b/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/config/PcapReplayChannelOption.java
deleted file mode 100644
index fefe74bc9e..0000000000
--- a/plc4j/utils/pcap-replay/src/main/java/org/apache/plc4x/java/utils/pcapreplay/netty/config/PcapReplayChannelOption.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.pcapreplay.netty.config;
-
-import io.netty.channel.ChannelOption;
-import org.apache.plc4x.java.utils.pcap.netty.config.PcapChannelOption;
-
-public class PcapReplayChannelOption extends PcapChannelOption {
-
- /**
- * Option to increase/decrease the replay speed of the recording.
- * 1.0 being real-time.
- */
- public static final ChannelOption<Float> SPEED_FACTOR =
- ChannelOption.valueOf(Float.class, "SPEED_FACTOR");
-
- /**
- * Option to tell the playback to automatically restart at the
- * beginning as soon as the end of the playback is reached.
- */
- public static final ChannelOption<Boolean> LOOP =
- ChannelOption.valueOf(Boolean.class, "LOOP");
-
- /**
- * set a BPF filter
- */
- public static final ChannelOption<String> FILTER =
- ChannelOption.valueOf(String.class, "FILTER");
-
-}
diff --git a/plc4j/utils/pcap-shared/pom.xml b/plc4j/utils/pcap-shared/pom.xml
deleted file mode 100644
index b861df98f7..0000000000
--- a/plc4j/utils/pcap-shared/pom.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- https://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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsd">
-
- <parent>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-utils</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>plc4j-utils-pcap-shared</artifactId>
-
- <name>PLC4J: Utils: Pcap (Shared)</name>
- <description>Classes shared between all PCAP related channels.</description>
-
- <properties>
- <project.build.outputTimestamp>2025-08-02T13:55:11Z</project.build.outputTimestamp>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.pcap4j</groupId>
- <artifactId>pcap4j-core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.pcap4j</groupId>
- <artifactId>pcap4j-packetfactory-static</artifactId>
- <scope>runtime</scope>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <configuration>
- <usedDependencies>
- <usedDependency>org.pcap4j:pcap4j-packetfactory-static</usedDependency>
- </usedDependencies>
- </configuration>
- </plugin>
-
- <!-- This is currently a work in progress ... skip this till it reaches a slightly more mature state -->
- <plugin>
- <groupId>org.sonarsource.scanner.maven</groupId>
- <artifactId>sonar-maven-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
\ No newline at end of file
diff --git a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/address/PcapSocketAddress.java b/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/address/PcapSocketAddress.java
deleted file mode 100644
index e5d3a13218..0000000000
--- a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/address/PcapSocketAddress.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.pcap.netty.address;
-
-import java.net.SocketAddress;
-
-public class PcapSocketAddress extends SocketAddress {
-
-}
diff --git a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/config/PcapChannelConfig.java b/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/config/PcapChannelConfig.java
deleted file mode 100644
index b1b0ab4096..0000000000
--- a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/config/PcapChannelConfig.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.pcap.netty.config;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelConfig;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.DefaultChannelConfig;
-import org.apache.plc4x.java.utils.pcap.netty.handlers.PacketHandler;
-import org.pcap4j.core.Pcaps;
-import org.pcap4j.packet.Packet;
-import org.pcap4j.util.MacAddress;
-
-import java.net.SocketAddress;
-import java.util.Map;
-
-public class PcapChannelConfig extends DefaultChannelConfig implements ChannelConfig {
-
- public static final int ALL_PROTOCOLS = -1;
- public static final int ALL_PORTS = -1;
-
- private boolean supportVlans = false;
- private int protocolId = ALL_PROTOCOLS;
- private int port = ALL_PORTS;
- private PacketHandler packetHandler = Packet::getRawData;
- private boolean resolveMacAddress = false;
-
- public PcapChannelConfig(Channel channel) {
- super(channel);
- }
-
- public PcapChannelConfig clone() {
- PcapChannelConfig clone = new PcapChannelConfig(channel);
- clone.supportVlans = this.supportVlans;
- clone.protocolId = this.protocolId;
- clone.port = this.port;
- clone.packetHandler = this.packetHandler;
- clone.resolveMacAddress = this.resolveMacAddress;
- return clone;
- }
-
- @Override
- public Map<ChannelOption<?>, Object> getOptions() {
- return getOptions(super.getOptions(),
- PcapChannelOption.SUPPORT_VLANS, PcapChannelOption.PORT, PcapChannelOption.PROTOCOL_ID,
- PcapChannelOption.PACKET_HANDLER, PcapChannelOption.RESOLVE_MAC_ADDRESS);
- }
-
- @Override
- public <T> boolean setOption(ChannelOption<T> option, T value) {
- if (option == PcapChannelOption.SUPPORT_VLANS) {
- if (value instanceof Boolean) {
- supportVlans = (Boolean) value;
- return true;
- }
- return false;
- } else if (option == PcapChannelOption.PORT) {
- if (value instanceof Integer) {
- port = (Integer) value;
- return true;
- }
- return false;
- } else if (option == PcapChannelOption.PROTOCOL_ID) {
- if (value instanceof Integer) {
- protocolId = (Integer) value;
- return true;
- }
- return false;
- } else if (option == PcapChannelOption.PACKET_HANDLER) {
- if (value instanceof PacketHandler) {
- packetHandler = (PacketHandler) value;
- return true;
- }
- return false;
- } else if (option == PcapChannelOption.RESOLVE_MAC_ADDRESS) {
- if (value instanceof Boolean) {
- resolveMacAddress = (Boolean) value;
- return true;
- }
- return false;
- } else {
- return super.setOption(option, value);
- }
- }
-
- public boolean isSupportVlans() {
- return supportVlans;
- }
-
- public int getPort() {
- return port;
- }
-
- public void setPort(int port) {
- this.port = port;
- }
-
- public int getProtocolId() {
- return protocolId;
- }
-
- public void setProtocolId(int protocolId) {
- this.protocolId = protocolId;
- }
-
- public void setPacketHandler(PacketHandler packetHandler) {
- this.packetHandler = packetHandler;
- }
-
- public PacketHandler getPacketHandler() {
- return packetHandler;
- }
-
- public boolean isResolveMacAddress() {
- return resolveMacAddress;
- }
-
- public String getMacBasedFilterString(MacAddress localMacAddress, MacAddress remoteMacAddress) {
- StringBuilder sb = new StringBuilder();
- if (getProtocolId() != ALL_PROTOCOLS) {
- sb.append(" and (ether proto ").append(getProtocolId()).append(")");
- }
- // Add a filter for TCP or UDP port.
- if (getPort() != ALL_PORTS) {
- sb.append(" and (port ").append(getPort()).append(")");
- }
- // Add a filter for source or target address.
- if(localMacAddress != null) {
- sb.append(" and (ether dst ").append(Pcaps.toBpfString(localMacAddress)).append(")");
- }
- // Add a filter for source or target address.
- if(remoteMacAddress != null) {
- sb.append(" and (ether src ").append(Pcaps.toBpfString(remoteMacAddress)).append(")");
- }
- return (sb.length() > 0) ? sb.substring(" and ".length()) : "";
- }
-
- public String getMacBasedFilterString(SocketAddress localAddress, SocketAddress remoteAddress) {
- StringBuilder sb = new StringBuilder();
- if (isSupportVlans()) {
- final PcapChannelConfig clone = this.clone();
- clone.supportVlans = false;
- String subFilterString = clone.getMacBasedFilterString(localAddress, remoteAddress);
- if (subFilterString.isEmpty()) {
- sb.append(" and (vlan)");
- } else {
- sb.append(" and ((vlan and ").append(subFilterString).append(") or (").append(subFilterString).append("))");
- }
- } else {
- if (getProtocolId() != ALL_PROTOCOLS) {
- sb.append(" and (ether proto ").append(getProtocolId()).append(")");
- }
- // Add a filter for TCP or UDP port.
- if (getPort() != ALL_PORTS) {
- sb.append(" and (port ").append(getPort()).append(")");
- }
- // Add a filter for source or target address.
- /*if(localAddress != null) {
- sb.append(" and (host ").append(localAddress.getHostAddress()).append(")");
- }
- // Add a filter for source or target address.
- if(remoteAddress != null) {
- sb.append(" and (host ").append(localAddress.getHostAddress()).append(")");
- }*/
- }
- return (sb.length() > 0) ? sb.substring(" and ".length()) : "";
- }
-
-}
diff --git a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/config/PcapChannelOption.java b/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/config/PcapChannelOption.java
deleted file mode 100644
index c792ea32bf..0000000000
--- a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/config/PcapChannelOption.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.pcap.netty.config;
-
-import io.netty.channel.ChannelOption;
-import org.apache.plc4x.java.utils.pcap.netty.handlers.PacketHandler;
-
-public class PcapChannelOption {
-
- /**
- * Option to restrict the captures based on packet port.
- */
- public static final ChannelOption<Boolean> SUPPORT_VLANS =
- ChannelOption.valueOf(Boolean.class, "SUPPORT_VLANS");
-
- /**
- * Option to restrict the captures based on packet port.
- */
- public static final ChannelOption<Integer> PORT =
- ChannelOption.valueOf(Integer.class, "PORT");
-
- /**
- * Option to restrict the captures based on TCP protocol ids.
- */
- public static final ChannelOption<Integer> PROTOCOL_ID =
- ChannelOption.valueOf(Integer.class, "PROTOCOL_ID");
-
- /**
- * Option for providing a PacketHandler, that intercepts the captured packets
- * before passing the data into the channel.
- */
- public static final ChannelOption<PacketHandler> PACKET_HANDLER =
- ChannelOption.valueOf(PacketHandler.class, "PACKET_HANDLER");
-
- /**
- * Option for automatically resolving the remote ips MAC address with an
- * ARP request.
- */
- public static final ChannelOption<Boolean> RESOLVE_MAC_ADDRESS =
- ChannelOption.valueOf("RESOLVE_MAC_ADDRESS");
-
-
-}
diff --git a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/exception/PcapException.java b/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/exception/PcapException.java
deleted file mode 100644
index bb27518907..0000000000
--- a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/exception/PcapException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.pcap.netty.exception;
-
-public class PcapException extends Exception {
-
- public PcapException() {
- super();
- }
-
- public PcapException(String message) {
- super(message);
- }
-
- public PcapException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
diff --git a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/handlers/PacketHandler.java b/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/handlers/PacketHandler.java
deleted file mode 100644
index 8b2c8f2a77..0000000000
--- a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/handlers/PacketHandler.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.pcap.netty.handlers;
-
-import org.pcap4j.packet.Packet;
-
-public interface PacketHandler {
-
- byte[] getData(Packet packet);
-
-}
diff --git a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/handlers/TcpIpPacketHandler.java b/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/handlers/TcpIpPacketHandler.java
deleted file mode 100644
index f0d7633382..0000000000
--- a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/handlers/TcpIpPacketHandler.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.pcap.netty.handlers;
-
-import org.pcap4j.packet.*;
-
-/**
- * Little helper to automatically unwrap TCP packets to only
- * pass along the payload and not the raw Ethernet packet.
- */
-public class TcpIpPacketHandler implements PacketHandler {
-
- @Override
- public byte[] getData(Packet packet) {
- EthernetPacket ethernetPacket = (EthernetPacket) packet;
- IpV4Packet ipv4Packet = (IpV4Packet) ethernetPacket.getPayload();
- TcpPacket tcpPacket = (TcpPacket) ipv4Packet.getPayload();
- if(tcpPacket.getPayload() instanceof UnknownPacket) {
- UnknownPacket unknownPacket = (UnknownPacket) tcpPacket.getPayload();
- return unknownPacket.getRawData();
- }
- return new byte[0];
- }
-
-}
diff --git a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/handlers/UdpIpPacketHandler.java b/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/handlers/UdpIpPacketHandler.java
deleted file mode 100644
index 7c0efe14c7..0000000000
--- a/plc4j/utils/pcap-shared/src/main/java/org/apache/plc4x/java/utils/pcap/netty/handlers/UdpIpPacketHandler.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.pcap.netty.handlers;
-
-import org.pcap4j.packet.*;
-
-/**
- * Little helper to automatically unwrap UDP packets to only
- * pass along the payload and not the raw Ethernet packet.
- */
-public class UdpIpPacketHandler implements PacketHandler {
-
- @Override
- public byte[] getData(Packet packet) {
- EthernetPacket ethernetPacket = (EthernetPacket) packet;
- IpV4Packet ipv4Packet = (IpV4Packet) ethernetPacket.getPayload();
- UdpPacket udpPacket = (UdpPacket) ipv4Packet.getPayload();
- if(udpPacket.getPayload() instanceof UnknownPacket) {
- UnknownPacket unknownPacket = (UnknownPacket) udpPacket.getPayload();
- return unknownPacket.getRawData();
- }
- return new byte[0];
- }
-
-}
diff --git a/plc4j/utils/pcap-shared/src/main/remote-resources/META-INF/LICENSE b/plc4j/utils/pcap-shared/src/main/remote-resources/META-INF/LICENSE
deleted file mode 100644
index 3122c985ac..0000000000
--- a/plc4j/utils/pcap-shared/src/main/remote-resources/META-INF/LICENSE
+++ /dev/null
@@ -1,6 +0,0 @@
-
-----------------------------------------------
-
-The Files:
-src/main/java/org/apache/plc4x/java/utils/pcap/netty/exception/PcapException.java
-Are copyrighted by the The Netty Project which is distributed under the Apache 2.0 license.
diff --git a/plc4j/utils/pcap-shared/src/main/remote-resources/META-INF/NOTICE b/plc4j/utils/pcap-shared/src/main/remote-resources/META-INF/NOTICE
deleted file mode 100644
index ccad4c46b7..0000000000
--- a/plc4j/utils/pcap-shared/src/main/remote-resources/META-INF/NOTICE
+++ /dev/null
@@ -1,4 +0,0 @@
-----------------------------------------------
-
-This product includes software developed at
-The Netty project (https://netty.io/).
diff --git a/plc4j/utils/plc-simulator/pom.xml b/plc4j/utils/plc-simulator/pom.xml
deleted file mode 100644
index 4a5fed7e1e..0000000000
--- a/plc4j/utils/plc-simulator/pom.xml
+++ /dev/null
@@ -1,131 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- https://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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsd">
-
- <modelVersion>4.1.0</modelVersion>
-
- <parent>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-utils</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>plc4j-utils-plc-simulator</artifactId>
-
- <name>PLC4J: Utils: PLC-Simulator</name>
-
- <properties>
- <project.build.outputTimestamp>2025-08-02T13:55:11Z</project.build.outputTimestamp>
- </properties>
-
- <build>
- <plugins>
- <!-- Build a fat jar containing all dependencies -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <executions>
- <execution>
- <id>generate-uber-jar</id>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- <configuration>
- <transformers combine.children="append">
- <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>org.apache.plc4x.simulator.PlcSimulator</mainClass>
- </transformer>
- </transformers>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <!-- The Server is based on the same generated code as the client -->
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-driver-bacnet</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-driver-c-bus</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-driver-s7</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-api</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-collections4</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-cli</groupId>
- <artifactId>commons-cli</artifactId>
- </dependency>
-
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-common</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </dependency>
-
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <!-- Explicitly override the scope to compile to include these -->
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>compile</scope>
- </dependency>
- </dependencies>
-
-</project>
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/java/s7/utils/StaticHelper.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/java/s7/utils/StaticHelper.java
deleted file mode 100644
index c8d6bea263..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/java/s7/utils/StaticHelper.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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
- *
- * https://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.java.s7.utils;
-
-import org.apache.commons.lang3.NotImplementedException;
-import org.apache.plc4x.java.api.value.PlcValue;
-import org.apache.plc4x.java.spi.buffers.api.ReadBuffer;
-import org.apache.plc4x.java.spi.buffers.api.WithOption;
-import org.apache.plc4x.java.spi.buffers.api.WriteBuffer;
-import org.apache.plc4x.java.spi.buffers.api.exceptions.BufferException;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.temporal.ChronoUnit;
-
-public class StaticHelper {
-
- public static LocalTime parseTiaTime(ReadBuffer io) {
- try {
- int millisSinceMidnight = io.readSignedInt(32);
- return LocalTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0).plus(
- millisSinceMidnight, ChronoUnit.MILLIS);
- } catch (BufferException e) {
- return null;
- }
- }
-
- public static void serializeTiaTime(WriteBuffer io, PlcValue value) {
- throw new NotImplementedException("Serializing TIME not implemented");
- }
-
- public static LocalTime parseS5Time(ReadBuffer io) {
- try {
- int stuff = io.readSignedInt(16);
- // TODO: Implement this correctly.
- throw new NotImplementedException("S5TIME not implemented");
- } catch (BufferException e) {
- return null;
- }
- }
-
- public static void serializeS5Time(WriteBuffer io, PlcValue value) {
- throw new NotImplementedException("Serializing S5TIME not implemented");
-
- }
-
- public static LocalTime parseTiaLTime(ReadBuffer io) {
- throw new NotImplementedException("LTIME not implemented");
- }
-
- public static void serializeTiaLTime(WriteBuffer io, PlcValue value) {
- throw new NotImplementedException("Serializing LTIME not implemented");
- }
-
- public static LocalTime parseTiaTimeOfDay(ReadBuffer io) {
- try {
- long millisSinceMidnight = io.readUnsignedLong(32);
- return LocalTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0).plus(
- millisSinceMidnight, ChronoUnit.MILLIS);
- } catch (BufferException e) {
- return null;
- }
- }
-
- public static void serializeTiaTimeOfDay(WriteBuffer io, PlcValue value) {
- throw new NotImplementedException("Serializing TIME_OF_DAY not implemented");
- }
-
- public static LocalDate parseTiaDate(ReadBuffer io) {
- try {
- int daysSince1990 = io.readUnsignedInt(16);
- return LocalDate.now().withYear(1990).withDayOfMonth(1).withMonth(1).plus(daysSince1990, ChronoUnit.DAYS);
- } catch (BufferException e) {
- return null;
- }
- }
-
- public static void serializeTiaDate(WriteBuffer io, PlcValue value) {
- throw new NotImplementedException("Serializing DATE not implemented");
- }
-
- public static LocalDateTime parseTiaDateTime(ReadBuffer io) {
- try {
- int year = io.readUnsignedInt(16);
- int month = io.readUnsignedInt(8);
- int day = io.readUnsignedInt(8);
- // Skip day-of-week
- io.readSignedByte(8);
- int hour = io.readSignedByte(8);
- int minute = io.readSignedByte(8);
- int second = io.readSignedByte(8);
- int nanosecond = io.readUnsignedInt(24);
-
- return LocalDateTime.of(year, month, day, hour, minute, second, nanosecond);
- } catch (Exception e) {
- return null;
- }
- }
-
- public static void serializeTiaDateTime(WriteBuffer io, PlcValue value) {
- throw new NotImplementedException("Serializing DATE_AND_TIME not implemented");
- }
-
- public static String parseS7String(ReadBuffer io, int stringLength, Object encoding) {
- try {
- // This is the maximum number of bytes a string can be long.
- short maxLength = io.readUnsignedShort(8);
- // This is the total length of the string on the PLC (Not necessarily the number of characters read)
- short totalStringLength = io.readSignedShort(8);
- // Read the full size of the string.
- String str = io.readString(stringLength * 8, WithOption.WithEncoding((String) encoding));
- // Cut off the parts that don't belong to it.
- return str.substring(0, totalStringLength);
- } catch (BufferException e) {
- return null;
- }
- }
-
- public static void serializeS7String(WriteBuffer io, PlcValue value, int stringLength, Object encoding) {
- // TODO: Need to implement the serialization or we can't write strings
- throw new NotImplementedException("Serializing STRING not implemented");
- }
-
- public static String parseS7Char(ReadBuffer io, Object encoding) throws BufferException {
- // Read the full size of the string.
- return io.readString(8, WithOption.WithEncoding((String) encoding));
- }
-
- public static void serializeS7Char(WriteBuffer io, PlcValue value, Object encoding) {
- // TODO: Need to implement the serialization or we can't write strings
- throw new NotImplementedException("Serializing STRING not implemented");
- }
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/PlcSimulator.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/PlcSimulator.java
deleted file mode 100644
index 14e3868da5..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/PlcSimulator.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator;
-
-import org.apache.commons.cli.*;
-import org.apache.plc4x.simulator.model.Context;
-import org.apache.plc4x.simulator.server.ServerModule;
-import org.apache.plc4x.simulator.simulation.SimulationModule;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Map;
-import java.util.ServiceLoader;
-import java.util.TreeMap;
-import java.util.concurrent.TimeUnit;
-
-public class PlcSimulator {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(PlcSimulator.class);
-
- private boolean running;
- private final Map<String, ServerModule> serverModules;
- private final SimulationModule simulationModule;
-
- private PlcSimulator(String simulationName, PlcSimulatorConfig config) {
- this(simulationName, config, Thread.currentThread().getContextClassLoader());
- }
-
- private PlcSimulator(String simulationName, PlcSimulatorConfig config, ClassLoader classLoader) {
- Context context = null;
- // Initialize all the simulation modules.
- LOGGER.info("Initializing Simulation Modules:");
- SimulationModule foundSimulationModule = null;
- ServiceLoader<SimulationModule> simulationModuleLoader = ServiceLoader.load(SimulationModule.class, classLoader);
- for (SimulationModule curSimulationModule : simulationModuleLoader) {
- if (!curSimulationModule.getName().equals(simulationName)) {
- continue;
- }
- LOGGER.info("Initializing simulation module: {} ...", simulationName);
- foundSimulationModule = curSimulationModule;
- context = curSimulationModule.getContext();
- LOGGER.info("Initialized");
- }
- // If we couldn't find the simulation module provided, report an error and exit.
- if (foundSimulationModule == null) {
- LOGGER.info("Couldn't find simulation module {}", simulationName);
- System.exit(1);
- }
- simulationModule = foundSimulationModule;
- LOGGER.info("Finished Initializing Simulation Modules\n");
-
- // Initialize all the server modules.
- LOGGER.info("Initializing Server Modules:");
- serverModules = new TreeMap<>();
- ServiceLoader<ServerModule> serverModuleLoader = ServiceLoader.load(ServerModule.class, classLoader);
- for (ServerModule serverModule : serverModuleLoader) {
- LOGGER.info("Initializing server module: {} ...", serverModule.getName());
- serverModules.put(serverModule.getName(), serverModule);
- // Inject the contexts.
- serverModule.setContext(context);
- serverModule.setConfig(config);
- LOGGER.info("Initialized");
- }
- LOGGER.info("Finished Initializing Server Modules\n");
-
- running = true;
- }
-
- private void stop() {
- running = false;
- }
-
- private void run() {
- // Start all server modules.
- LOGGER.info("Starting Server Modules:");
- for (ServerModule serverModule : serverModules.values()) {
- LOGGER.info("Starting server module: {}...", serverModule.getName());
- try {
- serverModule.start();
- LOGGER.info("Started");
- } catch (Exception e) {
- LOGGER.warn("Error starting server module: {}...", serverModule.getName(), e);
- }
- }
- LOGGER.info("Finished Starting Server Modules\n");
-
- try {
- LOGGER.info("Starting simulations ...");
- while (running) {
- try {
- simulationModule.loop();
- } catch (Exception e) {
- LOGGER.error("Caught error while executing loop() method of {} simulation.", simulationModule.getName(), e);
- }
- // Sleep 100 ms to not run the simulation too eagerly.
- try {
- TimeUnit.MILLISECONDS.sleep(100);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new RuntimeException(e);
- }
- }
- } finally {
- LOGGER.info("Simulations ended");
- // Start all server modules.
- for (ServerModule serverModule : serverModules.values()) {
- LOGGER.info("Stopping server module {} ...", serverModule.getName());
- try {
- serverModule.stop();
- LOGGER.info("Stopped");
- } catch (Exception e) {
- LOGGER.warn("Error stopping server module {} ...", serverModule.getName());
- }
-
- }
- }
- }
-
- public static void main(String... args) throws Exception {
- final PlcSimulator simulator = new PlcSimulator("Water Tank", plcSimulatorConfigFromArgs(args));
- // Make sure we stop everything correctly.
- Runtime.getRuntime().addShutdownHook(new Thread(simulator::stop));
- // Start the simulator.
- simulator.run();
- }
-
- public static PlcSimulatorConfig plcSimulatorConfigFromArgs(String... args) throws Exception {
- PlcSimulatorConfig config = new PlcSimulatorConfig();
-
- // Build options
- Options options = new Options();
-
- options.addOption("public", false, "listen on all interfaces (overrides host option)");
- options.addOption("host", true, "the host interface");
- options.addOption("s7Port", true, "changes the s7 port");
- options.addOption("cBusPort", true, "changes the C-Bus port");
- options.addOption("bacnetPort", true, "changes the Bacnet port");
-
- // Parse args
- CommandLineParser parser = new DefaultParser();
- CommandLine cmd = parser.parse(options, args);
-
- // Map options
- config.host = cmd.getOptionValue("host", "localhost");
- if (cmd.hasOption("public")) {
- LOGGER.info("Listening on all interfaces. (omitting {})", config.host);
- config.host = null;
- }
- config.s7Port = cmd.getOptionValue("s7port");
- config.cBusPort = cmd.getOptionValue("cBusPort");
- config.bacnetPort = cmd.getOptionValue("bacnetPort");
-
- return config;
- }
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/PlcSimulatorConfig.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/PlcSimulatorConfig.java
deleted file mode 100644
index 99a0fc30be..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/PlcSimulatorConfig.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator;
-
-public class PlcSimulatorConfig {
- String host;
-
- String s7Port;
- String cBusPort;
-
- String bacnetPort;
-
- public String getHost() {
- return host;
- }
-
- public String getS7Port() {
- return s7Port;
- }
-
- public String getCBusPort() {
- return cBusPort;
- }
-
- public String getBacnetPort() {
- return bacnetPort;
- }
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/exceptions/SimulatorException.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/exceptions/SimulatorException.java
deleted file mode 100644
index 7c2fe63f06..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/exceptions/SimulatorException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator.exceptions;
-
-public class SimulatorException extends Exception {
-
- public SimulatorException(String message) {
- super(message);
- }
-
- public SimulatorException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public SimulatorException(Throwable cause) {
- super(cause);
- }
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/model/Context.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/model/Context.java
deleted file mode 100644
index 2f66197d64..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/model/Context.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator.model;
-
-import org.apache.commons.collections4.list.FixedSizeList;
-import org.apache.commons.collections4.map.FixedSizeMap;
-
-import java.util.*;
-
-public class Context {
-
- private final FixedSizeMap<String, Object> memory;
- private final FixedSizeList<Boolean> digitalInputs;
- private final FixedSizeList<Long> analogInputs;
- private final FixedSizeList<Boolean> digitalOutputs;
- private final FixedSizeList<Long> analogOutputs;
-
- public Context(FixedSizeMap<String, Object> memory,
- FixedSizeList<Boolean> digitalInputs, FixedSizeList<Long> analogInputs,
- FixedSizeList<Boolean> digitalOutputs, FixedSizeList<Long> analogOutputs) {
- this.memory = memory;
- this.digitalInputs = digitalInputs;
- this.analogInputs = analogInputs;
- this.digitalOutputs = digitalOutputs;
- this.analogOutputs = analogOutputs;
- }
-
- public Map<String, Object> getMemory() {
- return memory;
- }
-
- public List<Boolean> getDigitalInputs() {
- return digitalInputs;
- }
-
- public List<Long> getAnalogInputs() {
- return analogInputs;
- }
-
- public List<Boolean> getDigitalOutputs() {
- return digitalOutputs;
- }
-
- public List<Long> getAnalogOutputs() {
- return analogOutputs;
- }
-
- public static class ContextBuilder {
- private final Map<String, Object> memory;
- private final List<Boolean> digitalInputs;
- private final List<Long> analogInputs;
- private final List<Boolean> digitalOutputs;
- private final List<Long> analogOutputs;
-
- public ContextBuilder() {
- memory = new TreeMap<>();
- digitalInputs = new LinkedList<>();
- analogInputs = new LinkedList<>();
- digitalOutputs = new LinkedList<>();
- analogOutputs = new LinkedList<>();
- }
-
- public ContextBuilder addMemoryVariable(String name, Object defaultValue) {
- memory.put(name, defaultValue);
- return this;
- }
-
- public ContextBuilder addDigitalInput(Boolean defaultValue) {
- digitalInputs.add(defaultValue);
- return this;
- }
-
- public ContextBuilder addAnalogInput(Long defaultValue) {
- analogInputs.add(defaultValue);
- return this;
- }
-
- public ContextBuilder addDigitalOutput(Boolean defaultValue) {
- digitalOutputs.add(defaultValue);
- return this;
- }
-
- public ContextBuilder addAnalogOutput(Long defaultValue) {
- analogOutputs.add(defaultValue);
- return this;
- }
-
- public Context build() {
- return new Context(FixedSizeMap.fixedSizeMap(memory),
- FixedSizeList.fixedSizeList(digitalInputs), FixedSizeList.fixedSizeList(analogInputs),
- FixedSizeList.fixedSizeList(digitalOutputs), FixedSizeList.fixedSizeList(analogOutputs));
- }
-
- }
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/ServerModule.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/ServerModule.java
deleted file mode 100644
index eed2e42b0a..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/ServerModule.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator.server;
-
-import org.apache.plc4x.simulator.PlcSimulatorConfig;
-import org.apache.plc4x.simulator.exceptions.SimulatorException;
-import org.apache.plc4x.simulator.model.Context;
-
-public interface ServerModule {
-
- /**
- * @return the name of the server module
- */
- String getName();
-
- void setConfig(PlcSimulatorConfig config);
-
- void setContext(Context contexts);
-
- void start() throws SimulatorException;
-
- void stop() throws SimulatorException;
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/BacnetServerModule.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/BacnetServerModule.java
deleted file mode 100644
index a907a0fb74..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/BacnetServerModule.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator.server.bacnet;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.DatagramPacket;
-import io.netty.channel.socket.nio.NioDatagramChannel;
-import io.netty.handler.codec.MessageToMessageDecoder;
-import io.netty.handler.codec.MessageToMessageEncoder;
-import io.netty.util.concurrent.FastThreadLocal;
-import org.apache.plc4x.java.bacnetip.BacNetIpDriver;
-import org.apache.plc4x.java.bacnetip.readwrite.BVLC;
-import org.apache.plc4x.java.bacnetip.readwrite.Constants;
-import org.apache.plc4x.java.spi.connection.GeneratedProtocolMessageCodec;
-import org.apache.plc4x.java.spi.generation.ByteOrder;
-import org.apache.plc4x.simulator.PlcSimulatorConfig;
-import org.apache.plc4x.simulator.exceptions.SimulatorException;
-import org.apache.plc4x.simulator.model.Context;
-import org.apache.plc4x.simulator.server.ServerModule;
-import org.apache.plc4x.simulator.server.bacnet.protocol.BacnetServerAdapter;
-
-import java.net.InetSocketAddress;
-import java.util.List;
-
-public class BacnetServerModule implements ServerModule {
-
- private EventLoopGroup loopGroup;
- private EventLoopGroup workerGroup;
- private Context context;
- private PlcSimulatorConfig config;
-
- private final FastThreadLocal<String> returnToSender = new FastThreadLocal<>();
-
- @Override
- public String getName() {
- return "Bacnet";
- }
-
- @Override
- public void setConfig(PlcSimulatorConfig config) {
- this.config = config;
- }
-
- @Override
- public void setContext(Context context) {
- this.context = context;
- }
-
- @Override
- public void start() throws SimulatorException {
- if (loopGroup != null) {
- return;
- }
-
- try {
- loopGroup = new NioEventLoopGroup();
-
- Bootstrap bootstrap = new Bootstrap();
- bootstrap.group(loopGroup)
- .channel(NioDatagramChannel.class)
- .option(ChannelOption.SO_BROADCAST, true)
- .handler(new ChannelInitializer<NioDatagramChannel>() {
- @Override
- public void initChannel(NioDatagramChannel channel) {
- channel.pipeline()
- .addLast(new MessageToMessageDecoder<DatagramPacket>() {
- @Override
- protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {
- final ByteBuf content = msg.content();
- out.add(content.retain());
- String value = msg.sender().getHostString();
- returnToSender.set(value);
- }
- })
- .addLast(new MessageToMessageEncoder<ByteBuf>() {
- @Override
- protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
- msg.retain();
- out.add(new DatagramPacket(msg, new InetSocketAddress(returnToSender.get(), 47808)));
- }
- })
- .addLast(new GeneratedProtocolMessageCodec<>(BVLC.class,
- BVLC::staticParse, ByteOrder.BIG_ENDIAN,
- new BacNetIpDriver.ByteLengthEstimator(),
- new BacNetIpDriver.CorruptPackageCleaner()))
- .addLast(new BacnetServerAdapter(context));
- }
- });
-
- int port = Constants.BACNETUDPDEFAULTPORT;
- if (config.getCBusPort() != null) {
- port = Integer.parseInt(config.getCBusPort());
- }
- String host = config.getHost();
- if (host != null) {
- bootstrap.bind(host, port).sync();
- } else {
- bootstrap.bind(port).sync();
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new SimulatorException(e);
- }
- }
-
- @Override
- public void stop() {
- if (workerGroup == null) {
- return;
- }
-
- workerGroup.shutdownGracefully();
- loopGroup.shutdownGracefully();
- }
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/protocol/BacnetServerAdapter.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/protocol/BacnetServerAdapter.java
deleted file mode 100644
index 2ee7c5d3d9..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/bacnet/protocol/BacnetServerAdapter.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator.server.bacnet.protocol;
-
-import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import org.apache.plc4x.java.bacnetip.readwrite.Error;
-import org.apache.plc4x.java.bacnetip.readwrite.*;
-import org.apache.plc4x.java.bacnetip.readwrite.utils.StaticHelper;
-import org.apache.plc4x.simulator.model.Context;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class BacnetServerAdapter extends ChannelInboundHandlerAdapter {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(BacnetServerAdapter.class);
-
- private Context context;
-
- // TODO: make configurable
- private static final int DEVICE_INSTANCE = 4711;
-
- // TODO: make configurable
- private static final int DEVICE_ID = 815;
-
- public BacnetServerAdapter(Context context) {
- LOGGER.info("Creating adapter with context {}", context);
- }
-
-
- @Override
- public void channelInactive(ChannelHandlerContext ctx) throws Exception {
- super.channelInactive(ctx);
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- System.out.println("Got request");
- System.out.println(msg);
- if (!(msg instanceof BVLC)) {
- return;
- }
- BVLC bvlc = (BVLC) msg;
- if (!(bvlc instanceof BVLCOriginalUnicastNPDU)) {
- // TODO: write useful error
- ctx.writeAndFlush(new BVLCOriginalUnicastNPDU(
- new NPDU(
- (short) 1,
- new NPDUControl(true, false, false, false, NPDUNetworkPriority.NORMAL_MESSAGE),
- 0,
- (short) 0,
- null,
- 0,
- (short) 0,
- null,
- (short) 0,
- null,
- new APDUError(
- (short) 0,
- BACnetConfirmedServiceChoice.READ_PROPERTY,
- new BACnetErrorGeneral(new Error(
- new ErrorClassTagged(new BACnetTagHeader((byte) 0, TagClass.APPLICATION_TAGS, (byte) 1, (short) 0, (short) 0, 0, 0L), ErrorClass.COMMUNICATION, 0L),
- new ErrorCodeTagged(new BACnetTagHeader((byte) 0, TagClass.APPLICATION_TAGS, (byte) 1, (short) 0, (short) 0, 0, 0L), ErrorCode.VENDOR_PROPRIETARY_VALUE, 0L)
- ))
- )
- )
- )).addListener((ChannelFutureListener) f -> {
- if (!f.isSuccess()) {
- f.cause().printStackTrace();
- }
- });
- return;
- }
- BVLCOriginalUnicastNPDU bvlcOriginalUnicastNPDU = (BVLCOriginalUnicastNPDU) bvlc;
- // TODO: get messageTypeTag
- APDU apdu = bvlcOriginalUnicastNPDU.getNpdu().getApdu();
- if (apdu instanceof APDUUnconfirmedRequest) {
- APDUUnconfirmedRequest apduUnconfirmedRequest = (APDUUnconfirmedRequest) apdu;
- BACnetUnconfirmedServiceRequest serviceRequest = apduUnconfirmedRequest.getServiceRequest();
- if (serviceRequest instanceof BACnetUnconfirmedServiceRequestWhoIs) {
- BACnetUnconfirmedServiceRequestWhoIs baCnetUnconfirmedServiceRequestWhoIs = (BACnetUnconfirmedServiceRequestWhoIs) serviceRequest;
- if (baCnetUnconfirmedServiceRequestWhoIs.getDeviceInstanceRangeLowLimit() != null) {
- if (DEVICE_INSTANCE < baCnetUnconfirmedServiceRequestWhoIs.getDeviceInstanceRangeLowLimit().getActualValue().longValue()) {
- // Ignoring because we out if limit
- return;
- }
- }
- if (baCnetUnconfirmedServiceRequestWhoIs.getDeviceInstanceRangeHighLimit() != null) {
- if (DEVICE_INSTANCE > baCnetUnconfirmedServiceRequestWhoIs.getDeviceInstanceRangeHighLimit().getActualValue().longValue()) {
- // Ignoring because we out if limit
- return;
- }
- }
- BVLCOriginalUnicastNPDU response = new BVLCOriginalUnicastNPDU(
- new NPDU(
- (short) 1,
- new NPDUControl(false, false, false, false, NPDUNetworkPriority.NORMAL_MESSAGE),
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- new APDUUnconfirmedRequest(
- new BACnetUnconfirmedServiceRequestIAm(
- StaticHelper.createBACnetApplicationTagObjectIdentifier(BACnetObjectType.DEVICE.getValue(), DEVICE_INSTANCE),
- StaticHelper.createBACnetApplicationTagUnsignedInteger(1024),
- StaticHelper.creatBACnetSegmentationTagged(BACnetSegmentation.NO_SEGMENTATION),
- StaticHelper.createBACnetVendorIdApplicationTagged(BACnetVendorId.MAPPED.getVendorId())
- )
- )
- )
- );
- System.out.println("Writing response");
- System.out.println(response);
- ctx.writeAndFlush(response).addListener((ChannelFutureListener) f -> {
- if (!f.isSuccess()) {
- f.cause().printStackTrace();
- }
- });
- } else {
- throw new Exception(apdu.getClass() + " not set supported");
- }
- } else if (apdu instanceof APDUConfirmedRequest) {
- APDUConfirmedRequest apduConfirmedRequest = (APDUConfirmedRequest) apdu;
- // TODO: just handle read for now
- BVLCOriginalUnicastNPDU response = new BVLCOriginalUnicastNPDU(
- new NPDU(
- (short) 1,
- new NPDUControl(false, false, false, false, NPDUNetworkPriority.NORMAL_MESSAGE),
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- new APDUComplexAck(
- false,
- false,
- apduConfirmedRequest.getInvokeId(),
- null,
- null,
- new BACnetServiceAckReadProperty(
- 0L,
- StaticHelper.createBACnetContextTagObjectIdentifier((byte) 0, (short) 2, 1),
- StaticHelper.createBACnetPropertyIdentifierTagged((byte) 1, 85),
- null,
- new BACnetConstructedDataAnalogValuePresentValue(
- StaticHelper.createBACnetOpeningTag((short) 3),
- StaticHelper.createBACnetTagHeaderBalanced(true, (short) 3, 3L),
- StaticHelper.createBACnetClosingTag((short) 3),
- StaticHelper.createBACnetApplicationTagReal(101L)
- )
- ),
- null,
- null
- )
- )
- );
- System.out.println("Writing response");
- System.out.println(response);
- ctx.writeAndFlush(response).addListener((ChannelFutureListener) f -> {
- if (!f.isSuccess()) {
- f.cause().printStackTrace();
- }
- });
- }
- }
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/CBusServerModule.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/CBusServerModule.java
deleted file mode 100644
index fdb7576ee3..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/CBusServerModule.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator.server.cbus;
-
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import org.apache.plc4x.java.cbus.CBusDriver;
-import org.apache.plc4x.java.cbus.readwrite.CBusMessage;
-import org.apache.plc4x.java.cbus.readwrite.CBusOptions;
-import org.apache.plc4x.java.cbus.readwrite.Constants;
-import org.apache.plc4x.java.cbus.readwrite.RequestContext;
-import org.apache.plc4x.java.spi.connection.GeneratedProtocolMessageCodec;
-import org.apache.plc4x.java.spi.generation.ByteOrder;
-import org.apache.plc4x.java.spi.generation.MessageInput;
-import org.apache.plc4x.simulator.PlcSimulatorConfig;
-import org.apache.plc4x.simulator.exceptions.SimulatorException;
-import org.apache.plc4x.simulator.model.Context;
-import org.apache.plc4x.simulator.server.ServerModule;
-import org.apache.plc4x.simulator.server.cbus.protocol.CBusServerAdapter;
-
-public class CBusServerModule implements ServerModule {
-
- public static final MessageInput<CBusMessage> MESSAGE_INPUT = io ->
- CBusMessage.staticParse(io, false, new RequestContext(false),
- new CBusOptions(false, false, false, false, false, false, false, false, false));
-
- private EventLoopGroup loopGroup;
- private EventLoopGroup workerGroup;
- private Context context;
- private PlcSimulatorConfig config;
-
- @Override
- public String getName() {
- return "C-BUS";
- }
-
- @Override
- public void setConfig(PlcSimulatorConfig config) {
- this.config = config;
- }
-
- @Override
- public void setContext(Context context) {
- this.context = context;
- }
-
- @Override
- public void start() throws SimulatorException {
- if (loopGroup != null) {
- return;
- }
-
- try {
- loopGroup = new NioEventLoopGroup();
- workerGroup = new NioEventLoopGroup();
-
- ServerBootstrap bootstrap = new ServerBootstrap();
- bootstrap.group(loopGroup, workerGroup)
- .channel(NioServerSocketChannel.class)
- .childHandler(new ChannelInitializer<SocketChannel>() {
- @Override
- public void initChannel(SocketChannel channel) {
- ChannelPipeline pipeline = channel.pipeline();
- pipeline.addLast(new GeneratedProtocolMessageCodec<>(CBusMessage.class,
- MESSAGE_INPUT, ByteOrder.BIG_ENDIAN,
- new CBusDriver.ByteLengthEstimator(),
- new CBusDriver.CorruptPackageCleaner()));
- pipeline.addLast(new CBusServerAdapter(context));
- }
- })
- .option(ChannelOption.SO_BACKLOG, 128)
- .childOption(ChannelOption.SO_KEEPALIVE, true);
-
- int port = Constants.CBUSTCPDEFAULTPORT;
- if (config.getCBusPort() != null) {
- port = Integer.parseInt(config.getCBusPort());
- }
- String host = config.getHost();
- if (host != null) {
- bootstrap.bind(host, port).sync();
- } else {
- bootstrap.bind(port).sync();
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new SimulatorException(e);
- }
- }
-
- @Override
- public void stop() {
- if (workerGroup == null) {
- return;
- }
-
- workerGroup.shutdownGracefully();
- loopGroup.shutdownGracefully();
- }
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/protocol/CBusServerAdapter.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/protocol/CBusServerAdapter.java
deleted file mode 100644
index d745f2823c..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/protocol/CBusServerAdapter.java
+++ /dev/null
@@ -1,715 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator.server.cbus.protocol;
-
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import org.apache.plc4x.java.cbus.readwrite.*;
-import org.apache.plc4x.simulator.model.Context;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-public class CBusServerAdapter extends ChannelInboundHandlerAdapter {
-
- private static final List<Byte> AVAILABLE_UNITS = Arrays.asList((byte) 3, (byte) 23, (byte) 48);
-
- private static final Logger LOGGER = LoggerFactory.getLogger(CBusServerAdapter.class);
-
- private final Context context;
-
- private static final RequestContext requestContext = new RequestContext(false);
-
- private static boolean connect;
- private static boolean smart;
- private static boolean idmon;
- private static boolean exstat;
- private static boolean monitor;
- private static boolean monall;
- private static boolean pun;
- private static boolean pcn;
- private static boolean srchk;
-
- private static byte monitorApplicationAddress1;
-
- private static byte monitorApplicationAddress2;
- private static CBusOptions cBusOptions;
-
- private final Lock outputLock = new ReentrantLock();
-
- private ScheduledFuture<?> salMonitorFuture;
-
- private ScheduledFuture<?> mmiMonitorFuture;
-
- public CBusServerAdapter(Context context) {
- LOGGER.info("Creating adapter with context {}", context);
- this.context = context;
- cBusOptions = new CBusOptions(connect, smart, idmon, exstat, monitor, monall, pun, pcn, srchk);
- }
-
- private static void buildCBusOptions() {
- LOGGER.info("Updating options {}", cBusOptions);
- cBusOptions = new CBusOptions(connect, smart, idmon, exstat, monitor, monall, pun, pcn, srchk);
- LOGGER.info("Updated options {}", cBusOptions);
- }
-
- @Override
- public void channelInactive(ChannelHandlerContext ctx) throws Exception {
- if (salMonitorFuture != null)
- salMonitorFuture.cancel(false);
- if (mmiMonitorFuture != null)
- mmiMonitorFuture.cancel(false);
- super.channelInactive(ctx);
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- if (!(msg instanceof CBusMessage)) {
- return;
- }
- try {
- outputLock.lock();
- syncChannelRead(ctx, msg);
- } finally {
- ctx.flush();
- outputLock.unlock();
- }
- }
-
- private void syncChannelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- LOGGER.debug("Working with cBusOptions\n{}", cBusOptions);
- // Serial is slow
- TimeUnit.MILLISECONDS.sleep(100);
- if (!smart && !connect) {
- // In this mode every message will be echoed
- LOGGER.info("Sending echo");
- ctx.write(msg);
- }
- CBusMessage packet = (CBusMessage) msg;
- if (packet instanceof CBusMessageToClient) {
- LOGGER.info("Message to client not supported\n{}", packet);
- return;
- }
- CBusMessageToServer cBusMessageToServer = (CBusMessageToServer) packet;
- Request request = cBusMessageToServer.getRequest();
- if (request instanceof RequestEmpty || request instanceof RequestNull) {
- LOGGER.debug("Ignoring\n{}", request);
- } else if (request instanceof RequestDirectCommandAccess) {
- handleDirectCommandAccess(ctx, (RequestDirectCommandAccess) request);
- } else if (request instanceof RequestCommand) {
- handleRequestCommand(ctx, (RequestCommand) request);
- } else if (request instanceof RequestObsolete) {
- RequestObsolete requestObsolete = (RequestObsolete) request;
- LOGGER.info("Handling RequestObsolete\n{}", requestObsolete);
- // TODO: handle this
- } else if (request instanceof RequestReset) {
- if (smart || connect) {
- // On reset, we need to send the echo if we had not sent it above
- LOGGER.info("Sending echo");
- ctx.write(msg);
- }
- LOGGER.info("Handling RequestReset\n{}", request);
- handleReset();
- } else if (request instanceof RequestSmartConnectShortcut) {
- handleSmartConnect((RequestSmartConnectShortcut) request);
- }
- }
-
- private void handleDirectCommandAccess(ChannelHandlerContext ctx, RequestDirectCommandAccess requestDirectCommandAccess) {
- CALData calData = requestDirectCommandAccess.getCalData();
- LOGGER.info("Handling RequestDirectCommandAccess\n{}", requestDirectCommandAccess);
- handleCalData(ctx, calData, requestDirectCommandAccess.getAlpha());
- }
-
- private void handleRequestCommand(ChannelHandlerContext ctx, RequestCommand requestCommand) {
- LOGGER.info("Handling RequestCommand\n{}", requestCommand);
- CBusCommand cbusCommand = requestCommand.getCbusCommand();
- LOGGER.info("Handling CBusCommand\n{}", cbusCommand);
- if (cbusCommand instanceof CBusCommandPointToPoint) {
- CBusCommandPointToPoint cBusCommandPointToPoint = (CBusCommandPointToPoint) cbusCommand;
- CBusPointToPointCommand command = cBusCommandPointToPoint.getCommand();
- UnitAddress unitAddress = null;
- if (command instanceof CBusPointToPointCommandIndirect) {
- CBusPointToPointCommandIndirect cBusPointToPointCommandIndirect = (CBusPointToPointCommandIndirect) command;
- // TODO: handle bridgeAddress
- // TODO: handle networkRoute
- unitAddress = cBusPointToPointCommandIndirect.getUnitAddress();
- }
- if (command instanceof CBusPointToPointCommandDirect) {
- CBusPointToPointCommandDirect cBusPointToPointCommandDirect = (CBusPointToPointCommandDirect) command;
- unitAddress = cBusPointToPointCommandDirect.getUnitAddress();
- }
- if (unitAddress == null) {
- throw new IllegalStateException("Unit address should be set at this point");
- }
- boolean knownUnit = AVAILABLE_UNITS.contains(unitAddress.getAddress());
- if (!knownUnit) {
- LOGGER.warn("{} not a known unit", unitAddress);
- ReplyOrConfirmation replyOrConfirmation = new ServerErrorReply((byte) 0x0);
- CBusMessageToClient cBusMessageToClient = new CBusMessageToClient(replyOrConfirmation);
- ctx.writeAndFlush(cBusMessageToClient);
- return;
- }
- CALData calData = command.getCalData();
- handleCalData(ctx, calData, requestCommand.getAlpha());
- return;
- } else if (cbusCommand instanceof CBusCommandPointToMultiPoint) {
- CBusCommandPointToMultiPoint cBusCommandPointToMultiPoint = (CBusCommandPointToMultiPoint) cbusCommand;
- CBusPointToMultiPointCommand command = cBusCommandPointToMultiPoint.getCommand();
- if (command instanceof CBusPointToMultiPointCommandStatus) {
- CBusPointToMultiPointCommandStatus cBusPointToMultiPointCommandStatus = (CBusPointToMultiPointCommandStatus) command;
- StatusRequest statusRequest = cBusPointToMultiPointCommandStatus.getStatusRequest();
- if (statusRequest instanceof StatusRequestBinaryState) {
- StatusRequestBinaryState statusRequestBinaryState = (StatusRequestBinaryState) statusRequest;
- LOGGER.info("Handling StatusRequestBinaryState\n{}", statusRequestBinaryState);
- handleStatusRequestBinary(ctx, requestCommand, statusRequestBinaryState.getApplication());
- }
- if (statusRequest instanceof StatusRequestBinaryStateDeprecated) {
- StatusRequestBinaryStateDeprecated statusRequestBinaryStateDeprecated = (StatusRequestBinaryStateDeprecated) statusRequest;
- LOGGER.info("Handling StatusRequestBinaryStateDeprecated\n{}", statusRequestBinaryStateDeprecated);
- handleStatusRequestBinary(ctx, requestCommand, statusRequestBinaryStateDeprecated.getApplication());
- return;
- }
- if (statusRequest instanceof StatusRequestLevel) {
- StatusRequestLevel statusRequestLevel = (StatusRequestLevel) statusRequest;
- handleStatusRequestLevel(ctx, requestCommand, statusRequestLevel);
- return;
- }
- throw new IllegalStateException();
- }
- if (command instanceof CBusPointToMultiPointCommandNormal) {
- CBusPointToMultiPointCommandNormal cBusPointToMultiPointCommandNormal = (CBusPointToMultiPointCommandNormal) command;
- LOGGER.info("Handling CBusPointToMultiPointCommandNormal\n{}", cBusPointToMultiPointCommandNormal);
- // TODO: handle this
- return;
- }
- // TODO: handle this
- return;
- } else if (cbusCommand instanceof CBusCommandPointToPointToMultiPoint) {
- CBusCommandPointToPointToMultiPoint cBusCommandPointToPointToMultiPoint = (CBusCommandPointToPointToMultiPoint) cbusCommand;
- LOGGER.info("Handling CBusCommandPointToPointToMultiPoint\n{}", cBusCommandPointToPointToMultiPoint);
- // TODO: handle this
- return;
- } else if (cbusCommand instanceof CBusCommandDeviceManagement) {
- CBusCommandDeviceManagement cBusCommandDeviceManagement = (CBusCommandDeviceManagement) cbusCommand;
- LOGGER.info("Handling CBusCommandDeviceManagement\n{}", cBusCommandDeviceManagement);
- // TODO: handle this
- return;
- }
-
- Alpha alpha = requestCommand.getAlpha();
- if (alpha != null) {
- Confirmation confirmation = new Confirmation(alpha, null, ConfirmationType.NOT_TRANSMITTED_CORRUPTION);
- ReplyOrConfirmationConfirmation replyOrConfirmationConfirmation = new ReplyOrConfirmationConfirmation(alpha.getCharacter(), confirmation, null);
- CBusMessage response = new CBusMessageToClient(replyOrConfirmationConfirmation);
- LOGGER.info("Send response\n{}", response);
- ctx.writeAndFlush(response);
- }
- }
-
- private static void handleStatusRequestLevel(ChannelHandlerContext ctx, RequestCommand requestCommand, StatusRequestLevel statusRequestLevel) {
- StatusCoding coding = StatusCoding.LEVEL_BY_THIS_SERIAL_INTERFACE;
- // TODO: map actual values from simulator
- byte blockStart = statusRequestLevel.getStartingGroupAddressLabel();
- List<LevelInformation> levelInformations = Collections.singletonList(new LevelInformationNormal(0x5555, LevelInformationNibblePair.Value_F, LevelInformationNibblePair.Value_F));
- CALData calData = new CALDataStatusExtended(requestContext, CALCommandTypeContainer.CALCommandReply_4Bytes, null, coding, statusRequestLevel.getApplication(), blockStart, null, levelInformations);
- CALReply calReply;
- if (exstat) {
- calReply = new CALReplyLong((byte) 0x0, calData, (byte) 0x0, new UnitAddress((byte) 0x04), null, new SerialInterfaceAddress((byte) 0x02), (byte) 0x0, null);
- } else {
- calReply = new CALReplyShort((byte) 0x0, calData);
- }
- CBusMessage response = createCBusMessageForReply(requestCommand.getAlpha(), calReply, cBusOptions);
- LOGGER.info("Send level status response\n{}", response);
- ctx.writeAndFlush(response);
- }
-
- private void handleStatusRequestBinary(ChannelHandlerContext ctx, RequestCommand requestCommand, ApplicationIdContainer application) {
- if (application == ApplicationIdContainer.NETWORK_CONTROL) {
- LOGGER.info("Handling installation MMI Request");
- sendInstallationMMIResponse(ctx, requestCommand.getAlpha());
- return;
- }
- List<StatusByte> statusBytes = new LinkedList<>();
- // TODO: map actual values from simulator
- for (int i = 0; i < 22; i++) {
- statusBytes.add(new StatusByte(GAVState.ON, GAVState.ERROR, GAVState.OFF, GAVState.DOES_NOT_EXIST));
- }
-
- LOGGER.info("Send binary status response");
- sendStatusBytes(ctx, "First parts {}", application, (byte) 0x0, statusBytes, requestCommand.getAlpha(), cBusOptions);
- }
-
- private void handleCalData(ChannelHandlerContext ctx, CALData calData, Alpha alpha) {
- if (calData instanceof CALDataGetStatus) {
- // TODO: implement me
- } else if (calData instanceof CALDataIdentify) {
- handleCalDataIdentify(ctx, (CALDataIdentify) calData, alpha);
- } else if (calData instanceof CALDataRecall) {
- // TODO: implement me
- } else if (calData instanceof CALDataReset) {
- CALDataReset calDataReset = (CALDataReset) calData;
- if (smart || connect) {
- // On reset, we need to send the echo if we had not sent it above
- LOGGER.info("Sending echo");
- ctx.write(calDataReset);
- }
- LOGGER.info("Handling CALDataReset\n{}", calDataReset);
- handleReset();
- } else if (calData instanceof CALDataWrite) {
- CALDataWrite calDataWrite = (CALDataWrite) calData;
- Runnable acknowledger = () -> {
- CALDataAcknowledge calDataAcknowledge = new CALDataAcknowledge(requestContext, CALCommandTypeContainer.CALCommandAcknowledge, null, calDataWrite.getParamNo(), (short) 0x0);
- CALReplyShort calReply = new CALReplyShort((byte) 0x0, calDataAcknowledge);
- EncodedReplyCALReply encodedReply = new EncodedReplyCALReply(requestContext, (byte) 0x0, calReply);
- ReplyEncodedReply replyEncodedReply = new ReplyEncodedReply((byte) 0x0, cBusOptions, encodedReply, null);
- ReplyOrConfirmation replyOrConfirmation = new ReplyOrConfirmationReply((byte) 0x0, replyEncodedReply, new ResponseTermination());
- if (alpha != null) {
- replyOrConfirmation = new ReplyOrConfirmationConfirmation((byte) 0x0, new Confirmation(alpha, null, ConfirmationType.CONFIRMATION_SUCCESSFUL), replyOrConfirmation);
- }
- CBusMessageToClient cBusMessageToClient = new CBusMessageToClient(replyOrConfirmation);
- LOGGER.info("Sending ack\n{}", cBusMessageToClient);
- ctx.writeAndFlush(cBusMessageToClient);
- };
- switch (calDataWrite.getParamNo().getParameterType()) {
- case APPLICATION_ADDRESS_1:
- ApplicationAddress1 applicationAddress1 = ((ParameterValueApplicationAddress1) calDataWrite.getParameterValue()).getValue();
- monitorApplicationAddress1 = applicationAddress1.getAddress();
- acknowledger.run();
- return;
- case APPLICATION_ADDRESS_2:
- ApplicationAddress2 applicationAddress2 = ((ParameterValueApplicationAddress2) calDataWrite.getParameterValue()).getValue();
- monitorApplicationAddress2 = applicationAddress2.getAddress();
- acknowledger.run();
- return;
- case INTERFACE_OPTIONS_1:
- InterfaceOptions1 interfaceOptions1 = ((ParameterValueInterfaceOptions1) calDataWrite.getParameterValue()).getValue();
- idmon = interfaceOptions1.getIdmon();
- monitor = interfaceOptions1.getMonitor();
- if (monitor) startMMIMonitor(ctx);
- else stopMMIMonitor();
- smart = interfaceOptions1.getSmart();
- srchk = interfaceOptions1.getSrchk();
- // TODO: add support for xonxoff
- // xonxoff = interfaceOptions1.getXonXoff();
- connect = interfaceOptions1.getConnect();
- if (connect) startSALMonitor(ctx);
- else stopSALMonitor();
- buildCBusOptions();
- acknowledger.run();
- return;
- case INTERFACE_OPTIONS_2:
- InterfaceOptions2 interfaceOptions2 = ((ParameterValueInterfaceOptions2) calDataWrite.getParameterValue()).getValue();
- // TODO: add support for burden
- // burden = interfaceOptions2.getBurden();
- // TODO: add support for clockgen
- // clockgen = interfaceOptions2.getClockGen();
- buildCBusOptions();
- acknowledger.run();
- return;
- case INTERFACE_OPTIONS_3:
- InterfaceOptions3 interfaceOptions3Value = ((ParameterValueInterfaceOptions3) calDataWrite.getParameterValue()).getValue();
- boolean oldExstat = exstat;
- exstat = interfaceOptions3Value.getExstat();
- if (oldExstat != exstat) {
- LOGGER.info("Restarting monitors");
- stopMMIMonitor();
- startMMIMonitor(ctx);
- stopSALMonitor();
- startSALMonitor(ctx);
- }
- pun = interfaceOptions3Value.getPun();
- // TODO: add support for localsal
- // localsal = interfaceOptions3Value.getLocalSal();
- pcn = interfaceOptions3Value.getPcn();
- buildCBusOptions();
- acknowledger.run();
- return;
- case BAUD_RATE_SELECTOR:
- BaudRateSelector baudRateSelector = ((ParameterValueBaudRateSelector) calDataWrite.getParameterValue()).getValue();
- // TODO: add support for baudrate
- // baudrate = baudRateSelector.getValue();
- buildCBusOptions();
- acknowledger.run();
- return;
- case INTERFACE_OPTIONS_1_POWER_UP_SETTINGS:
- InterfaceOptions1 interfaceOptions1PowerUpSettings = ((ParameterValueInterfaceOptions1PowerUpSettings) calDataWrite.getParameterValue()).getValue().getInterfaceOptions1();
- idmon = interfaceOptions1PowerUpSettings.getIdmon();
- monitor = interfaceOptions1PowerUpSettings.getMonitor();
- if (monitor) startMMIMonitor(ctx);
- else stopMMIMonitor();
- smart = interfaceOptions1PowerUpSettings.getSmart();
- srchk = interfaceOptions1PowerUpSettings.getSrchk();
- // TODO: add support for xonxoff
- // xonxoff = interfaceOptions1PowerUpSettings.getXonXoff();
- connect = interfaceOptions1PowerUpSettings.getConnect();
- if (connect) startSALMonitor(ctx);
- else stopSALMonitor();
- buildCBusOptions();
- acknowledger.run();
- return;
- case CUSTOM_MANUFACTURER:
- // TODO: handle other param typed
- acknowledger.run();
- return;
- case SERIAL_NUMBER:
- // TODO: handle other param typed
- acknowledger.run();
- return;
- case CUSTOM_TYPE:
- // TODO: handle other param typed
- acknowledger.run();
- return;
- default:
- throw new IllegalStateException("Unmapped type");
- }
- } else {
- throw new IllegalStateException("Unmapped type: " + calData.getClass());
- }
- }
-
- private static CBusMessage createCBusMessageForReply(Alpha alpha, CALReply calReply, CBusOptions cBusOptions) {
- EncodedReply encodedReply = new EncodedReplyCALReply(CBusServerAdapter.requestContext, (byte) 0x0, calReply);
- ReplyEncodedReply replyEncodedReply = new ReplyEncodedReply((byte) 0xC0, CBusServerAdapter.cBusOptions, encodedReply, null);
- ReplyOrConfirmation replyOrConfirmation = new ReplyOrConfirmationReply((byte) 0xFF, replyEncodedReply, new ResponseTermination());
- if (alpha != null) {
- Confirmation confirmation = new Confirmation(alpha, null, ConfirmationType.CONFIRMATION_SUCCESSFUL);
- replyOrConfirmation = new ReplyOrConfirmationConfirmation(alpha.getCharacter(), confirmation, replyOrConfirmation);
- }
- return new CBusMessageToClient(replyOrConfirmation);
- }
-
- private static void sendInstallationMMIResponse(ChannelHandlerContext ctx, Alpha alpha) {
- LOGGER.info("Send installation MMIs");
- sendMMIs(ctx, ApplicationIdContainer.NETWORK_CONTROL, alpha, cBusOptions);
- }
-
- private static void sendMonitoredMMIs(ChannelHandlerContext ctx) {
- LOGGER.info("Send installation MMIs");
- // TODO: for whatever reason those are not send with a crc
- CBusOptions cBusOptions = new CBusOptions(connect, smart, idmon, exstat, monitor, monall, pun, pcn, false);
- sendMMIs(ctx, ApplicationIdContainer.LIGHTING_38, null, cBusOptions);
- }
-
- private static void sendMMIs(ChannelHandlerContext ctx, ApplicationIdContainer application, Alpha alpha, CBusOptions cBusOptions) {
- {
- byte blockStart = 0x0;
- List<StatusByte> unitStatusBytes = new LinkedList<>();
- for (int i = blockStart; i <= 88 - 4; i = i + 4) {
- LOGGER.debug("Handling units 0-88 {},{},{},{}", i, (i + 1), (i + 2), (i + 3));
- addStatusBytesAtOffset(unitStatusBytes, i);
- }
- LOGGER.debug("Produced {}, status bytes which equates to {} status", unitStatusBytes.size(), unitStatusBytes.size() * 4);
- sendStatusBytes(ctx, "Sending second part {}", application, blockStart, unitStatusBytes, alpha, cBusOptions);
- }
- {
- byte blockStart = 88;
- List<StatusByte> unitStatusBytes = new LinkedList<>();
- for (int i = 88; i <= 88 + 88 - 4; i = i + 4) {
- LOGGER.debug("Handling units 88-176 {},{},{},{}", i, (i + 1), (i + 2), (i + 3));
- addStatusBytesAtOffset(unitStatusBytes, i);
- }
- LOGGER.debug("Produced {}, status bytes which equates to {} status", unitStatusBytes.size(), unitStatusBytes.size() * 4);
- sendStatusBytes(ctx, "Sending second part {}", application, blockStart, unitStatusBytes, null, cBusOptions);
- }
- {
- byte blockStart = (byte) 176;
- List<StatusByte> unitStatusBytes = new LinkedList<>();
- for (int i = 176; i <= 176 + 80 - 4; i = i + 4) {
- LOGGER.debug("Handling units 176-256 {},{},{},{}", i, (i + 1), (i + 2), (i + 3));
- addStatusBytesAtOffset(unitStatusBytes, i);
- }
- LOGGER.debug("Produced {}, status bytes which equates to {} status", unitStatusBytes.size(), unitStatusBytes.size() * 4);
- sendStatusBytes(ctx, "Sending third part {}", application, blockStart, unitStatusBytes, null, cBusOptions);
- }
- }
-
- private static void addStatusBytesAtOffset(List<StatusByte> unitStatusBytes, int i) {
- unitStatusBytes.add(
- new StatusByte(
- AVAILABLE_UNITS.contains((byte) (i + 3)) ? GAVState.ON : GAVState.DOES_NOT_EXIST,
- AVAILABLE_UNITS.contains((byte) (i + 2)) ? GAVState.ON : GAVState.DOES_NOT_EXIST,
- AVAILABLE_UNITS.contains((byte) (i + 1)) ? GAVState.ON : GAVState.DOES_NOT_EXIST,
- AVAILABLE_UNITS.contains((byte) (i)) ? GAVState.ON : GAVState.DOES_NOT_EXIST
- )
- );
- }
-
- private static void sendStatusBytes(ChannelHandlerContext ctx, String logMessage, ApplicationIdContainer application, byte blockStart, List<StatusByte> unitStatusBytes, Alpha alpha, CBusOptions cBusOptions) {
- int numberOfStatusBytes = unitStatusBytes.size();
- CALReply calReply;
- CALCommandTypeContainer commandTypeContainer = null;
- if (cBusOptions.getExstat()) {
- for (CALCommandTypeContainer calCommandTypeContainerElement : CALCommandTypeContainer.values()) {
- if (calCommandTypeContainerElement.getCommandType() != CALCommandType.STATUS_EXTENDED) {
- continue;
- }
- if (calCommandTypeContainerElement.getNumBytes() + 3 == numberOfStatusBytes) {
- commandTypeContainer = calCommandTypeContainerElement;
- break;
- }
- }
- CALData calData = new CALDataStatusExtended(requestContext, commandTypeContainer, null, StatusCoding.BINARY_BY_THIS_SERIAL_INTERFACE, application, blockStart, unitStatusBytes, null);
- // TODO: do we use a random unit or a fixed or do we need it as parameter
- int randomElementIndex = ThreadLocalRandom.current().nextInt(AVAILABLE_UNITS.size()) % AVAILABLE_UNITS.size();
- byte randomUnit = AVAILABLE_UNITS.get(randomElementIndex);
- calReply = new CALReplyLong((byte) 0x86, calData, 0x00, new UnitAddress(randomUnit), null, new SerialInterfaceAddress((byte) 0x02), (byte) 0x00, null);
- } else {
- for (CALCommandTypeContainer calCommandTypeContainerElement : CALCommandTypeContainer.values()) {
- if (calCommandTypeContainerElement.getCommandType() != CALCommandType.STATUS) {
- continue;
- }
- if (calCommandTypeContainerElement.getNumBytes() + 3 == numberOfStatusBytes) {
- commandTypeContainer = calCommandTypeContainerElement;
- break;
- }
- }
- CALData calData = new CALDataStatus(requestContext, commandTypeContainer, null, application, (byte) 0x00, unitStatusBytes);
- calReply = new CALReplyShort((byte) 0x0, calData);
- }
- CBusMessage response = createCBusMessageForReply(alpha, calReply, cBusOptions);
- LOGGER.debug(logMessage, response);
- ctx.writeAndFlush(response);
- }
-
- private void handleCalDataIdentify(ChannelHandlerContext ctx, CALDataIdentify calDataIdentify, Alpha alpha) {
- byte numBytes;
- IdentifyReplyCommand identifyReplyCommand;
- switch (calDataIdentify.getAttribute()) {
- case Manufacturer:
- numBytes = 0x08;
- identifyReplyCommand = new IdentifyReplyCommandManufacturer("Apache ");
- break;
- case Type:
- numBytes = 0x08;
- identifyReplyCommand = new IdentifyReplyCommandType("plc4x-si");
- break;
- case FirmwareVersion:
- numBytes = 0x08;
- identifyReplyCommand = new IdentifyReplyCommandFirmwareVersion(" 0.09 ");
- break;
- case Summary:
- numBytes = 0x09;
- identifyReplyCommand = new IdentifyReplyCommandSummary("NOIDEA", (byte) 0xAF, "0900");
- break;
- case ExtendedDiagnosticSummary:
- numBytes = 0x0C;
- identifyReplyCommand = new IdentifyReplyCommandExtendedDiagnosticSummary(ApplicationIdContainer.FREE_USAGE_01, ApplicationIdContainer.FREE_USAGE_0F, (byte) 0x0, 0x0, 4711L, (byte) 0x13, false, false, false, true, false, false, false, false, false, false, false, false, false);
- break;
- case NetworkTerminalLevels:
- numBytes = 0x0C;
- identifyReplyCommand = new IdentifyReplyCommandNetworkTerminalLevels(new byte[]{0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13});
- break;
- case TerminalLevel:
- numBytes = 0x0C;
- identifyReplyCommand = new IdentifyReplyCommandTerminalLevels(new byte[]{0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13});
- break;
- case NetworkVoltage:
- numBytes = 0x05;
- identifyReplyCommand = new IdentifyReplyCommandNetworkVoltage("48", "7");
- break;
- case GAVValuesCurrent:
- numBytes = 0x10;
- identifyReplyCommand = new IdentifyReplyCommandGAVValuesCurrent(new byte[]{
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- });
- break;
- case GAVValuesStored:
- numBytes = 0x10;
- identifyReplyCommand = new IdentifyReplyCommandGAVValuesStored(new byte[]{
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- });
- break;
- case GAVPhysicalAddresses:
- numBytes = 0x10;
- identifyReplyCommand = new IdentifyReplyCommandGAVPhysicalAddresses(new byte[]{
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- });
- break;
- case LogicalAssignment:
- numBytes = 0x0E;
- identifyReplyCommand = new IdentifyReplyCommandLogicalAssignment(Collections.singletonList(new LogicAssignment(false, true, true, true, true, true)));
- break;
- case Delays:
- numBytes = 0x0F;
- identifyReplyCommand = new IdentifyReplyCommandDelays(new byte[]{0x3}, (byte) 0x13);
- break;
- case MinimumLevels:
- numBytes = 0x0E;
- identifyReplyCommand = new IdentifyReplyCommandMinimumLevels(new byte[]{0x3});
- break;
- case MaximumLevels:
- numBytes = 0x0F;
- identifyReplyCommand = new IdentifyReplyCommandMaximumLevels(new byte[]{0xF});
- break;
- case CurrentSenseLevels:
- numBytes = 0x10;
- identifyReplyCommand = new IdentifyReplyCommandCurrentSenseLevels(new byte[]{0xF});
- break;
- case OutputUnitSummary:
- numBytes = 0x12;
- identifyReplyCommand = new IdentifyReplyCommandOutputUnitSummary(new IdentifyReplyCommandUnitSummary(false, false, false, false, false, false, false, false), (byte) 0x4, (byte) 0x4, (short) 45);
- break;
- case DSIStatus:
- numBytes = 0x12;
- identifyReplyCommand = new IdentifyReplyCommandDSIStatus(ChannelStatus.OK, ChannelStatus.OK, ChannelStatus.OK, ChannelStatus.OK, ChannelStatus.OK, ChannelStatus.OK, ChannelStatus.OK, ChannelStatus.OK, UnitStatus.OK, (byte) 0x34);
- break;
- default:
- throw new IllegalStateException("unmapped type " + calDataIdentify.getAttribute());
- }
-
- CALData calData = new CALDataIdentifyReply(requestContext, getReplyCommandType(numBytes + 1), null, calDataIdentify.getAttribute(), identifyReplyCommand);
- CALReply calReply;
- if (exstat) {
- calReply = new CALReplyLong((byte) 0x0, calData, (byte) 0x0, new UnitAddress((byte) 0x0), null, new SerialInterfaceAddress((byte) 0x02), (byte) 0x0, null);
- } else {
- calReply = new CALReplyShort((byte) 0x0, calData);
- }
- CBusMessage response = createCBusMessageForReply(alpha, calReply, cBusOptions);
- LOGGER.info("Send identify response\n{}", response);
- ctx.writeAndFlush(response);
- }
-
- private static void handleSmartConnect(RequestSmartConnectShortcut requestSmartConnectShortcut) {
- LOGGER.info("Handling RequestSmartConnectShortcut\n{}", requestSmartConnectShortcut);
- smart = true;
- connect = true;
- buildCBusOptions();
- }
-
- private void handleReset() {
- connect = false;
- smart = false;
- idmon = false;
- exstat = false;
- monitor = false;
- monall = false;
- pun = false;
- pcn = false;
- srchk = false;
- stopSALMonitor();
- stopMMIMonitor();
- }
-
- private void startSALMonitor(ChannelHandlerContext ctx) {
- if (salMonitorFuture != null) {
- LOGGER.debug("SAL Monitor already running");
- return;
- }
- LOGGER.info("Starting monitor");
- salMonitorFuture = ctx.executor().scheduleAtFixedRate(() -> {
- if (monitorApplicationAddress1 != 0x38 && monitorApplicationAddress2 != 0x38 && monitorApplicationAddress1 != (byte) 0xFF && monitorApplicationAddress2 != (byte) 0xFF) {
- LOGGER.debug("Filtered because monitor application address 1 {} monitor application address 1 {}", monitorApplicationAddress1, monitorApplicationAddress2);
- return;
- }
- try {
- int randomElementIndex = ThreadLocalRandom.current().nextInt(AVAILABLE_UNITS.size()) % AVAILABLE_UNITS.size();
- byte randomUnit = AVAILABLE_UNITS.get(randomElementIndex);
- outputLock.lock();
- MonitoredSAL monitoredSAL;
- SALData salData = createLightingData();
- if (cBusOptions.getExstat()) {
- monitoredSAL = new MonitoredSALLongFormSmartMode((byte) 0x05, (byte) 0x00, new UnitAddress(randomUnit), null, ApplicationIdContainer.LIGHTING_38, (byte) 0x00, null, salData);
- } else {
- monitoredSAL = new MonitoredSALShortFormBasicMode((byte) 0x0, (byte) 0x0, (short) 0x0, (short) 0x0, (byte) 0x0, ApplicationIdContainer.LIGHTING_38, salData);
- }
- EncodedReply encodedReply = new MonitoredSALReply(requestContext, (byte) 0x0, monitoredSAL);
- Reply reply = new ReplyEncodedReply((byte) 0x0, cBusOptions, encodedReply, null);
- ReplyOrConfirmation replyOrConfirmation = new ReplyOrConfirmationReply((byte) 0x00, reply, new ResponseTermination());
- CBusMessage message = new CBusMessageToClient(replyOrConfirmation);
- LOGGER.info("[SAL Monitor] Sending out\n{}", message);
- ctx.writeAndFlush(message);
- } finally {
- outputLock.unlock();
- }
- }, 5, 5, TimeUnit.SECONDS);
- }
-
- private static SALData createLightingData() {
- LightingData lightingData;
- double random = Math.random();
- if (random < 0.25) {
- lightingData = new LightingDataOn(LightingCommandTypeContainer.LightingCommandOn, (byte) 0xAF);
- } else if (random > 0.25 && random < 0.5) {
- lightingData = new LightingDataOff(LightingCommandTypeContainer.LightingCommandOff, (byte) 0xAF);
- } else if (random > 0.5 && random < 0.75) {
- lightingData = new LightingDataRampToLevel(LightingCommandTypeContainer.LightingCommandRampToLevel_20Second, (byte) 0xAF, (byte) 0xE0);
- } else {
- lightingData = new LightingDataTerminateRamp(LightingCommandTypeContainer.LightingCommandTerminateRamp, (byte) 0xAF);
- }
- return new SALDataLighting(null, lightingData);
- }
-
- private void stopSALMonitor() {
- if (salMonitorFuture == null) {
- return;
- }
- LOGGER.info("Stopping SAL monitor");
- salMonitorFuture.cancel(false);
- salMonitorFuture = null;
- }
-
- private void startMMIMonitor(ChannelHandlerContext ctx) {
- if (mmiMonitorFuture != null) {
- LOGGER.debug("MMI Monitor already running");
- return;
- }
- LOGGER.info("Starting MMI monitor");
- mmiMonitorFuture = ctx.executor().scheduleAtFixedRate(() -> {
- try {
- outputLock.lock();
- LOGGER.info("[MMI Monitor] Sending out infos");
- sendMonitoredMMIs(ctx);
- } finally {
- outputLock.unlock();
- }
- }, 5, 5, TimeUnit.SECONDS);
- }
-
- private void stopMMIMonitor() {
- if (mmiMonitorFuture == null) {
- return;
- }
- LOGGER.info("Stopping monitor");
- mmiMonitorFuture.cancel(false);
- mmiMonitorFuture = null;
- }
-
- private CALCommandTypeContainer getReplyCommandType(int numBytes) {
- for (CALCommandTypeContainer value : CALCommandTypeContainer.values()) {
- if (value.getCommandType() == CALCommandType.REPLY && value.getNumBytes() == numBytes) {
- return value;
- }
- }
- throw new IllegalArgumentException("No reply type for " + numBytes);
- }
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7ServerModule.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7ServerModule.java
deleted file mode 100644
index 4bcbce0d47..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/S7ServerModule.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator.server.s7;
-
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import org.apache.plc4x.simulator.PlcSimulatorConfig;
-import org.apache.plc4x.java.s7.S7Driver;
-import org.apache.plc4x.java.s7.readwrite.TPKTPacket;
-import org.apache.plc4x.java.spi.connection.GeneratedProtocolMessageCodec;
-import org.apache.plc4x.java.spi.generation.ByteOrder;
-import org.apache.plc4x.simulator.exceptions.SimulatorException;
-import org.apache.plc4x.simulator.model.Context;
-import org.apache.plc4x.simulator.server.ServerModule;
-import org.apache.plc4x.simulator.server.s7.protocol.S7Step7ServerAdapter;
-
-public class S7ServerModule implements ServerModule {
-
- private static final int ISO_ON_TCP_PORT = 102;
-
- private EventLoopGroup loopGroup;
- private EventLoopGroup workerGroup;
- private Context context;
- private PlcSimulatorConfig config;
-
- @Override
- public String getName() {
- return "S7-STEP7";
- }
-
- @Override
- public void setConfig(PlcSimulatorConfig config) {
- this.config = config;
- }
-
- @Override
- public void setContext(Context context) {
- this.context = context;
- }
-
-
- @Override
- public void start() throws SimulatorException {
- if (loopGroup != null) {
- return;
- }
-
- try {
- loopGroup = new NioEventLoopGroup();
- workerGroup = new NioEventLoopGroup();
-
- ServerBootstrap bootstrap = new ServerBootstrap();
- bootstrap.group(loopGroup, workerGroup)
- .channel(NioServerSocketChannel.class)
- .childHandler(new ChannelInitializer<SocketChannel>() {
- @Override
- public void initChannel(SocketChannel channel) {
- ChannelPipeline pipeline = channel.pipeline();
- pipeline.addLast(new GeneratedProtocolMessageCodec<>(TPKTPacket.class,
- TPKTPacket::staticParse, ByteOrder.BIG_ENDIAN,
- new S7Driver.ByteLengthEstimator(),
- new S7Driver.CorruptPackageCleaner()));
- pipeline.addLast(new S7Step7ServerAdapter(context));
- }
- }).option(ChannelOption.SO_BACKLOG, 128)
- .childOption(ChannelOption.SO_KEEPALIVE, true);
-
- int port = ISO_ON_TCP_PORT;
- if (config.getS7Port() != null) {
- port = Integer.parseInt(config.getS7Port());
- }
- String host = config.getHost();
- if (host != null) {
- bootstrap.bind(host, port).sync();
- } else {
- bootstrap.bind(port).sync();
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new SimulatorException(e);
- }
- }
-
- @Override
- public void stop() {
- if (workerGroup == null) {
- return;
- }
-
- workerGroup.shutdownGracefully();
- loopGroup.shutdownGracefully();
- }
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerAdapter.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerAdapter.java
deleted file mode 100644
index 795e0d1d89..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/s7/protocol/S7Step7ServerAdapter.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator.server.s7.protocol;
-
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import org.apache.plc4x.java.s7.readwrite.*;
-import org.apache.plc4x.java.spi.generation.ReadBuffer;
-import org.apache.plc4x.java.spi.generation.ReadBufferByteBased;
-import org.apache.plc4x.java.spi.generation.WriteBuffer;
-import org.apache.plc4x.java.spi.generation.WriteBufferByteBased;
-import org.apache.plc4x.simulator.model.Context;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.List;
-
-public class S7Step7ServerAdapter extends ChannelInboundHandlerAdapter {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(S7Step7ServerAdapter.class);
-
- private final Context context;
-
- private State state;
-
- // COTP parameters
- private static final int localReference = 42;
- private int remoteReference = -1;
- private COTPProtocolClass protocolClass;
- private static final int localTsapId = 1;
- private int remoteTsapId = -1;
- private static final COTPTpduSize maxTpduSize = COTPTpduSize.SIZE_256;
- private COTPTpduSize tpduSize;
- // S7 parameters
- // Set this to 1 as we don't want to handle stuff in parallel
- private static final int maxAmqCaller = 1;
- private int amqCaller;
- // Set this to 1 as we don't want to handle stuff in parallel
- private static final int maxAmqCallee = 1;
- private int amqCallee;
- private static final int maxPduLength = 240;
- private int pduLength;
-
- public S7Step7ServerAdapter(Context context) {
- this.context = context;
- state = State.INITIAL;
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- if (msg instanceof TPKTPacket) {
- TPKTPacket packet = (TPKTPacket) msg;
- final COTPPacket cotpPacket = packet.getPayload();
- switch (state) {
- case INITIAL: {
- if (!(cotpPacket instanceof COTPPacketConnectionRequest)) {
- LOGGER.error("Expecting COTP Connection-Request");
- return;
- }
-
- COTPTpduSize proposedTpduSize = null;
- COTPPacketConnectionRequest cotpConnectionRequest = (COTPPacketConnectionRequest) cotpPacket;
- for (COTPParameter parameter : cotpConnectionRequest.getParameters()) {
- if (parameter instanceof COTPParameterCalledTsap) {
- // this is actually ignored as it doesn't contain any information.
- } else if (parameter instanceof COTPParameterCallingTsap) {
- COTPParameterCallingTsap callingTsapParameter = (COTPParameterCallingTsap) parameter;
- remoteTsapId = callingTsapParameter.getTsapId();
- } else if (parameter instanceof COTPParameterTpduSize) {
- COTPParameterTpduSize tpduSizeParameter = (COTPParameterTpduSize) parameter;
- proposedTpduSize = tpduSizeParameter.getTpduSize();
- } else {
- LOGGER.error(String.format("Unexpected COTP Connection-Request Parameter %s",
- parameter.getClass().getName()));
- return;
- }
- }
- if (proposedTpduSize == null) {
- LOGGER.error("Missing COTP Connection-Request Parameter Tpdu Size");
- return;
- }
-
- remoteReference = cotpConnectionRequest.getSourceReference();
- protocolClass = cotpConnectionRequest.getProtocolClass();
- tpduSize = (proposedTpduSize.getSizeInBytes() > maxTpduSize.getSizeInBytes()) ? maxTpduSize : proposedTpduSize;
-
- // Prepare a response and send it back to the remote.
- List<COTPParameter> parameters = new ArrayList<>();
- parameters.add(new COTPParameterCalledTsap(remoteTsapId));
- parameters.add(new COTPParameterCallingTsap(localTsapId));
- parameters.add(new COTPParameterTpduSize(tpduSize));
- COTPPacketConnectionResponse response = new COTPPacketConnectionResponse(
- parameters, null, remoteReference, localReference, protocolClass
- );
- ctx.writeAndFlush(new TPKTPacket(response));
-
- state = State.COTP_CONNECTED;
- break;
- }
- case COTP_CONNECTED: {
- if (!(cotpPacket instanceof COTPPacketData)) {
- LOGGER.error("Expecting COTP Data packet");
- return;
- }
-
- COTPPacketData packetData = (COTPPacketData) cotpPacket;
- final byte cotpTpduRef = packetData.getTpduRef();
- final S7Message payload = packetData.getPayload();
- if (!(payload instanceof S7MessageRequest)) {
- LOGGER.error("Expecting S7 Message Request");
- return;
- }
- S7MessageRequest s7MessageRequest = (S7MessageRequest) payload;
- final int s7TpduReference = s7MessageRequest.getTpduReference();
- final S7Parameter s7Parameter = s7MessageRequest.getParameter();
- if (!(s7Parameter instanceof S7ParameterSetupCommunication)) {
- LOGGER.error("Expecting S7 Message Request containing a S7 Setup Communication Parameter");
- return;
- }
- S7ParameterSetupCommunication s7ParameterSetupCommunication =
- (S7ParameterSetupCommunication) s7Parameter;
-
- amqCaller = Math.min(s7ParameterSetupCommunication.getMaxAmqCaller(), maxAmqCaller);
- amqCallee = Math.min(s7ParameterSetupCommunication.getMaxAmqCallee(), maxAmqCallee);
- pduLength = Math.min(s7ParameterSetupCommunication.getPduLength(), maxPduLength);
-
- S7ParameterSetupCommunication s7ParameterSetupCommunicationResponse =
- new S7ParameterSetupCommunication(amqCaller, amqCallee, pduLength);
- // TODO should send S7MessageResponseData
- S7MessageResponseData s7MessageResponse = new S7MessageResponseData(
- s7TpduReference, s7ParameterSetupCommunicationResponse, null, (short) 0, (short) 0);
- ctx.writeAndFlush(new TPKTPacket(new COTPPacketData(null, s7MessageResponse, true, cotpTpduRef)));
-
- state = State.S7_CONNECTED;
- break;
- }
- case S7_CONNECTED: {
- if (!(cotpPacket instanceof COTPPacketData)) {
- LOGGER.error("Expecting COTP Data packet");
- return;
- }
-
- COTPPacketData packetData = (COTPPacketData) cotpPacket;
- final byte cotpTpduRef = packetData.getTpduRef();
- final S7Message payload = packetData.getPayload();
- if (payload instanceof S7MessageUserData) {
- S7MessageUserData s7MessageUserData = (S7MessageUserData) payload;
- final int s7TpduReference = s7MessageUserData.getTpduReference();
- final S7Parameter s7Parameter = s7MessageUserData.getParameter();
- if (s7Parameter instanceof S7ParameterUserData) {
- S7ParameterUserData userDataParameter = (S7ParameterUserData) s7Parameter;
- for (S7ParameterUserDataItem item : userDataParameter.getItems()) {
- if (item instanceof S7ParameterUserDataItemCPUFunctions) {
- S7ParameterUserDataItemCPUFunctions function =
- (S7ParameterUserDataItemCPUFunctions) item;
- final S7PayloadUserData userDataPayload =
- (S7PayloadUserData) s7MessageUserData.getPayload();
-
- for (S7PayloadUserDataItem userDataPayloadItem : userDataPayload.getItems()) {
- if (userDataPayloadItem instanceof S7PayloadUserDataItemCpuFunctionReadSzlRequest) {
- S7PayloadUserDataItemCpuFunctionReadSzlRequest readSzlRequestPayload =
- (S7PayloadUserDataItemCpuFunctionReadSzlRequest) userDataPayloadItem;
-
- final SzlId szlId = readSzlRequestPayload.getSzlId();
- // This is a request to list the type of device
- if ((szlId.getTypeClass() == SzlModuleTypeClass.CPU) &&
- (szlId.getSublistList() == SzlSublist.MODULE_IDENTIFICATION)) {
-
- S7ParameterUserDataItemCPUFunctions readSzlResponseParameter =
- new S7ParameterUserDataItemCPUFunctions((short) 0x12,
- (byte) 0x08, function.getCpuFunctionGroup(),
- function.getCpuSubfunction(), (short) 1,
- (short) 0, (short) 0, 0);
-
- // This is the product number of a S7-1200
- List<SzlDataTreeItem> items = new ArrayList<>();
- items.add(new SzlDataTreeItem((short) 0x0001,
- "6ES7 212-1BD30-0XB0 ".getBytes(), 0x2020, 0x0001, 0x2020));
-
- WriteBuffer writeBuffer = new WriteBufferByteBased(items.get(0).getLengthInBytes());
- ReadBuffer readBuffer = new ReadBufferByteBased(new byte[items.get(0).getLengthInBytes()]);
- items.get(0).serialize(writeBuffer);
-
- //TODO: Fix this section. Fail!!!
- S7PayloadUserDataItemCpuFunctionReadSzlResponse readSzlResponsePayload =
-// new S7PayloadUserDataItemCpuFunctionReadSzlResponse(
-// DataTransportErrorCode.OK, DataTransportSize.OCTET_STRING, szlId,
-// readSzlRequestPayload.getSzlIndex(), items);
- new S7PayloadUserDataItemCpuFunctionReadSzlResponse(
- DataTransportErrorCode.OK, DataTransportSize.OCTET_STRING, items.get(0).getLengthInBytes(), readBuffer.readByteArray(items.get(0).getLengthInBytes()));
-
- List<S7ParameterUserDataItem> responseParameterItems = new ArrayList<>();
- responseParameterItems.add(readSzlResponseParameter);
- S7ParameterUserData responseParameterUserData =
- new S7ParameterUserData(responseParameterItems);
-
- List<S7PayloadUserDataItem> responsePayloadItems = new ArrayList<>();
- responsePayloadItems.add(readSzlResponsePayload);
- S7PayloadUserData responsePayloadUserData =
- new S7PayloadUserData(responsePayloadItems);
-
- S7Message s7ResponseMessage = new S7MessageUserData(s7TpduReference,
- responseParameterUserData, responsePayloadUserData);
- ctx.writeAndFlush(new TPKTPacket(new COTPPacketData(null, s7ResponseMessage, true, cotpTpduRef)));
- } else {
- LOGGER.error("Not able to respond to the given request Read SZL with SZL type class " +
- szlId.getTypeClass().name() + " and SZL sublist " + szlId.getSublistList().name());
- }
-
- }
- }
- }
- }
- } else {
- LOGGER.error("Unsupported type of S7MessageUserData parameter " +
- s7Parameter.getClass().getName());
- }
- } else {
- if (cotpPacket.getPayload() instanceof S7MessageRequest) {
- S7MessageRequest request = (S7MessageRequest) cotpPacket.getPayload();
- if (request.getParameter() instanceof S7ParameterReadVarRequest) {
- S7ParameterReadVarRequest readVarRequestParameter =
- (S7ParameterReadVarRequest) request.getParameter();
- List<S7VarRequestParameterItem> items = readVarRequestParameter.getItems();
- List<S7VarPayloadDataItem> payloadItems = new ArrayList<>();
- for (S7VarRequestParameterItem item : items) {
- if (item instanceof S7VarRequestParameterItemAddress) {
- S7VarRequestParameterItemAddress address =
- (S7VarRequestParameterItemAddress) item;
- final S7Address address1 = address.getAddress();
- if (address1 instanceof S7AddressAny) {
- S7AddressAny addressAny = (S7AddressAny) address1;
- switch (addressAny.getArea()) {
- case DATA_BLOCKS: {
- final int dataBlockNumber = addressAny.getDbNumber();
- if (dataBlockNumber != 1) {
- // TODO: Return unknown object.
- }
- final int numberOfElements = addressAny.getNumberOfElements();
- if (numberOfElements != 1) {
- // TODO: Return invalid address.
- }
- final int byteAddress = addressAny.getByteAddress();
- if (byteAddress != 0) {
- // TODO: Return invalid address.
- }
- final byte bitAddress = addressAny.getBitAddress();
- switch (addressAny.getTransportSize()) {
- case BOOL:
- payloadItems.add(new S7VarPayloadDataItem(DataTransportErrorCode.OK, DataTransportSize.BIT, new byte[]{1}));
- break;
- case INT:
- case UINT: {
- String firstKey = context.getMemory().keySet().iterator().next();
- Object value = context.getMemory().get(firstKey);
- short shortValue = ((Number) value).shortValue();
- byte[] data = new byte[2];
- data[1] = (byte) (shortValue & 0xff);
- data[0] = (byte) ((shortValue >> 8) & 0xff);
- payloadItems.add(new S7VarPayloadDataItem(DataTransportErrorCode.OK, DataTransportSize.BYTE_WORD_DWORD, data));
- break;
- }
- default: {
- // TODO: Return invalid address.
- }
- }
- break;
- }
- case INPUTS:
- case OUTPUTS: {
- final int ioNumber = (addressAny.getByteAddress() * 8) + addressAny.getBitAddress();
- final int numElements = (addressAny.getTransportSize() == TransportSize.BOOL) ?
- addressAny.getNumberOfElements() : addressAny.getTransportSize().getSizeInBytes() * 8;
- final BitSet bitSet = toBitSet(context.getDigitalInputs(), ioNumber, numElements);
- final byte[] data = Arrays.copyOf(bitSet.toByteArray(), (numElements + 7) / 8);
- payloadItems.add(new S7VarPayloadDataItem(DataTransportErrorCode.OK, DataTransportSize.BYTE_WORD_DWORD, data));
- break;
- }
- }
- }
- }
- }
- S7ParameterReadVarResponse readVarResponseParameter = new S7ParameterReadVarResponse((short) items.size());
- S7PayloadReadVarResponse readVarResponsePayload = new S7PayloadReadVarResponse(payloadItems);
- S7MessageResponseData response = new S7MessageResponseData(request.getTpduReference(),
- readVarResponseParameter, readVarResponsePayload, (short) 0x00, (short) 0x00);
- ctx.writeAndFlush(new TPKTPacket(new COTPPacketData(null, response, true, cotpTpduRef)));
- } else if (request.getParameter() instanceof S7ParameterWriteVarRequest) {
- S7ParameterWriteVarRequest writeVarRequestParameter =
- (S7ParameterWriteVarRequest) request.getParameter();
-
- } else {
- LOGGER.error("Unsupported type of S7MessageRequest parameter " +
- request.getParameter().getClass().getName());
- }
- } else {
- LOGGER.error("Unsupported type of message " + payload.getClass().getName());
- }
- }
- break;
- }
- default:
- throw new IllegalStateException("Unexpected value: " + state);
- }
- }
- }
-
- private enum State {
- INITIAL,
- COTP_CONNECTED,
- S7_CONNECTED
- }
-
- private BitSet toBitSet(List<Boolean> booleans, int startIndex, int numElements) {
- BitSet bitSet = new BitSet(booleans.size());
- for (int i = 0; i < Math.min(booleans.size() - startIndex, numElements); i++) {
- bitSet.set(i, booleans.get(i + startIndex));
- }
- return bitSet;
- }
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/SimulationModule.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/SimulationModule.java
deleted file mode 100644
index 7bc77c8a2f..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/SimulationModule.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator.simulation;
-
-import org.apache.plc4x.simulator.model.Context;
-
-public interface SimulationModule {
-
- /**
- * @return the name of the simulation module
- */
- String getName();
-
- /**
- * Gives access to the internal simulations context.
- * @return reference to the simulations context
- */
- Context getContext();
-
- /**
- * Method for doing the actual processing inside the simulation.
- * In this method the simulation can do calculations and update it's context variables.
- */
- void loop();
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/watertank/WaterTankSimulationModule.java b/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/watertank/WaterTankSimulationModule.java
deleted file mode 100644
index 5b4dd6116e..0000000000
--- a/plc4j/utils/plc-simulator/src/main/java/org/apache/plc4x/simulator/simulation/watertank/WaterTankSimulationModule.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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
- *
- * https://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.simulator.simulation.watertank;
-
-import org.apache.plc4x.simulator.model.Context;
-import org.apache.plc4x.simulator.simulation.SimulationModule;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * This is a little simulation that simulates a Water tank.
- * This tank has a capacity who's "waterLevel" is represented as a Long value.
- * Water can flow into the tank if the input valve is opened, and it can flow
- * out of the tank if the output valve is open.
- * <p>
- * The capacity of the output is slightly smaller than that of the input, so
- * opening both valves will result in the tank filling.
- * <p>
- * To prevent the tank from bursting, there's an emergency valve which is opened
- * as soon as the water-level reaches a critical maximum.
- */
-public class WaterTankSimulationModule implements SimulationModule {
-
- private static final long MAX_WATER_LEVEL = 27648L;
- private static final long EMERGENCY_VALVE_WATER_LEVEL = 27500L;
-
- private static final int NUM_INPUT_VALVE_INPUT = 0;
- private static final int NUM_OUTPUT_VALVE_INPUT = 1;
-
- private static final int EMERGENCY_VALVE_OUTPUT = 0;
-
- private static final String PROP_WATER_LEVEL = "waterLevel";
-
- private final Context context;
-
- public WaterTankSimulationModule() {
- context = new Context.ContextBuilder()
- // The input valve
- .addDigitalInput(false)
- // The output valve
- .addDigitalInput(true)
- // The emergency valve
- .addDigitalOutput(false)
- // The water level
- .addMemoryVariable(PROP_WATER_LEVEL, 0L).build();
- }
-
- @Override
- public String getName() {
- return "Water Tank";
- }
-
- @Override
- public Context getContext() {
- return context;
- }
-
- @Override
- public void loop() {
- // TODO: Do something sensible ;-)
- // Just a POC for now ... to be replaced by a "real" simulation ...
- try {
- // Get the current value for the water tank level.
- Long value = (Long) context.getMemory().get(PROP_WATER_LEVEL);
-
- // If the input valve is open, add 10.
- if (context.getDigitalInputs().get(NUM_INPUT_VALVE_INPUT)) {
- value += 10;
- value = Math.min(MAX_WATER_LEVEL, value);
- }
-
- // If the output valve is open, subtract 8 (It's slightly less throughput than the input)
- if (context.getDigitalInputs().get(NUM_OUTPUT_VALVE_INPUT)) {
- value -= 8;
- value = Math.max(0, value);
- }
-
- // Calculate if the emergency valve should be open
- boolean emergencyValveOpen = value > EMERGENCY_VALVE_WATER_LEVEL;
-
- // Update the memory.
- context.getMemory().put(PROP_WATER_LEVEL, value);
- // Update the state of the emergency valve.
- context.getDigitalOutputs().set(EMERGENCY_VALVE_OUTPUT, emergencyValveOpen);
-
- // Should probably be handled by the simulator
- TimeUnit.MILLISECONDS.sleep(100);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
-
-}
diff --git a/plc4j/utils/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.server.ServerModule b/plc4j/utils/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.server.ServerModule
deleted file mode 100644
index d859c97455..0000000000
--- a/plc4j/utils/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.server.ServerModule
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# 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
-#
-# https://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.simulator.server.s7.S7ServerModule
-org.apache.plc4x.simulator.server.cbus.CBusServerModule
-org.apache.plc4x.simulator.server.bacnet.BacnetServerModule
\ No newline at end of file
diff --git a/plc4j/utils/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.simulation.SimulationModule b/plc4j/utils/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.simulation.SimulationModule
deleted file mode 100644
index 941372c880..0000000000
--- a/plc4j/utils/plc-simulator/src/main/resources/META-INF/services/org.apache.plc4x.simulator.simulation.SimulationModule
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# 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
-#
-# https://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.simulator.simulation.watertank.WaterTankSimulationModule
\ No newline at end of file
diff --git a/plc4j/utils/plc-simulator/src/main/resources/logback.xml b/plc4j/utils/plc-simulator/src/main/resources/logback.xml
deleted file mode 100644
index 264277d573..0000000000
--- a/plc4j/utils/plc-simulator/src/main/resources/logback.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- https://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.
--->
-<configuration xmlns="http://ch.qos.logback/xml/ns/logback"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://ch.qos.logback/xml/ns/logback https://raw.githubusercontent.com/enricopulatzo/logback-XSD/master/src/main/xsd/logback.xsd">
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="error">
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration>
\ No newline at end of file
diff --git a/plc4j/utils/pom.xml b/plc4j/utils/pom.xml
index db392fa000..fdd7a43f54 100644
--- a/plc4j/utils/pom.xml
+++ b/plc4j/utils/pom.xml
@@ -38,18 +38,11 @@
<subprojects>
<subproject>audit-log</subproject>
<subproject>subscription-emulation</subproject>
- <!-- Non-default input options -->
- <subproject>pcap-replay</subproject>
- <subproject>pcap-shared</subproject>
<subproject>raw-sockets</subproject>
<!-- Utilities for building tests -->
<subproject>test-generator</subproject>
<subproject>test-utils</subproject>
-
- <!-- Utilities for working with PLCs -->
- <!-- TODO: Re-Enable as soon as we have ported the driver logic -->
- <!--subproject>plc-simulator</subproject-->
</subprojects>
</project>
\ No newline at end of file
diff --git a/plc4j/utils/raw-sockets/pom.xml b/plc4j/utils/raw-sockets/pom.xml
index 99ab11631d..599fbf94b5 100644
--- a/plc4j/utils/raw-sockets/pom.xml
+++ b/plc4j/utils/raw-sockets/pom.xml
@@ -44,13 +44,6 @@
<usedDependencies>
<usedDependency>org.pcap4j:pcap4j-packetfactory-static</usedDependency>
</usedDependencies>
- <ignoredDependencies combine.children="append">
- <!--
- For some reason we need to do this. The compiler needs it in order to compile,
- but the plugin doesn't detect this.
- -->
- <ignoredDependency>io.netty:netty-common</ignoredDependency>
- </ignoredDependencies>
</configuration>
</plugin>
@@ -75,25 +68,6 @@
</build>
<dependencies>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-utils-pcap-shared</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-common</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </dependency>
-
<dependency>
<groupId>org.pcap4j</groupId>
<artifactId>pcap4j-core</artifactId>
@@ -122,13 +96,6 @@
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
-
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-utils-test-utils</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <scope>test</scope>
- </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/RawSocketChannel.java b/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/RawSocketChannel.java
deleted file mode 100644
index a51000b3d6..0000000000
--- a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/RawSocketChannel.java
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.rawsockets.netty;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.*;
-import io.netty.channel.oio.OioByteStreamChannel;
-import org.apache.commons.lang3.NotImplementedException;
-import org.apache.commons.net.util.SubnetUtils;
-import org.apache.plc4x.java.utils.pcap.netty.exception.PcapException;
-import org.apache.plc4x.java.utils.rawsockets.netty.address.RawSocketAddress;
-import org.apache.plc4x.java.utils.rawsockets.netty.address.RawSocketPassiveAddress;
-import org.apache.plc4x.java.utils.rawsockets.netty.config.RawSocketChannelConfig;
-import org.apache.plc4x.java.utils.rawsockets.netty.utils.ArpUtils;
-import org.pcap4j.core.*;
-import org.pcap4j.packet.EthernetPacket;
-import org.pcap4j.packet.IllegalRawDataException;
-import org.pcap4j.packet.Packet;
-import org.pcap4j.util.MacAddress;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.*;
-
-/**
- * Channel based on a Pcap4J raw-socket, allowing to actively communicate based on ethernet frames.
- */
-public class RawSocketChannel extends OioByteStreamChannel {
-
- private static final Logger logger = LoggerFactory.getLogger(RawSocketChannel.class);
-
- private final RawSocketChannelConfig config;
-
- private MacAddress remoteMacAddress;
- private SocketAddress remoteAddress;
- private MacAddress localMacAddress;
- private SocketAddress localAddress;
- private PcapHandle receiveHandle;
- private Thread loopThread;
-
- public RawSocketChannel() {
- super(null);
- config = new RawSocketChannelConfig(this);
- }
-
- public void setRemoteMacAddress(MacAddress remoteMacAddress) {
- this.remoteMacAddress = remoteMacAddress;
-
- // Update the filter expression, if the handle is already open.
- if((receiveHandle != null) && (receiveHandle.isOpen())){
- MacAddress tempRemoteMacAddress = remoteMacAddress != null ? remoteMacAddress : MacAddress.getByAddress(new byte[]{0,0,0,0,0,0});
- String filter = config.getMacBasedFilterString(localMacAddress, tempRemoteMacAddress);
- if(!filter.isEmpty()) {
- try {
- receiveHandle.setFilter(filter, BpfProgram.BpfCompileMode.OPTIMIZE);
- } catch (NotOpenException | PcapNativeException e) {
- throw new RuntimeException("Error updating filter expression");
- }
- }
- }
- }
-
- @Override
- protected boolean isInputShutdown() {
- return false;
- }
-
- @Override
- protected ChannelFuture shutdownInput() {
- throw new NotImplementedException("");
- }
-
- @Override
- protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
- if(!((remoteAddress instanceof RawSocketPassiveAddress) || (remoteAddress instanceof InetSocketAddress) || (remoteAddress instanceof RawSocketAddress))) {
- logger.error("Expecting remote address of type RawSocketPassiveAddress or InetSocketAddress");
- pipeline().fireExceptionCaught(
- new PcapException("Expecting remote address of type RawSocketPassiveAddress or InetSocketAddress"));
- return;
- }
- this.localAddress = localAddress;
- this.remoteAddress = remoteAddress;
-
- PcapNetworkInterface nif = null;
- // Try to get the device name of the network interface that we want to open.
- if(remoteAddress instanceof RawSocketPassiveAddress) {
- RawSocketPassiveAddress rawSocketPassiveAddress = (RawSocketPassiveAddress) remoteAddress;
- String deviceName = getDeviceName(rawSocketPassiveAddress);
- if (deviceName == null) {
- logger.error("Network device not specified and couldn't detect it automatically");
- pipeline().fireExceptionCaught(
- new PcapException("Network device not specified and couldn't detect it automatically"));
- return;
- }
-
- // Get a handle to the network-device and open it.
- nif = Pcaps.getDevByName(deviceName);
- } else if (remoteAddress instanceof InetSocketAddress) {
- InetSocketAddress inetSocketAddress = (InetSocketAddress) remoteAddress;
- InetAddress address = inetSocketAddress.getAddress();
- deviceLoop:
- for (PcapNetworkInterface dev : Pcaps.findAllDevs()) {
- // We're only interested in real running network interfaces, skip the rest.
- if (dev.isLoopBack()) {
- continue;
- }
-
- // Go through all configured addresses and subnets and if we find a matching
- // device, use that as nif.
- for (PcapAddress curAddress : dev.getAddresses()) {
- if((curAddress.getAddress() == null) || (curAddress.getNetmask() == null)) {
- continue;
- }
- if((address instanceof Inet4Address) && !(curAddress instanceof PcapIpV4Address)) {
- continue;
- }
- if((address instanceof Inet6Address) && !(curAddress instanceof PcapIpV6Address)) {
- continue;
- }
- final SubnetUtils.SubnetInfo subnetInfo = new SubnetUtils(curAddress.getAddress().getHostAddress(), curAddress.getNetmask().getHostAddress()).getInfo();
- if(subnetInfo.isInRange(address.getHostAddress())) {
- nif = dev;
- // Update the local address
- this.localAddress = new InetSocketAddress(curAddress.getAddress(), 0);
- this.localMacAddress = dev.getLinkLayerAddresses().stream()
- .filter(linkLayerAddress -> linkLayerAddress instanceof MacAddress).map(linkLayerAddress -> (MacAddress) linkLayerAddress)
- .findFirst().orElse(null);
- break deviceLoop;
- }
- }
- }
- }
- // This would be generally to use a remote MAC address as target.
- else {
- // Here we would need to do a reverse ARP lookup to find the
- throw new RuntimeException("Not Implemented yet ");
- // TODO: Implement finding out which device is used for communicating with a given MAC address.
- }
-
- if (nif == null) {
- logger.error(String.format("Couldn't find network device for %s", remoteAddress));
- pipeline().fireExceptionCaught(
- new PcapException(String.format("Couldn't find network device for %s", remoteAddress)));
- return;
- }
-
- // If desired: Try to get the mac address of the remote station by sending an ARP request.
- if(config.isResolveMacAddress()) {
- if ((this.remoteMacAddress == null) && (this.remoteAddress instanceof InetSocketAddress)) {
- this.remoteMacAddress = ArpUtils.resolveMacAddress(nif, (InetSocketAddress) this.remoteAddress,
- (InetSocketAddress) this.localAddress, localMacAddress).orElse(null);
- }
- }
-
- receiveHandle = nif.openLive(65535, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 10);
- if(logger.isDebugEnabled()) {
- logger.debug(String.format("Listening on device %s", nif.getName()));
- }
-
- // If the address allows fine-tuning which packets to process, set a filter to reduce the load.
- // If no remote mac address is set, we'll set it to 00:00:00:00:00, which is an invalid address
- // and therefore no traffic will be incoming.
- // TODO: Make configurable, if we should accept from any source or not.
- MacAddress tempRemoteMacAddress = remoteMacAddress != null ? remoteMacAddress : MacAddress.getByAddress(new byte[]{0,0,0,0,0,0});
- String filter = config.getMacBasedFilterString(localMacAddress, tempRemoteMacAddress);
- if(!filter.isEmpty()) {
- receiveHandle.setFilter(filter, BpfProgram.BpfCompileMode.OPTIMIZE);
- }
-
- // Create a buffer where the raw socket worker can send data to.
- ByteBuf buffer = Unpooled.buffer();
-
- // Start a thread that processes the callbacks from the raw socket and simply
- // forwards the bytes read to the buffer.
- loopThread = new Thread(() -> {
- try {
- receiveHandle.loop(-1,
- (PacketListener) packet -> buffer.writeBytes(config.getPacketHandler().getData(packet)));
- } catch (PcapNativeException | NotOpenException e) {
- // TODO this should close everything automatically
- logger.error("Pcap4j loop thread died!", e);
- pipeline().fireExceptionCaught(e);
- } catch (InterruptedException e) {
- // This usually happens when the raw socket transport is closed.
- }
- });
- loopThread.start();
-
- if(remoteAddress instanceof RawSocketPassiveAddress) {
- // Right now we're using an output stream that simply discards everything.
- // This is ok while implementing passive drivers for protocols, however as
- // soon as we start implementing ethernet layer protocols, we'll have to also
- // be able to actually send data. The PcapInputStream simply acts as a
- // breaking point if no packets are coming in and the read operation would
- // simply block indefinitely.
- activate(new PcapInputStream(buffer), new DiscardingOutputStream());
- } else {
- PcapHandle sendHandle = nif.openLive(65535, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 10);
- activate(new PcapInputStream(buffer), new PcapOutputStream(sendHandle));
- }
- }
-
- @Override
- protected SocketAddress localAddress0() {
- return localAddress;
- }
-
- @Override
- protected SocketAddress remoteAddress0() {
- return remoteAddress;
- }
-
- @Override
- protected void doBind(SocketAddress localAddress) {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- @Override
- protected void doDisconnect() throws NotOpenException {
- this.loopThread.interrupt();
- if (this.receiveHandle != null) {
- // Interrupt the receiving loop.
- receiveHandle.breakLoop();
- // Close the channel.
- receiveHandle.close();
- // Shutdown the loop-thread.
- // (Doing it the graceful way, didn't work)
- eventLoop().shutdownNow();
- }
- }
-
- @Override
- protected int doReadBytes(ByteBuf buf) throws Exception {
- if (receiveHandle == null || !receiveHandle.isOpen()) {
- return -1;
- }
- try {
- return super.doReadBytes(buf);
- } catch (SocketTimeoutException ignored) {
- return 0;
- }
- }
-
- @Override
- public ChannelConfig config() {
- return this.config;
- }
-
- @Override
- public boolean isOpen() {
- return true;
- }
-
- @Override
- protected AbstractUnsafe newUnsafe() {
- return new RawSocketUnsafe();
- }
-
- public SocketAddress getRemoteAddress() {
- return remoteAddress;
- }
-
- public MacAddress getRemoteMacAddress() {
- return remoteMacAddress;
- }
-
- public SocketAddress getLocalAddress() {
- return localAddress;
- }
-
- public MacAddress getLocalMacAddress() {
- return localMacAddress;
- }
-
- private String getDeviceName(RawSocketPassiveAddress rawSocketAddress) {
- // If the device name is provided, simply use this.
- if(rawSocketAddress.getDeviceName() != null) {
- return rawSocketAddress.getDeviceName();
- }
-
- // TODO: Implement this ...
- return null;
- }
-
- /**
- * This output stream simply discards anything it should send.
- */
- private static class DiscardingOutputStream extends OutputStream {
- @Override
- public void write(int b) {
- // discard
- logger.debug("Discarding {}", b);
- }
-
- @Override
- public void write(byte[] b, int off, int len) {
- logger.debug("Discarding {}", b);
- }
- }
-
- private static class PcapOutputStream extends OutputStream {
-
- private final PcapHandle sendHandle;
-
- public PcapOutputStream(PcapHandle sendHandle) {
- this.sendHandle = sendHandle;
- }
-
- @Override
- public void write(int b) {
- // This should actually not be called, as in contrast to TCP, Raw sockets are not a stream
- // messages which should be sent should be processed in total by the write(byte[]) method.
- throw new RuntimeException("write(byte) should never be called in a RawSocketChannel");
- }
-
- @Override
- public void write(byte[] packetBytes, int offset, int len) throws IOException {
- if((offset < 0) || (len < 0) || (offset + len > packetBytes.length)) {
- throw new IndexOutOfBoundsException();
- }
- try {
- // Create a new EthernetPacket with the raw content of the packet bytes.
- Packet rawPacket = EthernetPacket.newPacket(packetBytes, offset, len);
- // Send the packet.
- sendHandle.sendPacket(rawPacket);
- } catch (IllegalRawDataException | NotOpenException | PcapNativeException e) {
- throw new IOException("Error sending packet", e);
- }
- }
- }
-
- /**
- * InputStream that fulfills the contract of Netty for read operations to timeout.
- * Without this the InputStream would simply block indefinitely which would block
- * the entire IO module.
- */
- private static class PcapInputStream extends InputStream {
- final ByteBuf buf;
-
- private PcapInputStream(ByteBuf buf) {
- this.buf = buf;
- }
-
- @Override
- public int available() {
- return buf.readableBytes();
- }
-
- @Override
- public int read() throws IOException {
- // Timeout 10 ms
- final long timeout = System.nanoTime() + 10_000;
- // Yes, this could make the thread go nuts in case of no data,
- // but the Netty guys are doing it the same way and there probably
- // is a reason for it ;-)
- while (System.nanoTime() < timeout) {
- if (buf.readableBytes() > 0) {
- return buf.readByte() & 0xFF;
- }
- }
- throw new SocketTimeoutException();
- }
- }
-
- /**
- * Internal helper to wrap access to unsafe operations (Only used internally by netty)
- */
- private class RawSocketUnsafe extends AbstractUnsafe {
- @Override
- public void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
- try {
- doConnect(remoteAddress, localAddress);
- pipeline().fireChannelActive();
- promise.setSuccess();
- } catch (Exception e) {
- promise.setFailure(e);
- }
- }
-
- @Override
- public void close(ChannelPromise promise) {
- try {
- doDisconnect();
- promise.setSuccess();
- } catch (Exception e) {
- promise.setFailure(e);
- }
- }
- }
-
-}
diff --git a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/address/RawSocketAddress.java b/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/address/RawSocketAddress.java
deleted file mode 100644
index b2e45c9f9a..0000000000
--- a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/address/RawSocketAddress.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.rawsockets.netty.address;
-
-import java.net.SocketAddress;
-
-public class RawSocketAddress extends SocketAddress {
-
- private final byte[] macAddress;
-
- public RawSocketAddress(byte[] macAddress) {
- this.macAddress = macAddress;
- }
-
- public byte[] getMacAddress() {
- return macAddress;
- }
-
-}
diff --git a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/address/RawSocketPassiveAddress.java b/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/address/RawSocketPassiveAddress.java
deleted file mode 100644
index 852796c76b..0000000000
--- a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/address/RawSocketPassiveAddress.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.rawsockets.netty.address;
-
-import org.apache.plc4x.java.utils.pcap.netty.address.PcapSocketAddress;
-
-public class RawSocketPassiveAddress extends PcapSocketAddress {
-
- private static final long serialVersionUID = 1L;
-
- private final String deviceName;
-
- public RawSocketPassiveAddress(String deviceName) {
- this.deviceName = deviceName;
- }
-
- public String getDeviceName() {
- return deviceName;
- }
-
-}
diff --git a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/config/RawSocketChannelConfig.java b/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/config/RawSocketChannelConfig.java
deleted file mode 100644
index fdcdae64a2..0000000000
--- a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/config/RawSocketChannelConfig.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.rawsockets.netty.config;
-
-import io.netty.channel.*;
-import org.apache.plc4x.java.utils.pcap.netty.config.PcapChannelConfig;
-
-public class RawSocketChannelConfig extends PcapChannelConfig {
-
- public RawSocketChannelConfig(Channel channel) {
- super(channel);
- }
-
-}
diff --git a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/utils/ArpUtils.java b/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/utils/ArpUtils.java
index c19d56e0a8..ac6ea9f707 100644
--- a/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/utils/ArpUtils.java
+++ b/plc4j/utils/raw-sockets/src/main/java/org/apache/plc4x/java/utils/rawsockets/netty/utils/ArpUtils.java
@@ -37,7 +37,6 @@ import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.*;
-import java.util.stream.Collectors;
public class ArpUtils {
@@ -78,8 +77,7 @@ public class ArpUtils {
// Calculate all ip addresses, this device can reach.
Map<String, List<String>> addresses = new HashMap<>();
for (PcapAddress address : nif.getAddresses()) {
- if (address instanceof PcapIpV4Address) {
- final PcapIpV4Address ipV4Address = (PcapIpV4Address) address;
+ if (address instanceof PcapIpV4Address ipV4Address) {
SubnetUtils su = new SubnetUtils(ipV4Address.getAddress().getHostAddress(), ipV4Address.getNetmask().getHostAddress());
final String currentAddress = ipV4Address.getAddress().getHostAddress();
final List<String> reachableAddresses = new ArrayList<>(Arrays.asList(su.getInfo().getAllAddresses()));
diff --git a/plc4j/utils/raw-sockets/src/remote-resources/META-INF/LICENSE b/plc4j/utils/raw-sockets/src/remote-resources/META-INF/LICENSE
deleted file mode 100644
index fcab6f339b..0000000000
--- a/plc4j/utils/raw-sockets/src/remote-resources/META-INF/LICENSE
+++ /dev/null
@@ -1,9 +0,0 @@
-
-----------------------------------------------
-
-The Files:
-src/main/java/org/apache/plc4x/java/utils/rawsockets/attic/RawEthernetSocket.java
-src/main/java/org/apache/plc4x/java/utils/rawsockets/attic/RawIpSocket.java
-src/main/java/org/apache/plc4x/java/utils/rawsockets/attic/RawSocketListener.java
-src/test/java/org/apache/plc4x/java/utils/rawsockets/attic/RawIpSocketTest.java
-Are copyrighted by the The Netty Project which is distributed under the Apache 2.0 license.
diff --git a/plc4j/utils/raw-sockets/src/remote-resources/META-INF/NOTICE b/plc4j/utils/raw-sockets/src/remote-resources/META-INF/NOTICE
deleted file mode 100644
index ccad4c46b7..0000000000
--- a/plc4j/utils/raw-sockets/src/remote-resources/META-INF/NOTICE
+++ /dev/null
@@ -1,4 +0,0 @@
-----------------------------------------------
-
-This product includes software developed at
-The Netty project (https://netty.io/).
diff --git a/plc4j/utils/raw-sockets/src/test/java/org/apache/plc4x/java/utils/rawsockets/netty/ManualArpTest.java b/plc4j/utils/raw-sockets/src/test/java/org/apache/plc4x/java/utils/rawsockets/netty/ManualArpTest.java
deleted file mode 100644
index 7f8dda1841..0000000000
--- a/plc4j/utils/raw-sockets/src/test/java/org/apache/plc4x/java/utils/rawsockets/netty/ManualArpTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.rawsockets.netty;
-
-import org.apache.plc4x.java.utils.rawsockets.netty.utils.ArpUtils;
-import org.pcap4j.core.PcapNetworkInterface;
-import org.pcap4j.core.Pcaps;
-
-import java.net.InetAddress;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-public class ManualArpTest {
-
- public static void main(String[] args) throws Exception {
- for (PcapNetworkInterface dev : Pcaps.findAllDevs()) {
- final Set<InetAddress> inetAddresses = ArpUtils.scanNetworkDevice(dev);
- final List<Integer> inetAddresses1 = inetAddresses.stream().map(address -> (short) address.getAddress()[3] & 0xFF).sorted().collect(Collectors.toList());
- System.out.printf("Found %d ip addresses with device %s:\n %s%n", inetAddresses.size(), dev, inetAddresses1);
- }
- }
-
-}
diff --git a/plc4j/utils/raw-sockets/src/test/java/org/apache/plc4x/java/utils/rawsockets/netty/RawSocketChannelTest.java b/plc4j/utils/raw-sockets/src/test/java/org/apache/plc4x/java/utils/rawsockets/netty/RawSocketChannelTest.java
deleted file mode 100644
index 85e5fe2876..0000000000
--- a/plc4j/utils/raw-sockets/src/test/java/org/apache/plc4x/java/utils/rawsockets/netty/RawSocketChannelTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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
- *
- * https://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.java.utils.rawsockets.netty;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufUtil;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.*;
-import io.netty.channel.oio.OioEventLoopGroup;
-import org.apache.plc4x.java.utils.rawsockets.netty.address.RawSocketPassiveAddress;
-import org.apache.plc4x.java.utils.testutils.RequirePcap;
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-import org.pcap4j.core.PcapNetworkInterface;
-import org.pcap4j.core.Pcaps;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-public class RawSocketChannelTest {
-
- private static final Logger logger = LoggerFactory.getLogger(RawSocketChannelTest.class);
-
- @Test
- @RequirePcap
- @Disabled("Disabled as currently we can't seem to be able to get it working on Jenkins")
- public void doConnect() throws Exception {
- Channel channel = null;
- final EventLoopGroup workerGroup = new OioEventLoopGroup();
- try {
- Bootstrap bootstrap = new Bootstrap();
- bootstrap.group(workerGroup);
- bootstrap.channel(RawSocketChannel.class);
- // TODO we should use an explicit (configurable?) timeout here
- // bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000);
- bootstrap.handler(new ChannelInitializer<RawSocketChannel>() {
- @Override
- protected void initChannel(RawSocketChannel ch) throws Exception {
- logger.info("Initialize Buffer!");
- ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- System.out.println(ByteBufUtil.prettyHexDump(((ByteBuf) msg)));
- }
- });
- ch.pipeline().addLast(new ChannelHandlerAdapter() {
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
- logger.warn("Exception caught", cause);
- }
- });
- }
- });
- // Start the client.
- PcapNetworkInterface loopbackDevice = Pcaps.findAllDevs().stream().filter(
- PcapNetworkInterface::isLoopBack).findFirst().orElse(null);
- assertNotNull(loopbackDevice);
- final ChannelFuture f = bootstrap.connect(new RawSocketPassiveAddress(loopbackDevice.getName()));
- // Wait for sync
- f.sync();
- // Wait till the session is finished initializing.
- channel = f.channel();
-
- logger.info("Channel is connected and ready to use...");
-
-
- channel.writeAndFlush(Unpooled.wrappedBuffer("Hallo".getBytes()));
-
- // Prepare something to read
- Thread.sleep(10_000);
-
- } finally {
- if (channel != null) {
- channel.close().sync();
- }
- workerGroup.shutdownGracefully().sync();
- }
- }
-}
\ No newline at end of file
diff --git a/plc4j/utils/raw-sockets/src/test/resources/logback-test.xml b/plc4j/utils/raw-sockets/src/test/resources/logback-test.xml
deleted file mode 100644
index 2b9cea25dc..0000000000
--- a/plc4j/utils/raw-sockets/src/test/resources/logback-test.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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
-
- https://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.
- -->
-<configuration xmlns="http://ch.qos.logback/xml/ns/logback"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="
- http://ch.qos.logback/xml/ns/logback
- https://raw.githubusercontent.com/enricopulatzo/logback-XSD/master/src/main/xsd/logback.xsd">
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="error">
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration>
\ No newline at end of file
diff --git a/plc4j/utils/test-generator/pom.xml b/plc4j/utils/test-generator/pom.xml
index fc91d1460d..2339bbc7b1 100644
--- a/plc4j/utils/test-generator/pom.xml
+++ b/plc4j/utils/test-generator/pom.xml
@@ -77,7 +77,6 @@
<usedDependency>org.apache.plc4x:plc4j-driver-s7</usedDependency>
<usedDependency>org.apache.plc4x:plc4j-driver-eip</usedDependency>
<usedDependency>org.apache.plc4x:plc4j-driver-iec-60870</usedDependency>
- <usedDependency>org.apache.plc4x:plc4j-utils-pcap-shared</usedDependency>
</usedDependencies>
</configuration>
</plugin>
@@ -103,12 +102,6 @@
<artifactId>plc4j-spi-buffers-xml</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.apache.plc4x</groupId>
- <artifactId>plc4j-utils-pcap-shared</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
-
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy-xml</artifactId>
diff --git a/pom.xml b/pom.xml
index 01e5220b6e..1dbb3ffdc3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -103,21 +103,17 @@
<apiguardian.version>1.1.2</apiguardian.version>
<assertj.version>3.27.7</assertj.version>
<awaitility.version>4.3.0</awaitility.version>
- <!-- The currently available version is 2.0.5 and anything above 1.4.3 is no longer compatible with our code -->
- <bit-io.version>1.4.3</bit-io.version>
<bouncycastle.version>1.85</bouncycastle.version>
<byte-buddy.version>1.18.11</byte-buddy.version>
<cmake.version>3.31.5-b1</cmake.version>
<commons-beanutils.version>1.9.4</commons-beanutils.version>
<commons-cli.version>1.11.0</commons-cli.version>
<commons-codec.version>1.22.1</commons-codec.version>
- <commons-collections4.version>4.5.0</commons-collections4.version>
<commons-compress.version>1.28.0</commons-compress.version>
<commons-configuration2.version>2.15.1</commons-configuration2.version>
<commons-io.version>2.22.0</commons-io.version>
<commons-lang3.version>3.20.0</commons-lang3.version>
<commons-logging.version>1.3.5</commons-logging.version>
- <commons-math3.version>3.6.1</commons-math3.version>
<commons-net.version>3.13.0</commons-net.version>
<commons-text.version>1.15.0</commons-text.version>
<commons-csv.version>1.14.1</commons-csv.version>
@@ -141,13 +137,9 @@
<junit.platform.version>1.8.2</junit.platform.version>
<logback.version>1.6.1</logback.version>
<maven.clean.plugin.version>3.2.0</maven.clean.plugin.version>
- <milo.version>0.6.16</milo.version>
<mockito.version>5.23.0</mockito.version>
- <!-- Netty 4.2.x seems to break the serial transports -->
- <netty.version>4.1.123.Final</netty.version>
<pcap4j.version>1.8.2</pcap4j.version>
<slf4j.version>2.0.18</slf4j.version>
- <vavr.version>1.0.1</vavr.version>
<xmlunit.version>2.13.0</xmlunit.version>
<!-- Site properties -->
@@ -203,14 +195,6 @@
<version>${freemarker.version}</version>
</dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-bom</artifactId>
- <version>${netty.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
-
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
@@ -221,11 +205,6 @@
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-collections4</artifactId>
- <version>${commons-collections4.version}</version>
- </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
@@ -246,11 +225,6 @@
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-math3</artifactId>
- <version>${commons-math3.version}</version>
- </dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
@@ -267,31 +241,12 @@
<version>${commons-csv.version}</version>
</dependency>
- <dependency>
- <groupId>com.google.googlejavaformat</groupId>
- <artifactId>google-java-format</artifactId>
- <version>1.36.0</version>
- </dependency>
-
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${awaitility.version}</version>
</dependency>
- <!-- For Either types ... -->
- <dependency>
- <groupId>io.vavr</groupId>
- <artifactId>vavr</artifactId>
- <version>${vavr.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.github.jinahya</groupId>
- <artifactId>bit-io</artifactId>
- <version>${bit-io.version}</version>
- </dependency>
-
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
@@ -307,8 +262,6 @@
<groupId>org.pcap4j</groupId>
<artifactId>pcap4j-core</artifactId>
<version>${pcap4j.version}</version>
- <!-- Commented out, if there are problems occurring to this, we need to comment it back in. -->
- <!--scope>provided</scope-->
</dependency>
<dependency>
<groupId>org.pcap4j</groupId>
@@ -334,17 +287,6 @@
<version>0.4.8</version>
</dependency>
- <dependency>
- <groupId>com.github.purejavacomm</groupId>
- <artifactId>purejavacomm</artifactId>
- <version>1.0.2.RELEASE</version>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.woodstox</groupId>
- <artifactId>woodstox-core</artifactId>
- <version>${woodstox-core.version}</version>
- </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
@@ -408,11 +350,6 @@
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- <version>${slf4j.version}</version>
- </dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
@@ -436,28 +373,12 @@
<artifactId>bcprov-jdk18on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcutil-jdk18on</artifactId>
- <version>${bouncycastle.version}</version>
- </dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bctls-jdk18on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>stack-core</artifactId>
- <version>${milo.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.milo</groupId>
- <artifactId>stack-client</artifactId>
- <version>${milo.version}</version>
- </dependency>
-
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
@@ -498,6 +419,7 @@
</dependency>
<!-- TODO: Eliminate the usage of AssertJ (OPM and OPC-UA Driver) -->
+ <!-- TODO: Check if we actually need this -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
@@ -509,6 +431,7 @@
<version>${equalsverifier.version}</version>
</dependency>
+ <!-- TODO: Check if we actually need this -->
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy-test-junit5</artifactId>
@@ -593,6 +516,20 @@
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
+
+ <!-- Pulled in by jackson-dataformat-xml -->
+ <dependency>
+ <groupId>com.fasterxml.woodstox</groupId>
+ <artifactId>woodstox-core</artifactId>
+ <version>${woodstox-core.version}</version>
+ </dependency>
+
+ <!-- Pulled in by bcpkix-jdk18on and bctls-jdk18on -->
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcutil-jdk18on</artifactId>
+ <version>${bouncycastle.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
diff --git a/protocols/bacnetip/pom.xml b/protocols/bacnetip/pom.xml
index debf46d11a..f007148be5 100644
--- a/protocols/bacnetip/pom.xml
+++ b/protocols/bacnetip/pom.xml
@@ -57,6 +57,15 @@
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opentest4j</groupId>
+ <artifactId>opentest4j</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<profiles>
diff --git a/protocols/bacnetip/src/main/generated/protocols/bacnetip/bacnet-vendorids.mspec b/protocols/bacnetip/src/main/generated/protocols/bacnetip/bacnet-vendorids.mspec
index c17f6e3a7b..2f4cf9ee22 100644
--- a/protocols/bacnetip/src/main/generated/protocols/bacnetip/bacnet-vendorids.mspec
+++ b/protocols/bacnetip/src/main/generated/protocols/bacnetip/bacnet-vendorids.mspec
@@ -1651,6 +1651,12 @@
['1638' SPEC_PROM_DIZAJNOOO ['1638', '"SpecPromDizajn OOO"']]
['1639' FACTS_ENGINEERINGLLC ['1639', '"FACTS Engineering, LLC"']]
['1640' G_ASERV_GMBH ['1640', '"GAserv GmbH"']]
+ ['1641' LEEDS_ELECTRONICS_ENGINEERING_LIMITED ['1641', '"Leeds Electronics Engineering Limited"']]
+ ['1642' MITO_CONTRACTING_GROUP_INC ['1642', '"MITO Contracting Group Inc."']]
+ ['1643' CALECTROAB ['1643', '"Calectro AB"']]
+ ['1644' BMSOS_TECHNOLOGY_INC ['1644', '"bmsOS Technology Inc."']]
+ ['1645' VOSSLOH_SCHWABE_DEUTSCHAND_GMBH ['1645', '"Vossloh-Schwabe Deutschand GmbH"']]
+ ['1646' IVIVA_PTE_LTD ['1646', '"Iviva Pte Ltd"']]
['0xFFFF' UNKNOWN_VENDOR ['0xFFFF', '"Unknown"']]
]
diff --git a/protocols/c-bus/pom.xml b/protocols/c-bus/pom.xml
index c913bb4ef4..26ad4d6e40 100644
--- a/protocols/c-bus/pom.xml
+++ b/protocols/c-bus/pom.xml
@@ -46,6 +46,10 @@
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/protocols/cotp/pom.xml b/protocols/cotp/pom.xml
index 116a405810..e8f427b377 100644
--- a/protocols/cotp/pom.xml
+++ b/protocols/cotp/pom.xml
@@ -43,22 +43,11 @@
</dependency>
<!-- Test Dependencies -->
- <dependency>
- <groupId>org.opentest4j</groupId>
- <artifactId>opentest4j</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
-
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-api</artifactId>
- <scope>test</scope>
- </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/protocols/knxnetip/pom.xml b/protocols/knxnetip/pom.xml
index 31a1f96295..b74401173b 100644
--- a/protocols/knxnetip/pom.xml
+++ b/protocols/knxnetip/pom.xml
@@ -81,6 +81,16 @@
<artifactId>commons-compress</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<profiles>
diff --git a/protocols/opcua/pom.xml b/protocols/opcua/pom.xml
index c528d6bf84..e254a30e61 100644
--- a/protocols/opcua/pom.xml
+++ b/protocols/opcua/pom.xml
@@ -57,6 +57,10 @@
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
</dependencies>
<profiles>
diff --git a/protocols/plc4x-api/pom.xml b/protocols/plc4x-api/pom.xml
index 6a905469a2..6245dc23cc 100644
--- a/protocols/plc4x-api/pom.xml
+++ b/protocols/plc4x-api/pom.xml
@@ -46,6 +46,10 @@
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/protocols/plc4x/pom.xml b/protocols/plc4x/pom.xml
index 14572294b9..15431e88f5 100644
--- a/protocols/plc4x/pom.xml
+++ b/protocols/plc4x/pom.xml
@@ -46,6 +46,10 @@
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/protocols/pom.xml b/protocols/pom.xml
index 492d193cd0..e1afa62935 100644
--- a/protocols/pom.xml
+++ b/protocols/pom.xml
@@ -37,6 +37,39 @@
<build>
<plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <!--
+ Even if Maven transitively pulls in dependencies, relying on these can
+ quite often cause hard to find problems. So it's a good practice to make
+ sure everything directly required is also directly added as a dependency.
+ On the other side adding unused dependency only over-complicates the
+ the dependency graph, so the maven-dependency-plugin checks we depend on
+ what we need and only that and that runtime dependencies are correctly
+ imported with runtime scope.
+ -->
+ <execution>
+ <id>check-dependencies</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>analyze-only</goal>
+ </goals>
+ <configuration>
+ <failOnWarning>true</failOnWarning>
+ <ignoreNonCompile>true</ignoreNonCompile>
+ <ignoredDependencies>
+ <ignoredDependency>org.junit.jupiter:junit-jupiter</ignoredDependency>
+ <ignoredDependency>org.junit.jupiter:junit-jupiter-api</ignoredDependency>
+ <ignoredDependency>org.opentest4j:opentest4j</ignoredDependency>
+ <ignoredDependency>ch.qos.logback:logback-classic</ignoredDependency>
+ </ignoredDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
<!--
This plugin doesn't really do much, it makes sure the jacoco agent
is downloaded and that the path to this is saved in an environment
@@ -187,6 +220,19 @@
</build>
<dependencies>
+ <!--
+ Every protocol module implements the Protocol SPI and uses the type-model, so
+ instead of repeating these in all of them, we declare them here for all modules.
+ -->
+ <dependency>
+ <groupId>org.apache.plc4x.plugins</groupId>
+ <artifactId>plc4x-code-generation-types-base</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.plc4x.plugins</groupId>
+ <artifactId>plc4x-code-generation-protocol-base</artifactId>
+ </dependency>
+
<!-- JUnit 5 Support -->
<dependency>
<groupId>org.junit.jupiter</groupId>
diff --git a/protocols/profinet/pom.xml b/protocols/profinet/pom.xml
index c74d79c3ec..f23398f132 100644
--- a/protocols/profinet/pom.xml
+++ b/protocols/profinet/pom.xml
@@ -46,6 +46,10 @@
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file