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/04/20 12:05:35 UTC

[plc4x] branch develop updated: - Included Otto's proposal for a plc4c api - Removed the other alternatives that are now sort of obsolete

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 3396cf6  - Included Otto's proposal for a plc4c api - Removed the other alternatives that are now sort of obsolete
3396cf6 is described below

commit 3396cf66524ad25063abf92647332a3225e83a6d
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon Apr 20 14:05:27 2020 +0200

    - Included Otto's proposal for a plc4c api
    - Removed the other alternatives that are now sort of obsolete
---
 sandbox/plc4c/CMakeLists.txt                       |   2 +-
 sandbox/plc4c/api/CMakeLists.txt                   |   3 +-
 sandbox/plc4c/api/src/main/include/plc4c.h         | 280 +++++++++++++++++++++
 sandbox/plc4c/examples/CMakeLists.txt              |   2 -
 .../examples/hello-world-callbacks/CMakeLists.txt  |  25 --
 .../src/main/c/HelloWorldCallbackErrors.c          | 174 -------------
 .../hello-world-return-codes/CMakeLists.txt        |  25 --
 .../src/main/c/HelloWorldReturnCodeErrors.c        | 191 --------------
 sandbox/plc4c/examples/hello-world/CMakeLists.txt  |   9 +-
 .../examples/hello-world/src/main/c/HelloWorld.c   |  30 ---
 .../examples/hello-world/src/main/c/hello_world.c  |  71 ++++++
 sandbox/plc4c/spi/CMakeLists.txt                   |   7 +-
 sandbox/plc4c/spi/src/main/c/plc4c.c               | 100 ++++++++
 .../src/main/c/plc4c_private_types.c}              |  23 +-
 14 files changed, 483 insertions(+), 459 deletions(-)

diff --git a/sandbox/plc4c/CMakeLists.txt b/sandbox/plc4c/CMakeLists.txt
index b1558ca..f2349da 100644
--- a/sandbox/plc4c/CMakeLists.txt
+++ b/sandbox/plc4c/CMakeLists.txt
@@ -71,7 +71,7 @@ endif()
 ]]
 # Core stuff
 add_subdirectory(api)
-#add_subdirectory(spi)
+add_subdirectory(spi)
 #add_subdirectory(transports)
 add_subdirectory(drivers)
 #add_subdirectory(integrations)
diff --git a/sandbox/plc4c/api/CMakeLists.txt b/sandbox/plc4c/api/CMakeLists.txt
index 5d6486b..84766a9 100644
--- a/sandbox/plc4c/api/CMakeLists.txt
+++ b/sandbox/plc4c/api/CMakeLists.txt
@@ -19,7 +19,8 @@
 
 include_directories("src/main/include")
 file(GLOB sources "src/main/c/*.c")
-add_library(plc4c-api ${sources})
+
+add_library(plc4c-api SHARED ${sources})
 
 if(BUILD_PHASE STREQUAL test-compile)
     file(GLOB testSources "src/test/c/*.c")
