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/27 20:08:15 UTC

[plc4x] 01/02: - Added some super rudimentary API support for reading and writing

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

cdutz pushed a commit to branch feature/c-api-read-support-no-promises
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit c0da8baf78b8fefa38e0b59e6b1ab54256ceeb06
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon Apr 27 19:04:22 2020 +0200

    - Added some super rudimentary API support for reading and writing
---
 sandbox/plc4c/api/include/plc4c/connection.h       |  30 ++++--
 sandbox/plc4c/api/include/plc4c/read.h             |  18 +++-
 sandbox/plc4c/api/include/plc4c/system.h           |  11 +-
 sandbox/plc4c/api/include/plc4c/types.h            |  53 ++-------
 sandbox/plc4c/api/include/plc4c/write.h            |   8 +-
 .../plc4c/examples/hello-world/src/hello_world.c   | 120 +++++++++++++++------
 .../plc4c/spi/include/plc4c/spi/types_private.h    |  14 +--
 sandbox/plc4c/spi/src/connection.c                 |  43 ++++++--
 sandbox/plc4c/spi/src/read.c                       |  30 +++++-
 sandbox/plc4c/spi/src/system.c                     |   6 +-
 sandbox/plc4c/spi/src/types.c                      |  20 ----
 sandbox/plc4c/spi/src/write.c                      |   9 +-
 12 files changed, 211 insertions(+), 151 deletions(-)

diff --git a/sandbox/plc4c/api/include/plc4c/connection.h b/sandbox/plc4c/api/include/plc4c/connection.h
index c03e918..5743b83 100644
--- a/sandbox/plc4c/api/include/plc4c/connection.h
+++ b/sandbox/plc4c/api/include/plc4c/connection.h
@@ -37,18 +37,24 @@ extern "C" {
  * CONNECTION FUNCTIONS
  */
 
+bool plc4c_connection_is_connected(plc4c_connection *connection);
+
+bool plc4c_connection_has_error(plc4c_connection *connection);
+
 /**
  * Function to terminate a connection to a PLC.
  *
  * @param connection
- * @param plc4c_promise
+ * @param return_code
  */
-plc4c_promise* plc4c_connection_disconnect(plc4c_connection *connection);
+return_code plc4c_connection_disconnect(plc4c_connection *connection);
+
+void plc4c_connection_destroy(plc4c_connection *connection);
 
 /**
  * Get the connection string from a given connection.
  */
-char* plc4c_connection_get_connection_string(plc4c_connection *connection);
+char *plc4c_connection_get_connection_string(plc4c_connection *connection);
 
 /**
  * Check if the current connection supports read operations.
@@ -62,9 +68,13 @@ bool plc4c_connection_supports_reading(plc4c_connection *connection);
  * @param connection connection that this read-request will be executed on.
  * @param num_items number of items we want to read.
  * @param addresses array of address strings.
- * @return pointer to new read-request.
+ * @param read_request pointer to the read-request
+ * @param return_code
  */
-plc4c_read_request* plc4c_connection_create_read_request(plc4c_connection *connection, int num_items, char* addresses[]);
+return_code plc4c_connection_create_read_request(plc4c_connection *connection,
+                                                 int num_items,
+                                                 char *addresses[],
+                                                 plc4c_read_request **read_request);
 
 /**
  * Check if the current connection supports write operations.
@@ -79,9 +89,15 @@ bool plc4c_connection_supports_writing(plc4c_connection *connection);
  * @param num_items number of items we want to write.
  * @param addresses array of address strings.
  * @param values array of pointers to values.
- * @return pointer to new write_request
+ * @param write_request pointer to the write-request
+ * @param return_code
  */
-plc4c_write_request* plc4c_connection_create_write_request(plc4c_connection *connection, int num_items, char* addresses[], void* values[]);
+return_code
+plc4c_connection_create_write_request(plc4c_connection *connection,
+                                      int num_items,
+                                      char *addresses[],
+                                      void *values[],
+                                      plc4c_write_request **write_request);
 
 /**
  * Check if the current connection supports subscriptions.
diff --git a/sandbox/plc4c/api/include/plc4c/read.h b/sandbox/plc4c/api/include/plc4c/read.h
index 6d11041..4eb4f09 100644
--- a/sandbox/plc4c/api/include/plc4c/read.h
+++ b/sandbox/plc4c/api/include/plc4c/read.h
@@ -28,10 +28,22 @@ extern "C" {
  * Actually executes the read-request.
  * @param connection connection this read-request will be executed on.
  * @param read_request the read-request object.
- * @return a plc4c_promise which allows asynchronously handling the request execution.
+ * @param read_request_execution pointer to a data-structure handling one execution of the read-request.
+ * @return return_code
  */
-plc4c_promise* plc4c_read_request_execute(plc4c_connection *connection,
-                                          plc4c_read_request *read_request);
+return_code plc4c_read_request_execute(plc4c_connection *connection,
+                                       plc4c_read_request *read_request,
+                                       plc4c_read_request_execution **read_request_execution);
+
+bool plc4c_read_request_finished_successfully(plc4c_read_request_execution *read_request_execution);
+
+bool plc4c_read_request_has_error(plc4c_read_request_execution *read_request_execution);
+
+plc4c_read_response *plc4c_read_request_get_response(plc4c_read_request_execution *read_request_execution);
+
+void plc4c_read_request_destroy(plc4c_read_request *read_request);
+
+void plc4c_read_request_execution_destroy(plc4c_read_request_execution *read_request_execution);
 
 #ifdef __cplusplus
 }
