From b57b9ad0f3e636ab5594856ec685146ea7738d56 Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Fri, 22 Sep 2023 17:21:51 +0200 Subject: [PATCH 01/16] chore: Updated the KNX manufacturers --- .../readwrite/model/KnxManufacturer.go | 26 +++++++++++++++---- .../knxnetip/readwrite/KnxManufacturer.java | 5 ++-- .../readwrite/model/KnxManufacturer.cs | 19 +++++++++----- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/plc4go/protocols/knxnetip/readwrite/model/KnxManufacturer.go b/plc4go/protocols/knxnetip/readwrite/model/KnxManufacturer.go index f2c13df5ec8..15367746356 100644 --- a/plc4go/protocols/knxnetip/readwrite/model/KnxManufacturer.go +++ b/plc4go/protocols/knxnetip/readwrite/model/KnxManufacturer.go @@ -687,8 +687,9 @@ const ( KnxManufacturer_M_ILITE_KNX KnxManufacturer = 641 KnxManufacturer_M_LAZZEN KnxManufacturer = 642 KnxManufacturer_M_MOX_CONTROL_IT_CHINA_LIMITED KnxManufacturer = 643 - KnxManufacturer_M_ABB___RESERVED KnxManufacturer = 644 - KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED KnxManufacturer = 645 + KnxManufacturer_M_CLOWIRE KnxManufacturer = 644 + KnxManufacturer_M_ABB___RESERVED KnxManufacturer = 645 + KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED KnxManufacturer = 646 ) var KnxManufacturerValues []KnxManufacturer @@ -1340,6 +1341,7 @@ func init() { KnxManufacturer_M_ILITE_KNX, KnxManufacturer_M_LAZZEN, KnxManufacturer_M_MOX_CONTROL_IT_CHINA_LIMITED, + KnxManufacturer_M_CLOWIRE, KnxManufacturer_M_ABB___RESERVED, KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED, } @@ -3773,10 +3775,14 @@ func (e KnxManufacturer) Number() uint16 { } case 644: { /* '644' */ - return 43954 + return 702 } case 645: { /* '645' */ + return 43954 + } + case 646: + { /* '646' */ return 43959 } case 65: @@ -6375,10 +6381,14 @@ func (e KnxManufacturer) Name() string { } case 644: { /* '644' */ - return "ABB - reserved" + return "CLOWIRE" } case 645: { /* '645' */ + return "ABB - reserved" + } + case 646: + { /* '646' */ return "Busch-Jaeger Elektro - reserved" } case 65: @@ -7763,8 +7773,10 @@ func KnxManufacturerByValue(value uint16) (enum KnxManufacturer, ok bool) { case 643: return KnxManufacturer_M_MOX_CONTROL_IT_CHINA_LIMITED, true case 644: - return KnxManufacturer_M_ABB___RESERVED, true + return KnxManufacturer_M_CLOWIRE, true case 645: + return KnxManufacturer_M_ABB___RESERVED, true + case 646: return KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED, true case 65: return KnxManufacturer_M_JEPAZ, true @@ -9060,6 +9072,8 @@ func KnxManufacturerByName(value string) (enum KnxManufacturer, ok bool) { return KnxManufacturer_M_LAZZEN, true case "M_MOX_CONTROL_IT_CHINA_LIMITED": return KnxManufacturer_M_MOX_CONTROL_IT_CHINA_LIMITED, true + case "M_CLOWIRE": + return KnxManufacturer_M_CLOWIRE, true case "M_ABB___RESERVED": return KnxManufacturer_M_ABB___RESERVED, true case "M_BUSCH_JAEGER_ELEKTRO___RESERVED": @@ -10419,6 +10433,8 @@ func (e KnxManufacturer) PLC4XEnumName() string { return "M_LAZZEN" case KnxManufacturer_M_MOX_CONTROL_IT_CHINA_LIMITED: return "M_MOX_CONTROL_IT_CHINA_LIMITED" + case KnxManufacturer_M_CLOWIRE: + return "M_CLOWIRE" case KnxManufacturer_M_ABB___RESERVED: return "M_ABB___RESERVED" case KnxManufacturer_M_BUSCH_JAEGER_ELEKTRO___RESERVED: diff --git a/plc4j/drivers/knxnetip/src/main/generated/org/apache/plc4x/java/knxnetip/readwrite/KnxManufacturer.java b/plc4j/drivers/knxnetip/src/main/generated/org/apache/plc4x/java/knxnetip/readwrite/KnxManufacturer.java index 753491d4d06..16b14b9af5c 100644 --- a/plc4j/drivers/knxnetip/src/main/generated/org/apache/plc4x/java/knxnetip/readwrite/KnxManufacturer.java +++ b/plc4j/drivers/knxnetip/src/main/generated/org/apache/plc4x/java/knxnetip/readwrite/KnxManufacturer.java @@ -739,9 +739,10 @@ public enum KnxManufacturer { M_ILITE_KNX((int) 641, (int) 699, (String) "ILite-Knx"), M_LAZZEN((int) 642, (int) 700, (String) "LAZZEN"), M_MOX_CONTROL_IT_CHINA_LIMITED((int) 643, (int) 701, (String) "MOX CONTROL IT (CHINA) LIMITED"), - M_ABB___RESERVED((int) 644, (int) 43954, (String) "ABB - reserved"), + M_CLOWIRE((int) 644, (int) 702, (String) "CLOWIRE"), + M_ABB___RESERVED((int) 645, (int) 43954, (String) "ABB - reserved"), M_BUSCH_JAEGER_ELEKTRO___RESERVED( - (int) 645, (int) 43959, (String) "Busch-Jaeger Elektro - reserved"); + (int) 646, (int) 43959, (String) "Busch-Jaeger Elektro - reserved"); private static final Map map; static { diff --git a/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/KnxManufacturer.cs b/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/KnxManufacturer.cs index a020940b251..0ab33ee91d7 100644 --- a/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/KnxManufacturer.cs +++ b/plc4net/drivers/knxnetip/src/drivers/knxnetip/readwrite/model/KnxManufacturer.cs @@ -668,8 +668,9 @@ public enum KnxManufacturer M_ILITE_KNX = 641, M_LAZZEN = 642, M_MOX_CONTROL_IT_CHINA_LIMITED = 643, - M_ABB___RESERVED = 644, - M_BUSCH_JAEGER_ELEKTRO___RESERVED = 645, + M_CLOWIRE = 644, + M_ABB___RESERVED = 645, + M_BUSCH_JAEGER_ELEKTRO___RESERVED = 646, } public static class KnxManufacturerInfo @@ -2497,10 +2498,13 @@ public static class KnxManufacturerInfo case KnxManufacturer.M_MOX_CONTROL_IT_CHINA_LIMITED: { /* '643' */ return 701; } - case KnxManufacturer.M_ABB___RESERVED: { /* '644' */ + case KnxManufacturer.M_CLOWIRE: { /* '644' */ + return 702; + } + case KnxManufacturer.M_ABB___RESERVED: { /* '645' */ return 43954; } - case KnxManufacturer.M_BUSCH_JAEGER_ELEKTRO___RESERVED: { /* '645' */ + case KnxManufacturer.M_BUSCH_JAEGER_ELEKTRO___RESERVED: { /* '646' */ return 43959; } case KnxManufacturer.M_JEPAZ: { /* '65' */ @@ -4445,10 +4449,13 @@ public static string Name(this KnxManufacturer value) case KnxManufacturer.M_MOX_CONTROL_IT_CHINA_LIMITED: { /* '643' */ return "MOX CONTROL IT (CHINA) LIMITED"; } - case KnxManufacturer.M_ABB___RESERVED: { /* '644' */ + case KnxManufacturer.M_CLOWIRE: { /* '644' */ + return "CLOWIRE"; + } + case KnxManufacturer.M_ABB___RESERVED: { /* '645' */ return "ABB - reserved"; } - case KnxManufacturer.M_BUSCH_JAEGER_ELEKTRO___RESERVED: { /* '645' */ + case KnxManufacturer.M_BUSCH_JAEGER_ELEKTRO___RESERVED: { /* '646' */ return "Busch-Jaeger Elektro - reserved"; } case KnxManufacturer.M_JEPAZ: { /* '65' */ From cad4fd5f82443804167f9e52a509db747b760d56 Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Fri, 22 Sep 2023 17:24:31 +0200 Subject: [PATCH 02/16] fix: Fixed numerous issues when writing values to S7 --- .../templates/java/data-io-template.java.ftlh | 2 +- .../drivers/s7/src/driver_s7_encode_decode.c | 3 - plc4c/drivers/s7/src/driver_s7_packets.c | 1 - .../s7/include/transport_size.h | 4 +- plc4c/generated-sources/s7/src/data_item.c | 10 +- .../generated-sources/s7/src/transport_size.c | 91 ++------------ .../s7/readwrite/model/TransportSize.go | 112 +----------------- .../plc4x/java/s7/readwrite/DataItem.java | 6 +- .../java/s7/readwrite/TransportSize.java | 34 +----- .../java/s7/readwrite/utils/StaticHelper.java | 48 ++++++-- .../java/s7/readwrite/ManualS7DriverTest.java | 13 +- .../spi/generation/WriteBufferByteBased.java | 21 ++-- .../apache/plc4x/java/spi/values/PlcDATE.java | 3 +- .../plc4x/java/spi/values/PlcTIME_OF_DAY.java | 4 +- .../java/spi/values/PlcValueHandler.java | 8 ++ .../apache/plc4x/test/manual/ManualTest.java | 2 +- .../src/main/resources/protocols/s7/s7.mspec | 18 ++- 17 files changed, 99 insertions(+), 281 deletions(-) diff --git a/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh b/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh index a1fda21e904..fa472a86d6e 100644 --- a/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh +++ b/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh @@ -445,7 +445,7 @@ public class ${type.name} { <#elseif simpleField.name == "daysSinceEpoch"> ${helper.getLanguageTypeNameForField(simpleField)} ${simpleField.name} = (${helper.getLanguageTypeNameForField(field)}) _value.get${helper.getLanguageTypeNameForField(simpleField)?cap_first}(); <#elseif simpleField.name == "daysSinceSiemensEpoch"> - ${helper.getLanguageTypeNameForField(simpleField)} ${simpleField.name} = (${helper.getLanguageTypeNameForField(field)}) _value.get${helper.getLanguageTypeNameForField(simpleField)?cap_first}(); + ${helper.getLanguageTypeNameForField(simpleField)} ${simpleField.name} = (${helper.getLanguageTypeNameForField(field)}) ((PlcDATE) _value).getDaysSinceSiemensEpoch(); <#elseif simpleField.name == "year"> ${helper.getLanguageTypeNameForField(simpleField)} ${simpleField.name} = (${helper.getLanguageTypeNameForField(field)}) _value.get${helper.getLanguageTypeNameForField(simpleField)?cap_first}(); <#elseif simpleField.name == "month"> diff --git a/plc4c/drivers/s7/src/driver_s7_encode_decode.c b/plc4c/drivers/s7/src/driver_s7_encode_decode.c index af2bf2765eb..5ae625e6baf 100644 --- a/plc4c/drivers/s7/src/driver_s7_encode_decode.c +++ b/plc4c/drivers/s7/src/driver_s7_encode_decode.c @@ -330,9 +330,6 @@ plc4c_return_code plc4c_driver_s7_encode_address(char* address, void** item) { any_address->s7_address_any_number_of_elements = 254 * any_address->s7_address_any_number_of_elements; } - } else if (any_address->s7_address_any_transport_size == - plc4c_s7_read_write_transport_size_TOD) { - any_address->s7_address_any_transport_size = plc4c_s7_read_write_transport_size_TIME_OF_DAY; } free(string_length); diff --git a/plc4c/drivers/s7/src/driver_s7_packets.c b/plc4c/drivers/s7/src/driver_s7_packets.c index c3552139349..3c679190a7f 100644 --- a/plc4c/drivers/s7/src/driver_s7_packets.c +++ b/plc4c/drivers/s7/src/driver_s7_packets.c @@ -975,7 +975,6 @@ void plc4c_driver_s7_time_transport_size(plc4c_s7_read_write_transport_size *tra *transport_size = plc4c_s7_read_write_transport_size_UINT; break; case plc4c_s7_read_write_transport_size_TIME_OF_DAY: - case plc4c_s7_read_write_transport_size_TOD: *transport_size = plc4c_s7_read_write_transport_size_UDINT; break; } diff --git a/plc4c/generated-sources/s7/include/transport_size.h b/plc4c/generated-sources/s7/include/transport_size.h index 636bdfe63c1..4dcd59f71a4 100644 --- a/plc4c/generated-sources/s7/include/transport_size.h +++ b/plc4c/generated-sources/s7/include/transport_size.h @@ -54,9 +54,7 @@ enum plc4c_s7_read_write_transport_size { plc4c_s7_read_write_transport_size_LTIME = 0x16, plc4c_s7_read_write_transport_size_DATE = 0x17, plc4c_s7_read_write_transport_size_TIME_OF_DAY = 0x18, - plc4c_s7_read_write_transport_size_TOD = 0x19, - plc4c_s7_read_write_transport_size_DATE_AND_TIME = 0x1A, - plc4c_s7_read_write_transport_size_DT = 0x1B + plc4c_s7_read_write_transport_size_DATE_AND_TIME = 0x1A }; typedef enum plc4c_s7_read_write_transport_size plc4c_s7_read_write_transport_size; diff --git a/plc4c/generated-sources/s7/src/data_item.c b/plc4c/generated-sources/s7/src/data_item.c index c0e09c4108a..b02d7f210c7 100644 --- a/plc4c/generated-sources/s7/src/data_item.c +++ b/plc4c/generated-sources/s7/src/data_item.c @@ -687,17 +687,11 @@ uint16_t plc4c_s7_read_write_data_item_length_in_bits(plc4x_spi_context ctx, plc } else if(strcmp(dataProtocolId, "IEC61131_STRING") == 0) { /* STRING */ // Manual Field (value) - { - char* _value = data_item->data.string_value; - lengthInBits += (plc4c_spi_evaluation_helper_str_len(_value)) + (2); - } + lengthInBits += (((stringLength) * (8))) + (16); } else if(strcmp(dataProtocolId, "IEC61131_WSTRING") == 0) { /* STRING */ // Manual Field (value) - { - char* _value = data_item->data.string_value; - lengthInBits += (((plc4c_spi_evaluation_helper_str_len(_value)) * (2))) + (2); - } + lengthInBits += (((stringLength) * (16))) + (32); } else if(strcmp(dataProtocolId, "IEC61131_TIME") == 0) { /* TIME */ // Simple field (milliseconds) diff --git a/plc4c/generated-sources/s7/src/transport_size.c b/plc4c/generated-sources/s7/src/transport_size.c index b681e48047f..9284a3c7c47 100644 --- a/plc4c/generated-sources/s7/src/transport_size.c +++ b/plc4c/generated-sources/s7/src/transport_size.c @@ -131,20 +131,14 @@ plc4c_s7_read_write_transport_size plc4c_s7_read_write_transport_size_value_of(c if(strcmp(value_string, "TIME_OF_DAY") == 0) { return plc4c_s7_read_write_transport_size_TIME_OF_DAY; } - if(strcmp(value_string, "TOD") == 0) { - return plc4c_s7_read_write_transport_size_TOD; - } if(strcmp(value_string, "DATE_AND_TIME") == 0) { return plc4c_s7_read_write_transport_size_DATE_AND_TIME; } - if(strcmp(value_string, "DT") == 0) { - return plc4c_s7_read_write_transport_size_DT; - } return -1; } int plc4c_s7_read_write_transport_size_num_values() { - return 26; + return 24; } plc4c_s7_read_write_transport_size plc4c_s7_read_write_transport_size_value_for_index(int index) { @@ -219,14 +213,8 @@ plc4c_s7_read_write_transport_size plc4c_s7_read_write_transport_size_value_for_ return plc4c_s7_read_write_transport_size_TIME_OF_DAY; } case 23: { - return plc4c_s7_read_write_transport_size_TOD; - } - case 24: { return plc4c_s7_read_write_transport_size_DATE_AND_TIME; } - case 25: { - return plc4c_s7_read_write_transport_size_DT; - } default: { return -1; } @@ -304,15 +292,9 @@ bool plc4c_s7_read_write_transport_size_get_supported__s7_300(plc4c_s7_read_writ case plc4c_s7_read_write_transport_size_TIME_OF_DAY: { /* '0x18' */ return true; } - case plc4c_s7_read_write_transport_size_TOD: { /* '0x19' */ - return true; - } case plc4c_s7_read_write_transport_size_DATE_AND_TIME: { /* '0x1A' */ return true; } - case plc4c_s7_read_write_transport_size_DT: { /* '0x1B' */ - return true; - } default: { return 0; } @@ -398,15 +380,9 @@ bool plc4c_s7_read_write_transport_size_get_supported__logo(plc4c_s7_read_write_ case plc4c_s7_read_write_transport_size_TIME_OF_DAY: { /* '0x18' */ return true; } - case plc4c_s7_read_write_transport_size_TOD: { /* '0x19' */ - return true; - } case plc4c_s7_read_write_transport_size_DATE_AND_TIME: { /* '0x1A' */ return false; } - case plc4c_s7_read_write_transport_size_DT: { /* '0x1B' */ - return false; - } default: { return 0; } @@ -492,15 +468,9 @@ uint8_t plc4c_s7_read_write_transport_size_get_code(plc4c_s7_read_write_transpor case plc4c_s7_read_write_transport_size_TIME_OF_DAY: { /* '0x18' */ return 6; } - case plc4c_s7_read_write_transport_size_TOD: { /* '0x19' */ - return 6; - } case plc4c_s7_read_write_transport_size_DATE_AND_TIME: { /* '0x1A' */ return 15; } - case plc4c_s7_read_write_transport_size_DT: { /* '0x1B' */ - return 15; - } default: { return 0; } @@ -628,15 +598,9 @@ uint8_t plc4c_s7_read_write_transport_size_get_size_in_bytes(plc4c_s7_read_write case plc4c_s7_read_write_transport_size_TIME_OF_DAY: { /* '0x18' */ return 4; } - case plc4c_s7_read_write_transport_size_TOD: { /* '0x19' */ - return 4; - } case plc4c_s7_read_write_transport_size_DATE_AND_TIME: { /* '0x1A' */ return 12; } - case plc4c_s7_read_write_transport_size_DT: { /* '0x1B' */ - return 12; - } default: { return 0; } @@ -740,15 +704,9 @@ bool plc4c_s7_read_write_transport_size_get_supported__s7_400(plc4c_s7_read_writ case plc4c_s7_read_write_transport_size_TIME_OF_DAY: { /* '0x18' */ return true; } - case plc4c_s7_read_write_transport_size_TOD: { /* '0x19' */ - return true; - } case plc4c_s7_read_write_transport_size_DATE_AND_TIME: { /* '0x1A' */ return true; } - case plc4c_s7_read_write_transport_size_DT: { /* '0x1B' */ - return true; - } default: { return 0; } @@ -834,15 +792,9 @@ bool plc4c_s7_read_write_transport_size_get_supported__s7_1200(plc4c_s7_read_wri case plc4c_s7_read_write_transport_size_TIME_OF_DAY: { /* '0x18' */ return true; } - case plc4c_s7_read_write_transport_size_TOD: { /* '0x19' */ - return true; - } case plc4c_s7_read_write_transport_size_DATE_AND_TIME: { /* '0x1A' */ return false; } - case plc4c_s7_read_write_transport_size_DT: { /* '0x1B' */ - return false; - } default: { return 0; } @@ -928,15 +880,9 @@ uint8_t plc4c_s7_read_write_transport_size_get_short_name(plc4c_s7_read_write_tr case plc4c_s7_read_write_transport_size_TIME_OF_DAY: { /* '0x18' */ return 'X'; } - case plc4c_s7_read_write_transport_size_TOD: { /* '0x19' */ - return 'X'; - } case plc4c_s7_read_write_transport_size_DATE_AND_TIME: { /* '0x1A' */ return 'X'; } - case plc4c_s7_read_write_transport_size_DT: { /* '0x1B' */ - return 'X'; - } default: { return 0; } @@ -1034,15 +980,9 @@ bool plc4c_s7_read_write_transport_size_get_supported__s7_1500(plc4c_s7_read_wri case plc4c_s7_read_write_transport_size_TIME_OF_DAY: { /* '0x18' */ return true; } - case plc4c_s7_read_write_transport_size_TOD: { /* '0x19' */ - return true; - } case plc4c_s7_read_write_transport_size_DATE_AND_TIME: { /* '0x1A' */ return true; } - case plc4c_s7_read_write_transport_size_DT: { /* '0x1B' */ - return true; - } default: { return 0; } @@ -1105,16 +1045,16 @@ plc4c_s7_read_write_data_transport_size plc4c_s7_read_write_transport_size_get_d return -1; } case plc4c_s7_read_write_transport_size_CHAR: { /* '0x10' */ - return plc4c_s7_read_write_data_transport_size_BYTE_WORD_DWORD; + return plc4c_s7_read_write_data_transport_size_OCTET_STRING; } case plc4c_s7_read_write_transport_size_WCHAR: { /* '0x11' */ - return -1; + return plc4c_s7_read_write_data_transport_size_OCTET_STRING; } case plc4c_s7_read_write_transport_size_STRING: { /* '0x12' */ - return plc4c_s7_read_write_data_transport_size_BYTE_WORD_DWORD; + return plc4c_s7_read_write_data_transport_size_OCTET_STRING; } case plc4c_s7_read_write_transport_size_WSTRING: { /* '0x13' */ - return -1; + return plc4c_s7_read_write_data_transport_size_OCTET_STRING; } case plc4c_s7_read_write_transport_size_TIME: { /* '0x14' */ return -1; @@ -1128,15 +1068,9 @@ plc4c_s7_read_write_data_transport_size plc4c_s7_read_write_transport_size_get_d case plc4c_s7_read_write_transport_size_TIME_OF_DAY: { /* '0x18' */ return plc4c_s7_read_write_data_transport_size_BYTE_WORD_DWORD; } - case plc4c_s7_read_write_transport_size_TOD: { /* '0x19' */ - return plc4c_s7_read_write_data_transport_size_BYTE_WORD_DWORD; - } case plc4c_s7_read_write_transport_size_DATE_AND_TIME: { /* '0x1A' */ return -1; } - case plc4c_s7_read_write_transport_size_DT: { /* '0x1B' */ - return -1; - } default: { return 0; } @@ -1154,6 +1088,9 @@ plc4c_s7_read_write_transport_size plc4c_s7_read_write_transport_size_get_first_ case plc4c_s7_read_write_transport_size_INT: /* '0x06' */{ return plc4c_s7_read_write_transport_size_INT; } + case plc4c_s7_read_write_transport_size_CHAR: /* '0x10' */{ + return plc4c_s7_read_write_transport_size_CHAR; + } case plc4c_s7_read_write_transport_size_REAL: /* '0x0E' */{ return plc4c_s7_read_write_transport_size_REAL; } @@ -1237,15 +1174,9 @@ char* plc4c_s7_read_write_transport_size_get_data_protocol_id(plc4c_s7_read_writ case plc4c_s7_read_write_transport_size_TIME_OF_DAY: { /* '0x18' */ return "IEC61131_TIME_OF_DAY"; } - case plc4c_s7_read_write_transport_size_TOD: { /* '0x19' */ - return "IEC61131_TIME_OF_DAY"; - } case plc4c_s7_read_write_transport_size_DATE_AND_TIME: { /* '0x1A' */ return "IEC61131_DATE_AND_TIME"; } - case plc4c_s7_read_write_transport_size_DT: { /* '0x1B' */ - return "IEC61131_DATE_AND_TIME"; - } default: { return 0; } @@ -1398,15 +1329,9 @@ plc4c_s7_read_write_transport_size plc4c_s7_read_write_transport_size_get_base_t case plc4c_s7_read_write_transport_size_TIME_OF_DAY: { /* '0x18' */ return -1; } - case plc4c_s7_read_write_transport_size_TOD: { /* '0x19' */ - return -1; - } case plc4c_s7_read_write_transport_size_DATE_AND_TIME: { /* '0x1A' */ return -1; } - case plc4c_s7_read_write_transport_size_DT: { /* '0x1B' */ - return -1; - } default: { return 0; } diff --git a/plc4go/protocols/s7/readwrite/model/TransportSize.go b/plc4go/protocols/s7/readwrite/model/TransportSize.go index bae86742630..4aafa352b6a 100644 --- a/plc4go/protocols/s7/readwrite/model/TransportSize.go +++ b/plc4go/protocols/s7/readwrite/model/TransportSize.go @@ -75,9 +75,7 @@ const ( TransportSize_LTIME TransportSize = 0x16 TransportSize_DATE TransportSize = 0x17 TransportSize_TIME_OF_DAY TransportSize = 0x18 - TransportSize_TOD TransportSize = 0x19 TransportSize_DATE_AND_TIME TransportSize = 0x1A - TransportSize_DT TransportSize = 0x1B ) var TransportSizeValues []TransportSize @@ -108,9 +106,7 @@ func init() { TransportSize_LTIME, TransportSize_DATE, TransportSize_TIME_OF_DAY, - TransportSize_TOD, TransportSize_DATE_AND_TIME, - TransportSize_DT, } } @@ -208,18 +204,10 @@ func (e TransportSize) Supported_S7_300() bool { { /* '0x18' */ return true } - case 0x19: - { /* '0x19' */ - return true - } case 0x1A: { /* '0x1A' */ return true } - case 0x1B: - { /* '0x1B' */ - return true - } default: { return false @@ -330,18 +318,10 @@ func (e TransportSize) Supported_LOGO() bool { { /* '0x18' */ return true } - case 0x19: - { /* '0x19' */ - return true - } case 0x1A: { /* '0x1A' */ return false } - case 0x1B: - { /* '0x1B' */ - return false - } default: { return false @@ -452,18 +432,10 @@ func (e TransportSize) Code() uint8 { { /* '0x18' */ return 0x06 } - case 0x19: - { /* '0x19' */ - return 0x06 - } case 0x1A: { /* '0x1A' */ return 0x0F } - case 0x1B: - { /* '0x1B' */ - return 0x0F - } default: { return 0 @@ -574,18 +546,10 @@ func (e TransportSize) SizeInBytes() uint8 { { /* '0x18' */ return 4 } - case 0x19: - { /* '0x19' */ - return 4 - } case 0x1A: { /* '0x1A' */ return 12 } - case 0x1B: - { /* '0x1B' */ - return 12 - } default: { return 0 @@ -696,18 +660,10 @@ func (e TransportSize) Supported_S7_400() bool { { /* '0x18' */ return true } - case 0x19: - { /* '0x19' */ - return true - } case 0x1A: { /* '0x1A' */ return true } - case 0x1B: - { /* '0x1B' */ - return true - } default: { return false @@ -818,18 +774,10 @@ func (e TransportSize) Supported_S7_1200() bool { { /* '0x18' */ return true } - case 0x19: - { /* '0x19' */ - return true - } case 0x1A: { /* '0x1A' */ return false } - case 0x1B: - { /* '0x1B' */ - return false - } default: { return false @@ -940,18 +888,10 @@ func (e TransportSize) ShortName() uint8 { { /* '0x18' */ return 'X' } - case 0x19: - { /* '0x19' */ - return 'X' - } case 0x1A: { /* '0x1A' */ return 'X' } - case 0x1B: - { /* '0x1B' */ - return 'X' - } default: { return 0 @@ -1062,18 +1002,10 @@ func (e TransportSize) Supported_S7_1500() bool { { /* '0x18' */ return true } - case 0x19: - { /* '0x19' */ - return true - } case 0x1A: { /* '0x1A' */ return true } - case 0x1B: - { /* '0x1B' */ - return true - } default: { return false @@ -1154,19 +1086,19 @@ func (e TransportSize) DataTransportSize() DataTransportSize { } case 0x10: { /* '0x10' */ - return DataTransportSize_BYTE_WORD_DWORD + return DataTransportSize_OCTET_STRING } case 0x11: { /* '0x11' */ - return 0 + return DataTransportSize_OCTET_STRING } case 0x12: { /* '0x12' */ - return DataTransportSize_BYTE_WORD_DWORD + return DataTransportSize_OCTET_STRING } case 0x13: { /* '0x13' */ - return 0 + return DataTransportSize_OCTET_STRING } case 0x14: { /* '0x14' */ @@ -1184,18 +1116,10 @@ func (e TransportSize) DataTransportSize() DataTransportSize { { /* '0x18' */ return DataTransportSize_BYTE_WORD_DWORD } - case 0x19: - { /* '0x19' */ - return DataTransportSize_BYTE_WORD_DWORD - } case 0x1A: { /* '0x1A' */ return 0 } - case 0x1B: - { /* '0x1B' */ - return 0 - } default: { return 0 @@ -1306,18 +1230,10 @@ func (e TransportSize) DataProtocolId() string { { /* '0x18' */ return "IEC61131_TIME_OF_DAY" } - case 0x19: - { /* '0x19' */ - return "IEC61131_TIME_OF_DAY" - } case 0x1A: { /* '0x1A' */ return "IEC61131_DATE_AND_TIME" } - case 0x1B: - { /* '0x1B' */ - return "IEC61131_DATE_AND_TIME" - } default: { return "" @@ -1428,18 +1344,10 @@ func (e TransportSize) BaseType() TransportSize { { /* '0x18' */ return 0 } - case 0x19: - { /* '0x19' */ - return 0 - } case 0x1A: { /* '0x1A' */ return 0 } - case 0x1B: - { /* '0x1B' */ - return 0 - } default: { return 0 @@ -1503,12 +1411,8 @@ func TransportSizeByValue(value uint8) (enum TransportSize, ok bool) { return TransportSize_DATE, true case 0x18: return TransportSize_TIME_OF_DAY, true - case 0x19: - return TransportSize_TOD, true case 0x1A: return TransportSize_DATE_AND_TIME, true - case 0x1B: - return TransportSize_DT, true } return 0, false } @@ -1561,12 +1465,8 @@ func TransportSizeByName(value string) (enum TransportSize, ok bool) { return TransportSize_DATE, true case "TIME_OF_DAY": return TransportSize_TIME_OF_DAY, true - case "TOD": - return TransportSize_TOD, true case "DATE_AND_TIME": return TransportSize_DATE_AND_TIME, true - case "DT": - return TransportSize_DT, true } return 0, false } @@ -1680,12 +1580,8 @@ func (e TransportSize) PLC4XEnumName() string { return "DATE" case TransportSize_TIME_OF_DAY: return "TIME_OF_DAY" - case TransportSize_TOD: - return "TOD" case TransportSize_DATE_AND_TIME: return "DATE_AND_TIME" - case TransportSize_DT: - return "DT" } return fmt.Sprintf("Unknown(%v)", uint8(e)) } diff --git a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/DataItem.java b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/DataItem.java index fb5aaf564e2..40dfd1d4d61 100644 --- a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/DataItem.java +++ b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/DataItem.java @@ -376,7 +376,7 @@ public static void staticSerialize( /*TODO: migrate me*/ writeBuffer.writeUnsignedBigInteger("", 64, (BigInteger) (nanoseconds)); } else if (EvaluationHelper.equals(dataProtocolId, "IEC61131_DATE")) { // DATE // Simple Field (daysSinceSiemensEpoch) - int daysSinceSiemensEpoch = (int) _value.getInt(); + int daysSinceSiemensEpoch = (int) ((PlcDATE) _value).getDaysSinceSiemensEpoch(); /*TODO: migrate me*/ /*TODO: migrate me*/ writeBuffer.writeUnsignedInt( "", 16, ((Number) (daysSinceSiemensEpoch)).intValue()); @@ -491,10 +491,10 @@ public static int getLengthInBits(PlcValue _value, String dataProtocolId, Intege sizeInBits += 16; } else if (EvaluationHelper.equals(dataProtocolId, "IEC61131_STRING")) { // STRING // Manual Field (value) - sizeInBits += (STR_LEN(_value)) + (2); + sizeInBits += (((stringLength) * (8))) + (16); } else if (EvaluationHelper.equals(dataProtocolId, "IEC61131_WSTRING")) { // STRING // Manual Field (value) - sizeInBits += (((STR_LEN(_value)) * (2))) + (2); + sizeInBits += (((stringLength) * (16))) + (32); } else if (EvaluationHelper.equals(dataProtocolId, "IEC61131_TIME")) { // TIME // Simple Field (milliseconds) sizeInBits += 32; diff --git a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/TransportSize.java b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/TransportSize.java index d99705e7540..b15a9817d8b 100644 --- a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/TransportSize.java +++ b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/TransportSize.java @@ -231,7 +231,7 @@ public enum TransportSize { (boolean) true, (short) 'B', (boolean) true, - DataTransportSize.BYTE_WORD_DWORD, + DataTransportSize.OCTET_STRING, (String) "IEC61131_CHAR", null), WCHAR( @@ -244,7 +244,7 @@ public enum TransportSize { (boolean) true, (short) 'X', (boolean) true, - null, + DataTransportSize.OCTET_STRING, (String) "IEC61131_WCHAR", null), STRING( @@ -257,7 +257,7 @@ public enum TransportSize { (boolean) true, (short) 'X', (boolean) true, - DataTransportSize.BYTE_WORD_DWORD, + DataTransportSize.OCTET_STRING, (String) "IEC61131_STRING", null), WSTRING( @@ -270,7 +270,7 @@ public enum TransportSize { (boolean) true, (short) 'X', (boolean) true, - null, + DataTransportSize.OCTET_STRING, (String) "IEC61131_WSTRING", null), TIME( @@ -325,19 +325,6 @@ public enum TransportSize { DataTransportSize.BYTE_WORD_DWORD, (String) "IEC61131_TIME_OF_DAY", null), - TOD( - (short) 0x19, - (boolean) true, - (boolean) true, - (short) 0x06, - (short) 4, - (boolean) true, - (boolean) true, - (short) 'X', - (boolean) true, - DataTransportSize.BYTE_WORD_DWORD, - (String) "IEC61131_TIME_OF_DAY", - null), DATE_AND_TIME( (short) 0x1A, (boolean) true, @@ -350,19 +337,6 @@ public enum TransportSize { (boolean) true, null, (String) "IEC61131_DATE_AND_TIME", - null), - DT( - (short) 0x1B, - (boolean) true, - (boolean) false, - (short) 0x0F, - (short) 12, - (boolean) true, - (boolean) false, - (short) 'X', - (boolean) true, - null, - (String) "IEC61131_DATE_AND_TIME", null); private static final Map map; diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java index 2cf170530d0..b4de5f24d14 100644 --- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java +++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java @@ -37,6 +37,7 @@ import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; +import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.time.Duration; @@ -2745,23 +2746,46 @@ public static void serializeS7Char(WriteBuffer io, PlcValue value, String encodi * If your application does not handle S7string, you can handle * the String as char arrays from your application. */ - public static void serializeS7String(WriteBuffer io, PlcValue value, int stringLength, String encoding) { + public static void serializeS7String(WriteBuffer io, PlcValue value, int stringLength, String encoding) throws SerializationException { int k = 0xFF & ((stringLength > 250) ? 250 : stringLength); int m = 0xFF & value.getString().length(); m = (m > k) ? k : m; - byte[] chars = new byte[m]; - for (int i = 0; i < m; ++i) { - char c = value.getString().charAt(i); - chars[i] = (byte) c; + byte[] chars; + if("UTF-8".equals(encoding)) { + chars = new byte[k]; + for (int i = 0; i < m; ++i) { + char c = value.getString().charAt(i); + chars[i] = (byte) c; + } + try { + io.writeByte((byte)(k & 0xFF)); + io.writeByte((byte)(m & 0xFF)); + io.writeByteArray(chars); + } catch (SerializationException ex) { + Logger.getLogger(StaticHelper.class.getName()).log(Level.SEVERE, null, ex); + } + } else if ("UTF-16".equals(encoding)) { + chars = new byte[k*2]; + try { + byte[] rawBytes = value.getString().getBytes("UTF-16"); + for (int i = 0; i < m * 2; ++i) { + // For some reason the first two bytes are "-2" and "-1". + chars[i] = rawBytes[i + 2]; + } + } catch (UnsupportedEncodingException e) { + throw new SerializationException("Unsupported string encoding '%s'" + encoding, e); + } + try { + io.writeUnsignedInt(16, (short)(k & 0xFFFF)); + io.writeUnsignedInt(16, (short)(m & 0xFFFF)); + io.writeByteArray(chars); + } catch (SerializationException ex) { + Logger.getLogger(StaticHelper.class.getName()).log(Level.SEVERE, null, ex); + } + } else { + throw new SerializationException("Unsupported string encoding '%s'" + encoding); } - try { - io.writeByte((byte)(k & 0xFF)); - io.writeByte((byte)(m & 0xFF)); - io.writeByteArray(chars); - } catch (SerializationException ex) { - Logger.getLogger(StaticHelper.class.getName()).log(Level.SEVERE, null, ex); - } } } diff --git a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS7DriverTest.java b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS7DriverTest.java index 5632798e977..71ff6197a15 100644 --- a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS7DriverTest.java +++ b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS7DriverTest.java @@ -23,6 +23,7 @@ import java.time.LocalDate; import java.time.LocalTime; +import java.time.format.DateTimeFormatter; public class ManualS7DriverTest extends ManualTest { @@ -66,7 +67,7 @@ public class ManualS7DriverTest extends ManualTest { */ public ManualS7DriverTest(String connectionString) { - super(connectionString); + super(connectionString, true); } public static void main(String[] args) throws Exception { @@ -88,7 +89,7 @@ public static void main(String[] args) throws Exception { test.addTestCase("%DB4:46:REAL", new PlcREAL(3.141593F)); // Not supported in S7 1200 //test.addTestCase("%DB4:50:LREAL", new PlcLREAL(2.71828182846D)); - test.addTestCase("%DB4:58:TIME", "PT1.234S"); +// test.addTestCase("%DB4:58:TIME", "PT1.234S"); test.addTestCase("%DB4:136:CHAR", new PlcCHAR("H")); test.addTestCase("%DB4:138:WCHAR", new PlcWCHAR("w")); test.addTestCase("%DB4:140:STRING(10)", new PlcSTRING("hurz")); @@ -97,8 +98,8 @@ public static void main(String[] args) throws Exception { // Not supported in S7 1200 //test.addTestCase("%DB4:62:LTIME", new PlcLTIME(Duration.parse("PT24015H23M12.034002044S")); test.addTestCase("%DB4:70:DATE", new PlcDATE(LocalDate.parse("1998-03-28"))); - test.addTestCase("%DB4:72:TIME_OF_DAY", new PlcTIME_OF_DAY(LocalTime.parse("15:36:30.123"))); - test.addTestCase("%DB4:76:TOD", new PlcTIME_OF_DAY(LocalTime.parse("16:17:18.123"))); + test.addTestCase("%DB4:72:TIME_OF_DAY", new PlcTIME_OF_DAY(LocalTime.parse("15:36:30.123", DateTimeFormatter.ofPattern("HH:mm:ss.SSS")))); + //test.addTestCase("%DB4:76:TOD", new PlcTIME_OF_DAY(LocalTime.parse("16:17:18.123"))); // Not supported in S7 1200 //test.addTestCase("%DB4:96:DATE_AND_TIME", new PlcDATE_AND_TIME(LocalDateTime.parse("1996-05-06T15:36:30"))); // Not supported in S7 1200 @@ -110,4 +111,8 @@ public static void main(String[] args) throws Exception { test.run(); } + static void testRead() { + + } + } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferByteBased.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferByteBased.java index 848934d8f63..b9a8621b2e8 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferByteBased.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferByteBased.java @@ -22,7 +22,6 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.plc4x.java.spi.generation.io.MyDefaultBitOutput; -import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import java.nio.ByteBuffer; @@ -83,7 +82,7 @@ public void pushContext(String logicalName, WithWriterArgs... writerArgs) { public void writeBit(String logicalName, boolean value, WithWriterArgs... writerArgs) throws SerializationException { try { bo.writeBoolean(value); - } catch (IOException e) { + } catch (Exception e) { throw new SerializationException("Error writing bit", e); } } @@ -110,7 +109,7 @@ public void writeUnsignedByte(String logicalName, int bitLength, byte value, Wit } try { bo.writeByte(true, bitLength, value); - } catch (IOException e) { + } catch (Exception e) { throw new SerializationException("Error writing unsigned byte", e); } } @@ -147,7 +146,7 @@ public void writeUnsignedShort(String logicalName, int bitLength, short value, W default: throw new SerializationException("unsupported encoding '" + encoding + "'"); } - } catch (IOException e) { + } catch (Exception e) { throw new SerializationException("Error writing unsigned short", e); } } @@ -187,7 +186,7 @@ public void writeUnsignedInt(String logicalName, int bitLength, int value, WithW default: throw new SerializationException("unsupported encoding '" + encoding + "'"); } - } catch (IOException e) { + } catch (Exception e) { throw new SerializationException("Error writing unsigned int", e); } } @@ -227,7 +226,7 @@ public void writeUnsignedLong(String logicalName, int bitLength, long value, Wit default: throw new SerializationException("unsupported encoding '" + encoding + "'"); } - } catch (IOException e) { + } catch (Exception e) { throw new SerializationException("Error writing unsigned long", e); } } @@ -271,7 +270,7 @@ public void writeSignedByte(String logicalName, int bitLength, byte value, WithW } try { bo.writeByte(false, bitLength, value); - } catch (IOException e) { + } catch (Exception e) { throw new SerializationException("Error writing signed byte", e); } } @@ -289,7 +288,7 @@ public void writeShort(String logicalName, int bitLength, short value, WithWrite value = Short.reverseBytes(value); } bo.writeShort(false, bitLength, value); - } catch (IOException e) { + } catch (Exception e) { throw new SerializationException("Error writing signed short", e); } } @@ -307,7 +306,7 @@ public void writeInt(String logicalName, int bitLength, int value, WithWriterArg value = Integer.reverseBytes(value); } bo.writeInt(false, bitLength, value); - } catch (IOException e) { + } catch (Exception e) { throw new SerializationException("Error writing signed int", e); } } @@ -325,7 +324,7 @@ public void writeLong(String logicalName, int bitLength, long value, WithWriterA value = Long.reverseBytes(value); } bo.writeLong(false, bitLength, value); - } catch (IOException e) { + } catch (Exception e) { throw new SerializationException("Error writing signed long", e); } } @@ -415,7 +414,7 @@ public void writeString(String logicalName, int bitLength, String value, WithWri for (int i = 0; i < numZeroBytes; i++) { bo.writeByte(false, 8, (byte) 0x00); } - } catch (IOException e) { + } catch (Exception e) { throw new SerializationException("Error writing string", e); } } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE.java index fb670374983..4e87e2fc4dd 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcDATE.java @@ -87,7 +87,8 @@ public int getDaysSinceEpoch() { } public int getDaysSinceSiemensEpoch() { - return ((int) (value.atStartOfDay(ZoneId.systemDefault()).toEpochSecond() / 86400)) - 7305; + // For some reason we need to subtract one day less (guess because of the "start of day"). + return ((int) (value.atStartOfDay(ZoneId.systemDefault()).toEpochSecond() / 86400)) - 7304; } @Override diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME_OF_DAY.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME_OF_DAY.java index d7841f6fe4a..da75f58d6f8 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME_OF_DAY.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcTIME_OF_DAY.java @@ -56,7 +56,7 @@ public PlcValueType getPlcValueType() { } public long getMillisecondsSinceMidnight() { - return ((long) value.toSecondOfDay() * 1000) + (value.getNano() / 1000_000); + return (value.toNanoOfDay() / 1000_000); } @Override @@ -66,7 +66,7 @@ public boolean isLong() { @Override public long getLong() { - return ((long) value.toSecondOfDay()) * 1000; + return getMillisecondsSinceMidnight(); } @Override diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueHandler.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueHandler.java index 18b903d2d9b..60c493c6099 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueHandler.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcValueHandler.java @@ -130,6 +130,14 @@ public static PlcValue of(PlcTag tag, Object[] values) { } return new PlcNull(); } + if (value instanceof PlcValue) { + PlcValue plcValue = (PlcValue) value; + if (plcValue.getPlcValueType() == tag.getPlcValueType()) { + return (PlcValue) value; + } else { + throw new PlcRuntimeException("Expected PlcValue of type " + tag.getPlcValueType().name() + " but got " + plcValue.getPlcValueType().name()); + } + } switch (tag.getPlcValueType()) { case BOOL: return PlcBOOL.of(value); diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java index a3162624a60..924e614ae97 100644 --- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java +++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java @@ -120,7 +120,7 @@ public void run() throws Exception { PlcWriteResponse writeResponse = writeRequest.execute().get(); // Check the result - Assertions.assertEquals(PlcResponseCode.OK, writeResponse.getResponseCode(tagName)); + Assertions.assertEquals(PlcResponseCode.OK, writeResponse.getResponseCode(tagName), String.format("Got status %s for %s", writeResponse.getResponseCode(tagName).name(), testCase.address)); } } System.out.println("Success"); diff --git a/protocols/s7/src/main/resources/protocols/s7/s7.mspec b/protocols/s7/src/main/resources/protocols/s7/s7.mspec index 0dcb81b3de0..98cf4a69192 100644 --- a/protocols/s7/src/main/resources/protocols/s7/s7.mspec +++ b/protocols/s7/src/main/resources/protocols/s7/s7.mspec @@ -734,12 +734,10 @@ [simple string 16 value encoding='"UTF-16"'] ] ['"IEC61131_STRING"' STRING - // TODO: Fix this length - [manual vstring value 'STATIC_CALL("parseS7String", readBuffer, stringLength, _type.encoding)' 'STATIC_CALL("serializeS7String", writeBuffer, _value, stringLength, _type.encoding)' 'STR_LEN(_value) + 2' encoding='"UTF-8"'] + [manual vstring value 'STATIC_CALL("parseS7String", readBuffer, stringLength, _type.encoding)' 'STATIC_CALL("serializeS7String", writeBuffer, _value, stringLength, _type.encoding)' '(stringLength * 8) + 16' encoding='"UTF-8"'] ] ['"IEC61131_WSTRING"' STRING - // TODO: Fix this length - [manual vstring value 'STATIC_CALL("parseS7String", readBuffer, stringLength, _type.encoding)' 'STATIC_CALL("serializeS7String", writeBuffer, _value, stringLength, _type.encoding)' '(STR_LEN(_value) * 2) + 2' encoding='"UTF-16"'] + [manual vstring value 'STATIC_CALL("parseS7String", readBuffer, stringLength, _type.encoding)' 'STATIC_CALL("serializeS7String", writeBuffer, _value, stringLength, _type.encoding)' '(stringLength * 16) + 32' encoding='"UTF-16"'] ] // ----------------------------------------- @@ -854,10 +852,10 @@ ['0x0F' LREAL ['0x30' , 'X' , '8' , 'REAL' , 'null' , 'IEC61131_LREAL' , 'false' , 'false' , 'true' , 'true' , 'false' ]] // Characters and Strings - ['0x10' CHAR ['0x03' , 'B' , '1' , 'null' , 'BYTE_WORD_DWORD' , 'IEC61131_CHAR' , 'true' , 'true' , 'true' , 'true' , 'true' ]] - ['0x11' WCHAR ['0x13' , 'X' , '2' , 'null' , 'null' , 'IEC61131_WCHAR' , 'false' , 'false' , 'true' , 'true' , 'true' ]] - ['0x12' STRING ['0x03' , 'X' , '1' , 'null' , 'BYTE_WORD_DWORD' , 'IEC61131_STRING' , 'true' , 'true' , 'true' , 'true' , 'true' ]] - ['0x13' WSTRING ['0x00' , 'X' , '2' , 'null' , 'null' , 'IEC61131_WSTRING' , 'false' , 'false' , 'true' , 'true' , 'true' ]] + ['0x10' CHAR ['0x03' , 'B' , '1' , 'null' , 'OCTET_STRING' , 'IEC61131_CHAR' , 'true' , 'true' , 'true' , 'true' , 'true' ]] + ['0x11' WCHAR ['0x13' , 'X' , '2' , 'null' , 'OCTET_STRING' , 'IEC61131_WCHAR' , 'false' , 'false' , 'true' , 'true' , 'true' ]] + ['0x12' STRING ['0x03' , 'X' , '1' , 'null' , 'OCTET_STRING' , 'IEC61131_STRING' , 'true' , 'true' , 'true' , 'true' , 'true' ]] + ['0x13' WSTRING ['0x00' , 'X' , '2' , 'null' , 'OCTET_STRING' , 'IEC61131_WSTRING' , 'false' , 'false' , 'true' , 'true' , 'true' ]] // Dates and time values (Please note that we seem to have to rewrite queries for these types to reading bytes or we'll get "Data type not supported" errors) ['0x14' TIME ['0x0B' , 'X' , '4' , 'null' , 'null' , 'IEC61131_TIME' , 'true' , 'true' , 'true' , 'true' , 'true' ]] @@ -865,9 +863,9 @@ ['0x16' LTIME ['0x00' , 'X' , '8' , 'TIME' , 'null' , 'IEC61131_LTIME' , 'false' , 'false' , 'false' , 'true' , 'false' ]] ['0x17' DATE ['0x09' , 'X' , '2' , 'null' , 'BYTE_WORD_DWORD' , 'IEC61131_DATE' , 'true' , 'true' , 'true' , 'true' , 'true' ]] ['0x18' TIME_OF_DAY ['0x06' , 'X' , '4' , 'null' , 'BYTE_WORD_DWORD' , 'IEC61131_TIME_OF_DAY' , 'true' , 'true' , 'true' , 'true' , 'true' ]] - ['0x19' TOD ['0x06' , 'X' , '4' , 'null' , 'BYTE_WORD_DWORD' , 'IEC61131_TIME_OF_DAY' , 'true' , 'true' , 'true' , 'true' , 'true' ]] + //['0x19' TOD ['0x06' , 'X' , '4' , 'null' , 'BYTE_WORD_DWORD' , 'IEC61131_TIME_OF_DAY' , 'true' , 'true' , 'true' , 'true' , 'true' ]] ['0x1A' DATE_AND_TIME ['0x0F' , 'X' , '12' , 'null' , 'null' , 'IEC61131_DATE_AND_TIME', 'true' , 'true' , 'false' , 'true' , 'false' ]] - ['0x1B' DT ['0x0F' , 'X' , '12' , 'null' , 'null' , 'IEC61131_DATE_AND_TIME', 'true' , 'true' , 'false' , 'true' , 'false' ]] + //['0x1B' DT ['0x0F' , 'X' , '12' , 'null' , 'null' , 'IEC61131_DATE_AND_TIME', 'true' , 'true' , 'false' , 'true' , 'false' ]] ] [enum uint 8 MemoryArea(string 24 shortName) From 072d17981d60dc0a4b7c80dd5bd13746246cfa99 Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Fri, 22 Sep 2023 17:24:48 +0200 Subject: [PATCH 03/16] fix: Fixed a package-visibility issue --- .../org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java b/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java index 2acab7f9e5c..26758cbac7e 100644 --- a/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java +++ b/plc4j/tools/connection-cache/src/main/java/org/apache/plc4x/java/utils/cache/LeasedPlcConnection.java @@ -43,7 +43,7 @@ public class LeasedPlcConnection implements PlcConnection { private boolean invalidateConnection; private final Timer usageTimer; - public LeasedPlcConnection(ConnectionContainer connectionContainer, PlcConnection connection, Duration maxUseTime) { + LeasedPlcConnection(ConnectionContainer connectionContainer, PlcConnection connection, Duration maxUseTime) { this.connectionContainer = connectionContainer; this.connection = connection; this.invalidateConnection = false; From 35c6bb6c62ef6c3cf9b1e23b01cb656b3144caa5 Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Fri, 22 Sep 2023 17:44:54 +0200 Subject: [PATCH 04/16] chore: Extended the OPM example by quite a bit ... --- .../java/examples/helloopm/HelloOpm.java | 48 ++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/plc4j/examples/hello-opm/src/main/java/org/apache/plc4x/java/examples/helloopm/HelloOpm.java b/plc4j/examples/hello-opm/src/main/java/org/apache/plc4x/java/examples/helloopm/HelloOpm.java index 43333d010d6..4c48bf4ed7b 100644 --- a/plc4j/examples/hello-opm/src/main/java/org/apache/plc4x/java/examples/helloopm/HelloOpm.java +++ b/plc4j/examples/hello-opm/src/main/java/org/apache/plc4x/java/examples/helloopm/HelloOpm.java @@ -26,11 +26,11 @@ /** * This Example shows how to use OPM from plc4j via the @{@link PlcEntityManager}. - * A @{@link CachedPlcConnectionManager} is used to optimize the acces and to allow for automatic reconnection. + * A @{@link CachedPlcConnectionManager} is used to optimize the access and to allow for automatic reconnection. * * The {@link PlcEntityManager} is similar to JPAs EntityManager. * The "connected" Entity (shootCounter) can be kept and passed around and stays connected in the sense that all calls - * to a getter are forwared to the PLC. + * to a getter are forwarded to the PLC. * Finally, one can disconnect the Entity. * * This MT works against Tims S7 in Nürtingen. @@ -38,8 +38,8 @@ */ public class HelloOpm { - private static final String ADDRESS = "s7://192.168.167.210/0/0"; - private static final String PLC_TAG_ADDRESS = "%DB225.DBW0:INT"; + private static final String PLC_ADDRESS = "s7://192.168.23.30"; + private static final String PLC_TAG_ADDRESS = "%DB4:16:SINT"; private final PlcEntityManager entityManager; public static void main(String[] args) throws OPMException { @@ -67,10 +67,12 @@ public HelloOpm() { */ public void readValueFromPlcUsingConnectedEntity() throws OPMException { // Fetch connected Entity - DistanceSensor distanceSensor = entityManager.connect(DistanceSensor.class, ADDRESS); + DistanceSensor distanceSensor = entityManager.connect(DistanceSensor.class, PLC_ADDRESS); // Read shoot values a hundred times long distance = distanceSensor.getDistance(); System.out.println("Current distance: " + distance); + // Write the values back ... + //entityManager.write(DistanceSensor.class, PLC_ADDRESS, distanceSensor); // Disconnect the Entity (not necessary) entityManager.disconnect(distanceSensor); } @@ -84,7 +86,7 @@ public void readValueFromPlcUsingConnectedEntity() throws OPMException { */ public void readValueFromPlcUsingRead() throws OPMException { // Read Entity from PLC - DistanceSensor distanceSensor = entityManager.read(DistanceSensor.class, ADDRESS); + DistanceSensor distanceSensor = entityManager.read(DistanceSensor.class, PLC_ADDRESS); System.out.println("Current distance: " + distanceSensor.getDistance()); } @@ -94,6 +96,40 @@ public void readValueFromPlcUsingRead() throws OPMException { @PlcEntity public static class DistanceSensor { + @PlcTag("%DB4:0.0:BOOL") + private boolean bitValue; + + @PlcTag("%DB4:1:BYTE") + private short byteValue; + + @PlcTag("%DB4:2:WORD") + private int wordValue; + + @PlcTag("%DB4:4:DWORD") + private long dwordValue; + + @PlcTag("%DB4:16:SINT") + private byte sintValue; + + @PlcTag("%DB4:17:USINT") + private short usintValue; + + @PlcTag("%DB4:18:INT") + private short intValue; + + @PlcTag("%DB4:20:UINT") + private int uintValue; + + @PlcTag("%DB4:22:DINT") + private int dintValue; + + @PlcTag("%DB4:26:UDINT") + private long udintValue; + + // TODO: For some reason it doesn't work with the simple type "float" + @PlcTag("%DB4:46:REAL") + private Float realValue; + @PlcTag(PLC_TAG_ADDRESS) private long distance; From 45adf96fe0fbefbc06c3a7048efd41d395ddb5ee Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Fri, 22 Sep 2023 18:01:37 +0200 Subject: [PATCH 05/16] fix: Fixed the logging dependencies --- plc4j/examples/hello-opm/pom.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plc4j/examples/hello-opm/pom.xml b/plc4j/examples/hello-opm/pom.xml index 0b68575f5e1..aaee6fdfe98 100644 --- a/plc4j/examples/hello-opm/pom.xml +++ b/plc4j/examples/hello-opm/pom.xml @@ -52,8 +52,10 @@ slf4j-api - org.slf4j - log4j-over-slf4j + ch.qos.logback + logback-core + + compile ch.qos.logback @@ -68,7 +70,7 @@ maven-dependency-plugin - org.slf4j:log4j-over-slf4j + ch.qos.logback:logback-core From 0ed57ef254f69b7d9ab16c02e03bb1ebed3e4f11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:36:15 +0200 Subject: [PATCH 06/16] build(deps): bump golang.org/x/net from 0.14.0 to 0.15.0 in /plc4go (#1096) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.14.0 to 0.15.0. - [Commits](https://github.com/golang/net/compare/v0.14.0...v0.15.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- plc4go/go.mod | 8 ++++---- plc4go/go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/plc4go/go.mod b/plc4go/go.mod index 19a45ab1575..3603d7b2718 100644 --- a/plc4go/go.mod +++ b/plc4go/go.mod @@ -44,7 +44,7 @@ require ( github.com/subchen/go-xmldom v1.1.2 github.com/viney-shih/go-lock v1.1.2 golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb - golang.org/x/net v0.14.0 + golang.org/x/net v0.15.0 golang.org/x/tools v0.12.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -74,8 +74,8 @@ require ( github.com/subosito/gotenv v1.4.2 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/term v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/term v0.12.0 // indirect + golang.org/x/text v0.13.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) diff --git a/plc4go/go.sum b/plc4go/go.sum index a54b5b12f77..92d81eeb82c 100644 --- a/plc4go/go.sum +++ b/plc4go/go.sum @@ -329,8 +329,8 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -396,14 +396,14 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -413,8 +413,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From ee6eaf85f869be5317e32653efc0486530f0f228 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:36:28 +0200 Subject: [PATCH 07/16] build(deps): bump antlr.version from 4.13.0 to 4.13.1 (#1094) Bumps `antlr.version` from 4.13.0 to 4.13.1. Updates `org.antlr:antlr4-runtime` from 4.13.0 to 4.13.1 - [Release notes](https://github.com/antlr/antlr4/releases) - [Changelog](https://github.com/antlr/antlr4/blob/dev/doc/go-changes.md) - [Commits](https://github.com/antlr/antlr4/compare/4.13.0...4.13.1) Updates `org.antlr:antlr4-maven-plugin` from 4.13.0 to 4.13.1 - [Release notes](https://github.com/antlr/antlr4/releases) - [Changelog](https://github.com/antlr/antlr4/blob/dev/doc/go-changes.md) - [Commits](https://github.com/antlr/antlr4/compare/4.13.0...4.13.1) --- updated-dependencies: - dependency-name: org.antlr:antlr4-runtime dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.antlr:antlr4-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 10dc7d87b76..e783a9619f2 100644 --- a/pom.xml +++ b/pom.xml @@ -99,7 +99,7 @@ 1.7.0-SNAPSHOT - 4.13.0 + 4.13.1 1.1.2 3.24.2 4.2.0 From 125c966eed1e6737acd90950faa327f95177b76a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:36:40 +0200 Subject: [PATCH 08/16] build(deps): bump actions/checkout from 3 to 4 (#1093) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/c-platform.yml | 2 +- .github/workflows/changelog.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/dependency-review.yml | 2 +- .github/workflows/go-platform.yml | 2 +- .github/workflows/java-platform.yml | 2 +- .github/workflows/python-platform.yml | 2 +- .github/workflows/sast.yaml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/c-platform.yml b/.github/workflows/c-platform.yml index fbb417f063b..b4575eada8b 100644 --- a/.github/workflows/c-platform.yml +++ b/.github/workflows/c-platform.yml @@ -56,7 +56,7 @@ jobs: run: brew install libpcap - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Java uses: actions/setup-java@v3 diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index ca7a466d1ae..64ea2bdc38e 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -25,7 +25,7 @@ jobs: generate-changelog: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: BobAnkh/auto-generate-changelog@v1.2.5 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9cc7ae8b5f8..9994aeaab2a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -41,7 +41,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 7d5d95b7ecd..a96a674a9f9 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -34,6 +34,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Dependency Review' uses: actions/dependency-review-action@v3 diff --git a/.github/workflows/go-platform.yml b/.github/workflows/go-platform.yml index ee0bb06f631..0164a8265aa 100644 --- a/.github/workflows/go-platform.yml +++ b/.github/workflows/go-platform.yml @@ -102,7 +102,7 @@ jobs: run: choco install -y nmap - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Java uses: actions/setup-java@v3 diff --git a/.github/workflows/java-platform.yml b/.github/workflows/java-platform.yml index 8a5ed198aca..3ca0be0f35a 100644 --- a/.github/workflows/java-platform.yml +++ b/.github/workflows/java-platform.yml @@ -58,7 +58,7 @@ jobs: run: brew install libpcap - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Java uses: actions/setup-java@v3 diff --git a/.github/workflows/python-platform.yml b/.github/workflows/python-platform.yml index 1de6e0a3943..49e4e33ffe2 100644 --- a/.github/workflows/python-platform.yml +++ b/.github/workflows/python-platform.yml @@ -58,7 +58,7 @@ jobs: if: matrix.os == 'macos-latest' run: brew install libpcap - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: diff --git a/.github/workflows/sast.yaml b/.github/workflows/sast.yaml index c71560df71c..5f99c034950 100644 --- a/.github/workflows/sast.yaml +++ b/.github/workflows/sast.yaml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Run Trivy vulnerability scanner in repo mode uses: aquasecurity/trivy-action@master From 54e8c2df1dac24972bee9dedfa942fc69940ed86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:36:57 +0200 Subject: [PATCH 09/16] build(deps): bump com.google.protobuf:protobuf-java (#1098) Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 3.24.2 to 3.24.3. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.24.2...v3.24.3) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- plc4j/integrations/apache-calcite/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plc4j/integrations/apache-calcite/pom.xml b/plc4j/integrations/apache-calcite/pom.xml index 5fcb7ee25ce..3393684670c 100644 --- a/plc4j/integrations/apache-calcite/pom.xml +++ b/plc4j/integrations/apache-calcite/pom.xml @@ -153,7 +153,7 @@ com.google.protobuf protobuf-java - 3.24.2 + 3.24.3 org.checkerframework From 77ac465256a93a7352c6b112e19f9b6ec59932e6 Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Sat, 23 Sep 2023 11:34:29 +0200 Subject: [PATCH 10/16] chore: Bumped multiple dependencies to newer versions. --- plc4go/go.mod | 2 +- plc4go/go.sum | 4 ++-- plc4j/drivers/knxnetip/pom.xml | 2 +- plc4j/drivers/opcua/pom.xml | 4 ++-- plc4j/integrations/apache-calcite/pom.xml | 2 +- plc4j/integrations/opcua-server/pom.xml | 8 ++++---- pom.xml | 14 ++++++-------- 7 files changed, 17 insertions(+), 19 deletions(-) diff --git a/plc4go/go.mod b/plc4go/go.mod index 3603d7b2718..17ba1cecd59 100644 --- a/plc4go/go.mod +++ b/plc4go/go.mod @@ -45,7 +45,7 @@ require ( github.com/viney-shih/go-lock v1.1.2 golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb golang.org/x/net v0.15.0 - golang.org/x/tools v0.12.0 + golang.org/x/tools v0.13.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/plc4go/go.sum b/plc4go/go.sum index 92d81eeb82c..418bdb0ccad 100644 --- a/plc4go/go.sum +++ b/plc4go/go.sum @@ -466,8 +466,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/plc4j/drivers/knxnetip/pom.xml b/plc4j/drivers/knxnetip/pom.xml index 0012d7ca0ff..aeb36fb6cef 100644 --- a/plc4j/drivers/knxnetip/pom.xml +++ b/plc4j/drivers/knxnetip/pom.xml @@ -160,7 +160,7 @@ org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on diff --git a/plc4j/drivers/opcua/pom.xml b/plc4j/drivers/opcua/pom.xml index 333745bd2e1..277edfe04d8 100644 --- a/plc4j/drivers/opcua/pom.xml +++ b/plc4j/drivers/opcua/pom.xml @@ -160,11 +160,11 @@ org.bouncycastle - bcpkix-jdk15on + bcpkix-jdk18on org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on diff --git a/plc4j/integrations/apache-calcite/pom.xml b/plc4j/integrations/apache-calcite/pom.xml index 3393684670c..16f04fa6bf8 100644 --- a/plc4j/integrations/apache-calcite/pom.xml +++ b/plc4j/integrations/apache-calcite/pom.xml @@ -158,7 +158,7 @@ org.checkerframework checker-qual - 3.37.0 + 3.38.0 com.google.errorprone diff --git a/plc4j/integrations/opcua-server/pom.xml b/plc4j/integrations/opcua-server/pom.xml index fa82f3dbd86..a16a3629d52 100644 --- a/plc4j/integrations/opcua-server/pom.xml +++ b/plc4j/integrations/opcua-server/pom.xml @@ -168,15 +168,15 @@ org.bouncycastle - bcmail-jdk15on + bcmail-jdk18on org.bouncycastle - bcpkix-jdk15on + bcpkix-jdk18on org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on @@ -250,7 +250,7 @@ maven-dependency-plugin - org.bouncycastle:bcmail-jdk15on + org.bouncycastle:bcmail-jdk18on org.apache.plc4x:plc4j-driver-ab-eth org.apache.plc4x:plc4j-driver-ads org.apache.plc4x:plc4j-driver-canopen diff --git a/pom.xml b/pom.xml index e783a9619f2..45599d7650e 100644 --- a/pom.xml +++ b/pom.xml @@ -105,7 +105,7 @@ 4.2.0 1.4.3 - 1.70 + 1.75 1.14.7 3.22.1 @@ -144,13 +144,11 @@ 1.8.2 1.4.11 3.2.0 - - - 0.6.10 + 0.6.11 5.5.0 4.1.97.Final 1.8.2 - 2.0.7 + 2.0.9 0.10.4 2.9.1 @@ -470,17 +468,17 @@ org.bouncycastle - bcmail-jdk15on + bcmail-jdk18on ${bouncycastle.version} org.bouncycastle - bcpkix-jdk15on + bcpkix-jdk18on ${bouncycastle.version} org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on ${bouncycastle.version} From 002da8a2d3cbef0bf450873b56226ac00a7fe114 Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Sat, 23 Sep 2023 12:20:53 +0200 Subject: [PATCH 11/16] feat: Added support in the ByteBased read- and write-buffers for WINDOWS-1252 encoding --- .../plc4x/java/spi/generation/ReadBufferByteBased.java | 4 ++++ .../plc4x/java/spi/generation/WriteBufferByteBased.java | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBufferByteBased.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBufferByteBased.java index 5b7294c40de..8b8bb4be699 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBufferByteBased.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/ReadBufferByteBased.java @@ -476,6 +476,7 @@ public String readString(String logicalName, int bitLength, WithReaderArgs... re encoding = encoding.toUpperCase(); switch (encoding) { case "ASCII": + case "WINDOWS1252": case "UTF8": { byte[] strBytes = new byte[bitLength / 8]; int realLength = 0; @@ -498,6 +499,9 @@ public String readString(String logicalName, int bitLength, WithReaderArgs... re case "UTF8": charset = StandardCharsets.UTF_8; break; + case "WINDOWS1252": + charset = Charset.forName("windows-1252"); + break; default: charset = StandardCharsets.US_ASCII; } diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferByteBased.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferByteBased.java index b9a8621b2e8..6ec299b824f 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferByteBased.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/generation/WriteBufferByteBased.java @@ -25,6 +25,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.nio.ByteBuffer; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; public class WriteBufferByteBased implements WriteBuffer, BufferCommons { @@ -379,6 +380,10 @@ public void writeString(String logicalName, int bitLength, String value, WithWri bytes = value.getBytes(StandardCharsets.US_ASCII); break; } + case "WINDOWS1252": { + bytes = value.getBytes(Charset.forName("windows-1252")); + break; + } case "UTF8": { bytes = value.getBytes(StandardCharsets.UTF_8); break; From a5bdd809984340e8f75ee573dc688ccde284abe4 Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Sat, 23 Sep 2023 12:22:03 +0200 Subject: [PATCH 12/16] fix: Changed the encoding of strings from utf8 to WINDOW-S1252. Also fixed a bug with reading strings after the ADS refactoring. --- .../apache/plc4x/java/ads/readwrite/DataItem.java | 8 ++++---- .../plc4x/java/ads/protocol/AdsProtocolLogic.java | 10 +++++++++- .../plc4x/protocol/ads/ManualAdsDriverTest.java | 4 +++- .../ads/src/main/resources/protocols/ads/ads.mspec | 12 ++++++------ 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/plc4j/drivers/ads/src/main/generated/org/apache/plc4x/java/ads/readwrite/DataItem.java b/plc4j/drivers/ads/src/main/generated/org/apache/plc4x/java/ads/readwrite/DataItem.java index 4729ae49a71..1b69b1172c4 100644 --- a/plc4j/drivers/ads/src/main/generated/org/apache/plc4x/java/ads/readwrite/DataItem.java +++ b/plc4j/drivers/ads/src/main/generated/org/apache/plc4x/java/ads/readwrite/DataItem.java @@ -150,7 +150,7 @@ public static PlcValue staticParse( // Simple Field (value) String value = /*TODO: migrate me*/ /*TODO: migrate me*/ - readBuffer.readString("", 8, WithOption.WithEncoding("UTF-8")); + readBuffer.readString("", 8, WithOption.WithEncoding("Windows-1252")); return new PlcCHAR(value); } else if (EvaluationHelper.equals(plcValueType, PlcValueType.WCHAR)) { // WCHAR @@ -164,7 +164,7 @@ public static PlcValue staticParse( // Simple Field (value) String value = /*TODO: migrate me*/ /*TODO: migrate me*/ - readBuffer.readString("", (stringLength) * (8), WithOption.WithEncoding("UTF-8")); + readBuffer.readString("", (stringLength) * (8), WithOption.WithEncoding("Windows-1252")); // Reserved Field (Compartmentalized so the "reserved" variable can't leak) { @@ -355,7 +355,7 @@ public static void staticSerialize( String value = (String) _value.getString(); /*TODO: migrate me*/ /*TODO: migrate me*/ writeBuffer.writeString( - "", 8, (String) (value), WithOption.WithEncoding("UTF-8")); + "", 8, (String) (value), WithOption.WithEncoding("Windows-1252")); } else if (EvaluationHelper.equals(plcValueType, PlcValueType.WCHAR)) { // WCHAR // Simple Field (value) String value = (String) _value.getString(); @@ -367,7 +367,7 @@ public static void staticSerialize( String value = (String) _value.getString(); /*TODO: migrate me*/ /*TODO: migrate me*/ writeBuffer.writeString( - "", (stringLength) * (8), (String) (value), WithOption.WithEncoding("UTF-8")); + "", (stringLength) * (8), (String) (value), WithOption.WithEncoding("Windows-1252")); // Reserved Field /*TODO: migrate me*/ /*TODO: migrate me*/ writeBuffer.writeUnsignedShort( diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java index 0f3c2a39f24..5c24219ebe4 100644 --- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java +++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java @@ -1681,7 +1681,15 @@ protected DirectAdsTag getDirectAdsTagForSymbolicName(PlcTag tag) { protected DirectAdsTag resolveDirectAdsTagForSymbolicNameFromDataType(List remainingAddressParts, long currentGroup, long currentOffset, AdsDataTypeTableEntry adsDataTypeTableEntry) { if (remainingAddressParts.isEmpty()) { // TODO: Implement the Array support - return new DirectAdsTag(currentGroup, currentOffset, adsDataTypeTableEntry.getDataTypeName(), 1); + if(adsDataTypeTableEntry.getDataType() == AdsDataType.CHAR.getValue()) { + int stringLength = (int) adsDataTypeTableEntry.getSize() - 1; + return new DirectAdsStringTag(currentGroup, currentOffset, adsDataTypeTableEntry.getDataTypeName(), stringLength, 1); + } else if(adsDataTypeTableEntry.getDataType() == AdsDataType.WCHAR.getValue()) { + int stringLength = (int) (adsDataTypeTableEntry.getSize() - 2) / 2; + return new DirectAdsStringTag(currentGroup, currentOffset, adsDataTypeTableEntry.getDataTypeName(), stringLength, 1); + } else { + return new DirectAdsTag(currentGroup, currentOffset, adsDataTypeTableEntry.getDataTypeName(), 1); + } } // Go through all children looking for a matching one. diff --git a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java index 6011788fc05..97293efa579 100644 --- a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java +++ b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java @@ -76,7 +76,7 @@ public ManualAdsDriverTest(String connectionString) { public static void main(String[] args) throws Exception { String spsIp = "192.168.23.20"; - String clientIp = "192.168.23.200"; + String clientIp = "192.168.23.220"; String sourceAmsNetId = clientIp + ".1.1"; int sourceAmsPort = 65534; String targetAmsNetId = spsIp + ".1.1"; @@ -100,6 +100,8 @@ public static void main(String[] args) throws Exception { test.addTestCase("MAIN.hurz_LREAL", new PlcLREAL(2.71828182846D)); test.addTestCase("MAIN.hurz_STRING", new PlcSTRING("hurz")); test.addTestCase("MAIN.hurz_WSTRING", new PlcWSTRING("wolf")); + test.addTestCase("MAIN.hurz_Special_STRING", new PlcSTRING("€")); + test.addTestCase("MAIN.hurz_Special_WSTRING", new PlcWSTRING("€")); test.addTestCase("MAIN.hurz_TIME", new PlcTIME(Duration.parse("PT1.234S"))); test.addTestCase("MAIN.hurz_LTIME", new PlcLTIME(Duration.parse("PT24015H23M12.034002044S"))); test.addTestCase("MAIN.hurz_DATE", new PlcDATE(LocalDate.parse("1978-03-28"))); diff --git a/protocols/ads/src/main/resources/protocols/ads/ads.mspec b/protocols/ads/src/main/resources/protocols/ads/ads.mspec index 5ee6f8d9ea9..b2d2516f3e4 100644 --- a/protocols/ads/src/main/resources/protocols/ads/ads.mspec +++ b/protocols/ads/src/main/resources/protocols/ads/ads.mspec @@ -462,18 +462,18 @@ // Characters & Strings // ----------------------------------------- ['CHAR' CHAR - [simple string 8 value encoding='"UTF-8"' ] + [simple string 8 value encoding='"Windows-1252"'] ] ['WCHAR' WCHAR - [simple string 16 value encoding='"UTF-16LE"'] + [simple string 16 value encoding='"UTF-16LE"' ] ] ['STRING' STRING - [simple vstring 'stringLength * 8' value encoding='"UTF-8"' ] - [reserved uint 8 '0x00' ] + [simple vstring 'stringLength * 8' value encoding='"Windows-1252"'] + [reserved uint 8 '0x00' ] ] ['WSTRING' WSTRING - [simple vstring 'stringLength * 8 * 2' value encoding='"UTF-16LE"'] - [reserved uint 16 '0x0000' ] + [simple vstring 'stringLength * 8 * 2' value encoding='"UTF-16LE"' ] + [reserved uint 16 '0x0000' ] ] // ----------------------------------------- From 46648c03f0eea1b1594c3d6faa0b15de74987001 Mon Sep 17 00:00:00 2001 From: Christofer Dutz Date: Sat, 23 Sep 2023 12:46:19 +0200 Subject: [PATCH 13/16] fix: Changed the encoding of strings from utf8 to WINDOW-S1252. Also fixed a bug with reading strings after the ADS refactoring. --- plc4go/protocols/ads/readwrite/model/DataItem.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plc4go/protocols/ads/readwrite/model/DataItem.go b/plc4go/protocols/ads/readwrite/model/DataItem.go index 42e49f2a258..135895e46cb 100644 --- a/plc4go/protocols/ads/readwrite/model/DataItem.go +++ b/plc4go/protocols/ads/readwrite/model/DataItem.go @@ -166,7 +166,7 @@ func DataItemParseWithBuffer(ctx context.Context, readBuffer utils.ReadBuffer, p return values.NewPlcLREAL(value), nil case plcValueType == PlcValueType_CHAR: // CHAR // Simple Field (value) - value, _valueErr := readBuffer.ReadString("value", uint32(8), "UTF-8") + value, _valueErr := readBuffer.ReadString("value", uint32(8), "Windows-1252") if _valueErr != nil { return nil, errors.Wrap(_valueErr, "Error parsing 'value' field") } @@ -182,7 +182,7 @@ func DataItemParseWithBuffer(ctx context.Context, readBuffer utils.ReadBuffer, p return values.NewPlcWCHAR(value), nil case plcValueType == PlcValueType_STRING: // STRING // Simple Field (value) - value, _valueErr := readBuffer.ReadString("value", uint32((stringLength)*(8)), "UTF-8") + value, _valueErr := readBuffer.ReadString("value", uint32((stringLength)*(8)), "Windows-1252") if _valueErr != nil { return nil, errors.Wrap(_valueErr, "Error parsing 'value' field") } @@ -378,7 +378,7 @@ func DataItemSerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.Wri } case plcValueType == PlcValueType_CHAR: // CHAR // Simple Field (value) - if _err := writeBuffer.WriteString("value", uint32(8), "UTF-8", value.GetString()); _err != nil { + if _err := writeBuffer.WriteString("value", uint32(8), "Windows-1252", value.GetString()); _err != nil { return errors.Wrap(_err, "Error serializing 'value' field") } case plcValueType == PlcValueType_WCHAR: // WCHAR @@ -388,7 +388,7 @@ func DataItemSerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.Wri } case plcValueType == PlcValueType_STRING: // STRING // Simple Field (value) - if _err := writeBuffer.WriteString("value", uint32((stringLength)*(8)), "UTF-8", value.GetString()); _err != nil { + if _err := writeBuffer.WriteString("value", uint32((stringLength)*(8)), "Windows-1252", value.GetString()); _err != nil { return errors.Wrap(_err, "Error serializing 'value' field") } From b492b674a08aea74f548b8d7f5ccb21f5a03fbc0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 07:55:05 +0200 Subject: [PATCH 14/16] build(deps): bump org.checkerframework:checker-qual (#1091) Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.37.0 to 3.38.0. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.37.0...checker-framework-3.38.0) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From aefb7c5b8579b4551fee5c23e635dbcb18f17cc1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 07:55:28 +0200 Subject: [PATCH 15/16] build(deps): bump slf4j.version from 2.0.7 to 2.0.9 (#1092) Bumps `slf4j.version` from 2.0.7 to 2.0.9. Updates `org.slf4j:slf4j-api` from 2.0.7 to 2.0.9 Updates `org.slf4j:log4j-over-slf4j` from 2.0.7 to 2.0.9 --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.slf4j:log4j-over-slf4j dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From bd064a594440160d98da61e6eae741fa2777a263 Mon Sep 17 00:00:00 2001 From: takraj Date: Mon, 25 Sep 2023 07:58:36 +0200 Subject: [PATCH 16/16] fix(plc4j/opcua): Fix incorrectly handled GUID tags (#1099) 1. The driver tried to `arraycopy()` a `Long`, which caused `ArrayStoreException`. 2. GUIDs are structured objects, that matters when it comes to byte ordering. The OPC-UA protocol uses little (mixed) endian GUID encoding format, while Java uses the standard big endian one (RFC4122), so conversion is needed. References: * https://reference.opcfoundation.org/Core/Part6/v104/docs/5.2.2.6 * https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding * https://devblogs.microsoft.com/oldnewthing/20220928-00/?p=107221 * https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html * https://www.ietf.org/rfc/rfc4122.txt --- .../opcua/protocol/OpcuaProtocolLogic.java | 13 ++-- .../plc4x/java/opcua/ManualOpcuaGuidTag.java | 43 +++++++++++++ .../protocol/OpcuaProtocolLogicTest.java | 63 +++++++++++++++++++ 3 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcuaGuidTag.java create mode 100644 plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogicTest.java diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java index fb320c26d93..543db9acbcf 100644 --- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java +++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java @@ -18,6 +18,7 @@ */ package org.apache.plc4x.java.opcua.protocol; +import java.nio.ByteBuffer; import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.api.messages.*; import org.apache.plc4x.java.api.model.PlcConsumerRegistration; @@ -228,10 +229,14 @@ static NodeId generateNodeId(OpcuaTag tag) { nodeId = new NodeId(new NodeIdNumeric((short) tag.getNamespace(), Long.parseLong(tag.getIdentifier()))); } else if (tag.getIdentifierType() == OpcuaIdentifierType.GUID_IDENTIFIER) { UUID guid = UUID.fromString(tag.getIdentifier()); - byte[] guidBytes = new byte[16]; - System.arraycopy(guid.getMostSignificantBits(), 0, guidBytes, 0, 8); - System.arraycopy(guid.getLeastSignificantBits(), 0, guidBytes, 8, 8); - nodeId = new NodeId(new NodeIdGuid((short) tag.getNamespace(), guidBytes)); + ByteBuffer bb = ByteBuffer.allocate(16) + .order(java.nio.ByteOrder.LITTLE_ENDIAN) + .putInt((int)(guid.getMostSignificantBits() >> (4*8))) + .putShort((short)(guid.getMostSignificantBits() >> (2*8))) + .putShort((short)guid.getMostSignificantBits()) + .order(java.nio.ByteOrder.BIG_ENDIAN) + .putLong(guid.getLeastSignificantBits()); + nodeId = new NodeId(new NodeIdGuid((short) tag.getNamespace(), bb.array())); } else if (tag.getIdentifierType() == OpcuaIdentifierType.STRING_IDENTIFIER) { nodeId = new NodeId(new NodeIdString((short) tag.getNamespace(), new PascalString(tag.getIdentifier()))); } diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcuaGuidTag.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcuaGuidTag.java new file mode 100644 index 00000000000..1ab29c55194 --- /dev/null +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/ManualOpcuaGuidTag.java @@ -0,0 +1,43 @@ +/* + * 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. + */ + +package org.apache.plc4x.java.opcua; + +import org.apache.plc4x.java.DefaultPlcDriverManager; +import org.apache.plc4x.java.api.PlcConnection; +import org.apache.plc4x.java.api.messages.PlcReadRequest; +import org.apache.plc4x.java.api.messages.PlcReadResponse; + +public class ManualOpcuaGuidTag { + + public static void main(String... args) throws Exception { + DefaultPlcDriverManager driverManager = new DefaultPlcDriverManager(); + try (PlcConnection opcuaConnection = driverManager.getConnection("opcua:tcp://opcuaserver.com:48010")) { + PlcReadRequest request = opcuaConnection.readRequestBuilder() + .addTagAddress( + "VariableWithGuidNodeId", + "ns=2;g=5CE9DBCE-5D79-434C-9AC3-1CFBA9A6E92C" + ) + .build(); + + PlcReadResponse response = request.execute().get(); + System.out.println(response.getObject("VariableWithGuidNodeId")); + } + } +} diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogicTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogicTest.java new file mode 100644 index 00000000000..5a7694c4022 --- /dev/null +++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogicTest.java @@ -0,0 +1,63 @@ +/* + * 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. + */ + +package org.apache.plc4x.java.opcua.protocol; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.apache.plc4x.java.opcua.readwrite.NodeId; +import org.apache.plc4x.java.opcua.readwrite.NodeIdGuid; +import org.apache.plc4x.java.opcua.readwrite.NodeIdType; +import org.apache.plc4x.java.opcua.tag.OpcuaTag; +import org.junit.jupiter.api.Test; + +public class OpcuaProtocolLogicTest { + + @Test + public void testGenerateNodeId() { + OpcuaTag tag = OpcuaTag.of("ns=2;g=00112233-4455-6677-8899-aabbccddeeff"); + NodeId nodeId = OpcuaProtocolLogic.generateNodeId(tag); + assertEquals(NodeIdType.nodeIdTypeGuid, nodeId.getNodeId().getNodeType()); + + NodeIdGuid nodeIdGuid = (NodeIdGuid) nodeId.getNodeId(); + assertEquals(2, nodeIdGuid.getNamespaceIndex()); + assertArrayEquals( + new byte[] { + (byte) 0x33, + (byte) 0x22, + (byte) 0x11, + (byte) 0x00, + (byte) 0x55, + (byte) 0x44, + (byte) 0x77, + (byte) 0x66, + (byte) 0x88, + (byte) 0x99, + (byte) 0xaa, + (byte) 0xbb, + (byte) 0xcc, + (byte) 0xdd, + (byte) 0xee, + (byte) 0xff + }, + nodeIdGuid.getId() + ); + } +}