You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2020/09/14 07:15:39 UTC

[plc4x] branch feature/plc4c updated (65ef1a6 -> 7991d4a)

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

cdutz pushed a change to branch feature/plc4c
in repository https://gitbox.apache.org/repos/asf/plc4x.git.


    from 65ef1a6  - Fixed issues with the Docker build
     add 9ba1e0d  PLC4X-243 Support for enum parameters in protocol test suites.
     add 0a76716  - Fixed issues with the Docker build
     add 09e5b99  - Increased the testsuite timeout to avoid randomly failing tests on the CI Server.
     add d83b8ff  - Made the transaction-id reset to 1 when reaching the 0xFFFF
     add 72cb97f  PLC4X-245 - [Modbus] Apache NiFi processor throws java.io.IOException after a while
     add a4f11e2  PLC4X-132 - [S7] Communication to S7 PLC dies in some situations
     add d709e0e  Updated the RELEASE_NOTES
     add c7e6e3c  PLC4X-246 - S7 driver hangs on read
     add 9aa5221  PLC4X-246 - S7 driver hangs on read
     add c4ef148  - Updated to the latest NiFi version - Added the EIP and ADS drivers to the NiFi NAR - Added documentation on the NiFi integration
     add cb981c8  Use Gradle with compiled library
     add f960160  Merge pull request #183 from foxpluto/develop
     add 777b6c2  PLC4X-244 Support for variable length padding fields.
     add fe8283a  - Renamed the needsPadding variable to "timesPadding" to sort of implicate it's no longer a boolean.
     add 1413ffd  Merge pull request #182 from apache/PLC4X-244
     add 22268c5  - Fixed a bug in the C code-generation
     add b93eb85  - Removed the description of serial transport on the Modbus page (for now) - Fixed some wrong documentation on the config arguments of the Modbus driver.
     add 487efce  - Made the KNX driver add "area" and "line" to the PlcStructs it produces. - Ensured the connection state timer is stopped if the connection dies.
     add 64057df  PLC4X-248 Permit more locations for MSpec comments.
     add bc60162  - Make the NiFi module forward the exceptions which actually are the cause of a ProcessingException.
     add f2828a5  - Updated the release documentation for the code-generation part ...
     add 2309ba0  - Fixed an issue when reading floats
     add 361bbb4  - Minor housekeeping in the parent pom.
     new 9927030  Merge branch 'develop' of https://gitbox.apache.org/repos/asf/plc4x into feature/plc4c
     new 7991d4a  - Working on the C S7 driver

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 RELEASE_NOTES                                      |   3 +
 .../resources/templates/c/pojo-template-c.ftlh     |  11 +-
 .../main/resources/templates/java/io-template.ftlh |   8 +-
 .../resources/templates/java/pojo-template.ftlh    |   3 +-
 .../plugins/codegenerator/language/mspec/MSpec.g4  |   6 +-
 .../src/test/resources/testsuite/AdsDriverIT.xml   | 218 ++++++++++++++++++++-
 .../eip/readwrite/protocol/EipProtocolLogic.java   |  41 ++--
 .../plc4x/java/knxnetip/ets5/Ets5Parser.java       |  21 +-
 .../plc4x/java/knxnetip/ets5/model/Ets5Model.java  |   8 +-
 .../knxnetip/protocol/KnxNetIpProtocolLogic.java   |  18 +-
 .../java/modbus/protocol/ModbusProtocolLogic.java  |   8 +
 .../s7/readwrite/protocol/S7ProtocolLogic.java     | 153 +++++++++------
 .../s7/src/test/resources/testsuite/S7DriverIT.xml |  75 +++++++
 .../apache-nifi/nifi-plc4x-nar/pom.xml             |  24 +--
 .../apache-nifi/nifi-plc4x-processors/pom.xml      |   6 +
 .../org/apache/plc4x/nifi/BasePlc4xProcessor.java  |  23 +--
 .../org/apache/plc4x/nifi/Plc4xSinkProcessor.java  |  50 ++---
 .../apache/plc4x/nifi/Plc4xSourceProcessor.java    |  63 +++---
 plc4j/integrations/apache-nifi/pom.xml             |   2 +-
 .../plc4x/java/spi/generation/ReadBuffer.java      |   8 +-
 .../plc4x/test/driver/DriverTestsuiteRunner.java   |  35 ++--
 .../plc4x/test/driver/model/DriverTestsuite.java   |  20 +-
 .../ParserSerializerTestsuiteRunner.java           |   2 +
 pom.xml                                            |  20 +-
 .../s7/src/main/resources/protocols/s7/s7.mspec    |   2 +-
 sandbox/plc4c/api/include/plc4c/connection.h       |  10 +-
 sandbox/plc4c/api/include/plc4c/types.h            |   1 +
 .../drivers/modbus/src/driver_modbus_packets.c     |   7 +-
 .../drivers/modbus/src/driver_modbus_sm_connect.c  |   1 +
 sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h |   4 +-
 sandbox/plc4c/drivers/s7/src/driver_s7.c           |  25 +++
 .../plc4c/drivers/s7/src/driver_s7_encode_decode.c |   5 +-
 sandbox/plc4c/drivers/s7/src/driver_s7_packets.c   |  35 +++-
 .../plc4c/drivers/s7/src/driver_s7_sm_connect.c    |  14 +-
 .../s7/src/s7_payload_user_data_item.c             |   4 +-
 .../s7/src/s7_var_payload_data_item.c              |  11 +-
 .../plc4c/spi/include/plc4c/spi/types_private.h    |  13 +-
 sandbox/plc4c/spi/src/connection.c                 |   5 +
 sandbox/plc4c/spi/src/system.c                     |  17 +-
 sandbox/plc4c/spi/src/utils/list.c                 |   2 +-
 .../plc4c/transports/serial/src/transport_serial.c |   3 +-
 .../transports/tcp/include/plc4c/transport_tcp.h   |   8 +
 sandbox/plc4c/transports/tcp/src/transport_tcp.c   | 103 +++++++++-
 src/site/asciidoc/developers/building.adoc         |  23 ++-
 .../developers/code-gen/protocol/mspec.adoc        |   6 +-
 .../asciidoc/developers/release/build-tools.adoc   |  36 ++--
 .../asciidoc/users/integrations/apache-nifi.adoc   | 135 +++++++++++++
 src/site/asciidoc/users/protocols/modbus.adoc      |  20 +-
 .../images/integrations/nifi/add-processor.png     | Bin 0 -> 25508 bytes
 .../nifi/configure-processor-properties.png        | Bin 0 -> 36219 bytes
 .../integrations/nifi/configure-scheduling.png     | Bin 0 -> 37276 bytes
 .../images/integrations/nifi/configured-flow.png   | Bin 0 -> 130333 bytes
 .../integrations/nifi/configured-log-processor.png | Bin 0 -> 54626 bytes
 .../nifi/configured-plc4x-source-processor.png     | Bin 0 -> 41203 bytes
 .../integrations/nifi/configuring-connection.png   | Bin 0 -> 39490 bytes
 .../images/integrations/nifi/empty-nifi-flow.png   | Bin 0 -> 74244 bytes
 .../integrations/nifi/list-of-plc4x-processors.png | Bin 0 -> 103175 bytes
 .../images/integrations/nifi/running-flow.png      | Bin 0 -> 59506 bytes
 src/site/site.xml                                  |   2 +-
 59 files changed, 1025 insertions(+), 293 deletions(-)
 create mode 100644 src/site/resources/images/integrations/nifi/add-processor.png
 create mode 100644 src/site/resources/images/integrations/nifi/configure-processor-properties.png
 create mode 100644 src/site/resources/images/integrations/nifi/configure-scheduling.png
 create mode 100644 src/site/resources/images/integrations/nifi/configured-flow.png
 create mode 100644 src/site/resources/images/integrations/nifi/configured-log-processor.png
 create mode 100644 src/site/resources/images/integrations/nifi/configured-plc4x-source-processor.png
 create mode 100644 src/site/resources/images/integrations/nifi/configuring-connection.png
 create mode 100644 src/site/resources/images/integrations/nifi/empty-nifi-flow.png
 create mode 100644 src/site/resources/images/integrations/nifi/list-of-plc4x-processors.png
 create mode 100644 src/site/resources/images/integrations/nifi/running-flow.png


