From f6d84fb9c55419ce65350cdd5a769a2f328e2ad1 Mon Sep 17 00:00:00 2001 From: Otto Fowler Date: Tue, 5 May 2020 15:57:02 -0400 Subject: [PATCH] integrate writes with plc_data --- sandbox/plc4c/api/include/plc4c/data.h | 10 ++- sandbox/plc4c/api/include/plc4c/types.h | 18 ++-- .../drivers/simulated/src/driver_simulated.c | 88 +++++++------------ .../examples/hello-world/src/hello_world.c | 8 +- .../spi/include/plc4c/spi/types_private.h | 2 +- sandbox/plc4c/spi/src/connection.c | 2 +- sandbox/plc4c/spi/src/data.c | 23 +++-- sandbox/plc4c/spi/src/types.c | 42 +++++++++ 8 files changed, 117 insertions(+), 76 deletions(-) diff --git a/sandbox/plc4c/api/include/plc4c/data.h b/sandbox/plc4c/api/include/plc4c/data.h index 7afe2c50b56..56f2b85b8ec 100644 --- a/sandbox/plc4c/api/include/plc4c/data.h +++ b/sandbox/plc4c/api/include/plc4c/data.h @@ -104,9 +104,17 @@ plc4c_data *plc4c_data_create_float_data(float f); */ plc4c_data *plc4c_data_create_string_data( unsigned int size, char* s); +/** + * Creates a plc4c_data with a constant char* + * @param size the size of the string + * @param s the char *value + * @return pointer to plc4c_data + */ +plc4c_data *plc4c_data_create_constant_string_data( unsigned int size, char *s); + /** * Set a custom function to call when destroying this data. Typically when the type is - * a PLC4C_VOIDP + * a PLC4C_VOID_POINTER * @param data pointer to plc4c_data * @param data_custom_destroy the function to call */ diff --git a/sandbox/plc4c/api/include/plc4c/types.h b/sandbox/plc4c/api/include/plc4c/types.h index 27c70709453..6697815aed9 100644 --- a/sandbox/plc4c/api/include/plc4c/types.h +++ b/sandbox/plc4c/api/include/plc4c/types.h @@ -71,12 +71,13 @@ typedef enum plc4c_data_type { PLC4C_INT, PLC4C_UINT, PLC4C_FLOAT, - PLC4C_STRINGP, - PLC4C_VOIDP + PLC4C_STRING_POINTER, + PLC4C_CONSTANT_STRING, + PLC4C_VOID_POINTER } plc4c_data_type; /** - * Helper that translates from an return_code enum value to something a human can work with. + * Helper that translates from a return_code enum value to something a human can work with. * * @param err return code. * @return A human readable description. @@ -84,13 +85,20 @@ typedef enum plc4c_data_type { char *plc4c_return_code_to_message(plc4c_return_code err); /** - * Helper that translates from an plc4c_response_code enum value to something a human can work with. + * Helper that translates from a plc4c_response_code enum value to something a human can work with. * - * @param err return code. + * @param response_code plc4c_response_code. * @return A human readable description. */ char *plc4c_response_code_to_message(plc4c_response_code response_code); +/** + * Helper function translates from a plc4c_data_type enum value to something a human can work with. + * @param data_type plc4c_data_type + * @return string representation + */ +char *plc4c_data_type_name(plc4c_data_type data_type); + /** * The plc4c system. */ diff --git a/sandbox/plc4c/drivers/simulated/src/driver_simulated.c b/sandbox/plc4c/drivers/simulated/src/driver_simulated.c index 1e9f280531b..e97f9a720e7 100644 --- a/sandbox/plc4c/drivers/simulated/src/driver_simulated.c +++ b/sandbox/plc4c/drivers/simulated/src/driver_simulated.c @@ -30,10 +30,6 @@ enum plc4c_driver_simulated_field_type_t { }; typedef enum plc4c_driver_simulated_field_type_t plc4c_driver_simulated_field_type; -enum plc4c_driver_simulated_field_datatype_t { - INTEGER, - STRING -}; typedef enum plc4c_driver_simulated_field_datatype_t plc4c_driver_simulated_field_datatype; // State definitions @@ -50,7 +46,7 @@ enum write_states { struct plc4c_driver_simulated_item_t { char *name; plc4c_driver_simulated_field_type type; - plc4c_driver_simulated_field_datatype data_type; + plc4c_data_type data_type; int num_elements; }; typedef struct plc4c_driver_simulated_item_t plc4c_driver_simulated_item; @@ -99,17 +95,17 @@ plc4c_return_code plc4c_driver_simulated_read_machine_function(plc4c_system_task plc4c_list_element *cur_element = plc4c_utils_list_head(read_request->items); while (cur_element != NULL) { plc4c_driver_simulated_item *cur_item = cur_element->value; - - // Create a new random value. plc4c_response_value_item *value_item = malloc(sizeof(plc4c_response_value_item)); value_item->item = (plc4c_item *) cur_item; - // create the plc4c_data - // if this were a custom type we could set a custom destroy method - // we can also set a custom printf method + + /* + * create the plc4c_data + * if this were a custom type we could set a custom destroy method + * we can also set a custom printf method + * 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; - uint32_t *random_value = malloc(sizeof(uint32_t)); - *random_value = arc4random(); // Add the value to the response. plc4c_utils_list_insert_tail_value(read_response->items, value_item); @@ -151,32 +147,28 @@ plc4c_return_code plc4c_driver_simulated_write_machine_function(plc4c_system_tas while (cur_element != NULL) { plc4c_request_value_item *cur_value_item = cur_element->value; plc4c_driver_simulated_item *cur_item = (plc4c_driver_simulated_item*) cur_value_item->item; - + plc4c_data * write_data = cur_value_item->value; plc4c_response_code response_code = -1; switch (cur_item->type) { - case STDOUT: { - switch (cur_item->data_type) { - case INTEGER: { - printf("--> Simulated Driver Write: Value (INTEGER) %s: %d\n", cur_item->name, *((int*)cur_value_item->value)); - response_code = PLC4C_RESPONSE_CODE_OK; - break; - } - case STRING: { - printf("--> Simulated Driver Write: Value (STRING) %s: %s\n", cur_item->name, (char*)cur_value_item->value); - response_code = PLC4C_RESPONSE_CODE_OK; - break; - } - default: { - response_code = PLC4C_RESPONSE_CODE_INVALID_DATATYPE; - break; - } - } - break; - } - default: { - response_code = PLC4C_RESPONSE_CODE_INVALID_ADDRESS; - break; + case STDOUT: { + printf(""); + if (cur_item->data_type != write_data->data_type) { + printf("--> Simulated Driver Write: Value is %s but Item type is %s", plc4c_data_type_name(write_data->data_type), plc4c_data_type_name(cur_item->data_type)); + response_code = PLC4C_RESPONSE_CODE_INVALID_DATATYPE; + break; } + printf("--> Simulated Driver Write: Value (%s) %s: ", + plc4c_data_type_name(write_data->data_type), + cur_item->name); + plc4c_data_printf(write_data); + printf("\n"); + response_code = PLC4C_RESPONSE_CODE_OK; + break; + } + default: { + response_code = PLC4C_RESPONSE_CODE_INVALID_ADDRESS; + break; + } } // Create a response element and add that to the response ... @@ -207,7 +199,7 @@ plc4c_return_code plc4c_driver_simulated_write_machine_function(plc4c_system_tas plc4c_item *plc4c_driver_simulated_parse_address(char *address_string) { plc4c_driver_simulated_field_type type = RANDOM; char *name = NULL; - plc4c_driver_simulated_field_datatype data_type = -1; + plc4c_data_type data_type = -1; int num_elements = 0; int start_segment_index = 0; char *start_segment = address_string; @@ -242,9 +234,9 @@ plc4c_item *plc4c_driver_simulated_parse_address(char *address_string) { // Translate the string into a constant. if(strcmp(datatype_name, "INTEGER") == 0) { - data_type = INTEGER; + data_type = PLC4C_INT; } else if(strcmp(datatype_name, "STRING") == 0) { - data_type = STRING; + data_type = PLC4C_CONSTANT_STRING; } else { return NULL; } @@ -276,25 +268,6 @@ plc4c_item *plc4c_driver_simulated_parse_address(char *address_string) { return (plc4c_item *) item; } -plc4c_return_code plc4c_driver_simulated_encode_value(plc4c_item *item, void *value, void** encoded_value) { - plc4c_driver_simulated_item *simulated_item = (plc4c_driver_simulated_item*) item; - switch (simulated_item->data_type) { - case INTEGER: { - int* int_value = malloc(sizeof(int)); - *int_value = (int) *((int*)value); - *encoded_value = int_value; - return OK; - } - case STRING: { - char* string_value = malloc(sizeof(char) * strlen((char*) value)); - strcpy(string_value, (char*) value); - *encoded_value = string_value; - return OK; - } - } - return INTERNAL_ERROR; -} - plc4c_return_code plc4c_driver_simulated_connect_function(plc4c_connection *connection, plc4c_system_task **task) { @@ -368,7 +341,6 @@ plc4c_driver *plc4c_driver_simulated_create() { driver->protocol_name = "Simulated PLC4X Datasource"; driver->default_transport_code = "dummy"; driver->parse_address_function = &plc4c_driver_simulated_parse_address; - driver->encode_value_function = &plc4c_driver_simulated_encode_value; driver->connect_function = &plc4c_driver_simulated_connect_function; driver->disconnect_function = &plc4c_driver_simulated_disconnect_function; driver->read_function = &plc4c_driver_simulated_read_function; diff --git a/sandbox/plc4c/examples/hello-world/src/hello_world.c b/sandbox/plc4c/examples/hello-world/src/hello_world.c index 9f94a226730..9424bd497f3 100644 --- a/sandbox/plc4c/examples/hello-world/src/hello_world.c +++ b/sandbox/plc4c/examples/hello-world/src/hello_world.c @@ -17,6 +17,7 @@ * under the License. */ #include +#include #include #include #include @@ -210,9 +211,7 @@ int main() { while (cur_element != NULL) { plc4c_response_value_item *value_item = cur_element->value; - // Just cast the value to int for now ... - // TODO: We need to introduce a fully operational plc_value system later on. - printf("Value %s (%s):", value_item->name, plc4c_response_code_to_message(value_item->response_code)); + printf("Value %s (%s):", value_item->item->name, plc4c_response_code_to_message(value_item->response_code)); plc4c_data_printf(value_item->value); printf("\n"); @@ -231,7 +230,8 @@ int main() { plc4c_utils_list_insert_head_value(address_list, (void *) "STDOUT/foo:STRING"); plc4c_list *value_list = NULL; plc4c_utils_list_create(&value_list); - plc4c_utils_list_insert_head_value(value_list, (void *) "hurz"); + char value[] = "hurtz"; + plc4c_utils_list_insert_head_value(value_list, plc4c_data_create_constant_string_data(strlen(value), value)); result = plc4c_connection_create_write_request(connection, address_list, value_list, &write_request); // As we only used these to create the request, they can now be released again. diff --git a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h index 4a6fb86a57e..fac8bc51cf9 100644 --- a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h +++ b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h @@ -85,7 +85,6 @@ struct plc4c_driver_t { char *protocol_name; char *default_transport_code; plc4c_connection_parse_address_item parse_address_function; - plc4c_connection_encode_value_item encode_value_function; plc4c_connection_connect_function connect_function; plc4c_connection_disconnect_function disconnect_function; plc4c_connection_read_function read_function; @@ -149,6 +148,7 @@ struct plc4c_data_t { /* more */ float float_value; char *pstring_value; + char *const_string_value; void *pvoid_value; }data; diff --git a/sandbox/plc4c/spi/src/connection.c b/sandbox/plc4c/spi/src/connection.c index 5a98c7a17a8..dc1537e9aa2 100644 --- a/sandbox/plc4c/spi/src/connection.c +++ b/sandbox/plc4c/spi/src/connection.c @@ -113,7 +113,7 @@ plc4c_return_code plc4c_connection_create_write_request(plc4c_connection *connec // Create a new value item, binding an address item to a value. plc4c_request_value_item *value_item = malloc(sizeof(plc4c_request_value_item)); value_item->item = address_item; - connection->driver->encode_value_function(address_item, value_element->value, &value_item->value); + value_item->value = (plc4c_data*)value_element->value; // Add the new item ot the list of items. plc4c_utils_list_insert_tail_value(new_write_request->items, value_item); diff --git a/sandbox/plc4c/spi/src/data.c b/sandbox/plc4c/spi/src/data.c index 592e459306a..a3663214189 100644 --- a/sandbox/plc4c/spi/src/data.c +++ b/sandbox/plc4c/spi/src/data.c @@ -64,15 +64,23 @@ plc4c_data *plc4c_data_create_uint_data(unsigned int ui) { plc4c_data *plc4c_data_create_string_data(unsigned int size, char *s) { plc4c_data *data = malloc(sizeof(plc4c_data)); - data->data_type = PLC4C_STRINGP; + data->data_type = PLC4C_STRING_POINTER; data->size = size; data->data.pstring_value = s; return data; } +plc4c_data *plc4c_data_create_constant_string_data( unsigned int size, char *s) { + plc4c_data *data = malloc(sizeof(plc4c_data)); + data->data_type = PLC4C_CONSTANT_STRING; + data->size = size; + data->data.const_string_value = s; + return data; +} + plc4c_data *plc4c_data_create_void_pointer_data(void* v) { plc4c_data *data = malloc(sizeof(plc4c_data)); - data->data_type = PLC4C_VOIDP; + data->data_type = PLC4C_VOID_POINTER; data->size = 0; data->data.pvoid_value = v; return data; @@ -108,10 +116,13 @@ void plc4c_data_printf(plc4c_data *data) { case PLC4C_FLOAT: printf("%f", data->data.float_value); break; - case PLC4C_STRINGP: + case PLC4C_STRING_POINTER: printf("%s", data->data.pstring_value); break; - case PLC4C_VOIDP: + case PLC4C_CONSTANT_STRING: + printf("%s", data->data.const_string_value); + break; + case PLC4C_VOID_POINTER: if (data->custom_printf != NULL) { data->custom_printf(data); } else { @@ -138,10 +149,10 @@ void plc4c_data_delete(plc4c_data *data) { data->custom_destroy(data); } else { switch (data->data_type ) { - case PLC4C_VOIDP: + case PLC4C_VOID_POINTER: free(data->data.pvoid_value); break; - case PLC4C_STRINGP: + case PLC4C_STRING_POINTER: free(data->data.pstring_value); break; default: diff --git a/sandbox/plc4c/spi/src/types.c b/sandbox/plc4c/spi/src/types.c index 68fc7835242..50d1d8e34b3 100644 --- a/sandbox/plc4c/spi/src/types.c +++ b/sandbox/plc4c/spi/src/types.c @@ -104,3 +104,45 @@ char *plc4c_response_code_to_message(plc4c_response_code response_code) { } } } + +char *plc4c_data_type_name(plc4c_data_type data_type) { + switch (data_type) { + case PLC4C_CHAR: { + return "PLC4C_CHAR"; + } + case PLC4C_UCHAR: { + return "PLC4C_UCHAR"; + } + case PLC4C_SHORT: { + return "PLC4C_SHORT"; + } + case PLC4C_USHORT: { + return "PLC4C_USHORT"; + } + case PLC4C_BOOL: { + return "PLC4C_BOOL"; + } + case PLC4C_INT: { + return "PLC4C_INT"; + } + case PLC4C_UINT: { + return "PLC4C_UINT"; + } + case PLC4C_FLOAT: { + return "PLC4C_FLOAT"; + } + case PLC4C_STRING_POINTER: { + return "PLC4C_STRING_POINTER"; + } + case PLC4C_CONSTANT_STRING: { + return "PLC4C_CONSTANT_STRING"; + } + case PLC4C_VOID_POINTER: { + return "PLC4C_VOID_POINTER"; + } + default: { + return "UNKNOWN"; + } + } +} +