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 2021/02/14 16:57:53 UTC

[plc4x] branch develop updated: - Finished implmenting the processing of Modbus read-responses in the PLC4C Modbus Driver

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

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


The following commit(s) were added to refs/heads/develop by this push:
     new 1e1506a  - Finished implmenting the processing of Modbus read-responses in the PLC4C Modbus Driver
1e1506a is described below

commit 1e1506ac4039dc498431fe7f959e8eee076f1136
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Sun Feb 14 17:57:44 2021 +0100

    - Finished implmenting the processing of Modbus read-responses in the PLC4C Modbus Driver
---
 .../resources/templates/c/data-io-template-c.ftlh  |  5 ++
 sandbox/plc4c/api/include/plc4c/data.h             |  4 ++
 .../drivers/modbus/src/driver_modbus_packets.c     | 30 ++++++------
 .../drivers/modbus/src/driver_modbus_sm_read.c     | 35 ++++++++++++++
 .../hello-world-modbus/src/hello_world_modbus.c    |  4 +-
 .../plc4c/generated-sources/modbus/src/data_item.c | 21 +++++++--
 sandbox/plc4c/generated-sources/s7/src/data_item.c | 23 ++++++++++
 .../plc4c/spi/include/plc4c/spi/types_private.h    |  2 +-
 sandbox/plc4c/spi/src/data.c                       | 53 ++++++++++++++++++++++
 sandbox/plc4c/spi/src/system.c                     |  2 +-
 sandbox/plc4c/transports/tcp/src/transport_tcp.c   | 16 +++++--
 11 files changed, 166 insertions(+), 29 deletions(-)