diff --git a/sandbox/plc4c/api/src/main/include/plc4c.h b/sandbox/plc4c/api/src/main/include/plc4c.h
new file mode 100644
index 0000000..46c6dc3
--- /dev/null
+++ b/sandbox/plc4c/api/src/main/include/plc4c.h
@@ -0,0 +1,280 @@
+/*
+ * 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.
+ */
+#ifndef PLC4C_H_
+#define PLC4C_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+
+
+/**
+ * Public API
+ */
+
+/**
+ *
+ * PLC4C error codes
+*/
+typedef enum error_code {
+    OK,
+    UNKNOWN_ERROR,
+    NO_MEMORY,
+    INVALID_CONNECTION_STRING,
+    NOT_REACHABLE,
+    PERMISSION_DENIED,
+    INTERNAL_ERROR
+} error_code;
+
+/**
+ * Helper that translates from an error_code enum value to something a human can work with.
+ *
+ * @param err error code.
+ * @return A human readable error description.
+ */
+char *plc4c_error_code_to_error_message(error_code err);
+
+/**
+ * the plc4c system
+ */
+typedef struct plc4c_system_t plc4c_system;
+
+/**
+ * the plc4c_driver
+ */
+typedef struct plc4c_driver_t plc4c_driver;
+
+/**
+ * the plc4c_connection
+ */
+typedef struct plc4c_connection_t plc4c_connection;
+
+/**
+ * SYSTEM CALLBACKS
+ */
+
+/**
+ * Function pointer for a callback called when a driver is loaded.
+ * Set in plc4c_system @see plc4c_system_set_on_driver_loaded()
+ * @param driver
+ */
+typedef void (*plc4c_system_callback_on_driver_loaded)(plc4c_driver *driver);
+
+/**
+ * Function pointer for a callback called when loading a driver fails.
+ * Set in plc4c_system @see plc4c_system_set_on_driver_load_error
+ * NOTE: driver_name could be a pointer to the configuration for the driver instead....
+ * @param driver_name
+ * @param error_code
+ */
+typedef void (*plc4c_system_callback_driver_load_error)(const char *driver_name, error_code error);
+
+/**
+ * Function pointer for a callback called when is successfully made
+ * Set in plc4c_system @see plc4c_system_set_on_connection()
+ * @param connection
+ */
+typedef void (*plc4c_system_callback_on_connection)(plc4c_connection *connection);
+
+/**
+ * Function pointer for a callback called when connecting fails.
+ * Set in plc4c_system @see plc4c_system_set_on_connection_error
+ * @param connection_string
+ * @param error_code
+ */
+typedef void (*plc4c_system_callback_connection_error)(const char *connection_string, error_code error);
+
+/**
+ * Function pointer for a callback called when is successfully made
+ * Set in plc4c_system @see plc4c_system_set_on_connection()
+ * @param connection
+ */
+typedef void (*plc4c_system_callback_on_disconnection)(plc4c_connection *connection);
+
+/**
+ * Function pointer for a callback called when connecting fails.
+ * Set in plc4c_system @see plc4c_system_set_on_connection_error
+ * @param connection
+ * @param error_code
+ */
+typedef void (*plc4c_system_callback_disconnection_error)(plc4c_connection *connection, error_code error);
+
+/**
+ * Function pointer for a callback called when a driver returns an error
+ * @param driver
+ * @param connection
+ * @param error_code
+ */
+typedef void(*plc4c_system_callback_loop_error)
+        (plc4c_driver *driver, plc4c_connection *connection, error_code error);
+
+/**
+ * OTHER FUNCTION DEFS FOR SYSTEM
+ */
+
+
+/**
+ * SYSTEM FUNCTIONS
+ */
+
+/**
+ * Function to create a plc4c_system
+ * @param system
+ * @return NO_MEMORY if failed to create system
+ */
+error_code plc4c_system_create(plc4c_system **system);
+
+/**
+ * Function to destroy a plc4c_system
+ * This will also destroy all connections associated with the system
+ * @param system
+ */
+void plc4c_system_destroy(plc4c_system *system);
+
+/**
+ * Function to set the on_driver_loaded callback for the plc4c system
+ * @param system
+ * @param callback plc4c_system_callback_on_driver
+ */
+void plc4c_system_set_on_driver_loaded(plc4c_system *system,
+                                       plc4c_system_callback_on_driver_loaded callback);
+
+/**
+ * Function to set the error callback for loading drivers for the plc4c system
+ * @param system
+ * @param callback plc4c_system_callback_driver_load_error
+ */
+void plc4c_system_set_on_driver_load_error(plc4c_system *system,
+                                           plc4c_system_callback_driver_load_error callback);
+
+/**
+ * Function to set the on_connection callback for the plc4c system
+ * @param system
+ * @param callback plc4c_system_callback_on_connection
+ */
+void plc4c_system_set_on_connection(plc4c_system *system,
+                                    plc4c_system_callback_on_connection callback);
+
+/**
+ * Function to set the error callback for making connections for the plc4c system
+ * @param system
+ * @param callback plc4c_system_callback_connection_error
+ */
+void plc4c_system_set_on_connection_error(plc4c_system *system,
+                                          plc4c_system_callback_connection_error callback);
+
+/**
+ * Function to set the on_disconnection callback for the plc4c system
+ * @param system
+ * @param callback plc4c_system_callback_on_disconnection
+ */
+void plc4c_system_set_on_disconnection(plc4c_system *system,
+                                       plc4c_system_callback_on_disconnection callback);
+
+/**
+ * Function to set the error callback for shutting down connections for the plc4c system
+ * @param system
+ * @param callback
+ */
+void plc4c_system_set_on_disconnection_error(plc4c_system *system,
+                                             plc4c_system_callback_disconnection_error callback);
+
+/**
+ * Function to set the error callback loops
+ * @param system
+ * @param callback plc4c_system_callback_loop_error
+ */
+void plc4c_system_set_on_loop_error(plc4c_system *system,
+                                    plc4c_system_callback_loop_error callback);
+
+/**
+ * Function to initialize the PLC4C system (Initialize the driver manager and the list of enabled drivers)
+ * @param system
+ * @return error_code
+ */
+error_code plc4c_init(plc4c_system *system);
+
+/**
+ * Function to clean up the PLC4C system (Free any still used resources, terminate live connections, ...)
+ * @param system
+ */
+void plc4c_system_shutdown(plc4c_system *system);
+
+/**
+ * Function to initialize a connection to a PLC by parsing the given connection string
+ * and setting the passed connection system
+ *
+ * @param system
+ * @param connectionString
+ * @return error_code INVALID_CONNECTION_STRING, NO_MEMORY
+ */
+error_code plc4c_system_connect(plc4c_system *system,
+                                const char *connectionString,
+                                plc4c_connection **connection);
+
+/**
+ * Function to initialize a connection to a PLC by parsing the given connection string
+ * and setting the passed connection system and also providing callbacks for success and
+ * failure in case of problems.
+ *
+ * @param system
+ * @param connectionString
+ * @param connection
+ * @param success_callback
+ * @param error_callback
+ * @return error_code INVALID_CONNECTION_STRING, NO_MEMORY
+ */
+error_code plc4c_system_connect_callback(plc4c_system *system,
+                                         const char *connectionString,
+                                         plc4c_connection **connection,
+                                         plc4c_system_callback_on_connection success_callback,
+                                         plc4c_system_callback_connection_error error_callback);
+
+/**
+ * Function to terminate a connection to a PLC.
+ *
+ * @param connection
+ * @param plc4c_connection
+ */
+error_code plc4c_disconnect(plc4c_connection *connection);
+
+/**
+ * Function to terminate a connection to a PLC.
+ *
+ * @param connection
+ * @param plc4c_connection
+ */
+error_code plc4c_disconnect_callback(plc4c_connection *connection,
+                                     plc4c_system_callback_on_disconnection success_callback,
+                                     plc4c_system_callback_disconnection_error error_callback);
+
+/**
+ * Function to give any drivers the chance to do their work.
+ * In single-threaded environments we can't operate with event
+ * handler loops as they would block the rest of the application.
+ *
+ * @return error_code
+ */
+error_code plc4c_system_loop();
+
+#ifdef __cplusplus
+}
+#endif
+#endif //PLC4C_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/examples/CMakeLists.txt b/sandbox/plc4c/examples/CMakeLists.txt
index dfe1e96..27addc0 100644
--- a/sandbox/plc4c/examples/CMakeLists.txt
+++ b/sandbox/plc4c/examples/CMakeLists.txt
@@ -18,5 +18,3 @@
 ]]
 
 add_subdirectory(hello-world)
