You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2023/05/06 04:20:52 UTC

[plc4x] branch develop updated: Feat/profinet ip set (#927)

This is an automated email from the ASF dual-hosted git repository.

hutcheb pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new 2da0afab14 Feat/profinet ip set (#927)
2da0afab14 is described below

commit 2da0afab14ef4d89d6a7e0c7d713927f105d5852
Author: Ben Hutcheson <be...@gmail.com>
AuthorDate: Sat May 6 06:20:47 2023 +0200

    Feat/profinet ip set (#927)
    
    * fix(plc4j/profinet): Update the Measured Delay struct to include the portCableDelay
    
    * fix(plc4j/profinet): Update the Configuration to include an option to set the ip address
    
    * fix(plc4j/profinet): Use the chassis id as the device name, instead of the portid
    
    * fix(plc4j/profinet): Update the address pattern to allow for spaces in device name
    
    * fix(plc4x/profinet): Start filling out the GetSet PN-DCP PDU to allow for setting the IP Address.
    
    * fix(plc4x/profinet): Filled out a bt more of the SetGet IP Address.
    
    Need to get IP address settings from network device for subnet and gateway.
    
    * fix(plc4x/profinet): Filled out a bt more of the SetGet IP Address.Missed a file
    
    Need to get IP address settings from network device for subnet and gateway.
    
    * fix(plc4j/profinet): Started to Refactor code
    
    * fix(plc4j/profinet): refactored the PDevice network interface
    
    * fix(plc4j/profinet): not sure, might be lost
    
    * fix(plc4x/profinet): Fixed IP Set, Still need to get subnet and gateway.
    
    * fix(plc4x/profinet): Able to setup comms with Simcode
    
    * fix(plc4x/profinet): Add todo for re-enabling the write parameters step
    
    * fix(plc4x/profinet): Update manual test to a known working setup
    
    * fix(plc4x/profinet): Add comment about updating the cycle time or implementing the ping functionality.
---
 .../readwrite/PascalString16BitLength.java         | 164 ++++++++++
 .../java/profinet/readwrite/PcDcp_GetSet_Pdu.java  | 345 +++++++++++++++++++++
 .../plc4x/java/profinet/readwrite/PnDcp_Pdu.java   |   2 +
 .../profinet/readwrite/PnIoCm_Block_ArServer.java  |  15 +-
 .../profinet/readwrite/ProfinetDeviceState.java    |   1 +
 .../readwrite/TlvProfibusSubTypeMeasuredDelay.java |  34 +-
 .../apache/plc4x/java/profinet/ProfinetDriver.java |   6 +-
 .../config/ConfigurationProfinetDevice.java        |  64 ++++
 .../profinet/config/ProfinetConfiguration.java     |  11 +-
 .../{device => config}/ProfinetDevices.java        |  11 +-
 .../profinet/context/ProfinetDeviceContext.java    |  43 ++-
 .../{ProfinetCallable.java => MessageWrapper.java} |  17 +-
 ...ProfinetCallable.java => NetworkInterface.java} |  17 +-
 .../java/profinet/device/ProfinetCallable.java     |   2 -
 .../java/profinet/device/ProfinetChannel.java      |  45 +--
 .../plc4x/java/profinet/device/ProfinetDevice.java | 161 +++++++---
 .../device/ProfinetDeviceMessageHandler.java       |  16 +-
 .../profinet/device/ProfinetMessageWrapper.java    |   8 +-
 .../profinet/device/ProfinetNetworkInterface.java  | 102 ++++++
 .../profinet/discovery/ProfinetPlcDiscoverer.java  |   7 +-
 .../profinet/protocol/ProfinetProtocolLogic.java   |  57 ++--
 .../plc4x/java/profinet/tag/ProfinetTag.java       |   2 +-
 .../plc4x/java/profinet/DummyMessageWrapper.java}  |  20 +-
 .../plc4x/java/profinet/DummyNetworkInterface.java |  63 ++++
 .../plc4x/java/profinet/ManualProfinetIoTest.java  |   4 +-
 .../plc4x/java/profinet/ProfinetBrowseTests.java   |  53 +++-
 .../java/profinet/ProfinetDeviceContextTests.java  |  71 ++++-
 .../profinet/gsdml/ProfinetConfigurationTests.java | 180 ++++++++++-
 .../resources/protocols/profinet/ethernet.mspec    |   6 +
 .../main/resources/protocols/profinet/lldp.mspec   |   1 +
 .../main/resources/protocols/profinet/pndcp.mspec  |  11 +
 .../main/resources/protocols/profinet/pnio.mspec   |   3 +-
 32 files changed, 1349 insertions(+), 193 deletions(-)

diff --git a/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PascalString16BitLength.java b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PascalString16BitLength.java
new file mode 100644
index 0000000000..ca9757dc9c
--- /dev/null
+++ b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PascalString16BitLength.java
@@ -0,0 +1,164 @@
+/*
+ * 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.profinet.readwrite;
+
+import static org.apache.plc4x.java.spi.codegen.fields.FieldReaderFactory.*;
+import static org.apache.plc4x.java.spi.codegen.fields.FieldWriterFactory.*;
+import static org.apache.plc4x.java.spi.codegen.io.DataReaderFactory.*;
+import static org.apache.plc4x.java.spi.codegen.io.DataWriterFactory.*;
+import static org.apache.plc4x.java.spi.generation.StaticHelper.*;
+
+import java.time.*;
+import java.util.*;
+import org.apache.plc4x.java.api.exceptions.*;
+import org.apache.plc4x.java.api.value.*;
+import org.apache.plc4x.java.spi.codegen.*;
+import org.apache.plc4x.java.spi.codegen.fields.*;
+import org.apache.plc4x.java.spi.codegen.io.*;
+import org.apache.plc4x.java.spi.generation.*;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+public class PascalString16BitLength implements Message {
+
+  // Properties.
+  protected final String stringValue;
+
+  public PascalString16BitLength(String stringValue) {
+    super();
+    this.stringValue = stringValue;
+  }
+
+  public String getStringValue() {
+    return stringValue;
+  }
+
+  public short getStringLength() {
+    return (short) ((((getStringValue().length()) == (-(1))) ? 0 : getStringValue().length()));
+  }
+
+  public void serialize(WriteBuffer writeBuffer) throws SerializationException {
+    PositionAware positionAware = writeBuffer;
+    boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+    int startPos = positionAware.getPos();
+    writeBuffer.pushContext("PascalString16BitLength");
+
+    // Implicit Field (sLength) (Used for parsing, but its value is not stored as it's implicitly
+    // given by the objects content)
+    short sLength =
+        (short) ((((getStringValue().length()) == (0)) ? -(1) : getStringValue().length()));
+    writeImplicitField("sLength", sLength, writeSignedShort(writeBuffer, 16));
+
+    // Simple Field (stringValue)
+    writeSimpleField(
+        "stringValue",
+        stringValue,
+        writeString(writeBuffer, (((sLength) == (-(1))) ? 0 : (sLength) * (8))));
+
+    // Virtual field (doesn't actually serialize anything, just makes the value available)
+    short stringLength = getStringLength();
+    writeBuffer.writeVirtual("stringLength", stringLength);
+
+    writeBuffer.popContext("PascalString16BitLength");
+  }
+
+  @Override
+  public int getLengthInBytes() {
+    return (int) Math.ceil((float) getLengthInBits() / 8.0);
+  }
+
+  @Override
+  public int getLengthInBits() {
+    int lengthInBits = 0;
+    PascalString16BitLength _value = this;
+    boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+
+    // Implicit Field (sLength)
+    lengthInBits += 16;
+
+    // Simple field (stringValue)
+    lengthInBits +=
+        ((((((getStringValue().length()) == (0)) ? -(1) : getStringValue().length())) == (-(1)))
+            ? 0
+            : ((((getStringValue().length()) == (0)) ? -(1) : getStringValue().length())) * (8));
+
+    // A virtual field doesn't have any in- or output.
+
+    return lengthInBits;
+  }
+
+  public static PascalString16BitLength staticParse(ReadBuffer readBuffer, Object... args)
+      throws ParseException {
+    PositionAware positionAware = readBuffer;
+    return staticParse(readBuffer);
+  }
+
+  public static PascalString16BitLength staticParse(ReadBuffer readBuffer) throws ParseException {
+    readBuffer.pullContext("PascalString16BitLength");
+    PositionAware positionAware = readBuffer;
+    int startPos = positionAware.getPos();
+    int curPos;
+    boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+
+    short sLength = readImplicitField("sLength", readSignedShort(readBuffer, 16));
+
+    String stringValue =
+        readSimpleField(
+            "stringValue", readString(readBuffer, (((sLength) == (-(1))) ? 0 : (sLength) * (8))));
+    short stringLength =
+        readVirtualField(
+            "stringLength",
+            short.class,
+            (((stringValue.length()) == (-(1))) ? 0 : stringValue.length()));
+
+    readBuffer.closeContext("PascalString16BitLength");
+    // Create the instance
+    PascalString16BitLength _pascalString16BitLength;
+    _pascalString16BitLength = new PascalString16BitLength(stringValue);
+    return _pascalString16BitLength;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof PascalString16BitLength)) {
+      return false;
+    }
+    PascalString16BitLength that = (PascalString16BitLength) o;
+    return (getStringValue() == that.getStringValue()) && true;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(getStringValue());
+  }
+
+  @Override
+  public String toString() {
+    WriteBufferBoxBased writeBufferBoxBased = new WriteBufferBoxBased(true, true);
+    try {
+      writeBufferBoxBased.writeSerializable(this);
+    } catch (SerializationException e) {
+      throw new RuntimeException(e);
+    }
+    return "\n" + writeBufferBoxBased.getBox().toString() + "\n";
+  }
+}
diff --git a/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PcDcp_GetSet_Pdu.java b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PcDcp_GetSet_Pdu.java
new file mode 100644
index 0000000000..4d6d7c64a8
--- /dev/null
+++ b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PcDcp_GetSet_Pdu.java
@@ -0,0 +1,345 @@
+/*
+ * 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.profinet.readwrite;
+
+import static org.apache.plc4x.java.spi.codegen.fields.FieldReaderFactory.*;
+import static org.apache.plc4x.java.spi.codegen.fields.FieldWriterFactory.*;
+import static org.apache.plc4x.java.spi.codegen.io.DataReaderFactory.*;
+import static org.apache.plc4x.java.spi.codegen.io.DataWriterFactory.*;
+import static org.apache.plc4x.java.spi.generation.StaticHelper.*;
+
+import java.time.*;
+import java.util.*;
+import org.apache.plc4x.java.api.exceptions.*;
+import org.apache.plc4x.java.api.value.*;
+import org.apache.plc4x.java.spi.codegen.*;
+import org.apache.plc4x.java.spi.codegen.fields.*;
+import org.apache.plc4x.java.spi.codegen.io.*;
+import org.apache.plc4x.java.spi.generation.*;
+
+// Code generated by code-generation. DO NOT EDIT.
+
+public class PcDcp_GetSet_Pdu extends PnDcp_Pdu implements Message {
+
+  // Accessors for discriminator values.
+
+  // Constant values.
+  public static final Short SERVICEID = 0x04;
+
+  // Properties.
+  protected final boolean notSupported;
+  protected final boolean response;
+  protected final long xid;
+  protected final List<PnDcp_Block> blocks;
+
+  // Reserved Fields
+  private Short reservedField0;
+  private Byte reservedField1;
+  private Integer reservedField2;
+
+  public PcDcp_GetSet_Pdu(
+      int frameIdValue,
+      boolean notSupported,
+      boolean response,
+      long xid,
+      List<PnDcp_Block> blocks) {
+    super(frameIdValue);
+    this.notSupported = notSupported;
+    this.response = response;
+    this.xid = xid;
+    this.blocks = blocks;
+  }
+
+  public boolean getNotSupported() {
+    return notSupported;
+  }
+
+  public boolean getResponse() {
+    return response;
+  }
+
+  public long getXid() {
+    return xid;
+  }
+
+  public List<PnDcp_Block> getBlocks() {
+    return blocks;
+  }
+
+  public short getServiceId() {
+    return SERVICEID;
+  }
+
+  @Override
+  protected void serializePnDcp_PduChild(WriteBuffer writeBuffer) throws SerializationException {
+    PositionAware positionAware = writeBuffer;
+    boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+    int startPos = positionAware.getPos();
+    writeBuffer.pushContext("PcDcp_GetSet_Pdu");
+
+    // Const Field (serviceId)
+    writeConstField(
+        "serviceId",
+        SERVICEID,
+        writeUnsignedShort(writeBuffer, 8),
+        WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    // Reserved Field (reserved)
+    writeReservedField(
+        "reserved",
+        reservedField0 != null ? reservedField0 : (short) 0x00,
+        writeUnsignedShort(writeBuffer, 5),
+        WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    // Simple Field (notSupported)
+    writeSimpleField(
+        "notSupported",
+        notSupported,
+        writeBoolean(writeBuffer),
+        WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    // Reserved Field (reserved)
+    writeReservedField(
+        "reserved",
+        reservedField1 != null ? reservedField1 : (byte) 0x00,
+        writeUnsignedByte(writeBuffer, 1),
+        WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    // Simple Field (response)
+    writeSimpleField(
+        "response",
+        response,
+        writeBoolean(writeBuffer),
+        WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    // Simple Field (xid)
+    writeSimpleField(
+        "xid",
+        xid,
+        writeUnsignedLong(writeBuffer, 32),
+        WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    // Reserved Field (reserved)
+    writeReservedField(
+        "reserved",
+        reservedField2 != null ? reservedField2 : (int) 0x0000,
+        writeUnsignedInt(writeBuffer, 16),
+        WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    // Implicit Field (dcpDataLength) (Used for parsing, but its value is not stored as it's
+    // implicitly given by the objects content)
+    int dcpDataLength = (int) ((getLengthInBytes()) - (12));
+    writeImplicitField(
+        "dcpDataLength",
+        dcpDataLength,
+        writeUnsignedInt(writeBuffer, 16),
+        WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    // Array Field (blocks)
+    writeComplexTypeArrayField(
+        "blocks", blocks, writeBuffer, WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    writeBuffer.popContext("PcDcp_GetSet_Pdu");
+  }
+
+  @Override
+  public int getLengthInBytes() {
+    return (int) Math.ceil((float) getLengthInBits() / 8.0);
+  }
+
+  @Override
+  public int getLengthInBits() {
+    int lengthInBits = super.getLengthInBits();
+    PcDcp_GetSet_Pdu _value = this;
+    boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+
+    // Const Field (serviceId)
+    lengthInBits += 8;
+
+    // Reserved Field (reserved)
+    lengthInBits += 5;
+
+    // Simple field (notSupported)
+    lengthInBits += 1;
+
+    // Reserved Field (reserved)
+    lengthInBits += 1;
+
+    // Simple field (response)
+    lengthInBits += 1;
+
+    // Simple field (xid)
+    lengthInBits += 32;
+
+    // Reserved Field (reserved)
+    lengthInBits += 16;
+
+    // Implicit Field (dcpDataLength)
+    lengthInBits += 16;
+
+    // Array field
+    if (blocks != null) {
+      for (Message element : blocks) {
+        lengthInBits += element.getLengthInBits();
+      }
+    }
+
+    return lengthInBits;
+  }
+
+  public static PnDcp_PduBuilder staticParsePnDcp_PduBuilder(ReadBuffer readBuffer)
+      throws ParseException {
+    readBuffer.pullContext("PcDcp_GetSet_Pdu");
+    PositionAware positionAware = readBuffer;
+    int startPos = positionAware.getPos();
+    int curPos;
+    boolean _lastItem = ThreadLocalHelper.lastItemThreadLocal.get();
+
+    short serviceId =
+        readConstField(
+            "serviceId",
+            readUnsignedShort(readBuffer, 8),
+            PcDcp_GetSet_Pdu.SERVICEID,
+            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    Short reservedField0 =
+        readReservedField(
+            "reserved",
+            readUnsignedShort(readBuffer, 5),
+            (short) 0x00,
+            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    boolean notSupported =
+        readSimpleField(
+            "notSupported",
+            readBoolean(readBuffer),
+            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    Byte reservedField1 =
+        readReservedField(
+            "reserved",
+            readUnsignedByte(readBuffer, 1),
+            (byte) 0x00,
+            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    boolean response =
+        readSimpleField(
+            "response", readBoolean(readBuffer), WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    long xid =
+        readSimpleField(
+            "xid",
+            readUnsignedLong(readBuffer, 32),
+            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    Integer reservedField2 =
+        readReservedField(
+            "reserved",
+            readUnsignedInt(readBuffer, 16),
+            (int) 0x0000,
+            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    int dcpDataLength =
+        readImplicitField(
+            "dcpDataLength",
+            readUnsignedInt(readBuffer, 16),
+            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    List<PnDcp_Block> blocks =
+        readLengthArrayField(
+            "blocks",
+            new DataReaderComplexDefault<>(() -> PnDcp_Block.staticParse(readBuffer), readBuffer),
+            dcpDataLength,
+            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
+
+    readBuffer.closeContext("PcDcp_GetSet_Pdu");
+    // Create the instance
+    return new PcDcp_GetSet_PduBuilderImpl(
+        notSupported, response, xid, blocks, reservedField0, reservedField1, reservedField2);
+  }
+
+  public static class PcDcp_GetSet_PduBuilderImpl implements PnDcp_Pdu.PnDcp_PduBuilder {
+    private final boolean notSupported;
+    private final boolean response;
+    private final long xid;
+    private final List<PnDcp_Block> blocks;
+    private final Short reservedField0;
+    private final Byte reservedField1;
+    private final Integer reservedField2;
+
+    public PcDcp_GetSet_PduBuilderImpl(
+        boolean notSupported,
+        boolean response,
+        long xid,
+        List<PnDcp_Block> blocks,
+        Short reservedField0,
+        Byte reservedField1,
+        Integer reservedField2) {
+      this.notSupported = notSupported;
+      this.response = response;
+      this.xid = xid;
+      this.blocks = blocks;
+      this.reservedField0 = reservedField0;
+      this.reservedField1 = reservedField1;
+      this.reservedField2 = reservedField2;
+    }
+
+    public PcDcp_GetSet_Pdu build(int frameIdValue) {
+      PcDcp_GetSet_Pdu pcDcp_GetSet_Pdu =
+          new PcDcp_GetSet_Pdu(frameIdValue, notSupported, response, xid, blocks);
+      pcDcp_GetSet_Pdu.reservedField0 = reservedField0;
+      pcDcp_GetSet_Pdu.reservedField1 = reservedField1;
+      pcDcp_GetSet_Pdu.reservedField2 = reservedField2;
+      return pcDcp_GetSet_Pdu;
+    }
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof PcDcp_GetSet_Pdu)) {
+      return false;
+    }
+    PcDcp_GetSet_Pdu that = (PcDcp_GetSet_Pdu) o;
+    return (getNotSupported() == that.getNotSupported())
+        && (getResponse() == that.getResponse())
+        && (getXid() == that.getXid())
+        && (getBlocks() == that.getBlocks())
+        && super.equals(that)
+        && true;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(super.hashCode(), getNotSupported(), getResponse(), getXid(), getBlocks());
+  }
+
+  @Override
+  public String toString() {
+    WriteBufferBoxBased writeBufferBoxBased = new WriteBufferBoxBased(true, true);
+    try {
+      writeBufferBoxBased.writeSerializable(this);
+    } catch (SerializationException e) {
+      throw new RuntimeException(e);
+    }
+    return "\n" + writeBufferBoxBased.getBox().toString() + "\n";
+  }
+}
diff --git a/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PnDcp_Pdu.java b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PnDcp_Pdu.java
index fecec26267..a643ede656 100644
--- a/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PnDcp_Pdu.java
+++ b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PnDcp_Pdu.java
@@ -131,6 +131,8 @@ public abstract class PnDcp_Pdu implements Message {
     PnDcp_PduBuilder builder = null;
     if (EvaluationHelper.equals(frameId, PnDcp_FrameId.RT_CLASS_1)) {
       builder = PnDcp_Pdu_RealTimeCyclic.staticParsePnDcp_PduBuilder(readBuffer);
+    } else if (EvaluationHelper.equals(frameId, PnDcp_FrameId.DCP_GetSet_PDU)) {
+      builder = PcDcp_GetSet_Pdu.staticParsePnDcp_PduBuilder(readBuffer);
     } else if (EvaluationHelper.equals(frameId, PnDcp_FrameId.PTCP_DelayReqPDU)) {
       builder = PcDcp_Pdu_DelayReq.staticParsePnDcp_PduBuilder(readBuffer);
     } else if (EvaluationHelper.equals(frameId, PnDcp_FrameId.Alarm_Low)) {
diff --git a/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PnIoCm_Block_ArServer.java b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PnIoCm_Block_ArServer.java
index d6c6943859..82ef3c92ca 100644
--- a/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PnIoCm_Block_ArServer.java
+++ b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/PnIoCm_Block_ArServer.java
@@ -45,10 +45,10 @@ public class PnIoCm_Block_ArServer extends PnIoCm_Block implements Message {
   // Properties.
   protected final short blockVersionHigh;
   protected final short blockVersionLow;
-  protected final PascalString stationName;
+  protected final PascalString16BitLength stationName;
 
   public PnIoCm_Block_ArServer(
-      short blockVersionHigh, short blockVersionLow, PascalString stationName) {
+      short blockVersionHigh, short blockVersionLow, PascalString16BitLength stationName) {
     super();
     this.blockVersionHigh = blockVersionHigh;
     this.blockVersionLow = blockVersionLow;
@@ -63,7 +63,7 @@ public class PnIoCm_Block_ArServer extends PnIoCm_Block implements Message {
     return blockVersionLow;
   }
 
-  public PascalString getStationName() {
+  public PascalString16BitLength getStationName() {
     return stationName;
   }
 
@@ -173,10 +173,11 @@ public class PnIoCm_Block_ArServer extends PnIoCm_Block implements Message {
             readUnsignedShort(readBuffer, 8),
             WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
 
-    PascalString stationName =
+    PascalString16BitLength stationName =
         readSimpleField(
             "stationName",
-            new DataReaderComplexDefault<>(() -> PascalString.staticParse(readBuffer), readBuffer),
+            new DataReaderComplexDefault<>(
+                () -> PascalString16BitLength.staticParse(readBuffer), readBuffer),
             WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN));
 
     readPaddingField(
@@ -192,10 +193,10 @@ public class PnIoCm_Block_ArServer extends PnIoCm_Block implements Message {
   public static class PnIoCm_Block_ArServerBuilderImpl implements PnIoCm_Block.PnIoCm_BlockBuilder {
     private final short blockVersionHigh;
     private final short blockVersionLow;
-    private final PascalString stationName;
+    private final PascalString16BitLength stationName;
 
     public PnIoCm_Block_ArServerBuilderImpl(
-        short blockVersionHigh, short blockVersionLow, PascalString stationName) {
+        short blockVersionHigh, short blockVersionLow, PascalString16BitLength stationName) {
       this.blockVersionHigh = blockVersionHigh;
       this.blockVersionLow = blockVersionLow;
       this.stationName = stationName;
diff --git a/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/ProfinetDeviceState.java b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/ProfinetDeviceState.java
index d99ccabb86..9ded4be410 100644
--- a/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/ProfinetDeviceState.java
+++ b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/ProfinetDeviceState.java
@@ -30,6 +30,7 @@ public enum ProfinetDeviceState {
   WAITAPPLRDY((short) 0x03),
   APPLRDY((short) 0x04),
   CYCLICDATA((short) 0x05),
+  SET_IP((short) 0x06),
   ABORT((short) 0xFF);
   private static final Map<Short, ProfinetDeviceState> map;
 
diff --git a/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/TlvProfibusSubTypeMeasuredDelay.java b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/TlvProfibusSubTypeMeasuredDelay.java
index 6472465023..80a7b693af 100644
--- a/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/TlvProfibusSubTypeMeasuredDelay.java
+++ b/plc4j/drivers/profinet/src/main/generated/org/apache/plc4x/java/profinet/readwrite/TlvProfibusSubTypeMeasuredDelay.java
@@ -47,17 +47,20 @@ public class TlvProfibusSubTypeMeasuredDelay extends TlvOrgSpecificProfibusUnit
   protected final long remotePortRxDelay;
   protected final long localPortTxDelay;
   protected final long remotePortTxDelay;
+  protected final long portCableDelay;
 
   public TlvProfibusSubTypeMeasuredDelay(
       long localPortRxDelay,
       long remotePortRxDelay,
       long localPortTxDelay,
-      long remotePortTxDelay) {
+      long remotePortTxDelay,
+      long portCableDelay) {
     super();
     this.localPortRxDelay = localPortRxDelay;
     this.remotePortRxDelay = remotePortRxDelay;
     this.localPortTxDelay = localPortTxDelay;
     this.remotePortTxDelay = remotePortTxDelay;
+    this.portCableDelay = portCableDelay;
   }
 
   public long getLocalPortRxDelay() {
@@ -76,6 +79,10 @@ public class TlvProfibusSubTypeMeasuredDelay extends TlvOrgSpecificProfibusUnit
     return remotePortTxDelay;
   }
 
+  public long getPortCableDelay() {
+    return portCableDelay;
+  }
+
   @Override
   protected void serializeTlvOrgSpecificProfibusUnitChild(WriteBuffer writeBuffer)
       throws SerializationException {
@@ -96,6 +103,9 @@ public class TlvProfibusSubTypeMeasuredDelay extends TlvOrgSpecificProfibusUnit
     // Simple Field (remotePortTxDelay)
     writeSimpleField("remotePortTxDelay", remotePortTxDelay, writeUnsignedLong(writeBuffer, 32));
 
+    // Simple Field (portCableDelay)
+    writeSimpleField("portCableDelay", portCableDelay, writeUnsignedLong(writeBuffer, 32));
+
     writeBuffer.popContext("TlvProfibusSubTypeMeasuredDelay");
   }
 
@@ -122,6 +132,9 @@ public class TlvProfibusSubTypeMeasuredDelay extends TlvOrgSpecificProfibusUnit
     // Simple field (remotePortTxDelay)
     lengthInBits += 32;
 
+    // Simple field (portCableDelay)
+    lengthInBits += 32;
+
     return lengthInBits;
   }
 
@@ -141,10 +154,12 @@ public class TlvProfibusSubTypeMeasuredDelay extends TlvOrgSpecificProfibusUnit
 
     long remotePortTxDelay = readSimpleField("remotePortTxDelay", readUnsignedLong(readBuffer, 32));
 
+    long portCableDelay = readSimpleField("portCableDelay", readUnsignedLong(readBuffer, 32));
+
     readBuffer.closeContext("TlvProfibusSubTypeMeasuredDelay");
     // Create the instance
     return new TlvProfibusSubTypeMeasuredDelayBuilderImpl(
-        localPortRxDelay, remotePortRxDelay, localPortTxDelay, remotePortTxDelay);
+        localPortRxDelay, remotePortRxDelay, localPortTxDelay, remotePortTxDelay, portCableDelay);
   }
 
   public static class TlvProfibusSubTypeMeasuredDelayBuilderImpl
@@ -153,22 +168,29 @@ public class TlvProfibusSubTypeMeasuredDelay extends TlvOrgSpecificProfibusUnit
     private final long remotePortRxDelay;
     private final long localPortTxDelay;
     private final long remotePortTxDelay;
+    private final long portCableDelay;
 
     public TlvProfibusSubTypeMeasuredDelayBuilderImpl(
         long localPortRxDelay,
         long remotePortRxDelay,
         long localPortTxDelay,
-        long remotePortTxDelay) {
+        long remotePortTxDelay,
+        long portCableDelay) {
       this.localPortRxDelay = localPortRxDelay;
       this.remotePortRxDelay = remotePortRxDelay;
       this.localPortTxDelay = localPortTxDelay;
       this.remotePortTxDelay = remotePortTxDelay;
+      this.portCableDelay = portCableDelay;
     }
 
     public TlvProfibusSubTypeMeasuredDelay build() {
       TlvProfibusSubTypeMeasuredDelay tlvProfibusSubTypeMeasuredDelay =
           new TlvProfibusSubTypeMeasuredDelay(
-              localPortRxDelay, remotePortRxDelay, localPortTxDelay, remotePortTxDelay);
+              localPortRxDelay,
+              remotePortRxDelay,
+              localPortTxDelay,
+              remotePortTxDelay,
+              portCableDelay);
       return tlvProfibusSubTypeMeasuredDelay;
     }
   }
@@ -186,6 +208,7 @@ public class TlvProfibusSubTypeMeasuredDelay extends TlvOrgSpecificProfibusUnit
         && (getRemotePortRxDelay() == that.getRemotePortRxDelay())
         && (getLocalPortTxDelay() == that.getLocalPortTxDelay())
         && (getRemotePortTxDelay() == that.getRemotePortTxDelay())
+        && (getPortCableDelay() == that.getPortCableDelay())
         && super.equals(that)
         && true;
   }
@@ -197,7 +220,8 @@ public class TlvProfibusSubTypeMeasuredDelay extends TlvOrgSpecificProfibusUnit
         getLocalPortRxDelay(),
         getRemotePortRxDelay(),
         getLocalPortTxDelay(),
-        getRemotePortTxDelay());
+        getRemotePortTxDelay(),
+        getPortCableDelay());
   }
 
   @Override
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java
index d6852dd673..55f6597687 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java
@@ -24,7 +24,7 @@ import org.apache.plc4x.java.api.metadata.PlcDriverMetadata;
 import org.apache.plc4x.java.profinet.config.ProfinetConfiguration;
 import org.apache.plc4x.java.profinet.context.ProfinetDriverContext;
 import org.apache.plc4x.java.profinet.device.ProfinetChannel;
-import org.apache.plc4x.java.profinet.device.ProfinetDevices;
+import org.apache.plc4x.java.profinet.config.ProfinetDevices;
 import org.apache.plc4x.java.profinet.discovery.ProfinetPlcDiscoverer;
 import org.apache.plc4x.java.profinet.protocol.ProfinetProtocolLogic;
 import org.apache.plc4x.java.profinet.readwrite.Ethernet_Frame;
@@ -38,8 +38,6 @@ import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 import org.pcap4j.core.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.util.HashMap;
 import java.util.function.ToIntFunction;
@@ -66,7 +64,7 @@ public class ProfinetDriver extends GeneratedDriverBase<Ethernet_Frame> {
     @Override
     public PlcDiscoveryRequest.Builder discoveryRequestBuilder() {
         try {
-            ProfinetChannel channel = new ProfinetChannel(Pcaps.findAllDevs(), new ProfinetDevices(new HashMap<>()));
+            ProfinetChannel channel = new ProfinetChannel(Pcaps.findAllDevs(), new HashMap<>());
             ProfinetPlcDiscoverer discoverer = new ProfinetPlcDiscoverer(channel);
             channel.setDiscoverer(discoverer);
             return new DefaultPlcDiscoveryRequest.Builder(discoverer);
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/config/ConfigurationProfinetDevice.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/config/ConfigurationProfinetDevice.java
new file mode 100644
index 0000000000..1ea902a9dd
--- /dev/null
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/config/ConfigurationProfinetDevice.java
@@ -0,0 +1,64 @@
+/*
+ * 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.profinet.config;
+
+import org.apache.plc4x.java.profinet.device.ProfinetDevice;
+import org.apache.plc4x.java.profinet.gsdml.ProfinetISO15745Profile;
+
+import java.util.function.BiFunction;
+
+public class ConfigurationProfinetDevice {
+    private final String devicename;
+    private final String deviceaccess;
+    private final String submodules;
+    private final BiFunction<String, String, ProfinetISO15745Profile> gsdHandler;
+    private String ipaddress;
+
+    public ConfigurationProfinetDevice(String devicename, String deviceaccess, String submodules, BiFunction<String, String, ProfinetISO15745Profile> gsdHandler) {
+        this.devicename = devicename;
+        this.deviceaccess = deviceaccess;
+        this.submodules = submodules;
+        this.gsdHandler = gsdHandler;
+    }
+
+    public void setIpAddress(String ipaddress) {
+        this.ipaddress = ipaddress;
+    }
+
+    public String getDevicename() {
+        return devicename;
+    }
+
+    public String getDeviceaccess() {
+        return deviceaccess;
+    }
+
+    public String getSubmodules() {
+        return submodules;
+    }
+
+    public BiFunction<String, String, ProfinetISO15745Profile> getGsdHandler() {
+        return gsdHandler;
+    }
+
+    public String getIpaddress() {
+        return ipaddress;
+    }
+}
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..31e6885406 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
@@ -20,8 +20,6 @@ package org.apache.plc4x.java.profinet.config;
 
 import com.fasterxml.jackson.dataformat.xml.XmlMapper;
 import org.apache.plc4x.java.profinet.device.GsdFileMap;
-import org.apache.plc4x.java.profinet.device.ProfinetDevice;
-import org.apache.plc4x.java.profinet.device.ProfinetDevices;
 import org.apache.plc4x.java.profinet.gsdml.ProfinetISO15745Profile;
 import org.apache.plc4x.java.spi.configuration.Configuration;
 import org.apache.plc4x.java.spi.configuration.ConfigurationParameterConverter;
@@ -92,7 +90,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);
@@ -113,19 +111,22 @@ public class ProfinetConfiguration implements Configuration, RawSocketTransportC
                 throw new RuntimeException("Profinet Device Array is not in the correct format " + value + ".");
             }
 
-            Map<String, ProfinetDevice> devices = new HashMap<>();
+            Map<String, ConfigurationProfinetDevice> devices = new HashMap<>();
             String[] deviceParameters  = value.substring(1, value.length() - 1).split("[\\[\\]]");
             for (String deviceParameter : deviceParameters) {
                 if (deviceParameter.length() > 7) {
                     matcher = DEVICE_PARAMETERS.matcher(deviceParameter);
                     if (matcher.matches()) {
                         devices.put(matcher.group("devicename"),
-                            new ProfinetDevice(matcher.group("devicename"),
+                            new ConfigurationProfinetDevice(matcher.group("devicename"),
                                                matcher.group("deviceaccess"),
                                                matcher.group("submodules"),
                                                (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/ProfinetDevices.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/config/ProfinetDevices.java
similarity index 69%
copy from plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevices.java
copy to plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/config/ProfinetDevices.java
index d757c11a4d..a95916df4c 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevices.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/config/ProfinetDevices.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
@@ -17,19 +17,20 @@
  * under the License.
  */
 
-package org.apache.plc4x.java.profinet.device;
+package org.apache.plc4x.java.profinet.config;
+import org.apache.plc4x.java.profinet.device.ProfinetDevice;
 
 import java.util.Map;
 
 public class ProfinetDevices {
 
-    private final Map<String, ProfinetDevice> configuredDevices;
+    private final Map<String, ConfigurationProfinetDevice> configuredDevices;
 
-    public ProfinetDevices(Map<String, ProfinetDevice> configuredDevices) {
+    public ProfinetDevices(Map<String, ConfigurationProfinetDevice> configuredDevices) {
         this.configuredDevices = configuredDevices;
     }
 
-    public Map<String, ProfinetDevice> getConfiguredDevices() {
+    public Map<String, ConfigurationProfinetDevice> getConfiguredDevices() {
         return this.configuredDevices;
     }
 
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/context/ProfinetDeviceContext.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/context/ProfinetDeviceContext.java
index f57f715465..367e047c13 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/context/ProfinetDeviceContext.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/context/ProfinetDeviceContext.java
@@ -33,6 +33,7 @@ import org.apache.plc4x.java.spi.generation.*;
 
 import java.net.DatagramSocket;
 import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Matcher;
@@ -72,7 +73,7 @@ public class ProfinetDeviceContext implements DriverContext, HasConfiguration<Pr
     private MacAddress localMacAddress;
     private final DceRpc_ActivityUuid uuid;
     private ProfinetConfiguration configuration;
-    private InetAddress localIpAddress;
+
     private DatagramSocket socket;
     private ProfinetChannel channel;
     private MacAddress macAddress;
@@ -81,6 +82,8 @@ public class ProfinetDeviceContext implements DriverContext, HasConfiguration<Pr
     private boolean lldpReceived = false;
     private boolean dcpReceived = false;
     private String ipAddress;
+    private String subnetMask;
+    private String gateway;
     private String portId;
     private PnIoCm_Block_IoCrReq inputReq = null;
     private PnIoCm_Block_IoCrReq outputReq = null;
@@ -102,6 +105,7 @@ public class ProfinetDeviceContext implements DriverContext, HasConfiguration<Pr
     private ProfinetModule[] modules;
     private long sequenceNumber;
     private  DceRpc_ActivityUuid activityUuid;
+    private NetworkInterface networkInterface;
 
     public ProfinetDeviceContext() {
         // Generate a new Activity Id, which will be used throughout the connection.
@@ -167,14 +171,6 @@ public class ProfinetDeviceContext implements DriverContext, HasConfiguration<Pr
         return configuration;
     }
 
-    public InetAddress getLocalIpAddress() {
-        return localIpAddress;
-    }
-
-    public void setLocalIpAddress(InetAddress localIpAddress) {
-        this.localIpAddress = localIpAddress;
-    }
-
     public ProfinetChannel getChannel() {
         return channel;
     }
@@ -231,6 +227,27 @@ public class ProfinetDeviceContext implements DriverContext, HasConfiguration<Pr
         this.ipAddress = ipAddress;
     }
 
+    public byte[] getIpAddressAsByteArray() throws UnknownHostException {
+        if (this.ipAddress != null) {
+            return InetAddress.getByName(this.ipAddress).getAddress();
+        }
+        return new byte[4];
+    }
+
+    public byte[] getSubnetAsByteArray() throws UnknownHostException {
+        if (this.ipAddress != null) {
+            return InetAddress.getByName("255.255.255.0").getAddress();
+        }
+        return new byte[4];
+    }
+
+    public byte[] getGatewayAsByteArray() throws UnknownHostException {
+        if (this.ipAddress != null) {
+            return InetAddress.getByName("0.0.0.0").getAddress();
+        }
+        return new byte[4];
+    }
+
     public String getPortId() {
         return portId;
     }
@@ -533,4 +550,12 @@ public class ProfinetDeviceContext implements DriverContext, HasConfiguration<Pr
     public void removeSubscriptionHandle(String tag) {
         subscriptionHandles.remove(tag);
     }
+
+    public void setNetworkInterface(NetworkInterface networkInterface) {
+        this.networkInterface = networkInterface;
+    }
+
+    public NetworkInterface getNetworkInterface() {
+        return this.networkInterface;
+    }
 }
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetCallable.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/MessageWrapper.java
similarity index 60%
copy from plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetCallable.java
copy to plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/MessageWrapper.java
index 9798f9dfee..f374ada067 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetCallable.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/MessageWrapper.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
@@ -19,14 +19,11 @@
 
 package org.apache.plc4x.java.profinet.device;
 
-import org.apache.plc4x.java.api.exceptions.PlcException;
+import org.apache.plc4x.java.profinet.context.ProfinetDeviceContext;
+import org.apache.plc4x.java.profinet.readwrite.DceRpc_Packet;
+import org.apache.plc4x.java.profinet.readwrite.Ethernet_Frame;
 
-public interface ProfinetCallable<T> {
-    void handle(T packet);
-
-    T create();
-
-    long getId();
-
-    void setId(long id);
+public interface MessageWrapper {
+    void sendUdpMessage(ProfinetCallable<DceRpc_Packet> callable, ProfinetDeviceContext context) throws RuntimeException;
+    void sendPnioMessage(ProfinetCallable<Ethernet_Frame> callable, ProfinetDeviceContext context) throws RuntimeException;
 }
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetCallable.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/NetworkInterface.java
similarity index 75%
copy from plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetCallable.java
copy to plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/NetworkInterface.java
index 9798f9dfee..c1f1c5c31d 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetCallable.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/NetworkInterface.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
@@ -19,14 +19,13 @@
 
 package org.apache.plc4x.java.profinet.device;
 
-import org.apache.plc4x.java.api.exceptions.PlcException;
+public interface NetworkInterface {
 
-public interface ProfinetCallable<T> {
-    void handle(T packet);
+    String getIpAddress();
+    String getSubnet();
+    String getGateway();
+    byte[] getIpAddressAsByteArray();
+    byte[] getSubnetAsByteArray();
+    byte[] getGatewayAsByteArray();
 
-    T create();
-
-    long getId();
-
-    void setId(long id);
 }
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetCallable.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetCallable.java
index 9798f9dfee..26abe3c3a2 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetCallable.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetCallable.java
@@ -27,6 +27,4 @@ public interface ProfinetCallable<T> {
     T create();
 
     long getId();
-
-    void setId(long id);
 }
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetChannel.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetChannel.java
index a38a59aa1a..4123f0adc7 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetChannel.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetChannel.java
@@ -19,8 +19,7 @@
 
 package org.apache.plc4x.java.profinet.device;
 
-import org.apache.commons.codec.binary.Hex;
-import org.apache.plc4x.java.profinet.config.ProfinetConfiguration;
+import org.apache.plc4x.java.profinet.config.ProfinetDevices;
 import org.apache.plc4x.java.profinet.discovery.ProfinetPlcDiscoverer;
 import org.apache.plc4x.java.profinet.readwrite.*;
 import org.apache.plc4x.java.spi.generation.*;
@@ -32,7 +31,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.*;
-import java.util.function.Function;
 
 public class ProfinetChannel {
 
@@ -41,10 +39,10 @@ public class ProfinetChannel {
     private static final EtherType LLDP_EtherType = EtherType.getInstance((short) 0x88cc);
     private ProfinetPlcDiscoverer discoverer = null;
     private final Map<MacAddress, PcapHandle> openHandles;
-    private ProfinetDevices configuredDevices;
+    private Map<String, ProfinetDevice> devices;
 
-    public ProfinetChannel(List<PcapNetworkInterface> devs, ProfinetDevices devices) {
-        this.configuredDevices = devices;
+    public ProfinetChannel(List<PcapNetworkInterface> devs, Map<String, ProfinetDevice> devices) {
+        this.devices = devices;
         this.openHandles = getInterfaceHandles(devs);
         startListener();
     }
@@ -123,29 +121,36 @@ public class ProfinetChannel {
                                     if (discoverer != null) {
                                         discoverer.processPnDcp(pdu, ethernetPacket);
                                     }
-                                }  else if (pdu.getFrameId() == PnDcp_FrameId.Alarm_Low) {
-                                    for (Map.Entry<String, ProfinetDevice> device : this.configuredDevices.getConfiguredDevices().entrySet()) {
+                                } else if (pdu.getFrameId() == PnDcp_FrameId.DCP_GetSet_PDU) {
+                                    for (Map.Entry<String, ProfinetDevice> device : devices.entrySet()) {
                                         if (Arrays.equals(device.getValue().getDeviceContext().getMacAddress().getAddress(), ethernetFrame.getSource().getAddress())) {
-                                            PnDcp_Pdu_AlarmLow alarmPdu = (PnDcp_Pdu_AlarmLow) pdu;
-                                            device.getValue().handleAlarmResponse(alarmPdu);
+                                            PcDcp_GetSet_Pdu getSetPdu = (PcDcp_GetSet_Pdu) pdu;
+                                            device.getValue().handleSetIpAddressResponse(getSetPdu);
                                         }
                                     }
-                                }
-                                else if (pdu.getFrameId() == PnDcp_FrameId.RT_CLASS_1) {
-                                    for (Map.Entry<String, ProfinetDevice> device : this.configuredDevices.getConfiguredDevices().entrySet()) {
-                                        if (Arrays.equals(device.getValue().getDeviceContext().getMacAddress().getAddress(), ethernetFrame.getSource().getAddress())) {
-                                            PnDcp_Pdu_RealTimeCyclic cyclicPdu = (PnDcp_Pdu_RealTimeCyclic) pdu;
-                                            device.getValue().handleRealTimeResponse(cyclicPdu);
+                                } else if (pdu.getFrameId() == PnDcp_FrameId.Alarm_Low) {
+                                        for (Map.Entry<String, ProfinetDevice> device : devices.entrySet()) {
+                                            if (Arrays.equals(device.getValue().getDeviceContext().getMacAddress().getAddress(), ethernetFrame.getSource().getAddress())) {
+                                                PnDcp_Pdu_AlarmLow alarmPdu = (PnDcp_Pdu_AlarmLow) pdu;
+                                                device.getValue().handleAlarmResponse(alarmPdu);
+                                            }
+                                        }
+                                    }
+                                    else if (pdu.getFrameId() == PnDcp_FrameId.RT_CLASS_1) {
+                                        for (Map.Entry<String, ProfinetDevice> device : devices.entrySet()) {
+                                            if (Arrays.equals(device.getValue().getDeviceContext().getMacAddress().getAddress(), ethernetFrame.getSource().getAddress())) {
+                                                PnDcp_Pdu_RealTimeCyclic cyclicPdu = (PnDcp_Pdu_RealTimeCyclic) pdu;
+                                                device.getValue().handleRealTimeResponse(cyclicPdu);
+                                            }
                                         }
                                     }
-                                }
                             } else if (payload instanceof Ethernet_FramePayload_LLDP) {
                                 Lldp_Pdu pdu = ((Ethernet_FramePayload_LLDP) payload).getPdu();
                                 if (discoverer != null) {
                                     discoverer.processLldp(pdu);
                                 }
                             } else if (payload instanceof Ethernet_FramePayload_IPv4) {
-                                for (Map.Entry<String, ProfinetDevice> device : this.configuredDevices.getConfiguredDevices().entrySet()) {
+                                for (Map.Entry<String, ProfinetDevice> device : devices.entrySet()) {
                                     if (Arrays.equals(device.getValue().getDeviceContext().getMacAddress().getAddress(), ethernetFrame.getSource().getAddress())) {
                                         device.getValue().handleResponse((Ethernet_FramePayload_IPv4) payload);
                                     }
@@ -211,8 +216,8 @@ public class ProfinetChannel {
         return openHandles;
     }
 
-    public void setConfiguredDevices(ProfinetDevices configuredDevices) {
-        this.configuredDevices = configuredDevices;
+    public void setConfiguredDevices(Map<String, ProfinetDevice> configuredDevices) {
+        this.devices = devices;
     }
 
     private static MacAddress toPlc4xMacAddress(org.pcap4j.util.MacAddress pcap4jMacAddress) {
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 33556c8e4e..f1eb8afe66 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
@@ -56,24 +56,27 @@ import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
 
-public class ProfinetDevice implements PlcSubscriber{
+public class ProfinetDevice implements PlcSubscriber {
 
     private final Logger logger = LoggerFactory.getLogger(ProfinetDevice.class);
     private static final int DEFAULT_NUMBER_OF_PORTS_TO_SCAN = 100;
     private static final int MIN_CYCLE_NANO_SEC = 31250;
     private final BiFunction<String, String, ProfinetISO15745Profile> gsdHandler;
     private final ProfinetDeviceContext deviceContext = new ProfinetDeviceContext();
+    private final MessageWrapper messageWrapper;
 
     // Each device should create a receiving socket, all the packets are then automatically transferred to the listener for the channel though.
     private DatagramSocket socket = null;
     private String vendorId;
     private String deviceId;
     private Thread eventLoop = null;
-    final Map<String, List<Consumer<PlcSubscriptionEvent>>> registrations = new HashMap<>();
+    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)  {
+    public ProfinetDevice(MessageWrapper messageWrapper, String deviceName, String deviceAccess, String subModules, BiFunction<String, String, ProfinetISO15745Profile> gsdHandler) {
+        this.messageWrapper = messageWrapper;
         this.gsdHandler = gsdHandler;
         deviceContext.setDeviceAccess(deviceAccess);
         deviceContext.setSubModules(subModules);
@@ -126,7 +129,7 @@ public class ProfinetDevice implements PlcSubscriber{
 
     private void recordIdAndSend(ProfinetCallable<DceRpc_Packet> callable) {
         deviceContext.addToQueue(callable.getId(), callable);
-        ProfinetMessageWrapper.sendUdpMessage(
+        this.messageWrapper.sendUdpMessage(
             callable,
             deviceContext
         );
@@ -169,6 +172,9 @@ public class ProfinetDevice implements PlcSubscriber{
     }
 
     public boolean onConnect() throws ExecutionException, InterruptedException, TimeoutException {
+        if (this.setIpAddress) {
+            deviceContext.setState(ProfinetDeviceState.SET_IP);
+        }
         start();
         return true;
     }
@@ -178,13 +184,18 @@ public class ProfinetDevice implements PlcSubscriber{
      */
     public void start() {
         final long timeout = (long) deviceContext.getConfiguration().getReductionRatio() * deviceContext.getConfiguration().getSendClockFactor() * deviceContext.getConfiguration().getWatchdogFactor() * MIN_CYCLE_NANO_SEC;
-        final int cycleTime = (int) (deviceContext.getConfiguration().getSendClockFactor() * deviceContext.getConfiguration().getReductionRatio() * (MIN_CYCLE_NANO_SEC/1000000.0));
+        final int cycleTime = (int) (deviceContext.getConfiguration().getSendClockFactor() * deviceContext.getConfiguration().getReductionRatio() * (MIN_CYCLE_NANO_SEC / 1000000.0));
         Function<Object, Boolean> subscription =
             message -> {
                 long startTime = System.nanoTime();
                 while (deviceContext.getState() != ProfinetDeviceState.ABORT) {
                     try {
-                        switch(deviceContext.getState()) {
+                        switch (deviceContext.getState()) {
+                            case SET_IP:
+                                ProfinetMessageDcpIp setIpMessage = new ProfinetMessageDcpIp();
+                                this.messageWrapper.sendPnioMessage(setIpMessage, deviceContext);
+                                deviceContext.setState(ProfinetDeviceState.IDLE);
+                                break;
                             case IDLE:
                                 CreateConnection createConnection = new CreateConnection();
                                 recordIdAndSend(createConnection);
@@ -202,6 +213,7 @@ public class ProfinetDevice implements PlcSubscriber{
                                 break;
                             case WAITAPPLRDY:
                                 Thread.sleep(cycleTime);
+                                break;
                             case APPLRDY:
                                 ApplicationReadyResponse applicationReadyResponse = new ApplicationReadyResponse(deviceContext.getActivityUuid(), deviceContext.getSequenceNumber());
                                 recordIdAndSend(applicationReadyResponse);
@@ -210,7 +222,7 @@ public class ProfinetDevice implements PlcSubscriber{
                                 break;
                             case CYCLICDATA:
                                 CyclicData cyclicData = new CyclicData(startTime);
-                                ProfinetMessageWrapper.sendPnioMessage(cyclicData, deviceContext);
+                                this.messageWrapper.sendPnioMessage(cyclicData, deviceContext);
                                 Thread.sleep(cycleTime);
                                 break;
                         }
@@ -269,6 +281,13 @@ public class ProfinetDevice implements PlcSubscriber{
         return deviceContext.isDcpReceived();
     }
 
+    public void setIpAddress(String ipAddress) {
+        if (ipAddress != null) {
+            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();
@@ -300,7 +319,7 @@ public class ProfinetDevice implements PlcSubscriber{
 
     public void handle(PlcDiscoveryItem item) {
         logger.debug("Received Discovered item at device");
-        if (item.getOptions().containsKey("ipAddress")) {
+        if (item.getOptions().containsKey("ipAddress") && !this.setIpAddress) {
             deviceContext.setIpAddress(item.getOptions().get("ipAddress"));
         }
         if (item.getOptions().containsKey("portId")) {
@@ -412,19 +431,30 @@ public class ProfinetDevice implements PlcSubscriber{
         deviceContext.setState(ProfinetDeviceState.IDLE);
     }
 
+    public void handleSetIpAddressResponse(PcDcp_GetSet_Pdu pdu) {
+        deviceContext.setState(ProfinetDeviceState.IDLE);
+    }
+
+    public void setNetworkInterface(NetworkInterface networkInterface) {
+        this.deviceContext.setNetworkInterface(networkInterface);
+    }
+
+    public NetworkInterface getNetworkInterface() {
+        return this.deviceContext.getNetworkInterface();
+    }
+
     public class CreateConnection implements ProfinetCallable<DceRpc_Packet> {
 
         final CompletableFuture<Boolean> responseHandled = new CompletableFuture<>();
-        private long id = getObjectId();
+        private final long id = getObjectId();
+
         public CompletableFuture<Boolean> getResponseHandled() {
             return responseHandled;
         }
+
         public long getId() {
             return id;
         }
-        public void setId(long id) {
-            this.id = id;
-        }
 
         public DceRpc_Packet create() {
             deviceContext.setSessionKey(deviceContext.getAndIncrementSessionKey());
@@ -563,7 +593,8 @@ public class ProfinetDevice implements PlcSubscriber{
                 if (dceRpc_packet.getPayload().getPacketType() == DceRpc_PacketType.RESPONSE) {
                     final PnIoCm_Packet_Res connectResponse = (PnIoCm_Packet_Res) dceRpc_packet.getPayload();
                     if (connectResponse.getErrorCode() == 0) {
-                        deviceContext.setState(ProfinetDeviceState.STARTUP);
+                        // TODO:- Re-enable the Write Parameters step if need be. Need a pcap of a simocode connection.
+                        deviceContext.setState(ProfinetDeviceState.PREMED);
                         responseHandled.complete(true);
                         for (PnIoCm_Block module : connectResponse.getBlocks()) {
                             if (module.getBlockType() == PnIoCm_BlockType.MODULE_DIFF_BLOCK) {
@@ -598,7 +629,7 @@ public class ProfinetDevice implements PlcSubscriber{
     public class WriteParameters implements ProfinetCallable<DceRpc_Packet> {
 
         final CompletableFuture<Boolean> responseHandled = new CompletableFuture<>();
-        private long id = getObjectId();
+        private final long id = getObjectId();
 
         public CompletableFuture<Boolean> getResponseHandled() {
             return responseHandled;
@@ -608,10 +639,6 @@ public class ProfinetDevice implements PlcSubscriber{
             return id;
         }
 
-        public void setId(long id) {
-            this.id = id;
-        }
-
         public DceRpc_Packet create() {
 
             int seqNumber = 0;
@@ -667,7 +694,7 @@ public class ProfinetDevice implements PlcSubscriber{
                                 0x0001,
                                 record.getIndex(),
                                 record.getLength(),
-                                new UserData(ByteBuffer.allocate(4).putInt(Integer.parseInt(record.getRef().getDefaultValue())).array(), (long) record.getLength())
+                                new UserData(ByteBuffer.allocate(4).putInt(Integer.valueOf(record.getRef().getDefaultValue())).array(), (long) record.getLength())
                             ));
                         seqNumber += 1;
                     }
@@ -741,7 +768,7 @@ public class ProfinetDevice implements PlcSubscriber{
     public class WriteParametersEnd implements ProfinetCallable<DceRpc_Packet> {
 
         final CompletableFuture<Boolean> responseHandled = new CompletableFuture<>();
-        private long id = getObjectId();
+        private final long id = getObjectId();
 
         public CompletableFuture<Boolean> getResponseHandled() {
             return responseHandled;
@@ -751,10 +778,6 @@ public class ProfinetDevice implements PlcSubscriber{
             return id;
         }
 
-        public void setId(long id) {
-            this.id = id;
-        }
-
         public DceRpc_Packet create() {
             return new DceRpc_Packet(
                 DceRpc_PacketType.REQUEST, true, false, false,
@@ -813,7 +836,7 @@ public class ProfinetDevice implements PlcSubscriber{
     public class ApplicationReadyResponse implements ProfinetCallable<DceRpc_Packet> {
 
         private final DceRpc_ActivityUuid activityUuid;
-        private long id;
+        private final long id;
 
         public ApplicationReadyResponse(DceRpc_ActivityUuid activityUuid, long seqNumber) {
             this.activityUuid = activityUuid;
@@ -828,9 +851,6 @@ public class ProfinetDevice implements PlcSubscriber{
             return id;
         }
 
-        public void setId(long id) {
-            this.id = id;
-        }
 
         public DceRpc_Packet create() {
             return new DceRpc_Packet(
@@ -876,7 +896,7 @@ public class ProfinetDevice implements PlcSubscriber{
     public class DceRpcAck implements ProfinetCallable<DceRpc_Packet> {
 
         private final DceRpc_ActivityUuid activityUuid;
-        private long id;
+        private final long id;
 
         public DceRpcAck(DceRpc_ActivityUuid activityUuid, long seqNumber) {
             this.activityUuid = activityUuid;
@@ -891,10 +911,6 @@ public class ProfinetDevice implements PlcSubscriber{
             return id;
         }
 
-        public void setId(long id) {
-            this.id = id;
-        }
-
         public DceRpc_Packet create() {
             return new DceRpc_Packet(
                 DceRpc_PacketType.NO_CALL,
@@ -916,14 +932,14 @@ public class ProfinetDevice implements PlcSubscriber{
 
         @Override
         public void handle(DceRpc_Packet packet) {
-            logger.debug("Received an unintented packet");
+            logger.debug("Received an unintended packet");
         }
     }
 
     public class CyclicData implements ProfinetCallable<Ethernet_Frame> {
 
         private final long startTime;
-        private long id = getObjectId();
+        private final long id = getObjectId();
 
         public CyclicData(long startTime) {
             this.startTime = startTime;
@@ -933,10 +949,6 @@ public class ProfinetDevice implements PlcSubscriber{
             return id;
         }
 
-        public void setId(long id) {
-            this.id = id;
-        }
-
         public Ethernet_Frame create() {
 
             WriteBufferByteBased buffer = new WriteBufferByteBased(deviceContext.getOutputReq().getDataLength());
@@ -961,7 +973,8 @@ public class ProfinetDevice implements PlcSubscriber{
                     buffer.writeByte((byte) 0x00);
                 }
 
-                int elapsedTime = (int) ((((System.nanoTime() - startTime)/(MIN_CYCLE_NANO_SEC)) + offset) % 65536);
+                // TODO:- Still having issues with this. For the Simcode after a while we received an Alarm low message, Although it might be related to the ping functionality.
+                int elapsedTime = (int) ((((System.nanoTime() - startTime) / (MIN_CYCLE_NANO_SEC)) + offset) % 65536);
 
                 Ethernet_Frame frame = new Ethernet_Frame(
                     deviceContext.getMacAddress(),
@@ -987,7 +1000,7 @@ public class ProfinetDevice implements PlcSubscriber{
                 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);
+                int elapsedTime = (int) ((((System.nanoTime() - startTime) / (MIN_CYCLE_NANO_SEC)) + offset) % 65536);
 
                 Ethernet_Frame frame = new Ethernet_Frame(
                     deviceContext.getMacAddress(),
@@ -1013,9 +1026,73 @@ public class ProfinetDevice implements PlcSubscriber{
         }
 
         @Override
-        public void handle(Ethernet_Frame packet)  {
+        public void handle(Ethernet_Frame packet) {
             deviceContext.setState(ProfinetDeviceState.ABORT);
             logger.error("Error Parsing Cyclic Data from device {}", deviceContext.getDeviceName());
         }
     }
+
+    public class ProfinetMessageDcpIp implements ProfinetCallable<Ethernet_Frame> {
+
+        private long id = getObjectId();
+        private CompletableFuture<Boolean> responseHandled = new CompletableFuture<>();
+
+        public ProfinetMessageDcpIp() {
+        }
+
+        public long getId() {
+            return id;
+        }
+
+        public void setId(long id) {
+            this.id = id;
+        }
+
+        public CompletableFuture<Boolean> getResponseHandled() {
+            return responseHandled;
+        }
+
+        public Ethernet_Frame create() {
+            Ethernet_Frame frame = null;
+            try {
+                frame = new Ethernet_Frame(
+                    deviceContext.getMacAddress(),
+                    deviceContext.getLocalMacAddress(),
+                    new Ethernet_FramePayload_VirtualLan(
+                        VirtualLanPriority.INTERNETWORK_CONTROL,
+                        false,
+                        0,
+                        new Ethernet_FramePayload_PnDcp(
+                            new PcDcp_GetSet_Pdu(
+                                PnDcp_FrameId.DCP_GetSet_PDU.getValue(),
+                                false,
+                                false,
+                                0x10000001L,
+                                Collections.singletonList(
+                                    new PnDcp_Block_IpParameter(
+                                        false,
+                                        false,
+                                        true,
+                                        deviceContext.getIpAddressAsByteArray(),
+                                        deviceContext.getSubnetAsByteArray(),
+                                        deviceContext.getGatewayAsByteArray()
+                                    )
+                                )
+                            )
+                        )
+                    )
+                );
+            } catch (UnknownHostException e) {
+                logger.error("Error parsing IP Address for set ip address phase");
+                deviceContext.setState(ProfinetDeviceState.ABORT);
+            }
+
+            return frame;
+        }
+
+        @Override
+        public void handle(Ethernet_Frame ethernetFrame) {
+            logger.debug("Received a Set IP Address Response");
+        }
+    }
 }
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDeviceMessageHandler.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDeviceMessageHandler.java
index 1b8d3a6306..2763e0a3ed 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDeviceMessageHandler.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDeviceMessageHandler.java
@@ -21,26 +21,28 @@ package org.apache.plc4x.java.profinet.device;
 
 import org.apache.plc4x.java.api.messages.PlcDiscoveryItem;
 import org.apache.plc4x.java.api.messages.PlcDiscoveryItemHandler;
+import org.apache.plc4x.java.profinet.config.ProfinetDevices;
 
 import java.util.HashMap;
+import java.util.Map;
 
 public class ProfinetDeviceMessageHandler implements PlcDiscoveryItemHandler {
 
-    private ProfinetDevices configuredDevices;
+    private Map<String, ProfinetDevice> devices = new HashMap<>();
 
-    public ProfinetDeviceMessageHandler(ProfinetDevices configuredDevices) {
-        this.configuredDevices = configuredDevices;
+    public ProfinetDeviceMessageHandler(Map<String, ProfinetDevice> devices) {
+        this.devices = devices;
     }
 
     @Override
     public void handle(PlcDiscoveryItem discoveryItem) {
         String deviceName = discoveryItem.getOptions().get("deviceName").toUpperCase();
-        if (configuredDevices.getConfiguredDevices().containsKey(deviceName)) {
-            configuredDevices.getConfiguredDevices().get(deviceName).handle(discoveryItem);
+        if (devices.containsKey(deviceName)) {
+            devices.get(deviceName).handle(discoveryItem);
         }
     }
 
-    public void setConfiguredDevices(ProfinetDevices configuredDevices) {
-        this.configuredDevices = configuredDevices;
+    public void setConfiguredDevices(Map<String, ProfinetDevice> devices) {
+        this.devices = devices;
     }
 }
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetMessageWrapper.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetMessageWrapper.java
index 8c196f66ff..a373f3b551 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetMessageWrapper.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetMessageWrapper.java
@@ -28,11 +28,11 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.util.Random;
 
-public class ProfinetMessageWrapper {
+public class ProfinetMessageWrapper implements MessageWrapper {
 
     private static final Logger logger = LoggerFactory.getLogger(ProfinetMessageWrapper.class);
 
-    public static void sendUdpMessage(ProfinetCallable<DceRpc_Packet> callable, ProfinetDeviceContext context) throws RuntimeException {
+    public void sendUdpMessage(ProfinetCallable<DceRpc_Packet> callable, ProfinetDeviceContext context) throws RuntimeException {
         try {
             DceRpc_Packet packet = callable.create();
             Random rand = new Random();
@@ -42,7 +42,7 @@ public class ProfinetMessageWrapper {
                 true,
                 false,
                 (short) 64,
-                new IpAddress(context.getLocalIpAddress().getAddress()),
+                new IpAddress(context.getNetworkInterface().getIpAddressAsByteArray()),
                 new IpAddress(InetAddress.getByName(context.getIpAddress()).getAddress()),
                 context.getSourcePort(),
                 context.getDestinationPort(),
@@ -63,7 +63,7 @@ public class ProfinetMessageWrapper {
         }
     }
 
-    public static void sendPnioMessage(ProfinetCallable<Ethernet_Frame> callable, ProfinetDeviceContext context) throws RuntimeException {
+    public void sendPnioMessage(ProfinetCallable<Ethernet_Frame> callable, ProfinetDeviceContext context) throws RuntimeException {
         Ethernet_Frame packet = callable.create();
         context.getChannel().send(packet);
     }
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetNetworkInterface.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetNetworkInterface.java
new file mode 100644
index 0000000000..036eb30e4b
--- /dev/null
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetNetworkInterface.java
@@ -0,0 +1,102 @@
+/*
+ * 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.profinet.device;
+
+import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
+import org.pcap4j.core.PcapAddress;
+import org.pcap4j.core.PcapIpV4Address;
+import org.pcap4j.core.PcapNetworkInterface;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class ProfinetNetworkInterface implements NetworkInterface {
+
+    private String ipAddress;
+    private String subnet;
+    private String gateway;
+
+    public ProfinetNetworkInterface(PcapNetworkInterface networkInterface) {
+        if (networkInterface.getAddresses().size() == 0) {
+            throw new PlcRuntimeException("No Inet4 Address assigned to interface");
+        }
+        for (PcapAddress address : networkInterface.getAddresses()) {
+            if (address instanceof PcapIpV4Address) {
+                ipAddress = address.getAddress().toString();
+                subnet = address.getNetmask().toString();
+                if (address.getDestinationAddress() != null) {
+                    gateway = address.getDestinationAddress().toString();
+                } else {
+                    gateway = "0.0.0.0";
+                }
+            }
+        }
+
+    }
+
+    @Override
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    @Override
+    public String getSubnet() {
+        return subnet;
+    }
+
+    @Override
+    public String getGateway() {
+        return gateway;
+    }
+
+    public byte[] getIpAddressAsByteArray() {
+        try {
+            if (this.ipAddress != null) {
+                return InetAddress.getByName(this.ipAddress.replace("/", "")).getAddress();
+            }
+            return new byte[4];
+        } catch (UnknownHostException e) {
+            return new byte[4];
+        }
+    }
+
+    public byte[] getSubnetAsByteArray() {
+        try {
+            if (this.subnet != null) {
+                return InetAddress.getByName(this.subnet).getAddress();
+            }
+            return new byte[4];
+        } catch (UnknownHostException e) {
+            return new byte[4];
+        }
+    }
+
+    public byte[] getGatewayAsByteArray() {
+        try {
+            if (this.gateway != null) {
+                return InetAddress.getByName(this.gateway).getAddress();
+            }
+            return new byte[4];
+        } catch (UnknownHostException e) {
+            return new byte[4];
+        }
+    }
+
+}
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetPlcDiscoverer.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetPlcDiscoverer.java
index cb2595ced1..d7bb056791 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetPlcDiscoverer.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetPlcDiscoverer.java
@@ -236,14 +236,11 @@ public class ProfinetPlcDiscoverer implements PlcDiscoverer {
             if (unit instanceof TlvPortId) {
                 TlvPortId portIdPacket = (TlvPortId) unit;
                 options.put("portId", portIdPacket.getPortId());
-                if (portIdPacket.getPortId().contains(".")) {
-                    options.put("deviceName", portIdPacket.getPortId().split("\\.")[1]);
-                } else {
-                    options.put("deviceName", portIdPacket.getPortId());
-                }
+
             } else if (unit instanceof TlvChassisId) {
                 TlvChassisId chassisIdPacket = (TlvChassisId) unit;
                 options.put("chassisId", chassisIdPacket.getChassisId());
+                options.put("deviceName", chassisIdPacket.getChassisId());
             } else if (unit instanceof TlvManagementAddress) {
                 TlvManagementAddress managementAddressPacket = (TlvManagementAddress) unit;
                 try {
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
index 5d747e780e..991d5ee808 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
@@ -22,16 +22,13 @@ import org.apache.commons.lang3.NotImplementedException;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.exceptions.PlcException;
 import org.apache.plc4x.java.api.messages.*;
-import org.apache.plc4x.java.api.model.PlcConsumerRegistration;
 import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
 import org.apache.plc4x.java.api.model.PlcSubscriptionTag;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
+import org.apache.plc4x.java.profinet.config.ConfigurationProfinetDevice;
 import org.apache.plc4x.java.profinet.config.ProfinetConfiguration;
 import org.apache.plc4x.java.profinet.context.ProfinetDriverContext;
-import org.apache.plc4x.java.profinet.device.ProfinetChannel;
-import org.apache.plc4x.java.profinet.device.ProfinetDevice;
-import org.apache.plc4x.java.profinet.device.ProfinetDeviceMessageHandler;
-import org.apache.plc4x.java.profinet.device.ProfinetSubscriptionHandle;
+import org.apache.plc4x.java.profinet.device.*;
 import org.apache.plc4x.java.profinet.discovery.ProfinetPlcDiscoverer;
 import org.apache.plc4x.java.profinet.readwrite.*;
 import org.apache.plc4x.java.profinet.tag.ProfinetTag;
@@ -40,7 +37,6 @@ import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
 import org.apache.plc4x.java.spi.messages.*;
 import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
-import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
 import org.apache.plc4x.java.utils.rawsockets.netty.RawSocketChannel;
 import org.pcap4j.core.*;
@@ -48,19 +44,17 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.net.*;
-import java.time.Duration;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
-import java.util.function.Consumer;
-import java.util.regex.Pattern;
 
 public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> implements HasConfiguration<ProfinetConfiguration> {
 
     private final Logger LOGGER = LoggerFactory.getLogger(ProfinetProtocolLogic.class);
 
     private ProfinetDriverContext driverContext;
+    private Map<String, ProfinetDevice> devices = new HashMap<>();
 
     public ProfinetProtocolLogic() {
         super();
@@ -75,8 +69,24 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
     @Override
     public void setConfiguration(ProfinetConfiguration configuration) {
         driverContext.setConfiguration(configuration);
-        driverContext.setHandler(new ProfinetDeviceMessageHandler(configuration.getDevices()));
-        for (Map.Entry<String, ProfinetDevice> device : configuration.getDevices().getConfiguredDevices().entrySet()) {
+
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new ProfinetMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
+
+        driverContext.setHandler(new ProfinetDeviceMessageHandler(devices));
+        for (Map.Entry<String, ProfinetDevice> device : devices.entrySet()) {
             device.getValue().getDeviceContext().setConfiguration(configuration);
         }
     }
@@ -92,9 +102,9 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
             throw new RuntimeException(e);
         }
 
-        driverContext.getHandler().setConfiguredDevices(driverContext.getConfiguration().getDevices());
+        driverContext.getHandler().setConfiguredDevices(devices);
 
-        for (Map.Entry<String, ProfinetDevice> device : driverContext.getConfiguration().getDevices().getConfiguredDevices().entrySet()) {
+        for (Map.Entry<String, ProfinetDevice> device : devices.entrySet()) {
             device.getValue().setContext(context, this.driverContext.getChannel());
         }
     }
@@ -113,7 +123,7 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
         int count = 0;
         while (!discovered) {
             discovered = true;
-            for (Map.Entry<String, ProfinetDevice> device : driverContext.getConfiguration().getDevices().getConfiguredDevices().entrySet()) {
+            for (Map.Entry<String, ProfinetDevice> device : devices.entrySet()) {
                 if (!device.getValue().hasLldpPdu() || !device.getValue().hasDcpPdu()) {
                     discovered = false;
                 }
@@ -135,7 +145,7 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
         Map<String, PlcResponseCode> codes = new HashMap<>();
         Map<String, List<PlcBrowseItem>> responseValues = new HashMap<>();
 
-        for (Map.Entry<String, ProfinetDevice> device : driverContext.getConfiguration().getDevices().getConfiguredDevices().entrySet()) {
+        for (Map.Entry<String, ProfinetDevice> device : devices.entrySet()) {
             device.getValue().browseTags(values);
         }
 
@@ -156,8 +166,12 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
             String localAddress = channel.getLocalAddress().toString().substring(1).split(":")[0];
             localIpAddress = InetAddress.getByName(localAddress);
             PcapNetworkInterface devByAddress = Pcaps.getDevByAddress(localIpAddress);
-            driverContext.setChannel(new ProfinetChannel(Collections.singletonList(devByAddress), driverContext.getConfiguration().getDevices()));
-            driverContext.getChannel().setConfiguredDevices(driverContext.getConfiguration().getDevices());
+            driverContext.setChannel(new ProfinetChannel(Collections.singletonList(devByAddress), devices));
+            driverContext.getChannel().setConfiguredDevices(devices);
+            for (Map.Entry<String, ProfinetDevice> entry : devices.entrySet()) {
+                entry.getValue().setNetworkInterface(new ProfinetNetworkInterface(devByAddress));
+                entry.getValue().getDeviceContext().setChannel(driverContext.getChannel());
+            }
         } catch (PcapNativeException | UnknownHostException e) {
             throw new RuntimeException(e);
         }
@@ -168,13 +182,8 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
             throw new RuntimeException(e);
         }
 
-        for (Map.Entry<String, ProfinetDevice> device : driverContext.getConfiguration().getDevices().getConfiguredDevices().entrySet()) {
-            device.getValue().getDeviceContext().setChannel(driverContext.getChannel());
-            device.getValue().getDeviceContext().setLocalIpAddress(localIpAddress);
-        }
-
         try {
-            for (Map.Entry<String, ProfinetDevice> device : driverContext.getConfiguration().getDevices().getConfiguredDevices().entrySet()) {
+            for (Map.Entry<String, ProfinetDevice> device : devices.entrySet()) {
                 device.getValue().onConnect();
             }
             context.fireConnected();
@@ -212,7 +221,7 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
                 PlcSubscriptionTag tag = subscriptionRequest.getTag(fieldName);
                 final DefaultPlcSubscriptionTag fieldDefaultPlcSubscription = (DefaultPlcSubscriptionTag) subscriptionRequest.getTag(fieldName);
                 String deviceString = fieldDefaultPlcSubscription.getAddressString().split("\\.")[0].toUpperCase();
-                ProfinetDevice device = driverContext.getConfiguration().getDevices().getConfiguredDevices().get(deviceString);
+                ProfinetDevice device = devices.get(deviceString);
 
                 ProfinetSubscriptionHandle subscriptionHandle = new ProfinetSubscriptionHandle(device, fieldName, tag);
                 device.getDeviceContext().addSubscriptionHandle(fieldDefaultPlcSubscription.getAddressString(), subscriptionHandle);
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/tag/ProfinetTag.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/tag/ProfinetTag.java
index 254a2423f9..c7dd3f40ed 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/tag/ProfinetTag.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/tag/ProfinetTag.java
@@ -29,7 +29,7 @@ import java.util.regex.Pattern;
 
 public class ProfinetTag implements PlcTag {
 
-    public static final Pattern ADDRESS_PATTERN = Pattern.compile("(?<address>[\\w\\-.]+)(:(?<datatype>[a-zA-Z_]+)){1}(\\[(?<quantity>\\d+)])?");
+    public static final Pattern ADDRESS_PATTERN = Pattern.compile("(?<address>[\\w\\-. ]+)(:(?<datatype>[a-zA-Z_]+)){1}(\\[(?<quantity>\\d+)])?");
     private final String address;
     private final int quantity;
     private final PlcValueType dataType;
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevices.java b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/DummyMessageWrapper.java
similarity index 51%
rename from plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevices.java
rename to plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/DummyMessageWrapper.java
index d757c11a4d..bd3c5bcf08 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevices.java
+++ b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/DummyMessageWrapper.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
@@ -17,20 +17,20 @@
  * under the License.
  */
 
-package org.apache.plc4x.java.profinet.device;
+package org.apache.plc4x.java.profinet;
 
-import java.util.Map;
+import org.apache.plc4x.java.profinet.context.ProfinetDeviceContext;
+import org.apache.plc4x.java.profinet.device.MessageWrapper;
+import org.apache.plc4x.java.profinet.device.ProfinetCallable;
+import org.apache.plc4x.java.profinet.readwrite.DceRpc_Packet;
+import org.apache.plc4x.java.profinet.readwrite.Ethernet_Frame;
 
-public class ProfinetDevices {
+public class DummyMessageWrapper implements MessageWrapper {
 
-    private final Map<String, ProfinetDevice> configuredDevices;
-
-    public ProfinetDevices(Map<String, ProfinetDevice> configuredDevices) {
-        this.configuredDevices = configuredDevices;
+    public void sendUdpMessage(ProfinetCallable<DceRpc_Packet> callable, ProfinetDeviceContext context) throws RuntimeException {
     }
 
-    public Map<String, ProfinetDevice> getConfiguredDevices() {
-        return this.configuredDevices;
+    public void sendPnioMessage(ProfinetCallable<Ethernet_Frame> callable, ProfinetDeviceContext context) throws RuntimeException {
     }
 
 }
diff --git a/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/DummyNetworkInterface.java b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/DummyNetworkInterface.java
new file mode 100644
index 0000000000..826cf8bd61
--- /dev/null
+++ b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/DummyNetworkInterface.java
@@ -0,0 +1,63 @@
+/*
+ * 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.profinet;
+
+import org.apache.plc4x.java.profinet.device.NetworkInterface;
+
+public class DummyNetworkInterface implements NetworkInterface {
+
+    private String ipAddress;
+    private String subnet;
+    private String gateway;
+
+    public DummyNetworkInterface(String ipAddress, String subnet, String gateway) {
+        this.ipAddress = ipAddress;
+        this.subnet = subnet;
+        this.gateway = gateway;
+    }
+
+    @Override
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    @Override
+    public String getSubnet() {
+        return subnet;
+    }
+
+    @Override
+    public String getGateway() {
+        return gateway;
+    }
+
+    public byte[] getIpAddressAsByteArray() {
+        return null;
+    }
+
+    public byte[] getSubnetAsByteArray() {
+        return null;
+    }
+
+    public byte[] getGatewayAsByteArray() {
+        return null;
+    }
+
+}
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 8409ff9801..99d85b24eb 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
@@ -35,11 +35,11 @@ public class ManualProfinetIoTest {
     private static final Logger LOGGER = LoggerFactory.getLogger(ManualProfinetIoTest.class);
 
     public static void main(String[] args) throws Exception {
-        final PlcConnection connection = new DefaultPlcDriverManager().getConnection("profinet://192.168.90.1?gsddirectory=/Profinet/gsd&devices=[[test-device,MOD_1,(SUBMOD_1,SUBMOD_1,SUBMOD_1,)]]&reductionratio=16&sendclockfactor=32&dataholdfactor=3&watchdogfactor=2");
+        final PlcConnection connection = new DefaultPlcDriverManager().getConnection("profinet://192.168.54.2?gsddirectory=/home/missy/Documents/Profinet/gsd&devices=[[simocodexbpn156e,DAP%201,(1,),192.168.54.23]]&reductionratio=16&sendclockfactor=32&dataholdfactor=3&watchdogfactor=3");
         PlcBrowseRequest browseRequest = connection.browseRequestBuilder().addQuery("Browse", "").build();
         final PlcBrowseResponse browseResponse = browseRequest.execute().get();
         PlcSubscriptionRequest.Builder builder = connection.subscriptionRequestBuilder();
-        builder.addChangeOfStateTag("Input 4", ProfinetTag.of("test-device.1.1.SUBMOD.4:BOOL"));
+        builder.addChangeOfStateTag("Input 4", ProfinetTag.of("simocodexbpn156e.1.1.Inputs.2:BOOL"));
         PlcSubscriptionRequest request = builder.build();
 
         final PlcSubscriptionResponse response = request.execute().get();
diff --git a/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ProfinetBrowseTests.java b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ProfinetBrowseTests.java
index 55238b51d9..28228fe3cb 100644
--- a/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ProfinetBrowseTests.java
+++ b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ProfinetBrowseTests.java
@@ -20,7 +20,7 @@
 package org.apache.plc4x.java.profinet;
 
 import org.apache.plc4x.java.api.messages.PlcBrowseItem;
-import org.apache.plc4x.java.api.types.PlcValueType;
+import org.apache.plc4x.java.profinet.config.ConfigurationProfinetDevice;
 import org.apache.plc4x.java.profinet.config.ProfinetConfiguration;
 import org.apache.plc4x.java.profinet.device.ProfinetDevice;
 import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
@@ -42,7 +42,22 @@ public class ProfinetBrowseTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "gsddirectory=src/test/resources/&devices=[[device_name, PLC4X_1, (PLC4X_DUMMY_MODULE, , PLC4X_DUMMY_MODULE, )]]");
 
-        ProfinetDevice device = configuration.getDevices().getConfiguredDevices().get("DEVICE_NAME");
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
+
+        ProfinetDevice device = devices.get("DEVICE_NAME");
         device.setVendorDeviceId("CAFE", "0001");
 
         List<PlcBrowseItem> browseItems = new ArrayList<>();
@@ -55,7 +70,22 @@ public class ProfinetBrowseTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "gsddirectory=src/test/resources/&devices=[[device_name, PLC4X_1, (PLC4X_DUMMY_MODULE, , PLC4X_DUMMY_MODULE, )]]");
 
-        ProfinetDevice device = configuration.getDevices().getConfiguredDevices().get("DEVICE_NAME");
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
+
+        ProfinetDevice device = devices.get("DEVICE_NAME");
         device.setVendorDeviceId("CAFE", "0001");
 
         List<PlcBrowseItem> browseItems = new ArrayList<>();
@@ -70,7 +100,22 @@ public class ProfinetBrowseTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "gsddirectory=src/test/resources/&devices=[[device_name, PLC4X_1, (PLC4X_DUMMY_MODULE, , PLC4X_DUMMY_MODULE, )]]");
 
-        ProfinetDevice device = configuration.getDevices().getConfiguredDevices().get("DEVICE_NAME");
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
+
+        ProfinetDevice device = devices.get("DEVICE_NAME");
         device.setVendorDeviceId("CAFE", "0001");
 
         List<PlcBrowseItem> browseItems = new ArrayList<>();
diff --git a/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ProfinetDeviceContextTests.java b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ProfinetDeviceContextTests.java
index 623b0f8eba..4a4791a0df 100644
--- a/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ProfinetDeviceContextTests.java
+++ b/plc4j/drivers/profinet/src/test/java/org/apache/plc4x/java/profinet/ProfinetDeviceContextTests.java
@@ -19,6 +19,7 @@
 
 package org.apache.plc4x.java.profinet;
 
+import org.apache.plc4x.java.profinet.config.ConfigurationProfinetDevice;
 import org.apache.plc4x.java.profinet.config.ProfinetConfiguration;
 import org.apache.plc4x.java.profinet.device.ProfinetDevice;
 import org.apache.plc4x.java.profinet.device.ProfinetEmptyModule;
@@ -29,7 +30,9 @@ import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInstance;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
@@ -42,7 +45,22 @@ public class ProfinetDeviceContextTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "gsddirectory=src/test/resources/&devices=[[device_name_1, PLC4X_1, (PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE)]]");
 
-        ProfinetDevice device = configuration.getDevices().getConfiguredDevices().get("DEVICE_NAME_1");
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
+
+        ProfinetDevice device =devices.get("DEVICE_NAME_1");
         device.setVendorDeviceId("CAFE", "0001");
 
         ProfinetModule[] modules = device.getDeviceContext().getModules();
@@ -55,7 +73,22 @@ public class ProfinetDeviceContextTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "gsddirectory=src/test/resources/&devices=[[device_name_1, PLC4X_1, (PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE)]]");
 
-        ProfinetDevice device = configuration.getDevices().getConfiguredDevices().get("DEVICE_NAME_1");
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
+
+        ProfinetDevice device = devices.get("DEVICE_NAME_1");
         device.setVendorDeviceId("CAFE", "0001");
 
         ProfinetModule[] modules = device.getDeviceContext().getModules();
@@ -73,7 +106,22 @@ public class ProfinetDeviceContextTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "gsddirectory=src/test/resources/&devices=[[device_name_1, PLC4X_1, (PLC4X_DUMMY_MODULE, , PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE)]]");
 
-        ProfinetDevice device = configuration.getDevices().getConfiguredDevices().get("DEVICE_NAME_1");
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
+
+        ProfinetDevice device = devices.get("DEVICE_NAME_1");
         device.setVendorDeviceId("CAFE", "0001");
 
         ProfinetModule[] modules = device.getDeviceContext().getModules();
@@ -91,7 +139,22 @@ public class ProfinetDeviceContextTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "gsddirectory=src/test/resources/&devices=[[device_name_1, PLC4X_1, (PLC4X_DUMMY_MODULE, , PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE)]]");
 
-        ProfinetDevice device = configuration.getDevices().getConfiguredDevices().get("DEVICE_NAME_1");
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
+
+        ProfinetDevice device = devices.get("DEVICE_NAME_1");
         device.setVendorDeviceId("CAFE", "0001");
 
         List<PnIoCm_Block_ExpectedSubmoduleReq> moduleReq = device.getDeviceContext().getExpectedSubmoduleReq();
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..16321d3134 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
@@ -21,15 +21,24 @@ package org.apache.plc4x.java.profinet.gsdml;
 
 import com.fasterxml.jackson.dataformat.xml.XmlMapper;
 import org.apache.plc4x.java.api.exceptions.PlcException;
+import org.apache.plc4x.java.profinet.DummyMessageWrapper;
+import org.apache.plc4x.java.profinet.DummyNetworkInterface;
+import org.apache.plc4x.java.profinet.config.ConfigurationProfinetDevice;
 import org.apache.plc4x.java.profinet.config.ProfinetConfiguration;
-import org.apache.plc4x.java.profinet.context.ProfinetDriverContext;
-import org.apache.plc4x.java.profinet.device.ProfinetDevice;
-import org.apache.plc4x.java.profinet.protocol.ProfinetProtocolLogic;
+import org.apache.plc4x.java.profinet.device.*;
 import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInstance;
+import org.pcap4j.core.PcapNativeException;
+import org.pcap4j.core.PcapNetworkInterface;
+import org.pcap4j.core.Pcaps;
+import org.pcap4j.util.Inet4NetworkAddress;
 
 import java.io.File;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.HashMap;
 import java.util.Map;
 
 import static org.junit.jupiter.api.Assertions.*;
@@ -77,7 +86,7 @@ public class ProfinetConfigurationTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "devices=[[device_name_1, device_access_1, (submodule_1, submodule_2)]]&gsddirectory=src/test/resources");
 
-        Map<String, ProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ConfigurationProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
 
         for (String deviceName : deviceNames) {
             assert(devices.containsKey(deviceName));
@@ -91,7 +100,7 @@ public class ProfinetConfigurationTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "devices=[[device_name_1, PLC4X_1, (PLC4X_01,PLC4X_02,PLC4X_01,PLC4X_02)],[device_name_2, PLC4X_1, (PLC4X_01,PLC4X_02,PLC4X_01,PLC4X_02)],[device_name_3, PLC4X_1, (PLC4X_01,PLC4X_02,PLC4X_01,PLC4X_02)]]&gsddirectory=src/test/resources");
 
-        Map<String, ProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ConfigurationProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
 
         for (String deviceName : deviceNames) {
             assert(devices.containsKey(deviceName));
@@ -104,7 +113,7 @@ public class ProfinetConfigurationTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "devices=[[device_name_1, device_access_1, (submodule_1, submodule_2)]]&gsddirectory=src/test/resources");
 
-        Map<String, ProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ConfigurationProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
 
         for (String mac : deviceName) {
             assert(devices.containsKey(mac.replace(":", "").toUpperCase()));
@@ -116,7 +125,20 @@ public class ProfinetConfigurationTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "devices=[[device_name_1, PLC4X_1, (PLC4X_01, PLC4X_02, PLC4X_01, PLC4X_02)]]&gsddirectory=src/test/resources");
 
-        Map<String, ProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
 
         XmlMapper xmlMapper = new XmlMapper();
         assertThrows(PlcException.class, () -> devices.get("DEVICE_NAME_1").getDeviceContext().setGsdFile(xmlMapper.readValue(new File("src/test/resources/gsdml.xml"), ProfinetISO15745Profile.class)));
@@ -128,7 +150,20 @@ public class ProfinetConfigurationTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "devices=[[device_name_1, PLC4X_1, (PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE)]]&gsddirectory=src/test/resources");
 
-        Map<String, ProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
 
         XmlMapper xmlMapper = new XmlMapper();
         assertDoesNotThrow(() -> devices.get("DEVICE_NAME_1").getDeviceContext().setGsdFile(xmlMapper.readValue(new File("src/test/resources/gsdml.xml"), ProfinetISO15745Profile.class)));
@@ -139,7 +174,20 @@ public class ProfinetConfigurationTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "devices=[[device_name_1, PLC4X_1, (PLC4X_DUMMY_MODULE, PLC4X_dummy_MODULE, PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE)]]&gsddirectory=src/test/resources");
 
-        Map<String, ProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
 
         XmlMapper xmlMapper = new XmlMapper();
         assertDoesNotThrow(() -> devices.get("DEVICE_NAME_1").getDeviceContext().setGsdFile(xmlMapper.readValue(new File("src/test/resources/gsdml.xml"), ProfinetISO15745Profile.class)));
@@ -152,7 +200,20 @@ public class ProfinetConfigurationTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "devices=[[device_name_1, PLC4X 1, (PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE)]]&gsddirectory=src/test/resources");
 
-        Map<String, ProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
 
         for (String deviceName : deviceNames) {
             assert(devices.containsKey(deviceName));
@@ -167,7 +228,20 @@ public class ProfinetConfigurationTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "devices=[[device name 1, PLC4X 1, (PLC4X_DUMMY_MODULE, PLC4X_DUMMY_MODULE)]]&gsddirectory=src/test/resources");
 
-        Map<String, ProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
 
         for (String deviceName : deviceNames) {
             assert(devices.containsKey(deviceName));
@@ -181,7 +255,20 @@ public class ProfinetConfigurationTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "devices=[[device name 1, PLC4X 1, (PLC4X DUMMY MODULE, PLC4X DUMMY MODULE)]]&gsddirectory=src/test/resources");
 
-        Map<String, ProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
 
         for (String deviceName : deviceNames) {
             assert(devices.containsKey(deviceName));
@@ -197,7 +284,20 @@ public class ProfinetConfigurationTests {
         ProfinetConfiguration configuration = new ConfigurationFactory().createConfiguration(
             ProfinetConfiguration.class, "devices=[[device name 1, PLC4X 1, (PLC4X DUMMY MODULE, PLC4X DUMMY MODULE,,1)]]&gsddirectory=src/test/resources");
 
-        Map<String, ProfinetDevice> devices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
         XmlMapper xmlMapper = new XmlMapper();
 
         assertDoesNotThrow(() -> devices.get("DEVICE NAME 1").getDeviceContext().setGsdFile(xmlMapper.readValue(new File("src/test/resources/gsdml.xml"), ProfinetISO15745Profile.class)));
@@ -208,4 +308,58 @@ 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, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+        }
+
+        assertEquals(devices.get("DEVICE NAME 1").getDeviceContext().getIpAddress(), "10.1.1.1");
+    }
+
+    @Test
+    public void sendIPSetRequest() {
+        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");
+
+        NetworkInterface networkInterface = new DummyNetworkInterface("10.1.1.2", "255.255.255.0", "0.0.0.0");
+        Map<String, ConfigurationProfinetDevice> configuredDevices = configuration.getDevices().getConfiguredDevices();
+        Map<String, ProfinetDevice> devices = new HashMap<>();
+        MessageWrapper wrapper = new DummyMessageWrapper();
+
+        for (Map.Entry<String, ConfigurationProfinetDevice> entry : configuredDevices.entrySet()) {
+            devices.put(entry.getKey(),
+                new ProfinetDevice(
+                    new DummyMessageWrapper(),
+                    entry.getValue().getDevicename(),
+                    entry.getValue().getDeviceaccess(),
+                    entry.getValue().getSubmodules(),
+                    entry.getValue().getGsdHandler()
+                )
+            );
+            devices.get(entry.getValue().getDevicename()).setIpAddress(entry.getValue().getIpaddress());
+            devices.get(entry.getValue().getDevicename()).setNetworkInterface(networkInterface);
+        }
+
+    }
+
 }
diff --git a/protocols/profinet/src/main/resources/protocols/profinet/ethernet.mspec b/protocols/profinet/src/main/resources/protocols/profinet/ethernet.mspec
index 9e69be6dd4..03040f74d2 100644
--- a/protocols/profinet/src/main/resources/protocols/profinet/ethernet.mspec
+++ b/protocols/profinet/src/main/resources/protocols/profinet/ethernet.mspec
@@ -105,6 +105,12 @@
     [virtual  int 8 stringLength     'stringValue.length == -1 ? 0 : stringValue.length']
 ]
 
+[type PascalString16BitLength
+    [implicit int 16 sLength          'stringValue.length == 0 ? -1 : stringValue.length']
+    [simple vstring 'sLength == -1 ? 0 : sLength * 8' stringValue]
+    [virtual  int 16 stringLength     'stringValue.length == -1 ? 0 : stringValue.length']
+]
+
 [type Uuid
     [array byte data count '16']
 ]
diff --git a/protocols/profinet/src/main/resources/protocols/profinet/lldp.mspec b/protocols/profinet/src/main/resources/protocols/profinet/lldp.mspec
index f0bf82087d..1b4d0a6e6b 100644
--- a/protocols/profinet/src/main/resources/protocols/profinet/lldp.mspec
+++ b/protocols/profinet/src/main/resources/protocols/profinet/lldp.mspec
@@ -115,6 +115,7 @@
             [simple     uint 32                         remotePortRxDelay]
             [simple     uint 32                         localPortTxDelay]
             [simple     uint 32                         remotePortTxDelay]
+            [simple     uint 32                         portCableDelay]
         ]
         ['PORT_STATUS'  TlvProfibusSubTypePortStatus
             [simple     uint 16                         rtClass2PortStatus]
diff --git a/protocols/profinet/src/main/resources/protocols/profinet/pndcp.mspec b/protocols/profinet/src/main/resources/protocols/profinet/pndcp.mspec
index dbc515c62c..fa708d6999 100644
--- a/protocols/profinet/src/main/resources/protocols/profinet/pndcp.mspec
+++ b/protocols/profinet/src/main/resources/protocols/profinet/pndcp.mspec
@@ -51,6 +51,17 @@
             // which PLC4X will never be able to support
             [reserved uint 8                     '0x00'                   ] // transferStatus
         ]
+        ['DCP_GetSet_PDU' PcDcp_GetSet_Pdu
+            [const    uint 8      serviceId                    0x04                                ]
+            [reserved uint 5      '0x00'                                                           ]
+            [simple   bit         notSupported                                                     ]
+            [reserved uint 1      '0x00'                                                           ]
+            [simple   bit         response                                                         ]
+            [simple   uint 32     xid                                                              ]
+            [reserved uint 16      '0x0000'                                                        ]
+            [implicit uint 16     dcpDataLength                'lengthInBytes - 12'                ]
+            [array    PnDcp_Block blocks                        length              'dcpDataLength']
+        ]
         ['PTCP_DelayReqPDU' PcDcp_Pdu_DelayReq
             // Header Start
             [reserved uint 32 '0x00000000']
diff --git a/protocols/profinet/src/main/resources/protocols/profinet/pnio.mspec b/protocols/profinet/src/main/resources/protocols/profinet/pnio.mspec
index 0d0606a706..d693830581 100644
--- a/protocols/profinet/src/main/resources/protocols/profinet/pnio.mspec
+++ b/protocols/profinet/src/main/resources/protocols/profinet/pnio.mspec
@@ -292,7 +292,7 @@
             [implicit      uint 16          blockLength      'lengthInBytes - 4']
             [simple        uint 8           blockVersionHigh                    ]
             [simple        uint 8           blockVersionLow                     ]
-            [simple   PascalString                    stationName                                   ]
+            [simple   PascalString16BitLength            stationName            ]
             [padding  uint 8      pad '0x00'          '20 - 6 - (stationName.stringLength)'              ]
         ]
     ]
@@ -437,6 +437,7 @@
     ['0x03'     WAITAPPLRDY]
     ['0x04'     APPLRDY]
     ['0x05'     CYCLICDATA]
+    ['0x06'     SET_IP]
     ['0xFF'     ABORT]
 ]