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 2023/12/23 09:24:00 UTC
(plc4x) 02/02: feat: Continued working on getting the PN stuff working.
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 43b5e7d2f490ec7aa7b3aa924e017d499f6e6d8c
Author: Christofer Dutz <cd...@apache.org>
AuthorDate: Sat Dec 23 10:23:49 2023 +0100
feat: Continued working on getting the PN stuff working.
---
.../java/profinet/packets/PnDcpPacketFactory.java | 3 +-
.../profinet/protocol/ProfinetProtocolLogic.java | 81 ++++++++++------------
...oTest2.java => ManualProfinetIoTestAdamPN.java} | 2 +-
...Test.java => ManualProfinetIoTestSimocode.java} | 4 +-
...java => ManualProfinetIoTestWagoPNCoupler.java} | 2 +-
....java => ManualProfinetIoTestZylkSimocode.java} | 10 +--
.../plc4x/java/profinet/device/ProfinetDevice.java | 3 +-
.../plc4x/java/profinet/ManualProfinetIoTest.java | 4 +-
8 files changed, 52 insertions(+), 57 deletions(-)
diff --git a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/packets/PnDcpPacketFactory.java b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/packets/PnDcpPacketFactory.java
index 79fcffe6ac..17c26edbdd 100644
--- a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/packets/PnDcpPacketFactory.java
+++ b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/packets/PnDcpPacketFactory.java
@@ -206,7 +206,8 @@ public class PnDcpPacketFactory {
Collections.singletonList(
new IODReadRequestHeader((short) 1, (short) 0, 0,
new Uuid(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
- 0, 0, 1, 0xF000, 16696,
+ // * REMARK: It seems that it doesn't matter if we use subSlotNumber 0 or 1, the responses seem to be the same.
+ 0, 0, 0, 0xF000, 16696,
new Uuid(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}))
))
);
diff --git a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
index fefd5254e2..142d078e63 100644
--- a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
+++ b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
@@ -40,7 +40,6 @@ import org.apache.plc4x.java.spi.configuration.HasConfiguration;
import org.apache.plc4x.java.spi.context.DriverContext;
import org.apache.plc4x.java.spi.messages.DefaultPlcBrowseItem;
import org.apache.plc4x.java.spi.messages.DefaultPlcBrowseResponse;
-import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse;
import org.apache.plc4x.java.utils.rawsockets.netty.RawSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,13 +49,18 @@ import java.security.SecureRandom;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.atomic.AtomicInteger;
public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> implements HasConfiguration<ProfinetConfiguration> {
+ // This is the minimum cycle time defined in the PN Spec (Page 205): 31,25us
+ private static final int NANOS_PER_CYCLE = 31250;
+
private ProfinetDriverContext profinetDriverContext;
private ProfinetConfiguration configuration;
+ private Integer cycleOffset = null;
+ private boolean connected = false;
+
private final Logger logger = LoggerFactory.getLogger(ProfinetProtocolLogic.class);
@Override
@@ -722,6 +726,7 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
RawSocketChannel pnChannel = (RawSocketChannel) context.getChannel();
PnDcpPacketFactory.sendApplicationReadyResponse(context, pnChannel, profinetDriverContext, payloadIPv4.getSourcePort(), dceRpc_packet.getActivityUuid(), arUuid, sessionKey);
+ connected = true;
// TODO: Prepare the subscription response.
// future.complete(new DefaultPlcSubscriptionResponse(subscriptionRequest, ))
});
@@ -732,45 +737,6 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
// We needed to put the code to expect the ApplicationReady to subscribe before sending,
// as the device sends it within 4 ms, and we can't guarantee that we're done setting up
// the listener.
-
- // TODO: Start sending data.
- Thread task = new Thread(() -> {
- int curCounterValue = 0;
- RawSocketChannel pnChannel = (RawSocketChannel) context.getChannel();
- MacAddress srcAddress = new MacAddress(pnChannel.getLocalMacAddress().getAddress());
- MacAddress dstAddress = new MacAddress(pnChannel.getRemoteMacAddress().getAddress());
- byte[] data = new byte[40];
- data[0] = (byte) 0x80;
- data[1] = (byte) 0x80;
- data[2] = (byte) 0x80;
- data[3] = (byte) 0x80;
- long nextExecutionTime = System.currentTimeMillis();
- System.out.println("Starting Loop");
- while(context.getChannel().isOpen()) {
- if(nextExecutionTime < System.currentTimeMillis()) {
- curCounterValue += 512;
- Ethernet_Frame frame = new Ethernet_Frame(
- dstAddress,
- srcAddress,
- new Ethernet_FramePayload_VirtualLan(VirtualLanPriority.INTERNETWORK_CONTROL, false, (short) 0,
- new Ethernet_FramePayload_PnDcp(
- new PnDcp_Pdu_RealTimeCyclic(0x8003,
- new PnIo_CyclicServiceDataUnit(data, (short) 40),
- curCounterValue, false, true,
- true, true, false, true)
- )
- )
- );
- System.out.println("Sending");
- context.sendToWire(frame);
- // Send a packet every 16ms
- nextExecutionTime += 16;
- }
- }
- System.out.println("Channel closed");
- });
- task.setPriority(Thread.MAX_PRIORITY);
- task.start();
});
});
@@ -779,11 +745,41 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
@Override
protected void decode(ConversationContext<Ethernet_Frame> context, Ethernet_Frame msg) throws Exception {
+ RawSocketChannel pnChannel = (RawSocketChannel) context.getChannel();
+/* MacAddress srcAddress = new MacAddress(pnChannel.getLocalMacAddress().getAddress());
+ MacAddress dstAddress = new MacAddress(pnChannel.getRemoteMacAddress().getAddress());
+ byte[] data = new byte[40];
+ data[0] = (byte) 0x60;
+ data[1] = (byte) 0x60;
+ data[2] = (byte) 0x60;
+ data[3] = (byte) 0x60;
+ data[4] = (byte) 0x60;
+ data[6] = (byte) 0x60;*/
+
if (msg.getPayload() instanceof Ethernet_FramePayload_PnDcp) {
Ethernet_FramePayload_PnDcp dcpPacket = (Ethernet_FramePayload_PnDcp) msg.getPayload();
if (dcpPacket.getPdu() instanceof PnDcp_Pdu_RealTimeCyclic) {
PnDcp_Pdu_RealTimeCyclic realTimeCyclic = (PnDcp_Pdu_RealTimeCyclic) dcpPacket.getPdu();
-// System.out.println(realTimeCyclic);
+
+/* // Save the offset of the first packet.
+ cycleOffset = realTimeCyclic.getCycleCounter();
+
+ int newCycleCounter = (int) ((((System.nanoTime() - startTime) / (NANOS_PER_CYCLE)) + cycleOffset) % 65536);
+ Ethernet_Frame frame = new Ethernet_Frame(
+ dstAddress,
+ srcAddress,
+ new Ethernet_FramePayload_VirtualLan(VirtualLanPriority.INTERNETWORK_CONTROL, false, (short) 0,
+ new Ethernet_FramePayload_PnDcp(
+ new PnDcp_Pdu_RealTimeCyclic(0x8003,
+ new PnIo_CyclicServiceDataUnit(data, (short) 40),
+ newCycleCounter, false, true,
+ true, true, false, true)
+ )
+ )
+ );
+ System.out.println("Sending");
+ context.sendToWire(frame);*/
+
} else {
System.out.println(dcpPacket);
}
@@ -792,7 +788,6 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
if(payloadIPv4.getPayload().getPayload() instanceof PnIoCm_Packet_Ping) {
DceRpc_Packet pingPacket = payloadIPv4.getPayload();
// Send back a ping response
- RawSocketChannel pnChannel = (RawSocketChannel) context.getChannel();
PnDcpPacketFactory.sendPingResponse(context, pnChannel, profinetDriverContext, payloadIPv4);
}
// The remote device terminated the connection.
diff --git a/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest2.java b/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestAdamPN.java
similarity index 97%
copy from plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest2.java
copy to plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestAdamPN.java
index 201986a321..8f5352d8eb 100644
--- a/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest2.java
+++ b/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestAdamPN.java
@@ -27,7 +27,7 @@ import org.apache.plc4x.java.api.messages.PlcSubscriptionResponse;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
-public class ManualProfinetIoTest2 {
+public class ManualProfinetIoTestAdamPN {
public static void main(String[] args) throws Exception {
// WireShark filter: "eth.addr == 74:fe:48:63:f6:c2"
diff --git a/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest.java b/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestSimocode.java
similarity index 94%
rename from plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest.java
rename to plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestSimocode.java
index 838bb9a257..95072070d8 100644
--- a/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest.java
+++ b/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestSimocode.java
@@ -22,13 +22,11 @@ package org.apache.plc4x.java.profinet;
import org.apache.plc4x.java.DefaultPlcDriverManager;
import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.messages.*;
-import org.apache.plc4x.java.profinet.tag.ProfinetTag;
import java.time.Duration;
-import java.util.List;
import java.util.concurrent.TimeUnit;
-public class ManualProfinetIoTest {
+public class ManualProfinetIoTestSimocode {
public static void main(String[] args) throws Exception {
// WireShark filter: "eth.addr == 88:3f:99:00:06:ef"
diff --git a/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest3.java b/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestWagoPNCoupler.java
similarity index 97%
rename from plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest3.java
rename to plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestWagoPNCoupler.java
index f3f6aa61a2..aed2d41140 100644
--- a/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest3.java
+++ b/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestWagoPNCoupler.java
@@ -27,7 +27,7 @@ import org.apache.plc4x.java.api.messages.PlcSubscriptionResponse;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
-public class ManualProfinetIoTest3 {
+public class ManualProfinetIoTestWagoPNCoupler {
public static void main(String[] args) throws Exception {
// WireShark filter: "eth.addr == 00:30:de:61:37:79"
diff --git a/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest2.java b/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestZylkSimocode.java
similarity index 86%
rename from plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest2.java
rename to plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestZylkSimocode.java
index 201986a321..8170a6b5e8 100644
--- a/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest2.java
+++ b/plc4j/drivers/profinet-ng/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTestZylkSimocode.java
@@ -7,7 +7,7 @@
* "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
+ * 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
@@ -27,17 +27,17 @@ import org.apache.plc4x.java.api.messages.PlcSubscriptionResponse;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
-public class ManualProfinetIoTest2 {
+public class ManualProfinetIoTestZylkSimocode {
public static void main(String[] args) throws Exception {
- // WireShark filter: "eth.addr == 74:fe:48:63:f6:c2"
- try(PlcConnection connection = new DefaultPlcDriverManager().getConnection("profinet:raw://192.168.24.41")) {
+ // WireShark filter: eth.addr == 88:3f:99:03:ef:b0
+ try(PlcConnection connection = new DefaultPlcDriverManager().getConnection("profinet:raw://192.168.54.23")) {
// Create and execute the subscription request.
PlcSubscriptionRequest subscriptionRequest = connection.subscriptionRequestBuilder()
.addCyclicTagAddress("inputs", "1.1.INPUT.0:BYTE[10]", Duration.ofMillis(400))
.addCyclicTagAddress("output", "1.1.OUTPUT.0:DWORD", Duration.ofMillis(400))
.build();
- PlcSubscriptionResponse subscriptionResponse = subscriptionRequest.execute().get(10000, TimeUnit.MILLISECONDS);
+ PlcSubscriptionResponse subscriptionResponse = subscriptionRequest.execute().get(100000, TimeUnit.MILLISECONDS);
System.out.println(subscriptionResponse);
}
}
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java
index b9eb095147..1b8e2ec5a5 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java
@@ -215,8 +215,7 @@ public class ProfinetDevice implements PlcSubscriber {
recordIdAndSend(writeParameters, deviceContext.getSourcePort(), deviceContext.getDestinationPort());
writeParameters.getResponseHandled().get(timeout, TimeUnit.NANOSECONDS);
break;
- // Send a CONTROL packet
- // TODO: I assume this tells the PN device that we'll be the new "master"
+ // Send a CONTROL packet telling the device we're done configuring the connection.
case PREMED:
WriteParametersEnd writeParametersEnd = new WriteParametersEnd();
recordIdAndSend(writeParametersEnd, deviceContext.getSourcePort(), deviceContext.getDestinationPort());
diff --git a/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest.java b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest.java
index 0836021331..26bc1982b8 100644
--- a/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest.java
+++ b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ManualProfinetIoTest.java
@@ -34,11 +34,13 @@ public class ManualProfinetIoTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ManualProfinetIoTest.class);
public static void main(String[] args) throws Exception {
+ // eth.addr == 88:3f:99:03:ef:b0
+
// In this example 192.168.54.2 is the local IP of the computer running PLC4J and 192.168.54.23 is the IP of the PN device.
//final PlcConnection connection = new DefaultPlcDriverManager().getConnection("profinet://192.168.54.2?gsddirectory=~/.gsd&devices=[[simocodexbpn156e,DAP%201,(1,),192.168.54.23]]&reductionratio=16&sendclockfactor=32&dataholdfactor=3&watchdogfactor=3");
// REMARK: The driver would use the local network device with the given IP address and to an auto-discovery, trying to find any devices returned with the matching name.
// If this device is then found and an IP address is provided, it would use PN-DCP to set the IP address of that device to the given value.
- final PlcConnection connection = new DefaultPlcDriverManager().getConnection("profinet://192.168.24.220?gsddirectory=~/.gsd&devices=[[cdxb195b3,DAP%201,(1,)]]&reductionratio=16&sendclockfactor=32&dataholdfactor=3&watchdogfactor=3");
+ final PlcConnection connection = new DefaultPlcDriverManager().getConnection("profinet://192.168.54.220?gsddirectory=~/.gsd&devices=[[simocodexbpn156e,DAP%201,(1,)]]&reductionratio=16&sendclockfactor=32&dataholdfactor=3&watchdogfactor=3");
PlcBrowseRequest browseRequest = connection.browseRequestBuilder().addQuery("all", "*").build();
PlcBrowseResponse plcBrowseResponse = browseRequest.execute().get(4000, TimeUnit.MILLISECONDS);