-add_subdirectory(hello-world-callbacks)
-add_subdirectory(hello-world-return-codes)
diff --git a/sandbox/plc4c/examples/hello-world-callbacks/CMakeLists.txt b/sandbox/plc4c/examples/hello-world-callbacks/CMakeLists.txt
deleted file mode 100644
index 9dbc3f8..0000000
--- a/sandbox/plc4c/examples/hello-world-callbacks/CMakeLists.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-#[[
-  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.
-]]
-
-include_directories("src/main/include")
-file(GLOB sources "src/main/c/*.c")
-
-add_executable(plc4c-examples-hello-world-callbacks ${sources} src/main/c/HelloWorldCallbackErrors.c)
-
-target_link_libraries (plc4c-examples-hello-world-callbacks ${CMAKE_DL_LIBS})
\ No newline at end of file
diff --git a/sandbox/plc4c/examples/hello-world-callbacks/src/main/c/HelloWorldCallbackErrors.c b/sandbox/plc4c/examples/hello-world-callbacks/src/main/c/HelloWorldCallbackErrors.c
deleted file mode 100644
index 5737cb9..0000000
--- a/sandbox/plc4c/examples/hello-world-callbacks/src/main/c/HelloWorldCallbackErrors.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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.
- */
-#include<stdio.h>
-#include<stdbool.h>
-
-/**
- Some error types that can typically occur.
- */
-enum error_code {
-    OK,
-    NOT_REACHABLE,
-    PERMISSION_DENIED,
-    INTERNAL_ERROR
-};
-typedef enum error_code error_code;
-
-/**
- * Helper that translates from an error_code enum value to something a human can work with.
- *
- * @param err error code.
- * @return A human readable error description.
- */
-char* toErrorMessage(error_code err) {
-    if(err) {
-        switch (err) {
-            case OK:
-                return "OK";
-            case NOT_REACHABLE:
-                return "requested destination not reachable/not available";
-            case PERMISSION_DENIED:
-                return "permission denied";
-            case INTERNAL_ERROR:
-                return "An internal server error occured";
-            default:
-                return "WTF?!?!";
-        }
-    }
-    return "WTF?!?!";
-}
-
-bool loop = true;
-
-/**
- * Data structure containing all data related to an individual connection.
- */
-struct plc4c_connection {
-    bool connected;
-    error_code error;
-};
-typedef struct plc4c_connection plc4c_connection;
-
-/**
- * Function to initialize the PLC4C system (Initialize the driver manager and the list of enabled drivers)
- */
-void plc4c_init(void (*errorFuncPtr) (error_code)) {
-}
-
-/**
- * Function to clean up the PLC4C system (Free any still used resources, terminate live connections, ...)
- */
-void plc4c_shutdown(void (*errorFuncPtr) (error_code)) {
-}
-
-/**
- * Function to initialize a connection to a PLC by parsing the given connection string
- * and returning a corresponding plc4c_connection data structure.
- *
- * @param connectionString PLC4X connection string
- * @param plc4c_connection success handler function that gets called as soon as the connection is established.
- * @param errorFuncPtr error handler function that takes an error_code as argument.
- * @return plc4c_connection data structure.
- */
-void plc4c_connect(char* connectionString,
-        void (*successFuncPtr) (plc4c_connection),
-        void (*errorFuncPtr) (plc4c_connection, error_code)) {
-}
-
-/**
- * Function to terminate a connection to a PLC.
- *
- * @param connection pointer to a plc4c_connection data structure.
- * @param plc4c_connection success handler function that gets called as soon as the connection is terminated.
- * @param errorFuncPtr error handler function that gets called if anything goes wrong.
- */
-void plc4c_disconnect(plc4c_connection* connection,
-        void (*successFuncPtr) (plc4c_connection),
-        void (*errorFuncPtr) (plc4c_connection, error_code)) {
-}
-
-/**
- * Function to give any drivers the chance to do their work.
- * In single-threaded environments we can't operate with event
- * handler loops as they would block the rest of the application.
- *
- * @param errorFuncPtr error handler function that gets called if anything goes wrong.
- */
-void plc4c_loop(void (*errorFuncPtr) (error_code)) {
-}
-
-/**
- * Default error handler, that just translates a normal error_code to a message.
- *
- * @param errorCode error code.
- */
-void onError(error_code errorCode) {
-    printf(toErrorMessage(errorCode));
-}
-
-/**
- * Error handler that handles errors related to a specific connection.
- *
- * @param connection connection the error is related to.
- * @param errorCode error code.
- */
-void onConnectionError(plc4c_connection connection, error_code errorCode) {
-    printf(toErrorMessage(errorCode));
-}
-
-/**
- * Callback called as soon as the connection is established.
- *
- * @param connection connection object.
- */
-void onConnect(plc4c_connection connection) {
-
-}
-
-/**
- * Callback called as soon as the connection is terminated.
- *
- * @param connection connection object.
- */
-void onDisconnect(plc4c_connection connection) {
-
-}
-
-/**
- * Main application.
- *
- * @return return code (Usually 0)
- */
-int main() {
-    // Initialize the PLC4C system.
-    plc4c_init(&onError);
-
-    // Establish a connection to a remote device
-    plc4c_connect("s7://192.168.42.20", &onConnect, &onConnectionError);
-
-    // Central program loop ...
-    while(loop) {
-        plc4c_loop(&onError);
-    }
-
-    // Make sure everything is cleaned up correctly.
-    plc4c_shutdown(&onError);
-
-    return 0;
-}
\ No newline at end of file
diff --git a/sandbox/plc4c/examples/hello-world-return-codes/CMakeLists.txt b/sandbox/plc4c/examples/hello-world-return-codes/CMakeLists.txt
deleted file mode 100644
index eb10e74..0000000
--- a/sandbox/plc4c/examples/hello-world-return-codes/CMakeLists.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-#[[
-  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.
-]]
-
-include_directories("src/main/include")
-file(GLOB sources "src/main/c/*.c")
-
-add_executable(plc4c-examples-hello-world-return-codes ${sources} src/main/c/HelloWorldReturnCodeErrors.c)
-
-target_link_libraries (plc4c-examples-hello-world-return-codes ${CMAKE_DL_LIBS})
\ No newline at end of file
diff --git a/sandbox/plc4c/examples/hello-world-return-codes/src/main/c/HelloWorldReturnCodeErrors.c b/sandbox/plc4c/examples/hello-world-return-codes/src/main/c/HelloWorldReturnCodeErrors.c
deleted file mode 100644
index bd193ac..0000000
--- a/sandbox/plc4c/examples/hello-world-return-codes/src/main/c/HelloWorldReturnCodeErrors.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * 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.
- */
-#include<stdio.h>
-#include<stdbool.h>
-
-/**
- Some error types that can typically occur.
- */
-enum error_code {
-    OK,
-    NOT_REACHABLE,
-    PERMISSION_DENIED,
-    INTERNAL_ERROR
-};
-typedef enum error_code error_code;
-
-/**
- * Helper that translates from an error_code enum value to something a human can work with.
- *
- * @param err error code.
- * @return A human readable error description.
- */
-char* toErrorMessage(error_code err) {
-    if(err) {
-        switch (err) {
-            case OK:
-                return "OK";
-            case NOT_REACHABLE:
-                return "requested destination not reachable/not available";
-            case PERMISSION_DENIED:
-                return "permission denied";
-            case INTERNAL_ERROR:
-                return "An internal server error occured";
-            default:
-                return "WTF?!?!";
-        }
-    }
-    return "WTF?!?!";
-}
-
-/**
- * Data structure containing all data related to an individual connection.
- */
-struct plc4c_connection {
-    bool connected;
-    error_code error;
-};
-typedef struct plc4c_connection plc4c_connection;
-
-/**
- * Function to initialize the PLC4C system (Initialize the driver manager and the list of enabled drivers)
- *
- * @return an error code
- */
-error_code plc4c_init() {
-    return OK;
-}
-
-/**
- * Function to clean up the PLC4C system (Free any still used resources, terminate live connections, ...)
- *
- * @return an error code
- */
-error_code plc4c_shutdown() {
-    return OK;
-}
-
-/**
- * Function to initialize a connection to a PLC by parsing the given connection string
- * and filling in the plc4c_connection data structure.
- *
- * @param connectionString PLC4X connection string
- * @param connection (return) pointer to a plc4c_connection data structure.
- * @return an error code
- */
-error_code plc4c_connect(char* connectionString, plc4c_connection** connection) {
-    return OK;
-}
-
-/**
- * Function to terminate a connection to a PLC.
- *
- * @param connection pointer to a plc4c_connection data structure.
- * @return an error code
- */
-error_code plc4c_disconnect(plc4c_connection* connection) {
-    return OK;
-}
-
-/**
- * Function to give any drivers the chance to do their work.
- * In single-threaded environments we can't operate with event
- * handler loops as they would block the rest of the application.
- *
- * @return an error code (But only if there's something bad going
- * happening with PLC4C and not just something going wrong in a connection)
- */
-error_code plc4c_loop() {
-    return OK;
-}
-
-
-/**
- * Main application.
- *
- * @return return code (Usually 0)
- */
-int main() {
-    // Initialize the PLC4C system.
-    error_code res = plc4c_init();
-    if(res != OK) {
-        printf("ERROR: An error initializing PLC4C driver manager");
-    }
-
-    // Establish a connection to a remote device
-    plc4c_connection* connection = NULL;
-    res = plc4c_connect("s7://192.168.42.20", &connection);
-    // Check if all was ok
-    if(res != OK) {
-        printf("ERROR: An error occurred while connecting");
-        goto cleanup;
-    }
-
-    bool loop = true;
-    while(loop) {
-        // Give the plc4c internals the chance to do their work.
-        // NOTE: If for example one of two connections has a problem, this will not return
-        // an error code as we would have no way of knowing whihc connection was having issues.
-        res = plc4c_loop();
-        if(res != OK) {
-            printf("ERROR: An error occurred in the loop");
-            goto cleanup;
-        }
-
-        // As long as we're not connected and not in an error state, abort this loop iteration.
-        if(!connection->connected) {
-            // If the connection is in an error state, abort the loop.
-            if(connection->error) {
-                printf("An connection error occurred");
-                goto cleanup;
-            }
-            continue;
-        }
-
-        // TODO: Do stuff ...
-        loop = false;
-    }
-
-    // If we're connected, gracefully shut down the connection.
-    if(connection->connected) {
-        res = plc4c_disconnect(connection);
-        if(res != OK) {
-            printf("ERROR: An error while disconnecting");
-            goto cleanup;
-        }
-        // Give the connection some time to say goodbye.
-        while (1) {
-            res = plc4c_loop();
-            if(res != OK) {
-                printf("ERROR: An error occurred in the loop");
-                goto cleanup;
-            }
-            if(!connection->connected) {
-                printf("Disconnected");
-                goto cleanup;
-            }
-        }
-    }
-
-    cleanup:
-    // Make sure everything is cleaned up correctly.
-    plc4c_shutdown();
-
-    return 0;
-}
\ No newline at end of file
diff --git a/sandbox/plc4c/examples/hello-world/CMakeLists.txt b/sandbox/plc4c/examples/hello-world/CMakeLists.txt
index 90ab31b..d06d6b2 100644
--- a/sandbox/plc4c/examples/hello-world/CMakeLists.txt
+++ b/sandbox/plc4c/examples/hello-world/CMakeLists.txt
@@ -17,9 +17,12 @@
   under the License.
 ]]
 
