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 14:10:29 UTC

[plc4x] branch feature/c-api-read-support created (now 46a526d)

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

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


      at 46a526d  - Added some super rudimentary API support for reading and writing

This branch includes the following new commits:

     new 46a526d  - Added some super rudimentary API support for reading and writing

The 1 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.



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

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

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

commit 46a526d7751a8e94d11635f47084f22d7d4a7c83
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Mon Apr 27 16:10:22 2020 +0200

    - Added some super rudimentary API support for reading and writing
---
 sandbox/plc4c/api/include/plc4c/connection.h       | 44 +++++++++++++++++-
 sandbox/plc4c/api/include/plc4c/plc4c.h            |  2 +
 .../plc4c/api/include/plc4c/{plc4c.h => read.h}    | 19 +++++---
 sandbox/plc4c/api/include/plc4c/system.h           |  3 +-
 sandbox/plc4c/api/include/plc4c/types.h            | 10 ++++
 .../plc4c/api/include/plc4c/{plc4c.h => write.h}   | 19 +++++---
 .../plc4c/drivers/simulated/src/driver_simulated.c | 16 +++++++
 .../plc4c/examples/hello-world/src/hello_world.c   | 54 +++++++++++++++++-----
 .../plc4c/spi/include/plc4c/spi/types_private.h    | 37 +++++++++++++--
 sandbox/plc4c/spi/src/connection.c                 | 24 +++++++++-
 sandbox/plc4c/spi/src/{connection.c => read.c}     | 15 +++---
 sandbox/plc4c/spi/src/{connection.c => write.c}    | 15 +++---
 12 files changed, 206 insertions(+), 52 deletions(-)

diff --git a/sandbox/plc4c/api/include/plc4c/connection.h b/sandbox/plc4c/api/include/plc4c/connection.h
index 44f4e8b..c03e918 100644
--- a/sandbox/plc4c/api/include/plc4c/connection.h
+++ b/sandbox/plc4c/api/include/plc4c/connection.h
@@ -41,15 +41,55 @@ extern "C" {
  * Function to terminate a connection to a PLC.
  *
  * @param connection
- * @param plc4c_connection
+ * @param plc4c_promise
  */
-return_code plc4c_connection_disconnect(plc4c_connection *connection);
+plc4c_promise* plc4c_connection_disconnect(plc4c_connection *connection);
 
 /**
  * Get the connection string from a given connection.
  */
 char* plc4c_connection_get_connection_string(plc4c_connection *connection);
 
+/**
+ * Check if the current connection supports read operations.
+ * @param connection reference to the connection
+ * @return true if the connection supports reading, false otherwise
+ */
+bool plc4c_connection_supports_reading(plc4c_connection *connection);
+
+/**
+ * Initializes an empty read-request
+ * @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.
+ */
+plc4c_read_request* plc4c_connection_create_read_request(plc4c_connection *connection, int num_items, char* addresses[]);
+
+/**
+ * Check if the current connection supports write operations.
+ * @param connection reference to the connection
+ * @return true if the connection supports writing, false otherwise
+ */
+bool plc4c_connection_supports_writing(plc4c_connection *connection);
+
+/**
+ * Initializes an empty write-request
+ * @param connection connection that this write-request will be executed on.
+ * @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
+ */
+plc4c_write_request* plc4c_connection_create_write_request(plc4c_connection *connection, int num_items, char* addresses[], void* values[]);
+
+/**
+ * Check if the current connection supports subscriptions.
+ * @param connection reference to the connection
+ * @return true if the connection supports subscriptions, false otherwise
+ */
+bool plc4c_connection_supports_subscriptions(plc4c_connection *connection);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/sandbox/plc4c/api/include/plc4c/plc4c.h b/sandbox/plc4c/api/include/plc4c/plc4c.h
index ea09afd..a3ebd7d 100644
--- a/sandbox/plc4c/api/include/plc4c/plc4c.h
+++ b/sandbox/plc4c/api/include/plc4c/plc4c.h
@@ -27,6 +27,8 @@ extern "C" {
 #include "plc4c/types.h"
 #include "plc4c/system.h"
 #include "plc4c/connection.h"
+#include "plc4c/read.h"
+#include "plc4c/write.h"
 
 #ifdef __cplusplus
 }
diff --git a/sandbox/plc4c/api/include/plc4c/plc4c.h b/sandbox/plc4c/api/include/plc4c/read.h
similarity index 65%
copy from sandbox/plc4c/api/include/plc4c/plc4c.h
copy to sandbox/plc4c/api/include/plc4c/read.h
index ea09afd..6d11041 100644
--- a/sandbox/plc4c/api/include/plc4c/plc4c.h
+++ b/sandbox/plc4c/api/include/plc4c/read.h
@@ -16,19 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-#ifndef PLC4C_H_
-#define PLC4C_H_
+#ifndef PLC4C_READ_H_
+#define PLC4C_READ_H_
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/* Convenience header file that just imports all the different parts of the API */
-
 #include "plc4c/types.h"
-#include "plc4c/system.h"
-#include "plc4c/connection.h"
+
+/**
+ * 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.
+ */
+plc4c_promise* plc4c_read_request_execute(plc4c_connection *connection,
+                                          plc4c_read_request *read_request);
 
 #ifdef __cplusplus
 }
 #endif
