This is an automated email from the ASF dual-hosted git repository. cdutz pushed a commit to branch feature/c-api in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/feature/c-api by this push: new 8201450 - Made the drivers check the number of active system-tasks when disconnecting - Cleaned up the way the system-tasks are created - Ensured all properties of malloced structures are initialized 8201450 is described below commit 82014509987eea58cd57d8ec9dd1b5b03c0379c5 Author: Christofer Dutz <christofer.d...@c-ware.de> AuthorDate: Wed May 6 17:34:02 2020 +0200 - Made the drivers check the number of active system-tasks when disconnecting - Cleaned up the way the system-tasks are created - Ensured all properties of malloced structures are initialized --- sandbox/plc4c/drivers/modbus/src/driver_modbus.c | 4 + sandbox/plc4c/drivers/s7/src/driver_s7.c | 4 + .../plc4c/drivers/simulated/src/driver_simulated.c | 85 +++++++++++++++------- .../plc4c/examples/hello-world/src/hello_world.c | 4 +- .../plc4c/spi/include/plc4c/spi/types_private.h | 8 +- sandbox/plc4c/spi/src/read.c | 15 ++-- sandbox/plc4c/spi/src/write.c | 15 ++-- 7 files changed, 87 insertions(+), 48 deletions(-) diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus.c index f046d5d..9edaf20 100644 --- a/sandbox/plc4c/drivers/modbus/src/driver_modbus.c +++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus.c @@ -27,8 +27,12 @@ plc4c_driver *plc4c_driver_modbus_create() { driver->protocol_name = "Modbus"; driver->default_transport_code = "tcp"; driver->parse_address_function = NULL; + driver->connect_function = NULL; + driver->disconnect_function = NULL; driver->read_function = NULL; driver->write_function = NULL; + driver->free_read_response_function = NULL; + driver->free_write_response_function = NULL; return driver; } diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7.c b/sandbox/plc4c/drivers/s7/src/driver_s7.c index 739c0e2..8119f14 100644 --- a/sandbox/plc4c/drivers/s7/src/driver_s7.c +++ b/sandbox/plc4c/drivers/s7/src/driver_s7.c @@ -27,8 +27,12 @@ plc4c_driver *plc4c_driver_s7_create() { driver->protocol_name = "Siemens S7 (Basic)"; driver->default_transport_code = "tcp"; driver->parse_address_function = NULL; + driver->connect_function = NULL; + driver->disconnect_function = NULL; driver->read_function = NULL; driver->write_function = NULL; + driver->free_read_response_function = NULL; + driver->free_write_response_function = NULL; return driver; } diff --git a/sandbox/plc4c/drivers/simulated/src/driver_simulated.c b/sandbox/plc4c/drivers/simulated/src/driver_simulated.c index b9aacee..4c01019 100644 --- a/sandbox/plc4c/drivers/simulated/src/driver_simulated.c +++ b/sandbox/plc4c/drivers/simulated/src/driver_simulated.c @@ -33,14 +33,20 @@ typedef enum plc4c_driver_simulated_field_type_t plc4c_driver_simulated_field_ty typedef enum plc4c_driver_simulated_field_datatype_t plc4c_driver_simulated_field_datatype; // State definitions +enum plc4c_driver_simulated_disconnect_states { + PLC4C_DRIVER_SIMULATED_DISCONNECT_INIT, + PLC4C_DRIVER_SIMULATED_DISCONNECT_WAIT_TASKS_FINISHED, + PLC4C_DRIVER_SIMULATED_DISCONNECT_FINISHED +}; + enum read_states { - READ_INIT, - READ_FINISHED + PLC4C_DRIVER_SIMULATED_READ_INIT, + PLC4C_DRIVER_SIMULATED_READ_FINISHED }; enum write_states { - WRITE_INIT, - WRITE_FINISHED + PLC4C_DRIVER_SIMULATED_WRITE_INIT, + PLC4C_DRIVER_SIMULATED_WRITE_FINISHED }; struct plc4c_driver_simulated_item_t { @@ -69,11 +75,30 @@ plc4c_return_code plc4c_driver_simulated_disconnect_machine_function(plc4c_syste if (connection == NULL) { return INTERNAL_ERROR; } - if (!connection->connected) { - return INTERNAL_ERROR; + + switch (task->state_id) { + case PLC4C_DRIVER_SIMULATED_DISCONNECT_INIT: { + connection->disconnect = true; + task->state_id = PLC4C_DRIVER_SIMULATED_DISCONNECT_WAIT_TASKS_FINISHED; + break; + } + case PLC4C_DRIVER_SIMULATED_DISCONNECT_WAIT_TASKS_FINISHED: { + // The disconnect system-task also counts. + if(connection->num_running_system_tasks == 1) { + connection->connected = false; + task->completed = true; + task->state_id = PLC4C_DRIVER_SIMULATED_DISCONNECT_FINISHED; + } + break; + } + case PLC4C_DRIVER_SIMULATED_DISCONNECT_FINISHED: { + // Do nothing + break; + } + default: { + return INTERNAL_ERROR; + } } - connection->connected = false; - task->completed = true; return OK; } @@ -85,7 +110,7 @@ plc4c_return_code plc4c_driver_simulated_read_machine_function(plc4c_system_task plc4c_read_request_execution *read_request_execution = task->context; plc4c_read_request *read_request = read_request_execution->read_request; switch (task->state_id) { - case READ_INIT: { + case PLC4C_DRIVER_SIMULATED_READ_INIT: { // Create a response. plc4c_read_response *read_response = malloc(sizeof(plc4c_read_response)); read_response->read_request = read_request; @@ -97,7 +122,7 @@ plc4c_return_code plc4c_driver_simulated_read_machine_function(plc4c_system_task plc4c_driver_simulated_item *cur_item = cur_element->value; plc4c_response_value_item *value_item = malloc(sizeof(plc4c_response_value_item)); value_item->item = (plc4c_item *) cur_item; - + value_item->response_code = PLC4C_RESPONSE_CODE_OK; /* * create the plc4c_data * if this were a custom type we could set a custom destroy method @@ -105,7 +130,6 @@ plc4c_return_code plc4c_driver_simulated_read_machine_function(plc4c_system_task * right , now just create a new random value */ value_item->value = plc4c_data_create_uint_data(arc4random()); - value_item->response_code = PLC4C_RESPONSE_CODE_OK; // Add the value to the response. plc4c_utils_list_insert_tail_value(read_response->items, value_item); @@ -113,11 +137,11 @@ plc4c_return_code plc4c_driver_simulated_read_machine_function(plc4c_system_task } read_request_execution->read_response = read_response; - task->state_id = READ_FINISHED; + task->state_id = PLC4C_DRIVER_SIMULATED_READ_FINISHED; task->completed = true; break; } - case READ_FINISHED: { + case PLC4C_DRIVER_SIMULATED_READ_FINISHED: { // Do nothing break; } @@ -136,7 +160,7 @@ plc4c_return_code plc4c_driver_simulated_write_machine_function(plc4c_system_tas plc4c_write_request_execution *write_request_execution = task->context; plc4c_write_request *write_request = write_request_execution->write_request; switch (task->state_id) { - case WRITE_INIT: { + case PLC4C_DRIVER_SIMULATED_WRITE_INIT: { // Create a response. plc4c_write_response *write_response = malloc(sizeof(plc4c_write_response)); write_response->write_request = write_request; @@ -183,11 +207,11 @@ plc4c_return_code plc4c_driver_simulated_write_machine_function(plc4c_system_tas } write_request_execution->write_response = write_response; - task->state_id = WRITE_FINISHED; + task->state_id = PLC4C_DRIVER_SIMULATED_WRITE_FINISHED; task->completed = true; break; } - case WRITE_FINISHED: { + case PLC4C_DRIVER_SIMULATED_WRITE_FINISHED: { // Do nothing break; } @@ -274,10 +298,11 @@ plc4c_item *plc4c_driver_simulated_parse_address(char *address_string) { plc4c_return_code plc4c_driver_simulated_connect_function(plc4c_connection *connection, plc4c_system_task **task) { plc4c_system_task *new_task = malloc(sizeof(plc4c_system_task)); - new_task->context = connection; // There's nothing to do here, so no need for a state-machine. new_task->state_id = -1; new_task->state_machine_function = &plc4c_driver_simulated_connect_machine_function; + new_task->completed = false; + new_task->context = connection; new_task->connection = connection; *task = new_task; return OK; @@ -286,33 +311,41 @@ plc4c_return_code plc4c_driver_simulated_connect_function(plc4c_connection *conn plc4c_return_code plc4c_driver_simulated_disconnect_function(plc4c_connection *connection, plc4c_system_task **task) { plc4c_system_task *new_task = malloc(sizeof(plc4c_system_task)); - new_task->context = connection; - // There's nothing to do here, so no need for a state-machine. - new_task->state_id = -1; + new_task->state_id = PLC4C_DRIVER_SIMULATED_DISCONNECT_INIT; new_task->state_machine_function = &plc4c_driver_simulated_disconnect_machine_function; + new_task->completed = false; + new_task->context = connection; new_task->connection = connection; *task = new_task; return OK; } -plc4c_return_code plc4c_driver_simulated_read_function(plc4c_connection *connection, +plc4c_return_code plc4c_driver_simulated_read_function(plc4c_read_request_execution *read_request_execution, plc4c_system_task **task) { plc4c_system_task *new_task = malloc(sizeof(plc4c_system_task)); - new_task->state_id = READ_INIT; + new_task->state_id = PLC4C_DRIVER_SIMULATED_READ_INIT; new_task->state_machine_function = &plc4c_driver_simulated_read_machine_function; new_task->completed = false; - new_task->connection = connection; + new_task->context = read_request_execution; + new_task->connection = read_request_execution->read_request->connection; + + read_request_execution->system_task = new_task; + *task = new_task; return OK; } -plc4c_return_code plc4c_driver_simulated_write_function(plc4c_connection *connection, +plc4c_return_code plc4c_driver_simulated_write_function(plc4c_write_request_execution *write_request_execution, plc4c_system_task **task) { plc4c_system_task *new_task = malloc(sizeof(plc4c_system_task)); - new_task->state_id = WRITE_INIT; + new_task->state_id = PLC4C_DRIVER_SIMULATED_WRITE_INIT; new_task->state_machine_function = &plc4c_driver_simulated_write_machine_function; new_task->completed = false; - new_task->connection = connection; + new_task->context = write_request_execution; + new_task->connection = write_request_execution->write_request->connection; + + write_request_execution->system_task = new_task; + *task = new_task; return OK; } diff --git a/sandbox/plc4c/examples/hello-world/src/hello_world.c b/sandbox/plc4c/examples/hello-world/src/hello_world.c index d95616b..17806b1 100644 --- a/sandbox/plc4c/examples/hello-world/src/hello_world.c +++ b/sandbox/plc4c/examples/hello-world/src/hello_world.c @@ -220,7 +220,7 @@ int main() { } // Clean up. - plc4c_connection_read_response_destroy(read_response); + //plc4c_connection_read_response_destroy(read_response); plc4c_read_request_execution_destroy(read_request_execution); plc4c_read_request_destroy(read_request); @@ -284,7 +284,7 @@ int main() { // Clean up. plc4c_connection_write_response_destroy(write_response); - plc4c_read_request_execution_destroy(read_request_execution); + //plc4c_read_request_execution_destroy(read_request_execution); plc4c_read_request_destroy(read_request); // Disconnect. diff --git a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h index fb99b9f..cbcb723 100644 --- a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h +++ b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h @@ -47,10 +47,10 @@ typedef plc4c_return_code (*plc4c_connection_connect_function)(plc4c_connection typedef plc4c_return_code (*plc4c_connection_disconnect_function)(plc4c_connection *connection, plc4c_system_task **task); -typedef plc4c_return_code (*plc4c_connection_read_function)(plc4c_connection *connection, +typedef plc4c_return_code (*plc4c_connection_read_function)(plc4c_read_request_execution *read_request_execution, plc4c_system_task **task); -typedef plc4c_return_code (*plc4c_connection_write_function)(plc4c_connection *connection, +typedef plc4c_return_code (*plc4c_connection_write_function)(plc4c_write_request_execution *write_request_execution, plc4c_system_task **task); typedef void (*plc4c_connect_free_read_response_function)(plc4c_read_response *response); @@ -123,7 +123,6 @@ struct plc4c_connection_t { char *parameters; bool connected; - // Internal flag indicating the connection should be disconnected bool disconnect; // Number of system_tasks currently still active in the system. @@ -132,6 +131,7 @@ struct plc4c_connection_t { plc4c_system *system; plc4c_driver *driver; plc4c_transport *transport; + bool supports_reading; bool supports_writing; bool supports_subscriptions; @@ -216,9 +216,9 @@ struct plc4c_write_response_t { struct plc4c_system_task_t { int state_id; plc4c_system_task_state_machine_function state_machine_function; - void *context; bool completed; + void *context; // Reference to the connection that owns this task plc4c_connection *connection; }; diff --git a/sandbox/plc4c/spi/src/read.c b/sandbox/plc4c/spi/src/read.c index abcfda6..f0958d3 100644 --- a/sandbox/plc4c/spi/src/read.c +++ b/sandbox/plc4c/spi/src/read.c @@ -24,20 +24,19 @@ plc4c_return_code plc4c_read_request_execute(plc4c_read_request *read_request, plc4c_read_request_execution **read_request_execution) { + // Inject the default read context into the system task. + plc4c_read_request_execution *new_read_request_execution = malloc(sizeof(plc4c_read_request_execution)); + new_read_request_execution->read_request = read_request; + new_read_request_execution->read_response = NULL; + new_read_request_execution->system_task = NULL; + plc4c_system_task *system_task; - read_request->connection->driver->read_function(read_request->connection, &system_task); + read_request->connection->driver->read_function(new_read_request_execution, &system_task); // Increment the number of running tasks for this connection. read_request->connection->num_running_system_tasks++; // Add the new task to the task-list. plc4c_utils_list_insert_tail_value(read_request->connection->system->task_list, system_task); - // Inject the default read context into the system task. - plc4c_read_request_execution *new_read_request_execution = malloc(sizeof(plc4c_read_request_execution)); - new_read_request_execution->read_request = read_request; - new_read_request_execution->read_response = NULL; - new_read_request_execution->system_task = system_task; - new_read_request_execution->system_task->context = new_read_request_execution; - *read_request_execution = new_read_request_execution; return OK; } diff --git a/sandbox/plc4c/spi/src/write.c b/sandbox/plc4c/spi/src/write.c index 19c0ec0..228876a 100644 --- a/sandbox/plc4c/spi/src/write.c +++ b/sandbox/plc4c/spi/src/write.c @@ -23,20 +23,19 @@ plc4c_return_code plc4c_write_request_execute(plc4c_write_request *write_request, plc4c_write_request_execution **write_request_execution) { + // Inject the default write context into the system task. + plc4c_write_request_execution *new_write_request_execution = malloc(sizeof(plc4c_write_request_execution)); + new_write_request_execution->write_request = write_request; + new_write_request_execution->write_response = NULL; + new_write_request_execution->system_task = NULL; + plc4c_system_task *system_task; - write_request->connection->driver->write_function(write_request->connection, &system_task); + write_request->connection->driver->write_function(new_write_request_execution, &system_task); // Increment the number of running tasks for this connection. write_request->connection->num_running_system_tasks++; // Add the new task to the task-list. plc4c_utils_list_insert_tail_value(write_request->connection->system->task_list, system_task); - // Inject the default write context into the system task. - plc4c_write_request_execution *new_write_request_execution = malloc(sizeof(plc4c_write_request_execution)); - new_write_request_execution->write_request = write_request; - new_write_request_execution->write_response = NULL; - new_write_request_execution->system_task = system_task; - new_write_request_execution->system_task->context = new_write_request_execution; - *write_request_execution = new_write_request_execution; return OK; }