-include_directories("src/main/include")
+include_directories("src/main/include"
+        "../../api/src/main/include")
+
 file(GLOB sources "src/main/c/*.c")
 
-add_executable(plc4c-examples-hello-world ${sources} src/main/c/HelloWorld.c)
+add_executable(plc4c-examples-hello-world ${sources} src/main/c/hello_world.c)
 
-target_link_libraries (plc4c-examples-hello-world ${CMAKE_DL_LIBS})
\ No newline at end of file
+target_link_libraries (plc4c-examples-hello-world
+        plc4c-spi)
\ No newline at end of file
diff --git a/sandbox/plc4c/examples/hello-world/src/main/c/HelloWorld.c b/sandbox/plc4c/examples/hello-world/src/main/c/HelloWorld.c
deleted file mode 100644
index 2fc8fe7..0000000
--- a/sandbox/plc4c/examples/hello-world/src/main/c/HelloWorld.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-#include<stdio.h>
-
-#include "HelloWorld.h"
-
-int add(int a, int b) {
-    return a + b;
-}
-
-int main() {
-	printf("Hello World\n");
-	return 0;
-}
\ No newline at end of file
diff --git a/sandbox/plc4c/examples/hello-world/src/main/c/hello_world.c b/sandbox/plc4c/examples/hello-world/src/main/c/hello_world.c
new file mode 100644
index 0000000..592cc75
--- /dev/null
+++ b/sandbox/plc4c/examples/hello-world/src/main/c/hello_world.c
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+#include <stdio.h>
+#include "../../../../../api/src/main/include/plc4c.h"
+
+void onConnection2Success(plc4c_connection *connection) {
+
+}
+
+void onConnection2Error(const char *connection_string, error_code error) {
+
+}
+
+int main() {
+  bool loop = true;
+  plc4c_system *system = NULL;
+  plc4c_connection *connection1 = NULL;
+  plc4c_connection *connection2 = NULL;
+
+  error_code error = plc4c_system_create(&system);
+  if (error != OK) {
+    return -1;
+  }
+
+  error = plc4c_init(system);
+  if (error != OK) {
+    return -1;
+  }
+
+  // Establish connections to remote devices
+  // you may or may not care about the connection handle
+  error = plc4c_system_connect(system, "s7://192.168.42.20", &connection1);
+  if (error != OK) {
+    return -1;
+  }
+
+  error = plc4c_system_connect_callback(system, "s7://192.168.42.22", &connection2,
+          &onConnection2Success, &onConnection2Error);
+  if (error != OK) {
+    return -1;
+  }
+
+  // Central program loop ...
+  while (loop) {
+    if (plc4c_system_loop(system) != OK) {
+      break;
+    }
+  }
+
+  // Make sure everything is cleaned up correctly.
+  plc4c_system_shutdown(system);
+  plc4c_system_destroy(system);
+
+  return 0;
+}
diff --git a/sandbox/plc4c/spi/CMakeLists.txt b/sandbox/plc4c/spi/CMakeLists.txt
index 1b625e4..2b64d2f 100644
--- a/sandbox/plc4c/spi/CMakeLists.txt
+++ b/sandbox/plc4c/spi/CMakeLists.txt
@@ -17,7 +17,8 @@
   under the License.
 ]]
 