diff --git a/build-utils/language-c/src/main/resources/templates/c/data-io-template-c.ftlh b/build-utils/language-c/src/main/resources/templates/c/data-io-template-c.ftlh
index ba43136..60236c8 100644
--- a/build-utils/language-c/src/main/resources/templates/c/data-io-template-c.ftlh
+++ b/build-utils/language-c/src/main/resources/templates/c/data-io-template-c.ftlh
@@ -219,7 +219,12 @@ plc4c_return_code ${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                <#if case.name == "BitString">
+                *data_item = plc4c_data_create_${helper.getLanguageTypeNameForField(field)}_bit_string_data(${field.name});
+                <#else>
+                    // Hurz
                 *data_item = plc4c_data_create_${helper.getLanguageTypeNameForField(field)}_data(${field.name});
+                </#if>
 
                     <#break>
             </#switch>
diff --git a/sandbox/plc4c/api/include/plc4c/data.h b/sandbox/plc4c/api/include/plc4c/data.h
index 265f7aa..733c5ef 100644
--- a/sandbox/plc4c/api/include/plc4c/data.h
+++ b/sandbox/plc4c/api/include/plc4c/data.h
@@ -150,6 +150,10 @@ plc4c_data *plc4c_data_create_char_data(char* s);
  */
 plc4c_data *plc4c_data_create_list_data(plc4c_list list);
 
+plc4c_data *plc4c_data_create_uint8_t_bit_string_data(uint8_t uc);
+plc4c_data *plc4c_data_create_uint16_t_bit_string_data(uint16_t us);
+plc4c_data *plc4c_data_create_uint32_t_bit_string_data(uint32_t ui);
+plc4c_data *plc4c_data_create_uint64_t_bit_string_data(uint64_t ui);
 /**
  * Set a custom function to call when destroying this data.  Typically when the
  * type is a PLC4C_VOID_POINTER
diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus_packets.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus_packets.c
index 884edbb..70760ba 100644
--- a/sandbox/plc4c/drivers/modbus/src/driver_modbus_packets.c
+++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus_packets.c
@@ -24,6 +24,9 @@
 #include "modbus_tcp_adu.h"
 #include "plc4c/driver_modbus.h"
 
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
 /**
  * Function used by the driver to tell the transport if there is a full
  * packet the driver can operate on available.
@@ -114,39 +117,32 @@ plc4c_return_code plc4c_driver_modbus_create_modbus_read_request(
   }
 
   plc4c_driver_modbus_item* modbus_item = read_request_item->address;
-
+  uint16_t address = modbus_item->address - 1;
+  uint16_t num_modbus_bytes = modbus_item->num_elements * plc4c_modbus_read_write_modbus_data_type_get_data_type_size(modbus_item->datatype);
   switch (modbus_item->type) {
     case PLC4C_DRIVER_MODBUS_ADDRESS_TYPE_COIL: {
       pdu->_type =
           plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_coils_request;
-      pdu->modbus_pdu_read_coils_request_starting_address =
-          modbus_item->address;
-      pdu->modbus_pdu_read_coils_request_quantity =
-          modbus_item->num_elements;
+      pdu->modbus_pdu_read_coils_request_starting_address = address;
+      pdu->modbus_pdu_read_coils_request_quantity = num_modbus_bytes;
       break;
     }
     case PLC4C_DRIVER_MODBUS_ADDRESS_TYPE_DISCRETE_INPUT: {
       pdu->_type = plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_discrete_inputs_request;
-      pdu->modbus_pdu_read_discrete_inputs_request_starting_address =
-          modbus_item->address;
-      pdu->modbus_pdu_read_discrete_inputs_request_quantity =
-          modbus_item->num_elements;
+      pdu->modbus_pdu_read_discrete_inputs_request_starting_address = address;
+      pdu->modbus_pdu_read_discrete_inputs_request_quantity = MAX(2, num_modbus_bytes) / 2;
       break;
     }
     case PLC4C_DRIVER_MODBUS_ADDRESS_TYPE_INPUT_REGISTER: {
       pdu->_type = plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_input_registers_request;
-      pdu-> modbus_pdu_read_input_registers_request_starting_address =
-          modbus_item->address;
-      pdu-> modbus_pdu_read_input_registers_request_quantity =
-          modbus_item->num_elements;
+      pdu-> modbus_pdu_read_input_registers_request_starting_address = address;
+      pdu-> modbus_pdu_read_input_registers_request_quantity = MAX(2, num_modbus_bytes) / 2;
       break;
     }
     case PLC4C_DRIVER_MODBUS_ADDRESS_TYPE_HOLDING_REGISTER: {
       pdu->_type = plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_holding_registers_request;
-      pdu-> modbus_pdu_read_holding_registers_request_starting_address =
-          modbus_item->address;
-      pdu-> modbus_pdu_read_holding_registers_request_quantity =
-          modbus_item->num_elements;
+      pdu-> modbus_pdu_read_holding_registers_request_starting_address = address;
+      pdu-> modbus_pdu_read_holding_registers_request_quantity = MAX(2, num_modbus_bytes) / 2;
       break;
     }
     case PLC4C_DRIVER_MODBUS_ADDRESS_TYPE_EXTENDED_REGISTER: {
diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_read.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_read.c
index 9beed79..cfd553a 100644
--- a/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_read.c
+++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_read.c
@@ -50,6 +50,17 @@ plc4c_return_code plc4c_driver_modbus_read_machine_function(
     // First set the current item to the first item in the list (tail)
     case PLC4C_DRIVER_MODBUS_READ_INIT: {
       read_request_execution->cur_item = plc4c_utils_list_tail(read_request->items);
+
+      // Create an empty read-response and attach that to the execution.
+      plc4c_read_response* read_response = malloc(sizeof(plc4c_read_response));
+      if(read_response == NULL) {
+        return NO_MEMORY;
+      }
+      read_response->read_request = read_request;
+      read_request_execution->read_response = read_response;
+      plc4c_utils_list_create(&(read_response->items));
+      read_request_execution->read_response = read_response;
+
       task->state_id = PLC4C_DRIVER_MODBUS_READ_SEND_ITEM_REQUEST;
       break;
     }
@@ -147,10 +158,33 @@ plc4c_return_code plc4c_driver_modbus_read_machine_function(
         return result;
       }
 
+      // In case of a register request and a single bit datatype, consume the first byte.
+      if((modbus_item->type != PLC4C_DRIVER_MODBUS_ADDRESS_TYPE_COIL) &&
+          (plc4c_modbus_read_write_modbus_data_type_get_data_type_size(modbus_item->datatype) == 1)) {
+        uint8_t _ignored = 0;
+        result = plc4c_spi_read_unsigned_byte(read_buffer, 8, &_ignored);
+        if(result != OK) {
+          return result;
+        }
+      }
+
       // Decode the items in the response ...
       plc4c_data* data_item;
       plc4c_modbus_read_write_data_item_parse(read_buffer, modbus_item->datatype, modbus_item->num_elements, &data_item);
 
+      // Create a new response value-item
+      plc4c_response_value_item* response_value_item = malloc(sizeof(plc4c_response_value_item));
+      if(response_value_item == NULL) {
+        return NO_MEMORY;
+      }
+      response_value_item->item = read_request_execution->cur_item->value;
+      response_value_item->response_code = PLC4C_RESPONSE_CODE_OK;
+      response_value_item->value = data_item;
+
+      // Add the value-item to the list.
+      plc4c_utils_list_insert_head_value(
+          read_request_execution->read_response->items, response_value_item);
+
       // If there are more items to read, continue reading the next one.
       // Otherwise finish.
       if (read_request_execution->cur_item->next != NULL) {
@@ -163,6 +197,7 @@ plc4c_return_code plc4c_driver_modbus_read_machine_function(
     }
 
     case PLC4C_DRIVER_MODBUS_READ_FINISHED: {
+
       // TODO: Return the results to the API ...
       task->completed = true;
       break;
diff --git a/sandbox/plc4c/examples/hello-world-modbus/src/hello_world_modbus.c b/sandbox/plc4c/examples/hello-world-modbus/src/hello_world_modbus.c
index 3028b35..5a0ad52 100644
--- a/sandbox/plc4c/examples/hello-world-modbus/src/hello_world_modbus.c
+++ b/sandbox/plc4c/examples/hello-world-modbus/src/hello_world_modbus.c
@@ -110,7 +110,7 @@ int main() {
   // Establish connections to remote devices
   // you may or may not care about the connection handle
   printf("Connecting to 'modbus:tcp://192.168.23.30' ... ");
-  result = plc4c_system_connect(system, "modbus:tcp://192.168.23.30", &connection);
+  result = plc4c_system_connect(system, "modbus:tcp://192.168.23.30:502", &connection);
   if (result != OK) {
     printf("FAILED\n");
     return -1;
@@ -237,7 +237,7 @@ int main() {
           return -1;
         }
         result =
-            plc4c_read_request_add_item(read_request, "REAL", "holding-register:26:LREAL");
+            plc4c_read_request_add_item(read_request, "REAL", "holding-register:28:LREAL");
         if (result != OK) {
           printf("FAILED\n");
           return -1;
diff --git a/sandbox/plc4c/generated-sources/modbus/src/data_item.c b/sandbox/plc4c/generated-sources/modbus/src/data_item.c
index dbf2064..507be35 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/data_item.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/data_item.c
@@ -53,6 +53,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_bool_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_BOOL) { /* List */
@@ -82,7 +83,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
-                *data_item = plc4c_data_create_uint8_t_data(value);
+                *data_item = plc4c_data_create_uint8_t_bit_string_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_BYTE) { /* List */
 
@@ -111,7 +112,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
-                *data_item = plc4c_data_create_uint16_t_data(value);
+                *data_item = plc4c_data_create_uint16_t_bit_string_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_WORD) { /* List */
 
@@ -140,7 +141,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
-                *data_item = plc4c_data_create_uint32_t_data(value);
+                *data_item = plc4c_data_create_uint32_t_bit_string_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_DWORD) { /* List */
 
@@ -169,7 +170,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
-                *data_item = plc4c_data_create_uint64_t_data(value);
+                *data_item = plc4c_data_create_uint64_t_bit_string_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_LWORD) { /* List */
 
@@ -198,6 +199,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_int8_t_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_SINT) { /* List */
@@ -227,6 +229,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_int16_t_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_INT) { /* List */
@@ -256,6 +259,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_int32_t_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_DINT) { /* List */
@@ -285,6 +289,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_int64_t_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_LINT) { /* List */
@@ -314,6 +319,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint8_t_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_USINT) { /* List */
@@ -343,6 +349,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint16_t_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_UINT) { /* List */
@@ -372,6 +379,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint32_t_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_UDINT) { /* List */
@@ -401,6 +409,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint64_t_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_ULINT) { /* List */
@@ -430,6 +439,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_float_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_REAL) { /* List */
@@ -459,6 +469,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_double_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_LREAL) { /* List */
@@ -488,6 +499,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint8_t_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_CHAR) { /* List */
@@ -517,6 +529,7 @@ plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer*
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint16_t_data(value);
 
     } else     if(dataType == plc4c_modbus_read_write_modbus_data_type_WCHAR) { /* List */
diff --git a/sandbox/plc4c/generated-sources/s7/src/data_item.c b/sandbox/plc4c/generated-sources/s7/src/data_item.c
index 99988fe..f373900 100644
--- a/sandbox/plc4c/generated-sources/s7/src/data_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/data_item.c
@@ -53,6 +53,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_bool_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_BYTE") == 0) { /* List */
@@ -136,6 +137,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_int8_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_USINT") == 0) { /* USINT */
@@ -147,6 +149,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint8_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_INT") == 0) { /* INT */
@@ -158,6 +161,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_int16_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_UINT") == 0) { /* UINT */
@@ -169,6 +173,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint16_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_DINT") == 0) { /* DINT */
@@ -180,6 +185,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_int32_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_UDINT") == 0) { /* UDINT */
@@ -191,6 +197,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint32_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_LINT") == 0) { /* LINT */
@@ -202,6 +209,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_int64_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_ULINT") == 0) { /* ULINT */
@@ -213,6 +221,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint64_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_REAL") == 0) { /* REAL */
@@ -224,6 +233,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_float_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_LREAL") == 0) { /* LREAL */
@@ -235,6 +245,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_double_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_CHAR") == 0) { /* CHAR */
@@ -274,6 +285,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint32_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_LTIME") == 0) { /* LTIME */
@@ -285,6 +297,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint64_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_DATE") == 0) { /* DATE */
@@ -296,6 +309,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint16_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_TIME_OF_DAY") == 0) { /* TIME_OF_DAY */
@@ -307,6 +321,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint32_t_data(value);
 
     } else     if(strcmp(dataProtocolId, "IEC61131_DATE_AND_TIME") == 0) { /* DATE_AND_TIME */
@@ -318,6 +333,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint16_t_data(year);
 
 
@@ -328,6 +344,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint8_t_data(month);
 
 
@@ -338,6 +355,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint8_t_data(day);
 
 
@@ -348,6 +366,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint8_t_data(dayOfWeek);
 
 
@@ -358,6 +377,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint8_t_data(hour);
 
 
@@ -368,6 +388,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint8_t_data(minutes);
 
 
@@ -378,6 +399,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint8_t_data(seconds);
 
 
@@ -388,6 +410,7 @@ plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io,
                     return _res;
                 }
 