-#endif //PLC4C_H_
\ No newline at end of file
+#endif //PLC4C_READ_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/api/include/plc4c/system.h b/sandbox/plc4c/api/include/plc4c/system.h
index b656fa0..9ac46fe 100644
--- a/sandbox/plc4c/api/include/plc4c/system.h
+++ b/sandbox/plc4c/api/include/plc4c/system.h
@@ -184,7 +184,8 @@ void plc4c_system_shutdown(plc4c_system *system);
  * and setting the passed connection system
  *
  * @param system
- * @param connectionString
+ * @param connection_string
+ * @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,
diff --git a/sandbox/plc4c/api/include/plc4c/types.h b/sandbox/plc4c/api/include/plc4c/types.h
index 84c6645..912d6e6 100644
--- a/sandbox/plc4c/api/include/plc4c/types.h
+++ b/sandbox/plc4c/api/include/plc4c/types.h
@@ -64,6 +64,16 @@ typedef struct plc4c_driver_t plc4c_driver;
 typedef struct plc4c_connection_t plc4c_connection;
 
 /**
+ * a plc4c read-request
+ */
+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;
diff --git a/sandbox/plc4c/api/include/plc4c/plc4c.h b/sandbox/plc4c/api/include/plc4c/write.h
similarity index 65%
copy from sandbox/plc4c/api/include/plc4c/plc4c.h
copy to sandbox/plc4c/api/include/plc4c/write.h
index ea09afd..fa1d66e 100644
--- a/sandbox/plc4c/api/include/plc4c/plc4c.h
+++ b/sandbox/plc4c/api/include/plc4c/write.h
@@ -16,19 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-#ifndef PLC4C_H_
-#define PLC4C_H_
+#ifndef PLC4C_WRITE_H_
+#define PLC4C_WRITE_H_
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/* Convenience header file that just imports all the different parts of the API */
-
 #include "plc4c/types.h"
-#include "plc4c/system.h"
-#include "plc4c/connection.h"
+
+/**
+ * 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.
+ */
+plc4c_promise* plc4c_write_request_execute(plc4c_connection *connection,
+                                           plc4c_write_request *write_request);
 
 #ifdef __cplusplus
 }
 #endif
-#endif //PLC4C_H_
\ No newline at end of file
+#endif //PLC4C_WRITE_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/simulated/src/driver_simulated.c b/sandbox/plc4c/drivers/simulated/src/driver_simulated.c
index 4684340..11aab46 100644
--- a/sandbox/plc4c/drivers/simulated/src/driver_simulated.c
+++ b/sandbox/plc4c/drivers/simulated/src/driver_simulated.c
@@ -21,8 +21,24 @@
 #include <plc4c/spi/types_private.h>
 #include <plc4c/driver_simulated.h>
 
+struct plc4c_driver_simulated_item_t {
+    // Sort of senseless, but for keeping track of the fact that it's an plc4c_item.
+    plc4c_item super;
+
+    // Actual properties goes here ...
+};
+typedef struct plc4c_driver_simulated_item_t plc4c_driver_simulated_item ;
+
+plc4c_item *plc4c_driver_simulated_parse_address(const char* address_string) {
+    plc4c_driver_simulated_item* item = (plc4c_driver_simulated_item*) malloc(sizeof(plc4c_driver_simulated_item));
+    return (plc4c_item*) item;
+}
+
 plc4c_driver *plc4c_driver_simulated_create() {
     plc4c_driver* driver = (plc4c_driver*) malloc(sizeof(plc4c_driver));
+    driver->protocol_code = "simulated";
+    driver->protocol_name = "Simulated PLC4X Datasource";
+    driver->parse_address_function = &plc4c_driver_simulated_parse_address;
     return driver;
 }
 
diff --git a/sandbox/plc4c/examples/hello-world/src/hello_world.c b/sandbox/plc4c/examples/hello-world/src/hello_world.c
index e4b669e..10f7aa4 100644
--- a/sandbox/plc4c/examples/hello-world/src/hello_world.c
+++ b/sandbox/plc4c/examples/hello-world/src/hello_world.c
@@ -20,27 +20,57 @@
 #include <plc4c/plc4c.h>
 #include <plc4c/driver_simulated.h>
 