diff --git a/sandbox/plc4c/api/include/plc4c/system.h b/sandbox/plc4c/api/include/plc4c/system.h
index 9ac46fe..4e9799e 100644
--- a/sandbox/plc4c/api/include/plc4c/system.h
+++ b/sandbox/plc4c/api/include/plc4c/system.h
@@ -164,6 +164,11 @@ void plc4c_system_set_on_disconnection_error(plc4c_system *system,
 void plc4c_system_set_on_loop_error(plc4c_system *system,
                                     plc4c_system_callback_loop_error callback);
 
+/**
+ * Function to manually add a driver to the system.
+ * @param driver instance of the driver
+ * @return return_code
+ */
 return_code plc4c_system_add_driver(plc4c_driver *driver);
 
 /**
@@ -188,9 +193,9 @@ void plc4c_system_shutdown(plc4c_system *system);
  * @param ponter to where the connection object will be created.
  * @return return_code INVALID_CONNECTION_STRING, NO_MEMORY
  */
-plc4c_promise* plc4c_system_connect(plc4c_system *system,
-                                   const char *connectionString,
-                                   plc4c_connection **connection);
+return_code plc4c_system_connect(plc4c_system *system,
+                                 const char *connectionString,
+                                 plc4c_connection **connection);
 
 /**
  * Function to give any drivers the chance to do their work.
diff --git a/sandbox/plc4c/api/include/plc4c/types.h b/sandbox/plc4c/api/include/plc4c/types.h
index 912d6e6..b63ba6d 100644
--- a/sandbox/plc4c/api/include/plc4c/types.h
+++ b/sandbox/plc4c/api/include/plc4c/types.h
@@ -69,60 +69,21 @@ typedef struct plc4c_connection_t plc4c_connection;
 typedef struct plc4c_read_request_t plc4c_read_request;
 
 /**
- * a plc4c write-request
- */
-typedef struct plc4c_write_request_t plc4c_write_request;
-
-/**
- * Return type for any form of async operation.
- */
-typedef struct plc4c_promise_t plc4c_promise;
-
-/**
- * Callback for any form of successful async operation.
- */
-typedef void (*plc4c_success_callback)(plc4c_promise *promise);
-
-/**
- * Callback for any form of failed async operation.
+ * a plc4c read-request-execution
  */
-typedef void (*plc4c_failure_callback)(plc4c_promise *promise);
+typedef struct plc4c_read_request_execution_t plc4c_read_request_execution;
 
-/**
- * Function to register a success callback on a given plc4c_promise.
- * @param promise the promise to set the callback on
- * @param successCallback the callback
- */
-void plc4c_promise_set_success_callback(plc4c_promise* promise, plc4c_success_callback successCallback);
-
-/**
- * Function to register a failure callback on a given plc4c_promise.
- * @param promise the promise to set the callback on
- * @param successCallback the callback
- */
-void plc4c_promise_set_failure_callback(plc4c_promise* promise, plc4c_failure_callback failureCallback);
+typedef struct plc4c_read_response_t plc4c_read_response;
 
 /**
- * Check if a promise is completed
- * @param promise the promise
- * @return true if the promise is in a final state
- */
-bool plc4c_promise_completed(plc4c_promise* promise);
-
-/**
- * Check if a promise is completed successfully
- * @param promise the promise
- * @return true if the promise is the state OK
+ * a plc4c write-request
  */
-bool plc4c_promise_completed_successfully(plc4c_promise* promise);
+typedef struct plc4c_write_request_t plc4c_write_request;
 
 /**
- * Check if a promise is completed unsuccessfully
- * @param promise the promise
- * @return true if the promise is in a final state other than OK
+ * a plc4c write-request-execution
  */
-bool plc4c_promise_completed_unsuccessfully(plc4c_promise* promise);
-
+typedef struct plc4c_write_request_execution_t plc4c_write_request_execution;
 
 #ifdef __cplusplus
 }