+                    // Hurz
                 *data_item = plc4c_data_create_uint32_t_data(nanos);
 
     }
diff --git a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
index fb170b2..c27cee7 100644
--- a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
+++ b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
@@ -87,7 +87,7 @@ 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);
+    char* transport_connect_information, plc4c_list* parameters, void** configuration);
 
 // TODO: Implement the argument.
 typedef plc4c_return_code (*plc4c_transport_open_function)(void* config);
diff --git a/sandbox/plc4c/spi/src/data.c b/sandbox/plc4c/spi/src/data.c
index f12f00a..8fa4c4f 100644
--- a/sandbox/plc4c/spi/src/data.c
+++ b/sandbox/plc4c/spi/src/data.c
@@ -177,6 +177,54 @@ plc4c_data *plc4c_data_create_list_data(plc4c_list list) {
   return data;
 }
 
+plc4c_data *plc4c_data_create_uint8_t_bit_string_data(uint8_t uc) {
+  uint8_t cur_bit = ((uint8_t) 1) << 7;
+  plc4c_list* list = NULL;
+  plc4c_utils_list_create(&list);
+  for(int i = 0; i < 8; i++) {
+    plc4c_data *item = plc4c_data_create_bool_data((uc & cur_bit) != 0);
+    plc4c_utils_list_insert_head_value(list, item);
+    cur_bit = cur_bit >> 1;
+  }
+  return plc4c_data_create_list_data(*list);
+}
+
+plc4c_data *plc4c_data_create_uint16_t_bit_string_data(uint16_t us) {
+  uint16_t cur_bit = ((uint16_t) 1) << 15;
+  plc4c_list* list = NULL;
+  plc4c_utils_list_create(&list);
+  for(int i = 0; i < 16; i++) {
+    plc4c_data *item = plc4c_data_create_bool_data((us & cur_bit) != 0);
+    plc4c_utils_list_insert_head_value(list, item);
+    cur_bit = cur_bit >> 1;
+  }
+  return plc4c_data_create_list_data(*list);
+}
+
+plc4c_data *plc4c_data_create_uint32_t_bit_string_data(uint32_t ui) {
+  uint32_t cur_bit = ((uint32_t) 1) << 31;
+  plc4c_list* list = NULL;
+  plc4c_utils_list_create(&list);
+  for(int i = 0; i < 32; i++) {
+    plc4c_data *item = plc4c_data_create_bool_data((ui & cur_bit) != 0);
+    plc4c_utils_list_insert_head_value(list, item);
+    cur_bit = cur_bit >> 1;
+  }
+  return plc4c_data_create_list_data(*list);
+}
+
+plc4c_data *plc4c_data_create_uint64_t_bit_string_data(uint64_t ui) {
+  uint64_t cur_bit = ((uint64_t) 1) << 63;
+  plc4c_list* list = NULL;
+  plc4c_utils_list_create(&list);
+  for(int i = 0; i < 64; i++) {
+    plc4c_data *item = plc4c_data_create_bool_data((ui & cur_bit) != 0);
+    plc4c_utils_list_insert_head_value(list, item);
+    cur_bit = cur_bit >> 1;
+  }
+  return plc4c_data_create_list_data(*list);
+}
+
 plc4c_data *plc4c_data_create_void_pointer_data(void *v) {
   plc4c_data *data = malloc(sizeof(plc4c_data));
   data->data_type = PLC4C_VOID_POINTER;
@@ -223,6 +271,9 @@ void plc4c_data_printf(plc4c_data *data) {
     case PLC4C_FLOAT:
       printf("%f", data->data.float_value);
       break;
+    case PLC4C_DOUBLE:
+      printf("%.20f", data->data.double_value);
+      break;
     case PLC4C_STRING_POINTER:
       printf("%s", data->data.pstring_value);
       break;
@@ -251,6 +302,8 @@ void plc4c_data_printf(plc4c_data *data) {
       }
       break;
     default:
+      printf("unknown");
+
       break;
   }
 }
