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 2018/02/09 14:51:12 UTC
[incubator-plc4x] branch feature/junit4 updated: PLC4X-3 -
Implement a testing framework for protocols
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch feature/junit4
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git
The following commit(s) were added to refs/heads/feature/junit4 by this push:
new d1c1e63 PLC4X-3 - Implement a testing framework for protocols
d1c1e63 is described below
commit d1c1e63da3eebdae580388ffc6442c629bb5f64f
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Fri Feb 9 15:51:07 2018 +0100
PLC4X-3 - Implement a testing framework for protocols
- Implemented a first integration-test that tests a s7 connection using a Netty EmbeddedChannel for testing.
---
.../dummydriver/connection/DummyConnection.java | 11 ++
.../apache/plc4x/edgent/mock/MockConnection.java | 11 +-
.../plc4x/java/api/connection/PlcConnection.java | 7 ++
.../plc4x/java/s7/connection/S7PlcConnection.java | 82 +++++++------
.../org/apache/plc4x/java/s7/netty/S7Protocol.java | 2 +-
.../java/s7/connection/S7PlcConnectionIT.java | 74 ++++++++++++
.../java/s7/connection/S7PlcConnectionTests.java | 47 +++++---
.../java/s7/connection/S7PlcTestConnection.java | 129 +++++++++++++++++++++
.../test-utils/src/main/resources/logback.xml | 36 ++++++
9 files changed, 344 insertions(+), 55 deletions(-)
diff --git a/examples/dummy-driver/src/main/java/org/apache/plc4x/java/examples/dummydriver/connection/DummyConnection.java b/examples/dummy-driver/src/main/java/org/apache/plc4x/java/examples/dummydriver/connection/DummyConnection.java
index 4edf6c0..9619fe4 100644
--- a/examples/dummy-driver/src/main/java/org/apache/plc4x/java/examples/dummydriver/connection/DummyConnection.java
+++ b/examples/dummy-driver/src/main/java/org/apache/plc4x/java/examples/dummydriver/connection/DummyConnection.java
@@ -44,9 +44,11 @@ public class DummyConnection extends AbstractPlcConnection implements PlcReader,
private EventLoopGroup workerGroup;
private Channel channel;
+ private boolean connected;
public DummyConnection(String hostName) {
this.hostName = hostName;
+ this.connected = false;
}
public String getHostName() {
@@ -83,6 +85,8 @@ public class DummyConnection extends AbstractPlcConnection implements PlcReader,
channel = f.channel();
sessionSetupCompleteFuture.get();
+
+ connected = true;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new PlcConnectionException(e);
@@ -101,6 +105,13 @@ public class DummyConnection extends AbstractPlcConnection implements PlcReader,
if (workerGroup != null) {
workerGroup.shutdownGracefully();
}
+
+ connected = false;
+ }
+
+ @Override
+ public boolean isConnected() {
+ return true;
}
@Override
diff --git a/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java b/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java
index 81121ac..1b52ff9 100644
--- a/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java
+++ b/integrations/apache-edgent/src/test/java/org/apache/plc4x/edgent/mock/MockConnection.java
@@ -54,6 +54,7 @@ public class MockConnection extends AbstractPlcConnection implements PlcReader,
private long curWriteCnt;
private int writeExceptionTriggerCount;
private String writeExceptionMsg;
+ private boolean connected;
public MockConnection(String url) {
this(url, null);
@@ -62,6 +63,7 @@ public class MockConnection extends AbstractPlcConnection implements PlcReader,
public MockConnection(String url, PlcAuthentication authentication) {
this.url = url;
this.authentication = authentication;
+ this.connected = false;
}
public PlcAuthentication getAuthentication() {
@@ -73,13 +75,18 @@ public class MockConnection extends AbstractPlcConnection implements PlcReader,
}
@Override
- public void connect() throws PlcConnectionException {
+ public boolean isConnected() {
+ return connected;
+ }
+ @Override
+ public void connect() throws PlcConnectionException {
+ connected = true;
}
@Override
public void close() throws Exception {
-
+ connected = false;
}
@Override
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java
index f0680c8..47d3ff4 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/connection/PlcConnection.java
@@ -41,6 +41,13 @@ public interface PlcConnection extends AutoCloseable {
void connect() throws PlcConnectionException;
/**
+ * Returns true if the PlcConnection is connected to a remote PLC.
+ *
+ * @return true, if connected, false, if not.
+ */
+ boolean isConnected();
+
+ /**
* Closes the connection to the remote PLC.
*
* @throws Exception an exception if shutting down the connection failed.
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java
index 2913585..2dce3ba 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/connection/S7PlcConnection.java
@@ -69,17 +69,19 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
private final int rack;
private final int slot;
- private final int paramPduSize;
+ private final TpduSize paramPduSize;
private final short paramMaxAmqCaller;
private final short paramMaxAmqCallee;
private EventLoopGroup workerGroup;
- private Channel channel;
+ protected Channel channel;
+ protected boolean connected;
public S7PlcConnection(String hostName, int rack, int slot, String params) {
this.hostName = hostName;
this.rack = rack;
this.slot = slot;
+ this.connected = false;
int paramPduSize = 1024;
short paramMaxAmqCaller = 8;
@@ -109,7 +111,10 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
}
}
}
- this.paramPduSize = paramPduSize;
+
+ // IsoTP uses pre defined sizes. Find the smallest box,
+ // that would be able to contain the requested pdu size.
+ this.paramPduSize = TpduSize.valueForGivenSize(paramPduSize);
this.paramMaxAmqCaller = paramMaxAmqCaller;
this.paramMaxAmqCallee = paramMaxAmqCallee;
@@ -129,7 +134,7 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
return slot;
}
- public int getParamPduSize() {
+ public TpduSize getParamPduSize() {
return paramPduSize;
}
@@ -142,6 +147,11 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
}
@Override
+ public boolean isConnected() {
+ return connected;
+ }
+
+ @Override
public void connect() throws PlcConnectionException {
workerGroup = new NioEventLoopGroup();
@@ -153,42 +163,12 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
InetAddress serverInetAddress = InetAddress.getByName(hostName);
- // IsoTP uses pre defined sizes. Find the smallest box,
- // that would be able to contain the requested pdu size.
- TpduSize isoTpTpduSize = TpduSize.valueForGivenSize(paramPduSize);
-
- // If the pdu size was very big, it might have exceeded the
- // maximum of 8MB defined in the IsoTP protocol, so we have
- // to generally downgrade the requested size.
- int pduSize = (isoTpTpduSize.getValue() < paramPduSize) ? isoTpTpduSize.getValue() : paramPduSize;
-
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(workerGroup);
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
bootstrap.option(ChannelOption.TCP_NODELAY, true);
- bootstrap.handler(new ChannelInitializer() {
- @Override
- protected void initChannel(Channel channel) {
- // Build the protocol stack for communicating with the s7 protocol.
- ChannelPipeline pipeline = channel.pipeline();
- pipeline.addLast(new ChannelInboundHandlerAdapter() {
- @Override
- public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
- if(evt instanceof S7ConnectionEvent &&
- ((S7ConnectionEvent) evt).getState() == S7ConnectionState.SETUP_COMPLETE) {
- sessionSetupCompleteFuture.complete(null);
- } else {
- super.userEventTriggered(ctx, evt);
- }
- }
- });
- pipeline.addLast(new IsoOnTcpProtocol());
- pipeline.addLast(new IsoTPProtocol((byte) rack, (byte) slot, isoTpTpduSize));
- pipeline.addLast(new S7Protocol(paramMaxAmqCaller, paramMaxAmqCallee, (short) pduSize));
- pipeline.addLast(new Plc4XS7Protocol());
- }
- });
+ bootstrap.handler(getChannelHandler(sessionSetupCompleteFuture));
// Start the client.
ChannelFuture f = bootstrap.connect(serverInetAddress, ISO_ON_TCP_PORT).sync();
f.awaitUninterruptibly();
@@ -199,13 +179,14 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
channel.pipeline().fireUserEventTriggered(new S7ConnectionEvent());
sessionSetupCompleteFuture.get();
+
+ connected = true;
} catch (UnknownHostException e) {
throw new PlcConnectionException("Unknown Host " + hostName, e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new PlcConnectionException(e);
- }
- catch (ExecutionException e) {
+ } catch (ExecutionException e) {
throw new PlcConnectionException(e);
}
}
@@ -224,6 +205,8 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
workerGroup.shutdownGracefully();
});
sendDisconnectRequestFuture.awaitUninterruptibly();
+
+ connected = false;
} else if (workerGroup != null) {
workerGroup.shutdownGracefully();
}
@@ -269,4 +252,29 @@ public class S7PlcConnection extends AbstractPlcConnection implements PlcReader,
return writeFuture;
}
+ ChannelHandler getChannelHandler(CompletableFuture<Void> sessionSetupCompleteFuture) {
+ return new ChannelInitializer() {
+ @Override
+ protected void initChannel(Channel channel) {
+ // Build the protocol stack for communicating with the s7 protocol.
+ ChannelPipeline pipeline = channel.pipeline();
+ pipeline.addLast(new ChannelInboundHandlerAdapter() {
+ @Override
+ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
+ if(evt instanceof S7ConnectionEvent &&
+ ((S7ConnectionEvent) evt).getState() == S7ConnectionState.SETUP_COMPLETE) {
+ sessionSetupCompleteFuture.complete(null);
+ } else {
+ super.userEventTriggered(ctx, evt);
+ }
+ }
+ });
+ pipeline.addLast(new IsoOnTcpProtocol());
+ pipeline.addLast(new IsoTPProtocol((byte) rack, (byte) slot, paramPduSize));
+ pipeline.addLast(new S7Protocol(paramMaxAmqCaller, paramMaxAmqCallee, (short) paramPduSize.getValue()));
+ pipeline.addLast(new Plc4XS7Protocol());
+ }
+ };
+ }
+
}
diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/S7Protocol.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/S7Protocol.java
index e42013b..2aa4a75 100644
--- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/S7Protocol.java
+++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/S7Protocol.java
@@ -49,7 +49,7 @@ import java.util.List;
public class S7Protocol extends MessageToMessageCodec<IsoTPMessage, S7Message> {
- private static final byte S7_PROTOCOL_MAGIC_NUMBER = 0x32;
+ public static final byte S7_PROTOCOL_MAGIC_NUMBER = 0x32;
private static final Logger logger = LoggerFactory.getLogger(S7Protocol.class);
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcConnectionIT.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcConnectionIT.java
new file mode 100644
index 0000000..fe6476e
--- /dev/null
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcConnectionIT.java
@@ -0,0 +1,74 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+package org.apache.plc4x.java.s7.connection;
+
+import io.netty.channel.Channel;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.assertj.core.api.Assertions;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.Timeout;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class S7PlcConnectionIT {
+
+ private static final Logger logger = LoggerFactory.getLogger(S7PlcConnectionIT.class);
+
+ @Rule
+ public Timeout globalTimeout = Timeout.seconds(2); // 2 seconds max per method tested
+
+ private S7PlcTestConnection s7PlcConnection;
+ private Channel channel;
+
+ @Before
+ public void setUp() {
+ try {
+ s7PlcConnection = new S7PlcTestConnection("localhost", 1, 2, "");
+ s7PlcConnection.connect();
+ channel = s7PlcConnection.getChannel();
+ } catch (PlcConnectionException e) {
+ logger.error("Error initializing connection", e);
+ Assertions.fail("Error initializing connection");
+ }
+ }
+
+ @After
+ public void tearDown() {
+ if(s7PlcConnection.isConnected()) {
+ s7PlcConnection.close();
+ }
+ s7PlcConnection = null;
+ channel = null;
+ }
+
+ @Test
+ public void connect() {
+ assertThat(s7PlcConnection).isNotNull();
+ assertThat(s7PlcConnection.isConnected()).isTrue()
+ .withFailMessage("The connection should be 'connected'");
+ }
+
+ // TODO more tests for connect, close, read and write
+
+}
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcConnectionTests.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcConnectionTests.java
index c6cc76d..069f174 100644
--- a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcConnectionTests.java
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcConnectionTests.java
@@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import org.apache.plc4x.java.api.exceptions.PlcException;
+import org.apache.plc4x.java.isotp.netty.model.types.TpduSize;
import org.apache.plc4x.java.s7.model.S7Address;
import org.apache.plc4x.java.s7.model.S7BitAddress;
import org.apache.plc4x.java.s7.model.S7DataBlockAddress;
@@ -47,12 +48,18 @@ public class S7PlcConnectionTests {
@Test
public void initialState() {
- assertThat(s7PlcConnection.getHostName()).isEqualToIgnoringCase("localhost").withFailMessage("Hostname is incorrect");
- assertThat(s7PlcConnection.getRack()).isEqualTo(1).withFailMessage("Rack is incorrect");
- assertThat(s7PlcConnection.getSlot()).isEqualTo(2).withFailMessage("Slot is incorrect");
- assertThat(s7PlcConnection.getParamPduSize()).isEqualTo(1024).withFailMessage("Pdu size is incorrect");
- assertThat(s7PlcConnection.getParamMaxAmqCaller()).isEqualTo(8).withFailMessage("Max AMQ Caller size is incorrect");
- assertThat(s7PlcConnection.getParamMaxAmqCallee()).isEqualTo(8).withFailMessage("Max AMQ Callee size is incorrect");
+ assertThat(s7PlcConnection.getHostName()).isEqualToIgnoringCase("localhost")
+ .withFailMessage("Hostname is incorrect");
+ assertThat(s7PlcConnection.getRack()).isEqualTo(1)
+ .withFailMessage("Rack is incorrect");
+ assertThat(s7PlcConnection.getSlot()).isEqualTo(2)
+ .withFailMessage("Slot is incorrect");
+ assertThat(s7PlcConnection.getParamPduSize()).isEqualTo(TpduSize.SIZE_1024)
+ .withFailMessage("Pdu size is incorrect");
+ assertThat(s7PlcConnection.getParamMaxAmqCaller()).isEqualTo(8)
+ .withFailMessage("Max AMQ Caller size is incorrect");
+ assertThat(s7PlcConnection.getParamMaxAmqCallee()).isEqualTo(8)
+ .withFailMessage("Max AMQ Callee size is incorrect");
}
@Test
@@ -68,9 +75,13 @@ public class S7PlcConnectionTests {
@Test
public void parseDatablockAddress() {
try {
- S7DataBlockAddress address = (S7DataBlockAddress) s7PlcConnection.parseAddress("DATA_BLOCKS/20/100");
- assertThat(address.getDataBlockNumber()).isEqualTo((short) 20).withFailMessage("unexpected data block");
- assertThat(address.getByteOffset()).isEqualTo((short) 100).withFailMessage("unexpected byte offset");
+ S7DataBlockAddress address = (S7DataBlockAddress)
+ s7PlcConnection.parseAddress("DATA_BLOCKS/20/100");
+
+ assertThat(address.getDataBlockNumber()).isEqualTo((short) 20)
+ .withFailMessage("unexpected data block");
+ assertThat(address.getByteOffset()).isEqualTo((short) 100)
+ .withFailMessage("unexpected byte offset");
}
catch (PlcException exception) {
fail("valid data block address");
@@ -81,8 +92,11 @@ public class S7PlcConnectionTests {
public void parseAddressAddress() {
try {
S7Address address = (S7Address) s7PlcConnection.parseAddress("TIMERS/10");
- assertThat(address.getMemoryArea()).isEqualTo(MemoryArea.TIMERS).withFailMessage("unexpected memory area");
- assertThat(address.getByteOffset()).isEqualTo((short) 10).withFailMessage("unexpected byte offset");
+
+ assertThat(address.getMemoryArea()).isEqualTo(MemoryArea.TIMERS)
+ .withFailMessage("unexpected memory area");
+ assertThat(address.getByteOffset()).isEqualTo((short) 10)
+ .withFailMessage("unexpected byte offset");
}
catch (PlcException exception) {
fail("valid timer block address");
@@ -93,14 +107,17 @@ public class S7PlcConnectionTests {
public void parseAddressBitAddress() {
try {
S7BitAddress address = (S7BitAddress) s7PlcConnection.parseAddress("TIMERS/10/4");
- assertThat(address.getMemoryArea()).isEqualTo(MemoryArea.TIMERS).withFailMessage("unexpected memory area");
- assertThat(address.getByteOffset()).isEqualTo((short) 10).withFailMessage("unexpected byte offset");
- assertThat(address.getBitOffset()).isEqualTo((byte) 4).withFailMessage("unexpected but offset");
+
+ assertThat(address.getMemoryArea()).isEqualTo(MemoryArea.TIMERS)
+ .withFailMessage("unexpected memory area");
+ assertThat(address.getByteOffset()).isEqualTo((short) 10)
+ .withFailMessage("unexpected byte offset");
+ assertThat(address.getBitOffset()).isEqualTo((byte) 4)
+ .withFailMessage("unexpected but offset");
}
catch (PlcException exception) {
fail("valid timer block bit address");
}
}
- // TODO more tests for connect, close, read and write
}
\ No newline at end of file
diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcTestConnection.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcTestConnection.java
new file mode 100644
index 0000000..2f57265
--- /dev/null
+++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/connection/S7PlcTestConnection.java
@@ -0,0 +1,129 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+package org.apache.plc4x.java.s7.connection;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.embedded.EmbeddedChannel;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.apache.plc4x.java.isotp.netty.model.types.*;
+import org.apache.plc4x.java.netty.events.S7ConnectionEvent;
+import org.apache.plc4x.java.s7.netty.S7Protocol;
+import org.apache.plc4x.java.s7.netty.model.types.MessageType;
+import org.apache.plc4x.java.s7.netty.model.types.ParameterType;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+public class S7PlcTestConnection extends S7PlcConnection {
+
+ public S7PlcTestConnection(String hostName, int rack, int slot, String params) {
+ super(hostName, rack, slot, params);
+ }
+
+ @Override
+ public void connect() throws PlcConnectionException {
+ CompletableFuture<Void> sessionSetupCompleteFuture = new CompletableFuture<>();
+
+ // Create an embedded channel instance for testing.
+ EmbeddedChannel channel = new EmbeddedChannel(getChannelHandler(sessionSetupCompleteFuture));
+
+ // Send an event to the pipeline telling the Protocol filters what's going on.
+ channel.pipeline().fireUserEventTriggered(new S7ConnectionEvent());
+
+ ByteBuf writtenData = channel.readOutbound();
+ byte[] connectionRequest = new byte[writtenData.readableBytes()];
+ writtenData.readBytes(connectionRequest);
+ // TODO: Check the content of the Iso TP connection request.
+
+ // Send an Iso TP connection response back to the pipeline.
+ byte[] connectionConfirm = toByteArray(
+ new int[] {
+ // ISO on TCP packet
+ 0x03, 0x00, 0x00, 0x16,
+ // ISO TP packet
+ 0x11,
+ TpduCode.CONNECTION_CONFIRM.getCode(),
+ 0x00, 0x01, 0x00, 0x02,
+ ProtocolClass.CLASS_0.getCode(),
+
+ ParameterCode.CALLED_TSAP.getCode(), 0x02, DeviceGroup.PG_OR_PC.getCode(), 0x01,
+ ParameterCode.CALLING_TSAP.getCode(), 0x02, DeviceGroup.OTHERS.getCode(), 0x12,
+ ParameterCode.TPDU_SIZE.getCode(), 0x01, TpduSize.SIZE_512.getCode()
+ });
+ channel.writeInbound(Unpooled.wrappedBuffer(connectionConfirm));
+
+ // Read a S7 Setup Communication request.
+ writtenData = channel.readOutbound();
+ byte[] setupCommunicationRequest = new byte[writtenData.readableBytes()];
+ writtenData.readBytes(setupCommunicationRequest);
+ // TODO: Check the content of the S7 Setup Communication connection request.
+
+ // Send an S7 Setup Communication response back to the pipeline.
+ byte[] setupCommunicationResponse = toByteArray(
+ new int[] {
+ // ISO on TCP packet
+ 0x03, 0x00,
+ 0x00, 0x1B,
+ // ISO TP packet
+ 0x02,
+ TpduCode.DATA.getCode(),
+ 0x80,
+ S7Protocol.S7_PROTOCOL_MAGIC_NUMBER,
+ MessageType.ACK_DATA.getCode(), 0x00, 0x00,
+ 0x00, 0x01,
+ // Parameter Length
+ 0x00, 0x08,
+ // Data Length
+ 0x00, 0x00,
+ // Error codes
+ 0x00, 0x00,
+ // Parameters:
+ ParameterType.SETUP_COMMUNICATION.getCode(), 0x00, 0x00, 0x08, 0x00, 0x08, 0x01, 0x00
+ });
+ channel.writeInbound(Unpooled.wrappedBuffer(setupCommunicationResponse));
+
+ // Wait till the connection is established.
+ try {
+ sessionSetupCompleteFuture.get();
+
+ connected = true;
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new PlcConnectionException(e);
+ } catch (ExecutionException e) {
+ throw new PlcConnectionException(e);
+ }
+
+ this.channel = channel;
+ }
+
+ public EmbeddedChannel getChannel() {
+ return (EmbeddedChannel) channel;
+ }
+
+ public static byte[] toByteArray(int[] in) {
+ byte[] out = new byte[in.length];
+ for(int i = 0; i < in.length; i++) {
+ out[i] = (byte) in[i];
+ }
+ return out;
+ }
+
+}
diff --git a/plc4j/utils/test-utils/src/main/resources/logback.xml b/plc4j/utils/test-utils/src/main/resources/logback.xml
new file mode 100644
index 0000000..a8ddebb
--- /dev/null
+++ b/plc4j/utils/test-utils/src/main/resources/logback.xml
@@ -0,0 +1,36 @@
+<?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
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<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">
+ <!-- encoders are assigned the type
+ ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="trace">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+</configuration>
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
cdutz@apache.org.