Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.ci_config

# Vim
.*.swp
.*.swo
43 changes: 42 additions & 1 deletion include/odva_ethernetip/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,44 @@ class Connection
EIP_UINT o_to_t_buffer_size;
EIP_UINT t_to_o_buffer_size;

bool o_to_t_variable_size;
bool t_to_o_variable_size;

CONN_PRIORITY_T o_to_t_priority;
CONN_PRIORITY_T t_to_o_priority;

CONN_TYPE_T o_to_t_type;
CONN_TYPE_T t_to_o_type;

bool o_to_t_shared;
bool t_to_o_shared;

EIP_BYTE connection_type_;

/**
* Create a connection instance using the directional values and reasonable defaults
* @param o_to_t Originator to Target info
* @param t_to_o Target to Originator info
*/
Connection(const EIP_CONNECTION_INFO_T& o_to_t, const EIP_CONNECTION_INFO_T& t_to_o);

/**
* Create a connection instance using the directional values and reasonable defaults
* @param o_to_t Originator to Target info
* @param t_to_o Target to Originator info
* @param connection_type Byte
*/
Connection(const EIP_CONNECTION_INFO_T& o_to_t, const EIP_CONNECTION_INFO_T& t_to_o, EIP_BYTE connection_type);

/**
* Create a connection instance using the directional values and reasonable defaults
* @param o_to_t Originator to Target info
* @param t_to_o Target to Originator info
* @param connection_type Byte
* @param path Path already containing segments
*/
Connection(const EIP_CONNECTION_INFO_T& o_to_t, const EIP_CONNECTION_INFO_T& t_to_o, EIP_BYTE connection_type, const Path *path);

/**
* Get the path in the given message router request
* @return reference to the current Path
Expand All @@ -92,7 +123,17 @@ class Connection
/**
* Create the forward open request from the data in this connection object
*/
shared_ptr<ForwardOpenRequest> createForwardOpenRequest();
shared_ptr<ForwardOpenRequest> createForwardOpenRequest()
{
// Maintains backwards compatability
return createForwardOpenRequest(false);
}

/**
* Create the forward open request from the data in this connection object
* @param use_legacy_forward_open_request use 16 bit connection parameters instead of news 32 bit parameters
*/
shared_ptr<ForwardOpenRequest> createForwardOpenRequest(bool use_legacy_forward_open_request);

/**
* Create a forward close request from the data in this connection object
Expand Down
29 changes: 29 additions & 0 deletions include/odva_ethernetip/eip_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,25 @@ typedef enum
EIP_ITEM_SEQ_ADDRESS = 0x8002,
} EIP_ITEM_T;

typedef enum
{
CONN_PRIORITY_LOW = 0,
CONN_PRIORITY_HIGH = 1,
CONN_PRIORITY_SCHEDULED = 2,
CONN_PRIORITY_URGENT = 3,
} CONN_PRIORITY_T;

typedef enum
{
CONN_TYPE_NULL = 0,
CONN_TYPE_MULTICAST = 1,
CONN_TYPE_P2P = 2,
CONN_TYPE_RESERVED = 3,
} CONN_TYPE_T;

typedef struct
{
virtual void f() {}; // This allows dynamic_cast
/// Assembly ID for this endpoint of the connection
EIP_USINT assembly_id;
/// Buffer size to be used for routing
Expand All @@ -104,4 +121,16 @@ typedef struct
EIP_UDINT rpi;
} EIP_CONNECTION_INFO_T;

typedef struct _EIP_CONNECTION_INFO_ADVANCED_T : EIP_CONNECTION_INFO_T
{
// Variable Size: default o_to_t false, default t_to_o true
bool variable_size;
// Priority: default CONN_PRIORITY_SCHEDULED
CONN_PRIORITY_T priority;
//Connection Type: default CONN_TYPE_P2P
CONN_TYPE_T type;
// Connection Type: default false
bool shared;
} EIP_CONNECTION_INFO_ADVANCED_T;

#endif // ODVA_ETHERNETIP_EIP_TYPES_H
128 changes: 92 additions & 36 deletions include/odva_ethernetip/forward_open_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,6 @@ using serialization::Serializable;
using serialization::Reader;
using serialization::Writer;

typedef enum
{
CONN_PRIORITY_LOW = 0,
CONN_PRIORITY_HIGH = 1,
CONN_PRIORITY_SCHEDULED = 2,
CONN_PRIORITY_URGENT = 3,
} CONN_PRIORITY_T;

typedef enum
{
CONN_TYPE_NULL = 0,
CONN_TYPE_MULTICAST = 1,
CONN_TYPE_P2P = 2,
CONN_TYPE_RESERVED = 3,
} CONN_TYPE_T;

/**
* Class to encapsulate a ForwardOpenRequest data. Note that this is currently
* only LARGE forward open, but could be easily changed to support both.
Expand All @@ -77,12 +61,26 @@ class ForwardOpenRequest : public Serializable
EIP_USINT timeout_multiplyer;
EIP_UDINT o_to_t_rpi;
EIP_DWORD o_to_t_conn_params;
EIP_WORD o_to_t_conn_params_legacy;
EIP_UDINT t_to_o_rpi;
EIP_DWORD t_to_o_conn_params;
EIP_WORD t_to_o_conn_params_legacy;
EIP_BYTE conn_type;

bool use_legacy_forward_open_request;

ForwardOpenRequest()
: use_legacy_forward_open_request(false)
{
}

ForwardOpenRequest(bool use_legacy_forward_open_request)
: use_legacy_forward_open_request(use_legacy_forward_open_request)
{
}

/**
* Helper to calculate connection parameters
* Helper to calculate connection parameters for current 32 bit connection parameters
* @param size Maximum size of the messages in the connection in byte
* @param variable if set to true, variable message sizes
* @param priority Priority value for the connection
Expand All @@ -96,13 +94,35 @@ class ForwardOpenRequest : public Serializable
| (type & 0x03) << 29 | (shared ? 0x80000000 : 0);
}

/**
* Helper to calculate connection parameters for legacy 16 bit connection parameters
* @param size Maximum size of the messages in the connection in byte
* @param variable if set to true, variable message sizes
* @param priority Priority value for the connection
* @param type Connection type / class info
* @param shared If set to true, then a shared connection
*/
static EIP_WORD calcConnectionParamsLegacy(EIP_UINT size, bool variable, EIP_BYTE priority,
EIP_BYTE type, bool shared)
{
return (size & 0x1FF) | (variable ? 0x200 : 0) | (priority & 0x03) << 10
| (type & 0x03) << 13 | (shared ? 0x8000 : 0);
}