-add_library(plc4c-spi
-        )
+include_directories("src/main/include"
+        "../api/src/main/include")
+file(GLOB sources "src/main/c/*.c")
 
-target_link_libraries (plc4c-spi ${CMAKE_DL_LIBS})
\ No newline at end of file
+add_library(plc4c-spi SHARED ${sources})
\ No newline at end of file
diff --git a/sandbox/plc4c/spi/src/main/c/plc4c.c b/sandbox/plc4c/spi/src/main/c/plc4c.c
new file mode 100644
index 0000000..34cfe13
--- /dev/null
+++ b/sandbox/plc4c/spi/src/main/c/plc4c.c
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+#include "plc4c.h"
+
+error_code plc4c_system_create(plc4c_system **system) {
+    return OK;
+}
+
+void plc4c_system_destroy(plc4c_system *system) {
+
+}
+
+void plc4c_system_set_on_driver_loaded(plc4c_system *system,
+        plc4c_system_callback_on_driver_loaded callback) {
+
+}
+
+void plc4c_system_set_on_driver_load_error(plc4c_system *system,
+        plc4c_system_callback_driver_load_error callback) {
+
+}
+
+void plc4c_system_set_on_connection(plc4c_system *system,
+        plc4c_system_callback_on_connection callback) {
+
+}
+
+void plc4c_system_set_on_connection_error(plc4c_system *system,
+        plc4c_system_callback_connection_error callback) {
+
+}
+
+void plc4c_system_set_on_disconnection(plc4c_system *system,
+        plc4c_system_callback_on_disconnection callback) {
+
+}
+
+void plc4c_system_set_on_disconnection_error(plc4c_system *system,
+        plc4c_system_callback_disconnection_error callback) {
+
+}
+
+void plc4c_system_set_on_loop_error(plc4c_system *system,
+        plc4c_system_callback_loop_error callback) {
+
+}
+
+error_code plc4c_init(plc4c_system *system) {
+    return OK;
+}
+
+void plc4c_system_shutdown(plc4c_system *system) {
+
+}
+
+error_code plc4c_system_connect(plc4c_system *system,
+                                const char *connectionString,
+                                plc4c_connection **connection) {
+    return OK;
+}
+
+error_code plc4c_system_connect_callback(plc4c_system *system,
+                                         const char *connectionString,
+                                         plc4c_connection **connection,
+                                         plc4c_system_callback_on_connection success_callback,
+                                         plc4c_system_callback_connection_error error_callback) {
+    return OK;
+}
+
+error_code plc4c_disconnect(plc4c_connection *connection) {
+    return OK;
+}
+
+error_code plc4c_disconnect_callback(plc4c_connection *connection,
+                                     plc4c_system_callback_on_disconnection success_callback,
+                                     plc4c_system_callback_disconnection_error error_callback) {
+    return OK;
+}
+
+error_code plc4c_system_loop() {
+    return OK;
+}
+
diff --git a/sandbox/plc4c/examples/hello-world/src/main/include/HelloWorld.h b/sandbox/plc4c/spi/src/main/c/plc4c_private_types.c
similarity index 78%
rename from sandbox/plc4c/examples/hello-world/src/main/include/HelloWorld.h
rename to sandbox/plc4c/spi/src/main/c/plc4c_private_types.c
index e9125a4..8de071a 100644
--- a/sandbox/plc4c/examples/hello-world/src/main/include/HelloWorld.h
+++ b/sandbox/plc4c/spi/src/main/c/plc4c_private_types.c
@@ -17,9 +17,24 @@
  * under the License.
  */
 
-#ifndef _HELLO_WORLD_H_
-#define _HELLO_WORLD_H_
+#include "plc4c.h"
 
-int add(int, int);
+/* private!! */
 
-#endif
\ No newline at end of file
+struct plc4c_system_t {
+   /* drivers */
+
+   /* connections */
+
+   /* callbacks */
+};
+
+struct plc4c_driver_t {
+  /* name */
+
+  /* ??? */
+};
+
+struct plc4c_connection_t {
+ /* ???? */
+};
\ No newline at end of file