This is an automated email from the ASF dual-hosted git repository. hutcheb pushed a commit to branch feat/profinet_ip_set in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit 7814b208675b4071c1f93c46c9c9b3fe368ebad9 Author: Ben Hutcheson <[email protected]> AuthorDate: Wed Apr 12 05:53:33 2023 +0200 fix(plc4j/profinet): Update the Configuration to include an option to set the ip address --- .../profinet/config/ProfinetConfiguration.java | 5 +- .../plc4x/java/profinet/device/ProfinetDevice.java | 107 ++++++++++++++++++++- .../profinet/gsdml/ProfinetConfigurationTests.java | 14 +++ 3 files changed, 124 insertions(+), 2 deletions(-) diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/config/ProfinetConfiguration.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/config/ProfinetConfiguration.java index 8657c8c16a..98ac8be9fe 100644 --- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/config/ProfinetConfiguration.java +++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/config/ProfinetConfiguration.java @@ -92,7 +92,7 @@ public class ProfinetConfiguration implements Configuration, RawSocketTransportC public static class ProfinetDeviceConvertor implements ConfigurationParameterConverter<ProfinetDevices> { - public static final String DEVICE_STRING = "((?<devicename>[\\w- ]*){1}[, ]+(?<deviceaccess>[\\w ]*){1}[, ]+\\((?<submodules>[\\w, ]*)\\))"; + public static final String DEVICE_STRING = "((?<devicename>[\\w- ]*){1}[, ]+(?<deviceaccess>[\\w ]*){1}[, ]+\\((?<submodules>[\\w, ]*)\\)[, ]*(?<ipaddress>[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)?)"; public static final String DEVICE_ARRAY_STRING = "^\\[(?:(\\[" + DEVICE_STRING + "{1}\\])[, ]?)+\\]"; public static final Pattern DEVICE_NAME_ARRAY_PATTERN = Pattern.compile(DEVICE_ARRAY_STRING); public static final Pattern DEVICE_PARAMETERS = Pattern.compile(DEVICE_STRING); @@ -126,6 +126,9 @@ public class ProfinetConfiguration implements Configuration, RawSocketTransportC (vendorId, deviceId) -> gsdFiles.getGsdFiles().get("0x" + vendorId + "-0x" + deviceId) ) ); + if (matcher.group("ipaddress") != null) { + devices.get(matcher.group("devicename")).setIpAddress(matcher.group("ipaddress")); + } } } } 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 3e281301f5..eee86ad44c 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 @@ -72,6 +72,7 @@ public class ProfinetDevice implements PlcSubscriber{ Map<String, List<Consumer<PlcSubscriptionEvent>>> registrations = new HashMap<>(); private int offset = 0; private boolean firstMessage = true; + private boolean setIpAddress = false; public ProfinetDevice(String deviceName, String deviceAccess, String subModules, BiFunction<String, String, ProfinetISO15745Profile> gsdHandler) { this.gsdHandler = gsdHandler; @@ -269,6 +270,11 @@ public class ProfinetDevice implements PlcSubscriber{ return deviceContext.isDcpReceived(); } + public void setIpAddress(String ipAddress) { + this.setIpAddress = true; + this.deviceContext.setIpAddress(ipAddress); + } + public void handleResponse(Ethernet_FramePayload_IPv4 packet) { logger.debug("Received packet for {}", packet.getPayload().getObjectUuid()); long objectId = packet.getPayload().getSequenceNumber(); @@ -918,7 +924,7 @@ public class ProfinetDevice implements PlcSubscriber{ @Override public void handle(DceRpc_Packet packet) { - logger.debug("Received an unintented packet"); + logger.debug("Received an unintended packet"); } } @@ -1020,4 +1026,103 @@ public class ProfinetDevice implements PlcSubscriber{ logger.error("Error Parsing Cyclic Data from device {}", deviceContext.getDeviceName()); } } + + public class DcpSetIpAddress implements ProfinetCallable<Ethernet_Frame> { + + private final long startTime; + private long id = getObjectId(); + + public DcpSetIpAddress(long startTime) { + this.startTime = startTime; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Ethernet_Frame create() { + + WriteBufferByteBased buffer = new WriteBufferByteBased(deviceContext.getOutputReq().getDataLength()); + PnIoCm_IoCrBlockReqApi api = deviceContext.getOutputReq().getApis().get(0); + try { + for (PnIoCm_IoCs iocs : api.getIoCss()) { + PnIoCm_DataUnitIoCs ioc = new PnIoCm_DataUnitIoCs(false, (byte) 0x03, false); + ioc.serialize(buffer); + } + + for (PnIoCm_IoDataObject dataObject : api.getIoDataObjects()) { + // TODO: Need to specify the datatype length based on the gsd file + PnIoCm_DataUnitDataObject ioc = new PnIoCm_DataUnitDataObject( + new byte[1], + new PnIoCm_DataUnitIoCs(false, (byte) 0x03, false), + 1 + ); + ioc.serialize(buffer); + } + + while (buffer.getPos() < deviceContext.getOutputReq().getDataLength()) { + buffer.writeByte((byte) 0x00); + } + + int elapsedTime = (int) ((((System.nanoTime() - startTime)/(MIN_CYCLE_NANO_SEC)) + offset) % 65536); + + Ethernet_Frame frame = new Ethernet_Frame( + deviceContext.getMacAddress(), + deviceContext.getLocalMacAddress(), + new Ethernet_FramePayload_VirtualLan( + VirtualLanPriority.INTERNETWORK_CONTROL, + false, + 0, + new Ethernet_FramePayload_PnDcp( + new PnDcp_Pdu_RealTimeCyclic( + deviceContext.getOutputReq().getFrameId(), + new PnIo_CyclicServiceDataUnit(buffer.getBytes(), (short) deviceContext.getOutputReq().getDataLength()), + elapsedTime, + false, + true, + true, + true, + false, + true)) + )); + return frame; + } catch (SerializationException e) { + deviceContext.setState(ProfinetDeviceState.ABORT); + logger.error("Error serializing cyclic data for device {}", deviceContext.getDeviceName()); + + int elapsedTime = (int) ((((System.nanoTime() - startTime)/(MIN_CYCLE_NANO_SEC)) + offset) % 65536); + + Ethernet_Frame frame = new Ethernet_Frame( + deviceContext.getMacAddress(), + deviceContext.getLocalMacAddress(), + new Ethernet_FramePayload_VirtualLan( + VirtualLanPriority.INTERNETWORK_CONTROL, + false, + 0, + new Ethernet_FramePayload_PnDcp( + new PnDcp_Pdu_RealTimeCyclic( + deviceContext.getOutputReq().getFrameId(), + new PnIo_CyclicServiceDataUnit(new byte[]{}, (short) 0), + elapsedTime, + false, + true, + true, + true, + false, + true)) + )); + return frame; + } + } + + @Override + public void handle(Ethernet_Frame packet) { + deviceContext.setState(ProfinetDeviceState.ABORT); + logger.error("Error Parsing Cyclic Data from device {}", deviceContext.getDeviceName()); + } + } } diff --git a/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/gsdml/ProfinetConfigurationTests.java b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/gsdml/ProfinetConfigurationTests.java index 3b7199ae31..790ec9b27d 100644 --- a/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/gsdml/ProfinetConfigurationTests.java +++ b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/gsdml/ProfinetConfigurationTests.java @@ -208,4 +208,18 @@ public class ProfinetConfigurationTests { assertEquals(devices.get(deviceName).getDeviceContext().getSubModules()[3], "1"); } } + + @Test + public void parseIpAddress() { + String[] deviceNames = new String[] {"DEVICE NAME 1"}; + + ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration( + ProfinetConfiguration.class, "devices=[[device name 1, PLC4X 1, (PLC4X DUMMY MODULE, PLC4X DUMMY MODULE,,1), 10.1.1.1]]&gsddirectory=src/test/resources"); + + Map<String, ProfinetDevice> devices = configuration.getDevices().getConfiguredDevices(); + XmlMapper xmlMapper = new XmlMapper(); + + assertEquals(devices.get("DEVICE NAME 1").getDeviceContext().getIpAddress(), "10.1.1.1"); + + } }
