//
//  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.
//

== EtherNet/IP

`IP` in `EtherNet/IP` does not relate to the `Internet Protocol` but to `Industrial Protocol`, so EtherNet/IP does not necessarily have to go over `IP` but can be implemented on `ethernet frames`.
This driver however will utilize `EtherNet/IP` based on `TCP` and `UDP`.

EIP (the short form of: EtherNet/IP) generally supports two types of communication:

- `Explicit messaging`: Read explicitly addressed information (Pull) (CIP Class 3 and 2)
- `Implicit messaging`: Read information distributed by the device configuration (Push) (CIP Class 1 and 0)

TCP transport is used for Explicit Messaging
UDP transport is used for Implicit Messaging ("Real time" I/O)

In Explicit Messaging (classic Request/Response) there are two different types of access:

- Connected access: A handle 'connectionId' is assigned to an address and this is used to access the resource
- Unconnected access: No handle is used and the address has to be sent with every request

We'll concentrate on the connected access.

In all cases the payload of the data items is dependent on the encapsulated protocol used.
In our case we'll concentrate on the default CIP format.

Explicitly addressed object consists of the following data:

- Object-Number
- Instance-Number
- Attribute-Number

The format we have decided to use is: `#{objectId}#{instanceId}#{attributeId}`.

Here is the location of the Spec:
https://www.odva.org/Portals/0/Library/Publications_Numbered/PUB00123R1_Common-Industrial_Protocol_and_Family_of_CIP_Networks.pdf

As EtherNet/IP is used to encapsulate CIP traffic, this spec contains a chapter on the adaption of CIP for EtherNet/IP.

Another documentation I found discussing the explicit messaging thing a little better is this:
http://www.deltamotion.com/support/webhelp/rmctools/Communications/Ethernet/Supported_Protocols/EtherNetIP/EtherNet_IP_Explicit_Messaging.htm
https://www.odva.org/Portals/0/Library/Publications_Numbered/PUB00213R0_EtherNetIP_Developers_Guide.pdf
http://www.technologyuk.net/telecommunications/industrial-networks/cip.shtml

=== Reading

When reading values in a request/response type of communication (explicit), there are two options:

- Unconnected access: Ideal when requesting information irregularly and not frequently. Less performant.
- Connected access: Ideal when regularly requesting information. Higher performance, but requires multiple phases.

We will concentrate on explicit connected access.

In order to read/write values using connected access, first we have to get a connectionId for the resource we want to access.
In subsequent read/write operations, we don't have to provide the field, but just provide the connection id and the server will already know what we want to access.

Getting the connection id, is performed by sending an unconnected request to the server referencing the `Forward Open Service`.
This will register the connection in the Server and this will stay alive until the session is terminated.
So we have to make sure a session is created before using this service.

Part of this request is a parameter `vendor id`.
It turns out that this id has to be purchased from the ODVA organization.

https://secure.odva.org/forms/spec-vendor-id-order-form.htm

But probably we can live without a valid and registered id.