[plc4x] 01/02: Merge branch 'develop' of https://gitbox.apache.org/repos/asf/plc4x into feature/plc4c

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch feature/plc4c
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 99270302387e2eaa06ebf836fe51ebf67a34cb5c
Merge: 65ef1a6 361bbb4
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Thu Sep 10 10:53:38 2020 +0200

    Merge branch 'develop' of https://gitbox.apache.org/repos/asf/plc4x into feature/plc4c

 RELEASE_NOTES                                      |   3 +
 .../resources/templates/c/pojo-template-c.ftlh     |  11 +-
 .../main/resources/templates/java/io-template.ftlh |   8 +-
 .../resources/templates/java/pojo-template.ftlh    |   3 +-
 .../plugins/codegenerator/language/mspec/MSpec.g4  |   6 +-
 .../src/test/resources/testsuite/AdsDriverIT.xml   | 218 ++++++++++++++++++++-
 .../eip/readwrite/protocol/EipProtocolLogic.java   |  41 ++--
 .../plc4x/java/knxnetip/ets5/Ets5Parser.java       |  21 +-
 .../plc4x/java/knxnetip/ets5/model/Ets5Model.java  |   8 +-
 .../knxnetip/protocol/KnxNetIpProtocolLogic.java   |  18 +-
 .../java/modbus/protocol/ModbusProtocolLogic.java  |   8 +
 .../s7/readwrite/protocol/S7ProtocolLogic.java     | 140 ++++++++-----
 .../s7/src/test/resources/testsuite/S7DriverIT.xml |  75 +++++++
 .../apache-nifi/nifi-plc4x-nar/pom.xml             |  24 +--
 .../apache-nifi/nifi-plc4x-processors/pom.xml      |   6 +
 .../org/apache/plc4x/nifi/BasePlc4xProcessor.java  |  23 +--
 .../org/apache/plc4x/nifi/Plc4xSinkProcessor.java  |  50 ++---
 .../apache/plc4x/nifi/Plc4xSourceProcessor.java    |  63 +++---
 plc4j/integrations/apache-nifi/pom.xml             |   2 +-
 .../plc4x/java/spi/generation/ReadBuffer.java      |   8 +-
 .../plc4x/test/driver/DriverTestsuiteRunner.java   |  35 ++--
 .../plc4x/test/driver/model/DriverTestsuite.java   |  20 +-
 .../ParserSerializerTestsuiteRunner.java           |   2 +
 pom.xml                                            |  20 +-
 .../s7/src/main/resources/protocols/s7/s7.mspec    |   2 +-
 .../s7/src/s7_var_payload_data_item.c              |  11 +-
 src/site/asciidoc/developers/building.adoc         |  23 ++-
 .../developers/code-gen/protocol/mspec.adoc        |   6 +-
 .../asciidoc/developers/release/build-tools.adoc   |  36 ++--
 .../asciidoc/users/integrations/apache-nifi.adoc   | 135 +++++++++++++
 src/site/asciidoc/users/protocols/modbus.adoc      |  20 +-
 .../images/integrations/nifi/add-processor.png     | Bin 0 -> 25508 bytes
 .../nifi/configure-processor-properties.png        | Bin 0 -> 36219 bytes
 .../integrations/nifi/configure-scheduling.png     | Bin 0 -> 37276 bytes
 .../images/integrations/nifi/configured-flow.png   | Bin 0 -> 130333 bytes
 .../integrations/nifi/configured-log-processor.png | Bin 0 -> 54626 bytes
 .../nifi/configured-plc4x-source-processor.png     | Bin 0 -> 41203 bytes
 .../integrations/nifi/configuring-connection.png   | Bin 0 -> 39490 bytes
 .../images/integrations/nifi/empty-nifi-flow.png   | Bin 0 -> 74244 bytes
 .../integrations/nifi/list-of-plc4x-processors.png | Bin 0 -> 103175 bytes
 .../images/integrations/nifi/running-flow.png      | Bin 0 -> 59506 bytes
 src/site/site.xml                                  |   2 +-
 42 files changed, 785 insertions(+), 263 deletions(-)