diff --git a/sandbox/plc4c/api/include/plc4c/write.h b/sandbox/plc4c/api/include/plc4c/write.h
index fa1d66e..ad0167a 100644
--- a/sandbox/plc4c/api/include/plc4c/write.h
+++ b/sandbox/plc4c/api/include/plc4c/write.h
@@ -28,10 +28,12 @@ extern "C" {
  * Actually executes the write-request.
  * @param connection connection this write-request will be executed on.
  * @param write_request the write-request object.
- * @return a plc4c_promise which allows asynchronously handling the request execution.
+ * @param write_request_execution pointer to a data-structure handling one execution of the write-request.
+ * @return return_code
  */
-plc4c_promise* plc4c_write_request_execute(plc4c_connection *connection,
-                                           plc4c_write_request *write_request);
+return_code plc4c_write_request_execute(plc4c_connection *connection,
+                                        plc4c_write_request *write_reques,
+                                        plc4c_write_request_execution **write_request_execution);
 
 #ifdef __cplusplus
 }
diff --git a/sandbox/plc4c/examples/hello-world/src/hello_world.c b/sandbox/plc4c/examples/hello-world/src/hello_world.c
index 10f7aa4..f5aad2e 100644
--- a/sandbox/plc4c/examples/hello-world/src/hello_world.c
+++ b/sandbox/plc4c/examples/hello-world/src/hello_world.c
@@ -20,10 +20,6 @@
 #include <plc4c/plc4c.h>
 #include <plc4c/driver_simulated.h>
 