/**
* Shortcut to set the origin to target parameters.
*/
EIP_DWORD setOriginToTargetParams(EIP_UINT size, bool variable, EIP_BYTE priority,
EIP_BYTE type, bool shared)
{
o_to_t_conn_params = calcConnectionParams(size, variable, priority, type, shared);
if (use_legacy_forward_open_request)
{
o_to_t_conn_params_legacy = calcConnectionParamsLegacy(size, variable, priority, type, shared);
}
else
{
o_to_t_conn_params = calcConnectionParams(size, variable, priority, type, shared);
}
return 0;
}

Expand All @@ -112,7 +132,14 @@ class ForwardOpenRequest : public Serializable
EIP_DWORD setTargetToOriginParams(EIP_UINT size, bool variable, EIP_BYTE priority,
EIP_BYTE type, bool shared)
{
t_to_o_conn_params = calcConnectionParams(size, variable, priority, type, shared);
if (use_legacy_forward_open_request)
{
t_to_o_conn_params_legacy = calcConnectionParamsLegacy(size, variable, priority, type, shared);
}
else
{
t_to_o_conn_params = calcConnectionParams(size, variable, priority, type, shared);
}
return 0;
}

Expand All @@ -131,21 +158,36 @@ class ForwardOpenRequest : public Serializable
*/
virtual size_t getLength() const
{
return sizeof(timeout_tick_size)
+ sizeof(timeout_ticks)
+ sizeof(o_to_t_connection_id)
+ sizeof(t_to_o_connection_id)
+ sizeof(connection_sn)
+ sizeof(originator_vendor_id)
+ sizeof(originator_sn)
+ sizeof(timeout_multiplyer)
+ sizeof(o_to_t_rpi)
+ sizeof(o_to_t_conn_params)
+ sizeof(t_to_o_rpi)
+ sizeof(t_to_o_conn_params)
+ sizeof(conn_type)
+ 3 // reserved bytes
+ path_.getLength();
size_t ret = sizeof(timeout_tick_size);
ret += sizeof(timeout_ticks);
ret += sizeof(o_to_t_connection_id);
ret += sizeof(t_to_o_connection_id);
ret += sizeof(connection_sn);
ret += sizeof(originator_vendor_id);
ret += sizeof(originator_sn);
ret += sizeof(timeout_multiplyer);
ret += sizeof(o_to_t_rpi);
if (use_legacy_forward_open_request)
{
ret += sizeof(o_to_t_conn_params_legacy);
}
else
{
ret += sizeof(o_to_t_conn_params);
}
ret += sizeof(t_to_o_rpi);
if (use_legacy_forward_open_request)
{
ret += sizeof(t_to_o_conn_params_legacy);
}
else
{
ret += sizeof(t_to_o_conn_params);
}
ret += sizeof(conn_type);
ret += 3; // reserved bytes
ret += path_.getLength();
return ret;
}

/**
Expand All @@ -169,9 +211,23 @@ class ForwardOpenRequest : public Serializable
writer.write(reserved);
writer.write(reserved);
writer.write(o_to_t_rpi);
writer.write(o_to_t_conn_params);
if (use_legacy_forward_open_request)
{
writer.write(o_to_t_conn_params_legacy);
}
else
{
writer.write(o_to_t_conn_params);
}
writer.write(t_to_o_rpi);
writer.write(t_to_o_conn_params);
if (use_legacy_forward_open_request)
{
writer.write(t_to_o_conn_params_legacy);
}
else
{
writer.write(t_to_o_conn_params);
}
writer.write(conn_type);
path_.serialize(writer);
return writer;
Expand Down
12 changes: 12 additions & 0 deletions include/odva_ethernetip/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ class Path
pad_after_length_ = pad;
}

/**
* Add a port segment
* @param link_id ID Number of port's link address id to add to path
*/
void addPort(EIP_USINT link_id);

/**
* Add a port segment
* @param data data vector to add to path
*/
void addData(std::vector<EIP_USINT> data);

/**
* Add a logical class segment
* @param class_id ID Number of class to add to path
Expand Down
2 changes: 1 addition & 1 deletion include/odva_ethernetip/serialization/buffer_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class BufferWriter : public Writer
using boost::asio::buffer_size;
if (buffer_size(buf_) < buffer_size(b))
{
throw std::length_error("Buffer to small to serialize value");
throw std::length_error("Buffer too small to serialize value");
}
boost::asio::buffer_copy(buf_, b);
byte_count_ += buffer_size(b);
Expand Down
Loading