[plc4x] 02/02: - Working on the C S7 driver

Posted by cd...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch feature/plc4c
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 7991d4a8cab84fead0e4902fe1ce8acd099a5b4c
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon Sep 14 09:15:30 2020 +0200

    - Working on the C S7 driver
---
 .../s7/readwrite/protocol/S7ProtocolLogic.java     |  13 ++-
 sandbox/plc4c/api/include/plc4c/connection.h       |  10 +-
 sandbox/plc4c/api/include/plc4c/types.h            |   1 +
 .../drivers/modbus/src/driver_modbus_packets.c     |   7 +-
 .../drivers/modbus/src/driver_modbus_sm_connect.c  |   1 +
 sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h |   4 +-
 sandbox/plc4c/drivers/s7/src/driver_s7.c           |  25 +++++
 .../plc4c/drivers/s7/src/driver_s7_encode_decode.c |   5 +-
 sandbox/plc4c/drivers/s7/src/driver_s7_packets.c   |  35 +++++--
 .../plc4c/drivers/s7/src/driver_s7_sm_connect.c    |  14 ++-
 .../s7/src/s7_payload_user_data_item.c             |   4 +-
 .../plc4c/spi/include/plc4c/spi/types_private.h    |  13 ++-
 sandbox/plc4c/spi/src/connection.c                 |   5 +
 sandbox/plc4c/spi/src/system.c                     |  17 +++-
 sandbox/plc4c/spi/src/utils/list.c                 |   2 +-
 .../plc4c/transports/serial/src/transport_serial.c |   3 +-
 .../transports/tcp/include/plc4c/transport_tcp.h   |   8 ++
 sandbox/plc4c/transports/tcp/src/transport_tcp.c   | 103 ++++++++++++++++++++-
 18 files changed, 240 insertions(+), 30 deletions(-)

diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
index e0d5b0d..0b6e4ec 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
@@ -297,11 +297,14 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
     }
 
     private TPKTPacket createIdentifyRemoteMessage() {
-        S7MessageUserData identifyRemoteMessage = new S7MessageUserData(1, new S7ParameterUserData(new S7ParameterUserDataItem[]{
-            new S7ParameterUserDataItemCPUFunctions((short) 0x11, (byte) 0x4, (byte) 0x4, (short) 0x01, (short) 0x00, null, null, null)
-        }), new S7PayloadUserData(new S7PayloadUserDataItem[]{
-            new S7PayloadUserDataItemCpuFunctionReadSzlRequest(DataTransportErrorCode.OK, DataTransportSize.OCTET_STRING, new SzlId(SzlModuleTypeClass.CPU, (byte) 0x00, SzlSublist.MODULE_IDENTIFICATION), 0x0000)
-        }));
+        S7MessageUserData identifyRemoteMessage = new S7MessageUserData(1,
+            new S7ParameterUserData(new S7ParameterUserDataItem[]{
+                new S7ParameterUserDataItemCPUFunctions((short) 0x11, (byte) 0x4, (byte) 0x4, (short) 0x01, (short) 0x00, null, null, null)
+            }),
+            new S7PayloadUserData(new S7PayloadUserDataItem[]{
+                new S7PayloadUserDataItemCpuFunctionReadSzlRequest(DataTransportErrorCode.OK, DataTransportSize.OCTET_STRING, new SzlId(SzlModuleTypeClass.CPU, (byte) 0x00, SzlSublist.MODULE_IDENTIFICATION), 0x0000)
+            })
+        );
         COTPPacketData cotpPacketData = new COTPPacketData(null, identifyRemoteMessage, true, (short) 2);
         return new TPKTPacket(cotpPacketData);
     }