-bool loop = true;
-plc4c_system *system = NULL;
-plc4c_connection *connection = NULL;
-
 int numOpenConnections = 0;
 
 /**
@@ -43,34 +39,23 @@ void onGlobalDisconnect(plc4c_connection *cur_connection) {
     numOpenConnections--;
 }
 
-void onDisconnectSuccess(plc4c_promise *promise) {
-    // Terminate the execution loop.
-    loop = false;
-}
-
-void onReadSuccess(plc4c_promise *promise) {
-    // TODO: Do something with the result.
-
-    plc4c_promise* disconnect_promise = plc4c_connection_disconnect(connection);
-    plc4c_promise_set_success_callback(disconnect_promise, &onDisconnectSuccess);
-}
-
-void onLocalConnectionSuccess(plc4c_promise* promise) {
-    if(plc4c_connection_supports_reading(connection)) {
-        char* addresses[] = {"RANDOM/foo:INTEGER"};
-        plc4c_read_request* read_request = plc4c_connection_create_read_request(connection, 1, addresses);
-        plc4c_promise* read_promise = plc4c_read_request_execute(connection, read_request);
-        // As the read_request is actually executed the next time the plc4c_system_loop
-        // is executed, we can now register some callbacks.
-        plc4c_promise_set_success_callback(read_promise, &onReadSuccess);
-    }
-}
-
-void onLocalConnectionFailure(plc4c_promise* promise) {
-    // TODO: Do something with the error.
-}
+enum plc4c_connection_state_t {
+    PRE_CONNECTION,
+    CONNECTED,
+    READ_REQUEST_SENT,
+    READ_RESPONSE_RECEIVED,
+    DISCONNECTING,
+    DISCONNECTED
+};
+typedef enum plc4c_connection_state_t plc4c_connection_state ;
 
 int main() {
+    bool loop = true;
+    plc4c_system *system = NULL;
+    plc4c_connection *connection = NULL;
+    plc4c_read_request *read_request = NULL;
+    plc4c_read_request_execution *read_request_execution = NULL;
+
     // Create a new uninitialized plc4c_system
     return_code result = plc4c_system_create(&system);
     if (result != OK) {
@@ -96,19 +81,84 @@ int main() {
 
     // Establish connections to remote devices
     // you may or may not care about the connection handle
-    plc4c_promise* connect_promise = plc4c_system_connect(system, "s7://192.168.42.20", &connection);
-    // Register some callbacks to be called as soon as the connection is established or fails.
-    plc4c_promise_set_success_callback(connect_promise, &onLocalConnectionSuccess);
-    plc4c_promise_set_failure_callback(connect_promise, &onLocalConnectionFailure);
-    if (plc4c_promise_completed_unsuccessfully(connect_promise)) {
+    result = plc4c_system_connect(system, "s7://192.168.42.20", &connection);
+    if (result != OK) {
         return -1;
     }
 
     // Central program loop ...
+    plc4c_connection_state state = PRE_CONNECTION;
     while (loop) {
         if (plc4c_system_loop(system) != OK) {
             break;
         }
+        switch (state) {
+            case PRE_CONNECTION: {
+                // Check if the connection is established:
+                if (plc4c_connection_is_connected(connection)) {
+                    state = CONNECTED;
+                } else if (plc4c_connection_has_error(connection)) {
+                    return -1;
+                }
+                break;
+            }
+            case CONNECTED: {
+                // Create a new read-request.
+                char *addresses[] = {"RANDOM/foo:INTEGER"};
+                result = plc4c_connection_create_read_request(connection, 1, addresses, &read_request);
+                if(result != OK) {
+                    return -1;
+                }
+
+                // Execute the read-request.
+                result = plc4c_read_request_execute(connection, read_request, &read_request_execution);
+                if(result != OK) {
+                    return -1;
+                } else {
+                    state = READ_REQUEST_SENT;
+                }
+                break;
+            }
+            // Wait until the read-request execution is finished.
+            case READ_REQUEST_SENT: {
+                if(plc4c_read_request_finished_successfully(read_request_execution)) {
+                    state = READ_RESPONSE_RECEIVED;
+                } else if(plc4c_read_request_has_error(read_request_execution)) {
+                    return -1;
+                }
+                break;
+            }
+            case READ_RESPONSE_RECEIVED: {
+                // Get the response for the given read-request.
+                plc4c_read_response *response = plc4c_read_request_get_response(read_request_execution);
+
+                // TODO: Do something sensible ...
+
+                // Clean up.
+                plc4c_read_request_execution_destroy(read_request_execution);
+                plc4c_read_request_destroy(read_request);
+
+                // Disconnect.
+                result = plc4c_connection_disconnect(connection);
+                if(result != OK) {
+                    return -1;
+                }
+                state = DISCONNECTING;
+                break;
+            }
+            // Wait until the connection is disconnected
+            case DISCONNECTING: {
+                if(!plc4c_connection_is_connected(connection)) {
+                    plc4c_connection_destroy(connection);
+                    state = DISCONNECTED;
+                }
+                break;
+            }
+            case DISCONNECTED: {
+                // End the loop.
+                loop = false;
+            }
+        }
     }
 
     // Make sure everything is cleaned up correctly.
diff --git a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
index bd6793c..d353c53 100644
--- a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
+++ b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
@@ -49,28 +49,22 @@ struct plc4c_connection_t {
     bool supports_subscriptions;
 };
 
-struct plc4c_promise_t {
-    return_code returnCode;
-    plc4c_success_callback successCallback;
-    plc4c_failure_callback failureCallback;
-};
-
 struct plc4c_read_request_t {
     plc4c_connection* connection;
     int num_items;
     plc4c_item items[];
 };
 
-struct plc_write_item_t {
-    plc4c_item item;
+struct plc4c_write_item_t {
+    plc4c_item *item;
     void* value;
 };
-typedef struct plc_write_item_t plc_write_item;
+typedef struct plc4c_write_item_t plc4c_write_item;
 
 struct plc4c_write_request_t {
     plc4c_connection* connection;
     int num_items;
-    plc_write_item items[];
+    plc4c_write_item* items;
 };
 
 #endif //PLC4C_SPI_TYPES_PRIVATE_H_
diff --git a/sandbox/plc4c/spi/src/connection.c b/sandbox/plc4c/spi/src/connection.c
index dbdd523..debf9f8 100644
--- a/sandbox/plc4c/spi/src/connection.c
+++ b/sandbox/plc4c/spi/src/connection.c
@@ -21,10 +21,20 @@
 #include <plc4c/connection.h>
 #include <plc4c/spi/types_private.h>
 
-plc4c_promise* plc4c_connection_disconnect(plc4c_connection *connection) {
-    plc4c_promise* result = (plc4c_promise*) malloc(sizeof(plc4c_promise));
-    result->returnCode = UNFINISHED;
-    return result;
+bool plc4c_connection_is_connected(plc4c_connection *connection) {
+    return true;
+}
+
+bool plc4c_connection_has_error(plc4c_connection *connection) {
+    return false;
+}
+
+return_code plc4c_connection_disconnect(plc4c_connection *connection) {
+    return OK;
+}
+
+void plc4c_connection_destroy(plc4c_connection *connection) {
+    free(connection);
 }
 
 char* plc4c_connection_get_connection_string(plc4c_connection *connection) {
@@ -35,16 +45,29 @@ bool plc4c_connection_supports_reading(plc4c_connection *connection) {
     return connection->supports_reading;
 }
 
-plc4c_read_request* plc4c_connection_create_read_request(plc4c_connection *connection, int num_items, char* addresses[]) {
-    plc4c_read_request* read_request = (plc4c_read_request*) malloc(sizeof(plc4c_read_request));
-    return read_request;
+return_code plc4c_connection_create_read_request(plc4c_connection *connection, int num_items, char* addresses[], plc4c_read_request** read_request) {
+    return OK;
 }
 
 bool plc4c_connection_supports_writing(plc4c_connection *connection) {
     return connection->supports_writing;
 }
 
-plc4c_write_request* plc4c_connection_create_write_request(plc4c_connection *connection, int num_items, char* addresses[], void* values[]) {
-    plc4c_write_request* write_request = (plc4c_write_request*) malloc(sizeof(plc4c_write_request));
-    return write_request;
+return_code plc4c_connection_create_write_request(plc4c_connection *connection, int num_items, char* addresses[], void* values[], plc4c_write_request** write_request) {
+    plc4c_write_request* new_write_request = (plc4c_write_request*) malloc(sizeof(plc4c_write_request));
+    new_write_request->num_items = num_items;
+    new_write_request->items = malloc(num_items * sizeof(plc4c_write_item*));
+    for(int i = 0; i < num_items; i++) {
+        char* address = addresses[i];
+        plc4c_item* addressItem = connection->driver.parse_address_function(address);
+
+        plc4c_write_item* write_item = malloc(sizeof(plc4c_write_item));
+        write_item->item = addressItem;
+        write_item->value = values[i];
+
+        new_write_request->items = write_item;
+    }
+    write_request = &new_write_request;
+
+    return OK;
 }
diff --git a/sandbox/plc4c/spi/src/read.c b/sandbox/plc4c/spi/src/read.c
index 44990d8..307268c 100644
--- a/sandbox/plc4c/spi/src/read.c
+++ b/sandbox/plc4c/spi/src/read.c
@@ -21,9 +21,29 @@
 #include <plc4c/read.h>
 #include <plc4c/spi/types_private.h>
 
-plc4c_promise* plc4c_read_request_execute(plc4c_connection *connection,
-                                          plc4c_read_request *read_request) {
-    plc4c_promise* result = (plc4c_promise*) malloc(sizeof(plc4c_promise));
-    result->returnCode = UNFINISHED;
-    return result;
+return_code plc4c_read_request_execute(plc4c_connection *connection,
+        plc4c_read_request *read_request,
+        plc4c_read_request_execution **read_request_execution) {
+    return OK;
 }
+
+bool plc4c_read_request_finished_successfully(plc4c_read_request_execution *read_request_execution) {
+    return true;
+}
+
+bool plc4c_read_request_has_error(plc4c_read_request_execution *read_request_execution) {
+    return false;
+}
+
+plc4c_read_response *plc4c_read_request_get_response(plc4c_read_request_execution *read_request_execution) {
+    return NULL;
+}
+
+void plc4c_read_request_destroy(plc4c_read_request *read_request) {
+    free(read_request);
+}
+
+void plc4c_read_request_execution_destroy(plc4c_read_request_execution *read_request_execution) {
+    free(read_request_execution);
+}
+
diff --git a/sandbox/plc4c/spi/src/system.c b/sandbox/plc4c/spi/src/system.c
index 8edbddd..aa8761d 100644
--- a/sandbox/plc4c/spi/src/system.c
+++ b/sandbox/plc4c/spi/src/system.c
@@ -76,12 +76,10 @@ void plc4c_system_shutdown(plc4c_system *system) {
 
 }
 
-plc4c_promise* plc4c_system_connect(plc4c_system *system,
+return_code plc4c_system_connect(plc4c_system *system,
                                    const char *connectionString,
                                    plc4c_connection **connection) {
-    plc4c_promise* result = (plc4c_promise*) malloc(sizeof(plc4c_promise));
-    result->returnCode = UNFINISHED;
-    return result;
+    return OK;
 }
 
 return_code plc4c_system_loop() {
diff --git a/sandbox/plc4c/spi/src/types.c b/sandbox/plc4c/spi/src/types.c
index 301aa36..dd29caf 100644
--- a/sandbox/plc4c/spi/src/types.c
+++ b/sandbox/plc4c/spi/src/types.c
@@ -24,23 +24,3 @@ char *plc4c_return_code_to_message(return_code err) {
     return "hurz";
 }
 
-void plc4c_promise_set_success_callback(plc4c_promise* promise, plc4c_success_callback successCallback) {
-    promise->successCallback = successCallback;
-}
-
-void plc4c_promise_set_failure_callback(plc4c_promise* promise, plc4c_failure_callback failureCallback) {
-    promise->failureCallback = failureCallback;
-}
-
-bool plc4c_promise_completed(plc4c_promise* promise) {
-    return promise->returnCode != UNFINISHED;
-}
-
-bool plc4c_promise_completed_successfully(plc4c_promise* promise) {
-    return promise->returnCode == OK;
-}
-
-bool plc4c_promise_completed_unsuccessfully(plc4c_promise* promise) {
-    return plc4c_promise_completed(promise) && !plc4c_promise_completed_successfully(promise);
-}
-
diff --git a/sandbox/plc4c/spi/src/write.c b/sandbox/plc4c/spi/src/write.c
index 96e02e2..a54fb27 100644
--- a/sandbox/plc4c/spi/src/write.c
+++ b/sandbox/plc4c/spi/src/write.c
@@ -21,9 +21,8 @@
 #include <plc4c/read.h>
 #include <plc4c/spi/types_private.h>
 
-plc4c_promise* plc4c_write_request_execute(plc4c_connection *connection,
-                                          plc4c_write_request *write_request) {
-    plc4c_promise* result = (plc4c_promise*) malloc(sizeof(plc4c_promise));
-    result->returnCode = UNFINISHED;
-    return result;
+return_code plc4c_write_request_execute(plc4c_connection *connection,
+                                           plc4c_write_request *write_request,
+                                           plc4c_write_request_execution **write_request_execution) {
+    return OK;
 }