diff --git a/sandbox/plc4c/spi/src/system.c b/sandbox/plc4c/spi/src/system.c
index c4744c4..dbdbf8e 100644
--- a/sandbox/plc4c/spi/src/system.c
+++ b/sandbox/plc4c/spi/src/system.c
@@ -446,7 +446,7 @@ plc4c_return_code plc4c_system_connect(plc4c_system *system,
   // 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);
+  new_connection->transport->configure(new_connection->transport_connect_information, NULL, &new_connection->transport_configuration);
 
   // Create a new connection task.
   plc4c_system_task *new_connection_task = NULL;
diff --git a/sandbox/plc4c/transports/tcp/src/transport_tcp.c b/sandbox/plc4c/transports/tcp/src/transport_tcp.c
index b3a76b1..495e202 100644
--- a/sandbox/plc4c/transports/tcp/src/transport_tcp.c
+++ b/sandbox/plc4c/transports/tcp/src/transport_tcp.c
@@ -37,14 +37,22 @@
 extern int errno;
 
 plc4c_return_code plc4c_transport_tcp_configure_function(
-    plc4c_list* parameters, void** configuration) {
+    char* transport_connect_information, 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 = 502;
+
+  char *port;
+  char *host = strtok_s(transport_connect_information, ":", &port);
+  tcp_configuration->address = host;
+  // If no port was specified, generally use the default port for this driver
+  if(strlen(port) == 0) {
+    // TODO: Currently return an error.
+    return INTERNAL_ERROR;
+  } else {
+    tcp_configuration->port = atoi(port);
+  }
 
   *configuration = tcp_configuration;
   return OK;