diff --git a/sandbox/plc4c/api/include/plc4c/connection.h b/sandbox/plc4c/api/include/plc4c/connection.h
index c1e8e47..2818add 100644
--- a/sandbox/plc4c/api/include/plc4c/connection.h
+++ b/sandbox/plc4c/api/include/plc4c/connection.h
@@ -186,12 +186,20 @@ plc4c_driver *plc4c_connection_get_driver(plc4c_connection *connection);
 /**
  * Sets a plc4c_driver for a given connection
  * @param connection plc4c_connection
- * @param plc4c_driver
+ * @param plc4c_driver driver
  */
 void plc4c_connection_set_driver(plc4c_connection *connection,
                                  plc4c_driver *driver);
 
 /**
+ * Sets the configuration for a given connection.
+ *
+ * @param connection plc4c connection
+ * @param configuration configuration
+ */
+void plc4c_connection_set_configuration(plc4c_connection *connection,
+                                        void *configuration);
+/**
  * Check if an error occurred while connecting.
  *
  * @param connection the connection.
diff --git a/sandbox/plc4c/api/include/plc4c/types.h b/sandbox/plc4c/api/include/plc4c/types.h
index e364753..cc2157f 100644
--- a/sandbox/plc4c/api/include/plc4c/types.h
+++ b/sandbox/plc4c/api/include/plc4c/types.h
@@ -54,6 +54,7 @@ typedef enum plc4c_return_code {
   PARSE_ERROR,
 
   UNKNOWN_ERROR,
+  CONNECTION_ERROR,
   INTERNAL_ERROR,
   NOT_IMPLEMENTED
 } plc4c_return_code;
diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus_packets.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus_packets.c
index 54ce4cc..af50cbe 100644
--- a/sandbox/plc4c/drivers/modbus/src/driver_modbus_packets.c
+++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus_packets.c
@@ -68,7 +68,8 @@ plc4c_return_code plc4c_driver_modbus_send_packet(plc4c_connection* connection,
   plc4c_modbus_read_write_modbus_tcp_adu_serialize(write_buffer, packet);
 
   // Now send this to the recipient.
-  return_code = connection->transport->send_message(write_buffer);
+  return_code = connection->transport->send_message(
+      connection->transport_configuration, write_buffer);
   if (return_code != OK) {
     return return_code;
   }
@@ -82,7 +83,9 @@ plc4c_return_code plc4c_driver_modbus_receive_packet(plc4c_connection* connectio
   // If it is, get a read_buffer for reading it.
   plc4c_spi_read_buffer* read_buffer;
   plc4c_return_code return_code = connection->transport->select_message(
-      plc4c_driver_modbus_select_message_function, &read_buffer);
+      connection->transport_configuration,
+      6, plc4c_driver_modbus_select_message_function,
+      &read_buffer);
   // OK is only returned if a packet is available.
   if (return_code != OK) {
     return return_code;
diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_connect.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_connect.c
index 9ecbb66..a093567 100644
--- a/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_connect.c
+++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_connect.c
@@ -37,6 +37,7 @@ plc4c_return_code plc4c_driver_modbus_connect_machine_function(
 
 plc4c_return_code plc4c_driver_modbus_connect_function(
     plc4c_connection *connection, plc4c_system_task **task) {
+
   plc4c_system_task *new_task = malloc(sizeof(plc4c_system_task));
   // There's nothing to do here, so no need for a state-machine.
   new_task->state_id = -1;
diff --git a/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h
index 78bd46d..a0cb706 100644
--- a/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h
+++ b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h
@@ -25,6 +25,8 @@ extern "C" {
 #include <plc4c/types.h>
 #include <stdint.h>
 
+#include "../../../../generated-sources/s7/includes/cotp_tpdu_size.h"
+
 enum plc4c_driver_s7_controller_type {
   PLC4C_DRIVER_S7_CONTROLLER_TYPE_ANY = 0,
   PLC4C_DRIVER_S7_CONTROLLER_TYPE_S7_300 = 1,
@@ -49,7 +51,7 @@ struct plc4c_driver_s7_config {
   uint8_t remote_slot;
   uint16_t calling_tsap_id;
   uint16_t called_tsap_id;
-  uint16_t cotp_tpdu_size;
+  plc4c_s7_read_write_cotp_tpdu_size cotp_tpdu_size;
   uint16_t pdu_size;
   uint8_t max_amq_caller;
   uint8_t max_amq_callee;
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7.c b/sandbox/plc4c/drivers/s7/src/driver_s7.c
index d4f9862..2fe21e2 100644
--- a/sandbox/plc4c/drivers/s7/src/driver_s7.c
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7.c
@@ -17,14 +17,39 @@
   under the License.
 */
 
+#include "plc4c/driver_s7.h"
 #include "plc4c/driver_s7_sm.h"
 
