//
//  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
//
//      https://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.
//
:imagesdir: ../../images/users/protocols
:icons: font

= Profinet (In Development)

NOTE: No language implementation of this driver is usable yet. See the
xref:protocols/index.adoc[protocol support matrix] for what each implementation
currently does.

WARNING: The PROFINET driver is not usable yet. Two parallel implementations exist in the code base
(`plc4j-driver-profinet` and `plc4j-driver-profinet-ng`, of which only the latter is shipped) and
neither completes a working exchange - the subscription response future is never completed and
cyclic IO frames are logged rather than dispatched. This page describes the intended design and is
kept for reference; it is not linked from the navigation.

The PROFINET driver implements a class 3 real time controller. Which is able to communicate with multiple devices
on the same network segment.

== Connection String Options

[NOTE]
====
Array selection uses the shared notation - a single index, an inclusive range, and
optionally the array's declared lower bound, placed before the type. See
xref:array-notation.adoc[Addressing arrays].
====

On linux as the Java executable won't have permission to capture raw packets, this needs to be enabled via:-
----
sudo setcap cap_net_raw,cap_net_admin=eip /usr/lib/jvm/jdk-19/bin/java
----
The executable will change based on the jdk and OS you are using.

include::partial$profinet.adoc[]

[cols="2,2a,5a"]
|===
|Name |Value |Description

3+|Supported Operations

|| `discover` |Locates PROFINET devices on the network segment via DCP.

|| `browse` |Lists the submodules of a connected device as tags.

|| `subscribe` |*Does not deliver data.* The connect handshake is performed, but the subscription
response future is never completed and `ProfinetConnection.onRegisterConsumer` throws
`UnsupportedOperationException`, so no cyclic IO ever reaches an application.

|| `read` / `write` |*Not implemented.*

|===

== Connection String

The Profinet driver uses the connection string

----

profinet:raw://{ip-address}:{port}?{options}

----

Where the \{ip-address}, unlike other PLC4X driver, uses the local IP address of the network interface you would like to bind to.
This allows us to connect to multiple devices at once via the devices parameter.

An example of this connection string which has two devices test-device-1 and test-device-2, connected on the localhost interface would be:-

----

profinet:raw://127.0.0.1?gsddirectory=/Profinet/GSD&devices=[[test-device-1,MOD_1,(SUBMOD_1,,SUBMOD_1,)],[test-device-2,MOD_1,(SUBMOD_1,,SUBMOD_1,)]]

----

Note the transport, port fields shouldn't have to be changed


== Address Format
The format of address will be in the format.

----

device.slot.id.module_name.channel.bit:format

----

An example would be

----
device-1.1.1.DIGITAL_INPUT.0.1:BOOL
----

Note:-

=== Data Types

The following data types are supported

- BOOL (boolean)
- SINT (int 8)
- USINT (uint 8)
- BYTE (uint 8)
- INT (int 16)
- UINT (uint 16)
- WORD (uint 16)
- DINT (int 32)
- UDINT (uint 32)
- DWORD (uint 32)
- LINT (int 64)
- ULINT (uint 64)
- LWORD (uint 64)
- REAL (float)
- LREAL (double)
- CHAR (char)
- WCHAR (2 byte char)
- STRING (utf-8)
- WSTRING (utf-16)


== Some useful tips

Although the GSD file contains all the information needed to configure which data will be available from a device.
The easiest approach is to use the browsing function of the Profinet driver to return a list of all available tags.
Then only the addresses of interest can be selected.

