diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java index 3307de12ecb..a4ebba84161 100644 --- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java +++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/configuration/AdsConfiguration.java @@ -37,7 +37,7 @@ public class AdsConfiguration implements PlcConnectionConfiguration { @Required @ConfigurationParameter("target-ams-net-id") @ParameterConverter(AmsNetIdConverter.class) - @Description("AMS-Net-Id of the target.") + @Description("AMS-Net-Id of the target. An AMS-Net-Id has the regular format of an IPv4 IP-Address, however with 6 segments instead of 4.") protected AmsNetId targetAmsNetId; @Required @@ -48,7 +48,7 @@ public class AdsConfiguration implements PlcConnectionConfiguration { @Required @ConfigurationParameter("source-ams-net-id") @ParameterConverter(AmsNetIdConverter.class) - @Description("AMS-Net-Id of the source.") + @Description("AMS-Net-Id of the source. An AMS-Net-Id has the regular format of an IPv4 IP-Address, however with 6 segments instead of 4.") protected AmsNetId sourceAmsNetId; @Required diff --git a/plc4j/drivers/all/pom.xml b/plc4j/drivers/all/pom.xml index bbc11a2938d..1da47080434 100644 --- a/plc4j/drivers/all/pom.xml +++ b/plc4j/drivers/all/pom.xml @@ -180,5 +180,12 @@ 0.12.0-SNAPSHOT runtime + + + org.apache.plc4x + plc4j-transport-serial + 0.12.0-SNAPSHOT + runtime + diff --git a/plc4j/drivers/all/src/site/generated/ab-eth.adoc b/plc4j/drivers/all/src/site/generated/ab-eth.adoc index f2cb0c64303..7e3742eeb47 100644 --- a/plc4j/drivers/all/src/site/generated/ab-eth.adoc +++ b/plc4j/drivers/all/src/site/generated/ab-eth.adoc @@ -35,7 +35,10 @@ |Supported Transports 4+| - `tcp` 5+|Config options: -|`` |INT || |Id of the station we want to connect to +|`station` |INT | | |Id of the station we want to connect to 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. |=== diff --git a/plc4j/drivers/all/src/site/generated/ads.adoc b/plc4j/drivers/all/src/site/generated/ads.adoc index a9ef4f4b428..ade9f4e5023 100644 --- a/plc4j/drivers/all/src/site/generated/ads.adoc +++ b/plc4j/drivers/all/src/site/generated/ads.adoc @@ -35,13 +35,15 @@ |Supported Transports 4+| - `tcp` 5+|Config options: -|`` |STRUCT || | -|`target-ams-net-id` |STRUCT ||required |AMS-Net-Id of the target. -|`target-ams-port` |INT ||required |AMS port of the target. -|`source-ams-net-id` |STRUCT ||required |AMS-Net-Id of the source. -|`source-ams-port` |INT ||required |AMS port of the source. +|`target-ams-net-id` |STRING | |required |AMS-Net-Id of the target. +|`target-ams-port` |INT | |required |AMS port of the target. +|`source-ams-net-id` |STRING | |required |AMS-Net-Id of the source. +|`source-ams-port` |INT | |required |AMS port of the source. |`timeout-request` |INT |4000| |Default timeout for all types of requests. |`load-symbol-and-data-type-tables` |BOOLEAN |true| |Configures, if when connecting the data-type- and symbol-table should be read. This is an optimization that can help in cases, where the PLC program is pretty large and downloading the full tables is causing problems. When disabled, symbolic addresses will manually be resolved as soon as an address is used. 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. |=== diff --git a/plc4j/drivers/all/src/site/generated/bacnet-ip.adoc b/plc4j/drivers/all/src/site/generated/bacnet-ip.adoc index 5d36ca6012a..34acd17f5b8 100644 --- a/plc4j/drivers/all/src/site/generated/bacnet-ip.adoc +++ b/plc4j/drivers/all/src/site/generated/bacnet-ip.adoc @@ -37,11 +37,27 @@ - `tcp` - `pcap` 5+|Config options: -|`ede-file-path` |STRING || |Path to the location of a single EDE file, that contains the descriptor for the target device. -|`ede-directory-path` |STRING || |Path to the directory used for storing multiple EDE files. These files contain the descriptors for the possible target devices. +|`ede-file-path` |STRING | | |Path to the location of a single EDE file, that contains the descriptor for the target device. +|`ede-directory-path` |STRING | | |Path to the directory used for storing multiple EDE files. These files contain the descriptors for the possible target devices. 5+|Transport config options: 5+| - `udp` +|`udp.local-port` |INT |-1| |Some connections require a UDP listener to listen on a fixed port. +Use this configuration option in order to define the port number of the local port. 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. 5+| - `pcap` |`pcap.support-vlans` |BOOLEAN |false| |Enables support for VLans +|`pcap.replay-speed-factor` |FLOAT |1.0| |Numeric value for changing the replay speed: +- 1 = Normal speed (default) +- 0 = Maximum speed +- 0.5 = Half speed +- 2 = Double speed +|`pcap.loop` |BOOLEAN |false| |Should the replay start at the beginning of the file as soon as the end is reached? +- true = Automatically start again +- false = Stop at the end (default) +|`pcap.filter` |STRING | | |Filter expression used to filter out unwanted packets from the replay. +|`pcap.support-vlans` |BOOLEAN |false| |Should VLan packets be automatically unpacked? +|`pcap.protocol-id` |INT |-1| |When provided, filters all packets to let only packets matching this ethernet protocol-id pass. |=== diff --git a/plc4j/drivers/all/src/site/generated/c-bus.adoc b/plc4j/drivers/all/src/site/generated/c-bus.adoc index b1ba923bef1..a66ee9017bb 100644 --- a/plc4j/drivers/all/src/site/generated/c-bus.adoc +++ b/plc4j/drivers/all/src/site/generated/c-bus.adoc @@ -38,4 +38,7 @@ |`srchk` |BOOLEAN |false| |Source check. 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. |=== diff --git a/plc4j/drivers/all/src/site/generated/canopen.adoc b/plc4j/drivers/all/src/site/generated/canopen.adoc index a645815ae78..a1c7c179a60 100644 --- a/plc4j/drivers/all/src/site/generated/canopen.adoc +++ b/plc4j/drivers/all/src/site/generated/canopen.adoc @@ -33,8 +33,11 @@ ---- |Default Transport 4+|`socketcan` |Supported Transports 4+| + - `socketcan` 5+|Config options: -|`node-id` |INT || |CAN node identifier. Depending on used CAN version it might be 11 or 29 bit unsigned int. -|`` |BOOLEAN || |Forces PLC4X to send CANopen heartbeat (NMT) messages to the bus. +|`node-id` |INT | | |CAN node identifier. Depending on used CAN version it might be 11 or 29 bit unsigned int. +|`heartbeat` |BOOLEAN | | |Forces PLC4X to send CANopen heartbeat (NMT) messages to the bus. |`request-timeout` |INT |1000| |Time after which dispatched BUS operation (ie. SDO request) will be marked as failed. +5+|Transport config options: +5+| - `socketcan` |=== diff --git a/plc4j/drivers/all/src/site/generated/eip.adoc b/plc4j/drivers/all/src/site/generated/eip.adoc index 7a7c47188f1..e49d3cd8a6c 100644 --- a/plc4j/drivers/all/src/site/generated/eip.adoc +++ b/plc4j/drivers/all/src/site/generated/eip.adoc @@ -35,9 +35,12 @@ |Supported Transports 4+| - `tcp` 5+|Config options: -|`` |INT || |Without using routing information the backplane defaults to 1. This is overridden if communicationPath is provided. -|`` |INT || |The slot within the backplane the CPU is located. -|`` |BOOLEAN || |Configure if the connection should be set to transport data in Big-Endian format, or not. +|`backplane` |INT | | |Without using routing information the backplane defaults to 1. This is overridden if communicationPath is provided. +|`slot` |INT | | |The slot within the backplane the CPU is located. +|`bigEndian` |BOOLEAN | | |Configure if the connection should be set to transport data in Big-Endian format, or not. 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. |=== diff --git a/plc4j/drivers/all/src/site/generated/firmata.adoc b/plc4j/drivers/all/src/site/generated/firmata.adoc index 57fdb2965ea..f08198567b2 100644 --- a/plc4j/drivers/all/src/site/generated/firmata.adoc +++ b/plc4j/drivers/all/src/site/generated/firmata.adoc @@ -37,4 +37,32 @@ 5+|Config options: 5+|Transport config options: 5+| - `serial` +|`serial.baud-rate` |INT |57600| |Baud-rate the serial port is set to. +Typical values are: +- 9600 +- 14400 +- 19200 +- 38400 +- 57600 +- 115200 +- 128000 +But can also be smaller or larger values. +|`serial.num-data-bits` |INT |8| |Number of data-bits used to send data. +Typical values are: +- 7 +- 8 +But can also be smaller or larger values. +|`serial.num-stop-bits` |INT |1| |Number of stop-bits used to terminate data. +Typical values are: +- 1 +- 2 +(The theoretical 1.5 stop-bits setting is not supported) +|`serial.parity` |STRUCT |NO_PARITY| |Number of bits used to calculate data parity. +This is used to detect errors in transmission. +Allowed values are: +- NO_PARITY +- ODD_PARITY +- EVEN_PARITY +- MARK_PARITY +- SPACE_PARITY |=== diff --git a/plc4j/drivers/all/src/site/generated/genericcan.adoc b/plc4j/drivers/all/src/site/generated/genericcan.adoc index f0dd5e969d5..54b046c7669 100644 --- a/plc4j/drivers/all/src/site/generated/genericcan.adoc +++ b/plc4j/drivers/all/src/site/generated/genericcan.adoc @@ -33,7 +33,10 @@ ---- |Default Transport 4+|`socketcan` |Supported Transports 4+| + - `socketcan` 5+|Config options: -|`node-id` |INT || |Node id of the target device. +|`node-id` |INT | | |Node id of the target device. |`request-timeout` |INT |1000| |Default timeout for all types of requests. +5+|Transport config options: +5+| - `socketcan` |=== diff --git a/plc4j/drivers/all/src/site/generated/iec-60870-5-104.adoc b/plc4j/drivers/all/src/site/generated/iec-60870-5-104.adoc index 2c7083063dc..9e68fb28c14 100644 --- a/plc4j/drivers/all/src/site/generated/iec-60870-5-104.adoc +++ b/plc4j/drivers/all/src/site/generated/iec-60870-5-104.adoc @@ -38,4 +38,7 @@ |`request-timeout` |INT |4000| |Default timeout for all types of requests. 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. |=== diff --git a/plc4j/drivers/all/src/site/generated/knxnet-ip.adoc b/plc4j/drivers/all/src/site/generated/knxnet-ip.adoc index 046a601aafd..5efa68e6618 100644 --- a/plc4j/drivers/all/src/site/generated/knxnet-ip.adoc +++ b/plc4j/drivers/all/src/site/generated/knxnet-ip.adoc @@ -37,8 +37,8 @@ - `pcap` - `raw` 5+|Config options: -|`knxproj-file-path` |STRING || |Path to the `knxproj` file. The default KNXnet/IP protocol doesn't provide all the information needed to be able to fully decode the messages. -|`knxproj-password` |STRING || |Optional password needed to read the knxproj file. +|`knxproj-file-path` |STRING | | |Path to the `knxproj` file. The default KNXnet/IP protocol doesn't provide all the information needed to be able to fully decode the messages. +|`knxproj-password` |STRING | | |Optional password needed to read the knxproj file. |`group-address-num-levels` |INT |3| |KNX Addresses can be encoded in multiple ways. Which encoding is used, is too not provided by the protocol itself so it has to be provided externally: - 3 Levels: {main-group (5 bit)}/{middle-group (3 bit)}/{sub-group (8 bit)} @@ -53,6 +53,22 @@ The default is 3 levels. If the `knxproj-file-path` this information is provided - 'BUSMONITOR': The client operates as a busmonitor where he can't actively participate on the bus. Only one 'BUSMONITOR' connection is allowed at the same time on a KNXnet/IP gateway. 5+|Transport config options: 5+| - `udp` +|`udp.local-port` |INT |-1| |Some connections require a UDP listener to listen on a fixed port. +Use this configuration option in order to define the port number of the local port. 5+| - `pcap` +|`pcap.replay-speed-factor` |FLOAT |1.0| |Numeric value for changing the replay speed: +- 1 = Normal speed (default) +- 0 = Maximum speed +- 0.5 = Half speed +- 2 = Double speed +|`pcap.loop` |BOOLEAN |false| |Should the replay start at the beginning of the file as soon as the end is reached? +- true = Automatically start again +- false = Stop at the end (default) +|`pcap.filter` |STRING | | |Filter expression used to filter out unwanted packets from the replay. +|`pcap.support-vlans` |BOOLEAN |false| |Should VLan packets be automatically unpacked? +|`pcap.protocol-id` |INT |-1| |When provided, filters all packets to let only packets matching this ethernet protocol-id pass. 5+| - `raw` +|`raw.resolve-mac-address` |BOOLEAN | | |If set to true, the transport will automatically resolve the MAC address for a given IP address (Allows connecting to a raw-socket device using the devices host-name or ip-address). +|`raw.support-vlans` |BOOLEAN |false| |Should VLan packets be automatically unpacked? +|`raw.protocol-id` |INT |-1| |When provided, filters all packets to let only packets matching this ethernet protocol-id pass. |=== diff --git a/plc4j/drivers/all/src/site/generated/logix.adoc b/plc4j/drivers/all/src/site/generated/logix.adoc index 8af8932fecf..7ae3002a5f4 100644 --- a/plc4j/drivers/all/src/site/generated/logix.adoc +++ b/plc4j/drivers/all/src/site/generated/logix.adoc @@ -35,9 +35,15 @@ |Supported Transports 4+| - `tcp` 5+|Config options: -|`communication-path` |STRING || |The communication path allows for connection routing across multiple backplanes. It uses a common format found in logix controllers. +|`communication-path` |STRING | | |The communication path allows for connection routing across multiple backplanes. It uses a common format found in logix controllers. It consists of pairs of values, each pair begins with either 1 (Backplane) or 2 (Ethernet), followed by a slot in the case of a backplane address, or if using Ethernet an ip address. e.g. [1,4,2,192.168.0.1,1,1] - Routes to the 4th slot in the first rack, which is a ethernet module, it then connects to the address 192.168.0.1, then finds the module in slot 1. +|`backplane` |INT | | |Without using routing information the backplane defaults to 1. This is overridden if communicationPath is provided. +|`slot` |INT | | |The slot within the backplane the CPU is located. +|`bigEndian` |BOOLEAN | | |Configure if the connection should be set to transport data in Big-Endian format, or not. 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. |=== diff --git a/plc4j/drivers/all/src/site/generated/modbus-ascii.adoc b/plc4j/drivers/all/src/site/generated/modbus-ascii.adoc index c88bc14b63d..203d421145a 100644 --- a/plc4j/drivers/all/src/site/generated/modbus-ascii.adoc +++ b/plc4j/drivers/all/src/site/generated/modbus-ascii.adoc @@ -40,5 +40,36 @@ |`unit-identifier` |INT |1| |Unit-identifier that identifies the target PLC (On RS485 multiple Modbus Devices can be listening). Defaults to 1. 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. 5+| - `serial` +|`serial.baud-rate` |INT |57600| |Baud-rate the serial port is set to. +Typical values are: +- 9600 +- 14400 +- 19200 +- 38400 +- 57600 +- 115200 +- 128000 +But can also be smaller or larger values. +|`serial.num-data-bits` |INT |8| |Number of data-bits used to send data. +Typical values are: +- 7 +- 8 +But can also be smaller or larger values. +|`serial.num-stop-bits` |INT |1| |Number of stop-bits used to terminate data. +Typical values are: +- 1 +- 2 +(The theoretical 1.5 stop-bits setting is not supported) +|`serial.parity` |STRUCT |NO_PARITY| |Number of bits used to calculate data parity. +This is used to detect errors in transmission. +Allowed values are: +- NO_PARITY +- ODD_PARITY +- EVEN_PARITY +- MARK_PARITY +- SPACE_PARITY |=== diff --git a/plc4j/drivers/all/src/site/generated/modbus-rtu.adoc b/plc4j/drivers/all/src/site/generated/modbus-rtu.adoc index 06176ff476f..8dc898c0de5 100644 --- a/plc4j/drivers/all/src/site/generated/modbus-rtu.adoc +++ b/plc4j/drivers/all/src/site/generated/modbus-rtu.adoc @@ -40,5 +40,36 @@ |`unit-identifier` |INT |1| |Unit-identifier that identifies the target PLC (On RS485 multiple Modbus Devices can be listening). Defaults to 1. 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. 5+| - `serial` +|`serial.baud-rate` |INT |57600| |Baud-rate the serial port is set to. +Typical values are: +- 9600 +- 14400 +- 19200 +- 38400 +- 57600 +- 115200 +- 128000 +But can also be smaller or larger values. +|`serial.num-data-bits` |INT |8| |Number of data-bits used to send data. +Typical values are: +- 7 +- 8 +But can also be smaller or larger values. +|`serial.num-stop-bits` |INT |1| |Number of stop-bits used to terminate data. +Typical values are: +- 1 +- 2 +(The theoretical 1.5 stop-bits setting is not supported) +|`serial.parity` |STRUCT |NO_PARITY| |Number of bits used to calculate data parity. +This is used to detect errors in transmission. +Allowed values are: +- NO_PARITY +- ODD_PARITY +- EVEN_PARITY +- MARK_PARITY +- SPACE_PARITY |=== diff --git a/plc4j/drivers/all/src/site/generated/modbus-tcp.adoc b/plc4j/drivers/all/src/site/generated/modbus-tcp.adoc index c0f9cccdbf9..8f3f693f329 100644 --- a/plc4j/drivers/all/src/site/generated/modbus-tcp.adoc +++ b/plc4j/drivers/all/src/site/generated/modbus-tcp.adoc @@ -39,4 +39,7 @@ |`unit-identifier` |INT |1| |Unit-identifier that identifies the target PLC (On RS485 multiple Modbus Devices can be listening). Defaults to 1. 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. |=== diff --git a/plc4j/drivers/all/src/site/generated/opcua.adoc b/plc4j/drivers/all/src/site/generated/opcua.adoc index ca886c252e0..2bff9f83bed 100644 --- a/plc4j/drivers/all/src/site/generated/opcua.adoc +++ b/plc4j/drivers/all/src/site/generated/opcua.adoc @@ -35,37 +35,39 @@ |Supported Transports 4+| - `tcp` 5+|Config options: -|`protocol-code` |STRING || | -|`transport-code` |STRING || | -|`transport-config` |STRING || | +|`protocol-code` |STRING | | | +|`transport-code` |STRING | | | +|`transport-config` |STRING | | | |`discovery` |BOOLEAN |true| |Controls the feature of the discovery endpoint of an OPC UA server which every server will propagate over an '
/discovery' endpoint. The most common issue here is that most servers are not correctly configured and propagate the wrong external IP or URL address. If that is the case you can disable the discovery by configuring it with a `false` value. The discovery phase is always conducted using `NONE` security policy. -|`username` |STRING || |A username to authenticate to the OPCUA server with. -|`password` |STRING || |A password to authenticate to the OPCUA server with. +|`username` |STRING | | |A username to authenticate to the OPCUA server with. +|`password` |STRING | | |A password to authenticate to the OPCUA server with. |`security-policy` |STRING |NONE| |The security policy applied to communication channel between driver and OPC UA server. Default value assumes. Possible options are `NONE`, `Basic128Rsa15`, `Basic256`, `Basic256Sha256`, `Aes128_Sha256_RsaOaep`, `Aes256_Sha256_RsaPss`. |`message-security` |STRING |SIGN_ENCRYPT| |The security policy applied to messages exchanged after handshake phase. Possible options are `NONE`, `SIGN`, `SIGN_ENCRYPT`. This option is effective only when `securityPolicy` turns encryption (anything beyond `NONE`). -|`key-store-file` |STRING || |The Keystore file used to lookup client certificate and its private key. +|`key-store-file` |STRING | | |The Keystore file used to lookup client certificate and its private key. |`key-store-type` |STRING |pkcs12| |Keystore type used to access keystore and private key, defaults to PKCS (for Java 11+). Possible values are between others `jks`, `pkcs11`, `dks`, `jceks`. -|`key-store-password` |STRING || |Java keystore password used to access keystore and private key. -|`server-certificate-file` |STRING || |Filesystem location where server certificate is located, supported formats are `DER` and `PEM`. -|`trust-store-file` |STRING || |The trust store file used to verify server certificates and its chain. +|`key-store-password` |STRING | | |Java keystore password used to access keystore and private key. +|`server-certificate-file` |STRING | | |Filesystem location where server certificate is located, supported formats are `DER` and `PEM`. +|`trust-store-file` |STRING | | |The trust store file used to verify server certificates and its chain. |`trust-store-type` |STRING |pkcs12| |Keystore type used to access keystore and private key, defaults to PKCS (for Java 11+). Possible values are between others `jks`, `pkcs11`, `dks`, `jceks`. -|`trust-store-password` |STRING || |Password used to open trust store. -|`` |STRUCT || | +|`trust-store-password` |STRING | | |Password used to open trust store. |`channel-lifetime` |LONG |3600000| |Time for which negotiated secure channel, its keys and session remains open. Value in milliseconds, by default 60 minutes. |`session-timeout` |LONG |120000| |Expiry time for opened secure session, value in milliseconds. Defaults to 2 minutes. |`negotiation-timeout` |LONG |60000| |Timeout for all negotiation steps prior acceptance of application level operations - this timeout applies to open secure channel, create session and close calls. Defaults to 60 seconds. |`request-timeout` |LONG |30000| |Timeout for read/write/subscribe calls. Value in milliseconds. -|`` |STRUCT || |TCP encoding options +|`encoding` |STRUCT | | |TCP encoding options 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. |=== diff --git a/plc4j/drivers/all/src/site/generated/open-protocol.adoc b/plc4j/drivers/all/src/site/generated/open-protocol.adoc index 6e1567e9ad1..d024d4f78f9 100644 --- a/plc4j/drivers/all/src/site/generated/open-protocol.adoc +++ b/plc4j/drivers/all/src/site/generated/open-protocol.adoc @@ -37,4 +37,7 @@ 5+|Config options: 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. |=== diff --git a/plc4j/drivers/all/src/site/generated/plc4x.adoc b/plc4j/drivers/all/src/site/generated/plc4x.adoc index b36f62c317d..13dd89e7e3a 100644 --- a/plc4j/drivers/all/src/site/generated/plc4x.adoc +++ b/plc4j/drivers/all/src/site/generated/plc4x.adoc @@ -35,8 +35,11 @@ |Supported Transports 4+| - `tcp` 5+|Config options: -|`remote-connection-string` |STRING || |URL-Encoded connection string to use on the proxy side to reach the given PLC. +|`remote-connection-string` |STRING | | |URL-Encoded connection string to use on the proxy side to reach the given PLC. |`request-timeout` |INT |5000| |Default timeout for all types of requests. 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. |=== diff --git a/plc4j/drivers/all/src/site/generated/profinet.adoc b/plc4j/drivers/all/src/site/generated/profinet.adoc index 1a1e0a5d54f..796a086bab8 100644 --- a/plc4j/drivers/all/src/site/generated/profinet.adoc +++ b/plc4j/drivers/all/src/site/generated/profinet.adoc @@ -36,8 +36,11 @@ - `raw` 5+|Config options: |`gsd-directory` |STRING |~/.gsd|required | -|`dap-id` |STRING || | -|`ip-address` |STRING || | +|`dap-id` |STRING | | | +|`ip-address` |STRING | | | 5+|Transport config options: 5+| - `raw` +|`raw.resolve-mac-address` |BOOLEAN | | |If set to true, the transport will automatically resolve the MAC address for a given IP address (Allows connecting to a raw-socket device using the devices host-name or ip-address). +|`raw.support-vlans` |BOOLEAN |false| |Should VLan packets be automatically unpacked? +|`raw.protocol-id` |INT |-1| |When provided, filters all packets to let only packets matching this ethernet protocol-id pass. |=== diff --git a/plc4j/drivers/all/src/site/generated/s7.adoc b/plc4j/drivers/all/src/site/generated/s7.adoc index ffc1ba476ca..ea732a2cdf2 100644 --- a/plc4j/drivers/all/src/site/generated/s7.adoc +++ b/plc4j/drivers/all/src/site/generated/s7.adoc @@ -46,7 +46,7 @@ |`pdu-size` |INT |1024| |Maximum size of a data-packet sent to and received from the remote PLC. During the connection process both parties will negotiate a maximum size both parties can work with and is equal or smaller than the given value is used. The driver will automatically split up large requests to not exceed this value in a request or expected response. |`max-amq-caller` |INT |8| |Maximum number of unconfirmed requests the PLC will accept in parallel before discarding with errors. This parameter also will be negotiated during the connection process and the maximum both parties can work with and is equal or smaller than the given value is used. The driver will automatically take care not exceeding this value while processing requests. Too many requests can cause a growing queue. |`max-amq-callee` |INT |8| |Maximum number of unconfirmed responses or requests PLC4X will accept in parallel before discarding with errors. This option is available for completeness and is correctly handled out during the connection process, however it is currently not enforced on PLC4X’s side. So if a PLC would send more messages than agreed upon, these would still be processed. -|`controller-type` |STRING || |As part of the connection process, usually the PLC4X S7 driver would try to identify the remote device. However some devices seem to have problems with this and hang up or cause other problems. In such a case, providing the controller-type will skip the identification process and hereby avoid this type of problem. Possible values are:/n- S7_300 +|`controller-type` |STRING | | |As part of the connection process, usually the PLC4X S7 driver would try to identify the remote device. However some devices seem to have problems with this and hang up or cause other problems. In such a case, providing the controller-type will skip the identification process and hereby avoid this type of problem. Possible values are:/n- S7_300 - S7_400 - S7_1200 - S7-1500 @@ -57,4 +57,7 @@ |`retry-time` |INT |0| |Time value in seconds at which the execution of the PING will be scheduled. Generally set by developer experience, but generally should be the same as (read-timeout / 2). 5+|Transport config options: 5+| - `tcp` +|`tcp.keep-alive` |BOOLEAN |false| |Should keep-alive packets be sent? +|`tcp.no-delay` |BOOLEAN |true| |Should packets be sent instantly or should we give the OS some time to aggregate data. +|`tcp.default-timeout` |INT |1000| |Timeout after which a connection will be treated as disconnected. |=== diff --git a/plc4j/drivers/all/src/site/groovy/generate-config-documentation.groovy b/plc4j/drivers/all/src/site/groovy/generate-config-documentation.groovy index 1def409c20f..cb5042a88f1 100644 --- a/plc4j/drivers/all/src/site/groovy/generate-config-documentation.groovy +++ b/plc4j/drivers/all/src/site/groovy/generate-config-documentation.groovy @@ -44,6 +44,7 @@ try { throw new Exception( "Error creating classloader for loading message format schema from module dependencies", e); } +Thread.currentThread().setContextClassLoader(moduleClassloader) // Create a driver manager instance, that is using our custom built classloader. def plcDriverManager = new DefaultPlcDriverManager(moduleClassloader) diff --git a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/configuration/LogixConfiguration.java b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/configuration/LogixConfiguration.java index 19d211197e1..957011358b2 100644 --- a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/configuration/LogixConfiguration.java +++ b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/configuration/LogixConfiguration.java @@ -25,7 +25,7 @@ public class LogixConfiguration extends EIPConfiguration { @ConfigurationParameter("communication-path") - @Description("The communication path allows for connection routing across multiple backplanes. It uses a common format found in logix controllers.\n" + + @Description("The communication path allows for connection routing across multiple backplanes. It uses a common format found in Logix controllers.\n" + "It consists of pairs of values, each pair begins with either 1 (Backplane) or 2 (Ethernet), followed by a slot in the case of a backplane address,\n" + "or if using Ethernet an ip address. e.g. [1,4,2,192.168.0.1,1,1] - Routes to the 4th slot in the first rack, which is a ethernet module, it then connects to the address 192.168.0.1, then finds the module in slot 1.") private String communicationPath; diff --git a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java index e0a8334b40d..a8a023f6eef 100644 --- a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java +++ b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java @@ -20,6 +20,7 @@ import io.netty.buffer.ByteBuf; import org.apache.plc4x.java.api.configuration.PlcConnectionConfiguration; +import org.apache.plc4x.java.api.configuration.PlcTransportConfiguration; import org.apache.plc4x.java.api.exceptions.PlcRuntimeException; import org.apache.plc4x.java.firmata.readwrite.configuration.FirmataConfiguration; import org.apache.plc4x.java.firmata.readwrite.context.FirmataDriverContext; diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java index 5305ff26051..58c10014593 100644 --- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java +++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java @@ -30,9 +30,7 @@ import org.apache.plc4x.java.api.metadata.PlcDriverMetadata; import org.apache.plc4x.java.api.value.PlcValueHandler; import org.apache.plc4x.java.spi.configuration.ConfigurationFactory; -import org.apache.plc4x.java.spi.configuration.annotations.ConfigurationParameter; -import org.apache.plc4x.java.spi.configuration.annotations.Description; -import org.apache.plc4x.java.spi.configuration.annotations.Required; +import org.apache.plc4x.java.spi.configuration.annotations.*; import org.apache.plc4x.java.spi.configuration.annotations.defaults.*; import org.apache.plc4x.java.spi.generation.Message; import org.apache.plc4x.java.spi.metadata.DefaultOption; @@ -40,6 +38,7 @@ import org.apache.plc4x.java.spi.optimizer.BaseOptimizer; import org.apache.plc4x.java.spi.transport.Transport; +import java.lang.reflect.Field; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -86,6 +85,10 @@ public Optional getDefaultTransportCode() { @Override public List getSupportedTransportCodes() { + List supportedTransportCodes = GeneratedDriverBase.this.getSupportedTransportCodes(); + if(supportedTransportCodes.isEmpty() && (getDefaultTransportCode().isPresent())) { + return Collections.singletonList(getDefaultTransportCode().get()); + } return GeneratedDriverBase.this.getSupportedTransportCodes(); } @@ -95,11 +98,23 @@ public Optional getProtocolConfigurationOptionMetadata() { if (clazz == null) { return Optional.empty(); } - var options = Arrays.stream(clazz.getDeclaredFields()).map(field -> { - String key = ""; + var options = getAllFields(clazz).stream().map(field -> { + String key = null; var configurationParameterAnnotation = field.getAnnotation(ConfigurationParameter.class); if (configurationParameterAnnotation != null) { key = configurationParameterAnnotation.value(); + if(key.isEmpty()) { + key = field.getName(); + } + } else { + var complexConfigurationParameterAnnotation = field.getAnnotation(ComplexConfigurationParameter.class); + if (complexConfigurationParameterAnnotation != null) { + key = complexConfigurationParameterAnnotation.prefix(); + // TODO: Add support for listing the options of a complex configuration parameter. + } + } + if(key == null) { + return null; } String description = ""; var descriptionAnnotation = field.getAnnotation(Description.class); @@ -137,7 +152,13 @@ public Optional getProtocolConfigurationOptionMetadata() { type = OptionType.STRING; break; default: - type = OptionType.STRUCT; + // If there's a property-converter, use "STRING" as type. + var parameterConverterAnnotation = field.getAnnotation(ParameterConverter.class); + if(parameterConverterAnnotation != null) { + type = OptionType.STRING; + } else { + type = OptionType.STRUCT; + } break; } Object defaultValue = null; @@ -168,6 +189,7 @@ public Optional getProtocolConfigurationOptionMetadata() { } return new DefaultOption(key, type, description, required, defaultValue); }) + .filter(Objects::nonNull) .map(Option.class::cast) .collect(Collectors.toList()); return Optional.of(new DefaultOptionMetadata(options)); @@ -175,16 +197,28 @@ public Optional getProtocolConfigurationOptionMetadata() { @Override public Optional getTransportConfigurationOptionMetadata(String transportCode) { - var clazzOption = getTransportConfigurationClass(transportCode); + var clazzOption = resolveTransportConfigurationClass(transportCode); if (clazzOption.isEmpty()) { return Optional.empty(); } var clazz = clazzOption.get(); - var options = Arrays.stream(clazz.getDeclaredFields()).map(field -> { - String key = ""; + var options = getAllFields(clazz).stream().map(field -> { + String key = null; var configurationParameterAnnotation = field.getAnnotation(ConfigurationParameter.class); if (configurationParameterAnnotation != null) { key = configurationParameterAnnotation.value(); + if(key.isEmpty()) { + key = field.getName(); + } + } else { + var complexConfigurationParameterAnnotation = field.getAnnotation(ComplexConfigurationParameter.class); + if (complexConfigurationParameterAnnotation != null) { + key = complexConfigurationParameterAnnotation.prefix(); + // TODO: Add support for listing the options of a complex configuration parameter. + } + } + if(key == null) { + return null; } String description = ""; var descriptionAnnotation = field.getAnnotation(Description.class); @@ -222,7 +256,13 @@ public Optional getTransportConfigurationOptionMetadata(String t type = OptionType.STRING; break; default: - type = OptionType.STRUCT; + // If there's a property-converter, use "STRING" as type. + var parameterConverterAnnotation = field.getAnnotation(ParameterConverter.class); + if(parameterConverterAnnotation != null) { + type = OptionType.STRING; + } else { + type = OptionType.STRUCT; + } break; } Object defaultValue = null; @@ -252,6 +292,7 @@ public Optional getTransportConfigurationOptionMetadata(String t } return new DefaultOption(key, type, description, required, defaultValue); }) + .filter(Objects::nonNull) .map(Option.class::cast) .collect(Collectors.toList()); return Optional.of(new DefaultOptionMetadata(options)); @@ -430,4 +471,36 @@ public PlcConnection getConnection(String connectionString, PlcAuthentication au authentication); } + protected Optional> resolveTransportConfigurationClass(String transportCode) { + if (getTransportConfigurationClass(transportCode).isPresent()) { + return Optional.of(getTransportConfigurationClass(transportCode).get()); + } + + // Try to find a suitable transport-type for creating the communication channel. + Transport transport = null; + ServiceLoader transportLoader = ServiceLoader.load( + Transport.class, Thread.currentThread().getContextClassLoader()); + for (Transport curTransport : transportLoader) { + if (curTransport.getTransportCode().equals(transportCode)) { + transport = curTransport; + break; + } + } + if (transport == null) { + return Optional.empty(); + } + + // Find out the type of the transport configuration. + Class transportConfigurationType = transport.getTransportConfigType(); + return Optional.of(transportConfigurationType); + } + + protected List getAllFields(Class type) { + List fields = new ArrayList<>(Arrays.asList(type.getDeclaredFields())); + if(type.getSuperclass() != null) { + fields.addAll(getAllFields(type.getSuperclass())); + } + return fields; + } + }