+plc4c_return_code plc4c_driver_s7_configure_function(
+    plc4c_list* parameters, void** configuration) {
+  plc4c_driver_s7_config* s7_config = malloc(sizeof(plc4c_driver_s7_config));
+  if(s7_config == NULL) {
+    return NO_MEMORY;
+  }
+
+  // Initialize the parts that the user can influence.
+  s7_config->local_rack = 1;
+  s7_config->local_slot = 1;
+  s7_config->remote_rack = 0;
+  s7_config->remote_slot = 0;
+  s7_config->pdu_size = 1024;
+  s7_config->max_amq_caller = 8;
+  s7_config->max_amq_callee = 8;
+  s7_config->controller_type = PLC4C_DRIVER_S7_CONTROLLER_TYPE_ANY;
+
+  // TODO: Apply the values from the parameters.
+
+  *configuration = s7_config;
+  return OK;
+}
+
 plc4c_driver* plc4c_driver_s7_create() {
   plc4c_driver* driver = (plc4c_driver*)malloc(sizeof(plc4c_driver));
   driver->protocol_code = "s7";
   driver->protocol_name = "Siemens S7 (Basic)";
   driver->default_transport_code = "tcp";
   driver->parse_address_function = NULL;
+  driver->configure_function = &plc4c_driver_s7_configure_function;
   driver->connect_function = &plc4c_driver_s7_connect_function;
   driver->disconnect_function = &plc4c_driver_s7_disconnect_function;
   driver->read_function = &plc4c_driver_s7_read_function;
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7_encode_decode.c b/sandbox/plc4c/drivers/s7/src/driver_s7_encode_decode.c
index 95a4880..27972ea 100644
--- a/sandbox/plc4c/drivers/s7/src/driver_s7_encode_decode.c
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7_encode_decode.c
@@ -35,9 +35,10 @@ uint16_t plc4c_driver_s7_encode_tsap_id(
 uint16_t plc4c_driver_s7_get_nearest_matching_tpdu_size(uint16_t pdu_size) {
   for (int i = 0; i < plc4c_s7_read_write_cotp_tpdu_size_num_values(); i++) {
     uint16_t cur_value =
-        plc4c_s7_read_write_cotp_tpdu_size_get_size_in_bytes(i);
+        plc4c_s7_read_write_cotp_tpdu_size_get_size_in_bytes(
+            plc4c_s7_read_write_cotp_tpdu_size_value_for_index(i));
     if (cur_value >= pdu_size) {
-      return cur_value;
+      return plc4c_s7_read_write_cotp_tpdu_size_value_for_index(i);
     }
   }
   return 0;
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7_packets.c b/sandbox/plc4c/drivers/s7/src/driver_s7_packets.c
index c79a053..2fb06c5 100644
--- a/sandbox/plc4c/drivers/s7/src/driver_s7_packets.c
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7_packets.c
@@ -62,8 +62,8 @@ int16_t plc4c_driver_s7_select_message_function(uint8_t* buffer_data,
   // The length information is located in bytes 3 and 4
   if (buffer_length >= 4) {
     uint16_t packet_length =
-        ((uint16_t) (buffer_data + 2) << 8) |
-        ((uint16_t) (buffer_data + 3));
+        ((uint16_t) *(buffer_data + 2) << 8) |
+        ((uint16_t) *(buffer_data + 3));
     if (buffer_length >= packet_length) {
       return packet_length;
     }
@@ -79,6 +79,7 @@ int16_t plc4c_driver_s7_select_message_function(uint8_t* buffer_data,
       }
       return -(buffer_length - 1);
     }
+    return packet_length;
   }
   // In all other cases, we'll just have to wait for the next time.
   return 0;
@@ -97,10 +98,13 @@ plc4c_return_code plc4c_driver_s7_send_packet(plc4c_connection* connection,
   if (return_code != OK) {
     return return_code;
   }
-  plc4c_s7_read_write_tpkt_packet_serialize(write_buffer, packet);
+  return_code = plc4c_s7_read_write_tpkt_packet_serialize(write_buffer, packet);
+  if(return_code != OK) {
+    return return_code;
+  }
 
   // Now send this to the recipient.
-  return_code = connection->transport->send_message(write_buffer);
+  return_code = connection->transport->send_message(connection->transport_configuration, write_buffer);
   if (return_code != OK) {
     return return_code;
   }
@@ -114,7 +118,9 @@ plc4c_return_code plc4c_driver_s7_receive_packet(plc4c_connection* connection,
   // If it is, get a read_buffer for reading it.
   plc4c_spi_read_buffer* read_buffer;
   plc4c_return_code return_code = connection->transport->select_message(
-      plc4c_driver_s7_select_message_function, &read_buffer);
+      connection->transport_configuration,
+      4, plc4c_driver_s7_select_message_function,
+      &read_buffer);
   // OK is only returned if a packet is available.
   if (return_code != OK) {
     return return_code;
@@ -295,18 +301,19 @@ plc4c_return_code plc4c_driver_s7_create_s7_identify_remote_request(
   }
   (*s7_identify_remote_request_packet)->payload->payload->_type =
       plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_user_data;
+
+  // Create a Parameter
   (*s7_identify_remote_request_packet)->payload->payload->parameter =
       malloc(sizeof(plc4c_s7_read_write_s7_parameter));
-  if ((*s7_identify_remote_request_packet)->payload->payload->parameter ==
-      NULL) {
+  if ((*s7_identify_remote_request_packet)->payload->payload->parameter == NULL) {
     return NO_MEMORY;
   }
   (*s7_identify_remote_request_packet)->payload->payload->parameter->_type =
       plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_user_data;
-
   plc4c_utils_list_create(
       &((*s7_identify_remote_request_packet)
             ->payload->payload->parameter->s7_parameter_user_data_items));
+  // Create the Parameter Item
   plc4c_s7_read_write_s7_parameter_user_data_item* parameter_item =
       malloc(sizeof(plc4c_s7_read_write_s7_parameter_user_data_item));
   parameter_item->_type =
@@ -331,9 +338,17 @@ plc4c_return_code plc4c_driver_s7_create_s7_identify_remote_request(
           ->payload->payload->parameter->s7_parameter_user_data_items,
       parameter_item);
 
+  // Create the Payload
+  (*s7_identify_remote_request_packet)->payload->payload->payload = malloc(sizeof(plc4c_s7_read_write_s7_payload));
+  if ((*s7_identify_remote_request_packet)->payload->payload->parameter == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_identify_remote_request_packet)->payload->payload->payload->_type =
+      plc4c_s7_read_write_s7_payload_type_plc4c_s7_read_write_s7_payload_user_data;
   plc4c_utils_list_create(
       &((*s7_identify_remote_request_packet)
             ->payload->payload->payload->s7_payload_user_data_items));
+  // Create the Payload Item
   plc4c_s7_read_write_s7_payload_user_data_item* payload_item =
       malloc(sizeof(plc4c_s7_read_write_s7_payload_user_data_item));
   payload_item->_type =
@@ -351,6 +366,10 @@ plc4c_return_code plc4c_driver_s7_create_s7_identify_remote_request(
   payload_item->szl_id->sublist_extract = 0x00;
   payload_item->szl_id->sublist_list =
       plc4c_s7_read_write_szl_sublist_MODULE_IDENTIFICATION;
+  plc4c_utils_list_insert_head_value(
+      (*s7_identify_remote_request_packet)
+          ->payload->payload->payload->s7_payload_user_data_items,
+      payload_item);
 
   return OK;
 }
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7_sm_connect.c b/sandbox/plc4c/drivers/s7/src/driver_s7_sm_connect.c
index eb53967..a54c6e8 100644
--- a/sandbox/plc4c/drivers/s7/src/driver_s7_sm_connect.c
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7_sm_connect.c
@@ -30,6 +30,7 @@
 
 enum plc4c_driver_s7_connect_states {
   PLC4C_DRIVER_S7_CONNECT_INIT,
+  PLC4C_DRIVER_S7_CONNECT_TRANSPORT_CONNECT,
   PLC4C_DRIVER_S7_CONNECT_SEND_COTP_CONNECT_REQUEST,
   PLC4C_DRIVER_S7_CONNECT_RECEIVE_COTP_CONNECT_RESPONSE,
   PLC4C_DRIVER_S7_CONNECT_SEND_S7_CONNECT_REQUEST,
@@ -75,6 +76,15 @@ plc4c_return_code plc4c_driver_s7_connect_machine_function(
               configuration->pdu_size);
       configuration->pdu_size = configuration->cotp_tpdu_size - 16;
 
+      task->state_id = PLC4C_DRIVER_S7_CONNECT_TRANSPORT_CONNECT;
+      break;
+    }
+    case PLC4C_DRIVER_S7_CONNECT_TRANSPORT_CONNECT: {
+      plc4c_return_code return_code = connection->transport->open(connection->transport_configuration);
+      if(return_code != OK) {
+        return return_code;
+      }
+
       task->state_id = PLC4C_DRIVER_S7_CONNECT_SEND_COTP_CONNECT_REQUEST;
       break;
     }
@@ -192,7 +202,7 @@ plc4c_return_code plc4c_driver_s7_connect_machine_function(
         return INTERNAL_ERROR;
       }
       if (s7_connect_response_packet->payload->payload->_type !=
-          plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_response) {
+          plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_response_data) {
         return INTERNAL_ERROR;
       }
       if (s7_connect_response_packet->payload->payload->parameter->_type !=
@@ -213,7 +223,7 @@ plc4c_return_code plc4c_driver_s7_connect_machine_function(
               ->s7_parameter_setup_communication_max_amq_callee;
 
       // If no controller is explicitly selected, detect it.
-      if (configuration->controller_type !=
+      if (configuration->controller_type ==
           PLC4C_DRIVER_S7_CONTROLLER_TYPE_ANY) {
         task->state_id = PLC4C_DRIVER_S7_CONNECT_SEND_S7_IDENTIFICATION_REQUEST;
       }
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c b/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c
index ca75fb1..9ff710a 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c
@@ -120,7 +120,7 @@ plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_parse(plc4c_spi_
     }
 
 
-                    
+
     // Implicit Field (szlItemCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint16_t szlItemCount = 0;
     _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &szlItemCount);
@@ -141,7 +141,7 @@ plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_parse(plc4c_spi_
       uint8_t itemCount = szlItemCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         bool lastItem = curItem == (itemCount - 1);
-                          plc4c_list* _value = NULL;
+        plc4c_list* _value = NULL;
         _res = plc4c_s7_read_write_szl_data_tree_item_parse(buf, (void*) &_value);
         if(_res != OK) {
           return _res;
diff --git a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
index af4a762..b2cb006 100644
--- a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
+++ b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
@@ -38,6 +38,9 @@ typedef struct plc4c_response_item_t plc4c_response_item;
 typedef struct plc4c_response_subscription_item_t plc4c_response_subscription_item;
 typedef struct plc4c_response_unsubscription_item_t plc4c_response_unsubscription_item;
 
+typedef plc4c_return_code *(*plc4c_connection_configure_function)(
+    plc4c_list* parameters, void** configuration);
+
 typedef plc4c_item *(*plc4c_connection_parse_address_item)(
     char *address_string);
 
@@ -83,6 +86,9 @@ typedef void (*plc4c_connect_free_subscription_response_function)(
 typedef void (*plc4c_connect_free_unsubscription_response_function)(
     plc4c_unsubscription_response *response);
 
+typedef plc4c_return_code (*plc4c_transport_configure_function)(
+    plc4c_list* parameters, void** configuration);
+
 // TODO: Implement the argument.
 typedef plc4c_return_code (*plc4c_transport_open_function)(void* config);
 
@@ -90,7 +96,7 @@ typedef plc4c_return_code (*plc4c_transport_open_function)(void* config);
 typedef plc4c_return_code (*plc4c_transport_close_function)(void* config);
 
 typedef plc4c_return_code (*plc4c_transport_send_message_function)(
-    plc4c_spi_write_buffer* message);
+    void* transport_configuration, plc4c_spi_write_buffer* message);
 
 // Helper function that tells the transport what to do with the current input
 // on positive return value: a read-buffer with given number of bytes is
@@ -104,7 +110,7 @@ typedef int16_t (*accept_message_function)(
     uint8_t* data, uint16_t length);
 
 typedef plc4c_return_code (*plc4c_transport_select_message_function)(
-    accept_message_function accept_message, plc4c_spi_read_buffer** message);
+    void* transport_configuration, uint8_t min_size, accept_message_function accept_message, plc4c_spi_read_buffer** message);
 
 struct plc4c_system_t {
   /* drivers */
@@ -137,6 +143,7 @@ struct plc4c_driver_t {
   char *protocol_code;
   char *protocol_name;
   char *default_transport_code;
+  plc4c_connection_configure_function configure_function;
   plc4c_connection_parse_address_item parse_address_function;
   plc4c_connection_connect_function connect_function;
   plc4c_connection_disconnect_function disconnect_function;
@@ -164,6 +171,7 @@ struct plc4c_transport_t {
   char *transport_code;
   char* transport_name;
 
+  plc4c_transport_configure_function configure;
   plc4c_transport_open_function open;
   plc4c_transport_close_function close;
   plc4c_transport_send_message_function send_message;
@@ -183,6 +191,7 @@ struct plc4c_connection_t {
   char *protocol_code;
   char *transport_code;
   char *transport_connect_information;
+  void *transport_configuration;
   char *parameters;
   void *configuration;
 
diff --git a/sandbox/plc4c/spi/src/connection.c b/sandbox/plc4c/spi/src/connection.c
index f3a1a53..370cefa 100644
--- a/sandbox/plc4c/spi/src/connection.c
+++ b/sandbox/plc4c/spi/src/connection.c
@@ -154,6 +154,11 @@ void plc4c_connection_set_driver(plc4c_connection *connection,
   connection->driver = driver;
 }
 
+void plc4c_connection_set_configuration(plc4c_connection *connection,
+                                        void *configuration) {
+  connection->configuration = configuration;
+}
+
 bool plc4c_connection_has_error(plc4c_connection *connection) { return false; }
 
 plc4c_return_code plc4c_connection_disconnect(plc4c_connection *connection) {
diff --git a/sandbox/plc4c/spi/src/system.c b/sandbox/plc4c/spi/src/system.c
index 3d8a147..c4744c4 100644
--- a/sandbox/plc4c/spi/src/system.c
+++ b/sandbox/plc4c/spi/src/system.c
@@ -435,9 +435,22 @@ plc4c_return_code plc4c_system_connect(plc4c_system *system,
   // Initialize a new connection task and schedule that.
   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
+  plc4c_driver* driver = plc4c_connection_get_driver(new_connection);
+
+  // Configure the driver configuration first.
+  void* configuration = NULL;
+  // TODO: Pass in the configuration options ...
+  driver->configure_function(NULL, &configuration);
+  plc4c_connection_set_configuration(new_connection, configuration);
+
+  // TODO: Somehow let the driver inject default values which the transport can then pickup ...
+
+  // Prepare a configuration data structure for the current transport.
+  new_connection->transport->configure(NULL, &new_connection->transport_configuration);
+
+  // Create a new connection task.
   plc4c_system_task *new_connection_task = NULL;
-  result = plc4c_connection_get_driver(new_connection)
-               ->connect_function(new_connection, &new_connection_task);
+  result = driver->connect_function(new_connection, &new_connection_task);
   if (result != OK) {
     return -1;
   }
diff --git a/sandbox/plc4c/spi/src/utils/list.c b/sandbox/plc4c/spi/src/utils/list.c
index 5d81dbb..f6ceab7 100644
--- a/sandbox/plc4c/spi/src/utils/list.c
+++ b/sandbox/plc4c/spi/src/utils/list.c
@@ -28,7 +28,7 @@ void plc4c_utils_list_create(plc4c_list **list) {
 }
 
 size_t plc4c_utils_list_size(plc4c_list *list) {
-  if (list->tail == NULL) {
+  if ((list == NULL) || (list->tail == NULL)) {
     return 0;
   }
   plc4c_list_element *cur_element = list->tail;
diff --git a/sandbox/plc4c/transports/serial/src/transport_serial.c b/sandbox/plc4c/transports/serial/src/transport_serial.c
index 38222ef..2b1d073 100644
--- a/sandbox/plc4c/transports/serial/src/transport_serial.c
+++ b/sandbox/plc4c/transports/serial/src/transport_serial.c
@@ -35,7 +35,8 @@ plc4c_return_code plc4c_transport_serial_send_message_function(
 }
 
 plc4c_return_code plc4c_transport_serial_select_message_function(
-    accept_message_function accept_message, plc4c_spi_read_buffer** message) {
+    void* transport_configuration, accept_message_function accept_message,
+    plc4c_spi_read_buffer** message) {
   return OK;
 }
 
diff --git a/sandbox/plc4c/transports/tcp/include/plc4c/transport_tcp.h b/sandbox/plc4c/transports/tcp/include/plc4c/transport_tcp.h
index fb57734..18998b1 100644
--- a/sandbox/plc4c/transports/tcp/include/plc4c/transport_tcp.h
+++ b/sandbox/plc4c/transports/tcp/include/plc4c/transport_tcp.h
@@ -24,6 +24,14 @@ extern "C" {
 
 #include <plc4c/types.h>
 
+struct plc4c_transport_tcp_config {
+  char* address;
+  uint16_t port;
+
+  int sockfd;
+};
+typedef struct plc4c_transport_tcp_config plc4c_transport_tcp_config;
+
 plc4c_transport *plc4c_transport_tcp_create();
 
 #ifdef __cplusplus
diff --git a/sandbox/plc4c/transports/tcp/src/transport_tcp.c b/sandbox/plc4c/transports/tcp/src/transport_tcp.c
index 3d049cc..0bc0a79 100644
--- a/sandbox/plc4c/transports/tcp/src/transport_tcp.c
+++ b/sandbox/plc4c/transports/tcp/src/transport_tcp.c
@@ -20,22 +20,122 @@
 #include <plc4c/spi/types_private.h>
 #include <plc4c/transport_tcp.h>
 #include <stdlib.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <errno.h>
+
+extern int errno;
+
+plc4c_return_code plc4c_transport_tcp_configure_function(
+    plc4c_list* parameters, void** configuration) {
+  plc4c_transport_tcp_config* tcp_configuration = malloc(sizeof(plc4c_transport_tcp_config));
+  if(tcp_configuration == NULL) {
+    return NO_MEMORY;
+  }
+  // TODO: Implement this ...
+  tcp_configuration->address = "192.168.23.30";
+  tcp_configuration->port = 102;
+
+  *configuration = tcp_configuration;
+  return OK;
+}
 
 plc4c_return_code plc4c_transport_tcp_open_function(void* config) {
+  int sockfd;
+  int connfd;
+  struct sockaddr_in servaddr;
+
+  plc4c_transport_tcp_config* tcp_config = config;
+
+  tcp_config->sockfd = socket(AF_INET, SOCK_STREAM, 0);
+  if (tcp_config->sockfd < 0) {
+    return CONNECTION_ERROR;
+  }
+
+  // Configure where to connect to.
+  bzero(&servaddr, sizeof(struct sockaddr_in));
+  servaddr.sin_family = AF_INET;
+  servaddr.sin_addr.s_addr = inet_addr(tcp_config->address);
+  servaddr.sin_port = htons(tcp_config->port);
+
+  int result = connect(tcp_config->sockfd, (struct sockaddr*) &servaddr,
+                       sizeof(servaddr));
+  if(result != 0) {
+    char* error_msg = strerror(errno);
+    printf(error_msg);
+    return CONNECTION_ERROR;
+  }
   return OK;
 }
 
 plc4c_return_code plc4c_transport_tcp_close_function(void* config) {
+  plc4c_transport_tcp_config* tcp_config = config;
+
+  // If the sockfd is zero we're not really connected.
+  if(tcp_config->sockfd == 0) {
+    return INTERNAL_ERROR;
+  }
+
+  // Stop receiving as well as sending.
+  shutdown(tcp_config->sockfd, 2);
   return OK;
 }
 
 plc4c_return_code plc4c_transport_tcp_send_message_function(
-    plc4c_spi_write_buffer* message) {
+    void* transport_configuration, plc4c_spi_write_buffer* message) {
+  plc4c_transport_tcp_config* tcp_config = transport_configuration;
+
+  ssize_t bytes_sent = send(tcp_config->sockfd, message->data, message->length, MSG_DONTWAIT);
+  if(bytes_sent < 0) {
+    return CONNECTION_ERROR;
+  }
+
   return OK;
 }
 
 plc4c_return_code plc4c_transport_tcp_select_message_function(
+    void* transport_configuration, uint8_t min_size,
     accept_message_function accept_message, plc4c_spi_read_buffer** message) {
+  plc4c_transport_tcp_config* tcp_config = transport_configuration;
+
+  // First try to read the minimum number of bytes the driver needs to know
+  // how big a packet is.
+  uint8_t* size_buffer = malloc(sizeof(uint8_t) * min_size);
+  if(size_buffer == NULL) {
+    return NO_MEMORY;
+  }
+  int received_bytes = recv(tcp_config->sockfd, size_buffer, min_size, 0);
+  // TODO: if the value is negative, it's more a "please remove this much of corrupt data" ...
+  if(received_bytes < 0) {
+    return CONNECTION_ERROR;
+  }
+
+  // Now that we have enough data to find out how many bytes we need, have
+  // the accept_message function find out how many
+  int16_t message_size = accept_message(size_buffer, min_size);
+  if(message_size < 0) {
+    return INTERNAL_ERROR;
+  }
+  uint8_t* message_buffer = malloc(sizeof(uint8_t) * message_size);
+  if(message_size < 0) {
+    return NO_MEMORY;
+  }
+
+  // Copy the size_buffer to the start of the new buffer.
+  memcpy(message_buffer, size_buffer, min_size);
+  free(size_buffer);
+
+  // Read the rest of the packet.
+  received_bytes = recv(tcp_config->sockfd, message_buffer + min_size, message_size - min_size, 0);
+  if(received_bytes != message_size - min_size) {
+    return CONNECTION_ERROR;
+  }
+
+  // Create a new read-buffer with the read message data.
+  plc4c_spi_read_buffer_create(message_buffer, message_size, message);
   return OK;
 }
 
@@ -44,6 +144,7 @@ plc4c_transport *plc4c_transport_tcp_create() {
       (plc4c_transport *)malloc(sizeof(plc4c_transport));
   transport->transport_code = "tcp";
   transport->transport_name = "TCP transport";
+  transport->configure = &plc4c_transport_tcp_configure_function;
   transport->open = &plc4c_transport_tcp_open_function;
   transport->close = &plc4c_transport_tcp_close_function;
   transport->send_message = &plc4c_transport_tcp_send_message_function;