-void onGlobalConnectionSuccess(plc4c_connection *connection) {
-    printf("Connected to %s", plc4c_connection_get_connection_string(connection));
+bool loop = true;
+plc4c_system *system = NULL;
+plc4c_connection *connection = NULL;
+
+int numOpenConnections = 0;
+
+/**
+ * Here we could implement something that keeps track of all open connections.
+ * For example on embedded devices using the W5100 SPI Network device, this can
+ * only handle 4 simultaneous connections.
+ *
+ * @param connection the connection that was just established
+ */
+void onGlobalConnect(plc4c_connection *cur_connection) {
+    printf("Connected to %s", plc4c_connection_get_connection_string(cur_connection));
+    numOpenConnections++;
 }
 
-void onGlobalConnectionError(const char *connection_string, return_code error) {
-    printf("Error connecting to %s. Got error %s", connection_string, plc4c_return_code_to_message(error));
+void onGlobalDisconnect(plc4c_connection *cur_connection) {
+    printf("Disconnected from %s", plc4c_connection_get_connection_string(cur_connection));
+    numOpenConnections--;
 }
 
-void onLocalConnectionSuccess(plc4c_promise* promise) {
+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 onLocalConnectionFailure(plc4c_promise* promise) {
+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.
 }
 
 int main() {
-    bool loop = true;
-    plc4c_system *system = NULL;
-    plc4c_connection *connection = NULL;
-
     // Create a new uninitialized plc4c_system
     return_code result = plc4c_system_create(&system);
     if (result != OK) {
@@ -61,8 +91,8 @@ int main() {
     }
 
     // Register the global callbacks.
-    plc4c_system_set_on_connection(system, &onGlobalConnectionSuccess);
-    plc4c_system_set_on_connection_error(system, &onGlobalConnectionError);
+    plc4c_system_set_on_connection(system, &onGlobalConnect);
+    plc4c_system_set_on_disconnection(system, &onGlobalDisconnect);
 
     // Establish connections to remote devices
     // you may or may not care about the connection handle
diff --git a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
index afe3c83..bd6793c 100644
--- a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
+++ b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
@@ -29,15 +29,24 @@ struct plc4c_system_t {
   /* callbacks */
 };
 
-struct plc4c_driver_t {
-  /* name */
+struct plc4c_item_t {
+};
+typedef struct plc4c_item_t plc4c_item;
+
+typedef plc4c_item* (*plc4c_connection_parse_address_item)(const char *address_string);
 
-  /* ??? */
+struct plc4c_driver_t {
+    char* protocol_code;
+    char* protocol_name;
+    plc4c_connection_parse_address_item parse_address_function;
 };
 
 struct plc4c_connection_t {
-  char* connection_string;
-  /* ???? */
+    plc4c_driver driver;
+    char* connection_string;
+    bool supports_reading;
+    bool supports_writing;
+    bool supports_subscriptions;
 };
 
 struct plc4c_promise_t {
@@ -46,4 +55,22 @@ struct plc4c_promise_t {
     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;
+    void* value;
+};
+typedef struct plc_write_item_t plc_write_item;
+
+struct plc4c_write_request_t {
+    plc4c_connection* connection;
+    int num_items;
+    plc_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 4028f07..dbdd523 100644
--- a/sandbox/plc4c/spi/src/connection.c
+++ b/sandbox/plc4c/spi/src/connection.c
@@ -17,14 +17,34 @@
  * under the License.
  */
 
+#include <stdlib.h>
 #include <plc4c/connection.h>
 #include <plc4c/spi/types_private.h>
 
-return_code plc4c_connection_disconnect(plc4c_connection *connection) {
-    return OK;
+plc4c_promise* plc4c_connection_disconnect(plc4c_connection *connection) {
+    plc4c_promise* result = (plc4c_promise*) malloc(sizeof(plc4c_promise));
+    result->returnCode = UNFINISHED;
+    return result;
 }
 
 char* plc4c_connection_get_connection_string(plc4c_connection *connection) {
     return connection->connection_string;
 }
 
+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;
+}
+
+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;
+}
diff --git a/sandbox/plc4c/spi/src/connection.c b/sandbox/plc4c/spi/src/read.c
similarity index 72%
copy from sandbox/plc4c/spi/src/connection.c
copy to sandbox/plc4c/spi/src/read.c
index 4028f07..44990d8 100644
--- a/sandbox/plc4c/spi/src/connection.c
+++ b/sandbox/plc4c/spi/src/read.c
@@ -17,14 +17,13 @@
  * under the License.
  */
 
-#include <plc4c/connection.h>
+#include <stdlib.h>
+#include <plc4c/read.h>
 #include <plc4c/spi/types_private.h>
 
-return_code plc4c_connection_disconnect(plc4c_connection *connection) {
-    return OK;
+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;
 }
-
-char* plc4c_connection_get_connection_string(plc4c_connection *connection) {
-    return connection->connection_string;
-}
-
diff --git a/sandbox/plc4c/spi/src/connection.c b/sandbox/plc4c/spi/src/write.c
similarity index 72%
copy from sandbox/plc4c/spi/src/connection.c
copy to sandbox/plc4c/spi/src/write.c
index 4028f07..96e02e2 100644
--- a/sandbox/plc4c/spi/src/connection.c
+++ b/sandbox/plc4c/spi/src/write.c
@@ -17,14 +17,13 @@
  * under the License.
  */
 
-#include <plc4c/connection.h>
+#include <stdlib.h>
+#include <plc4c/read.h>
 #include <plc4c/spi/types_private.h>
 
-return_code plc4c_connection_disconnect(plc4c_connection *connection) {
-    return OK;
+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;
 }
-
-char* plc4c_connection_get_connection_string(plc4c_connection *connection) {
-    return connection->connection_string;
-}
-