Skip to content

Commit 1dd6785

Browse files
committed
Add support for early versions of CIP specification
http://read.pudn.com/downloads589/doc/2410232/CIP%20Vol1_3.3.pdf Page 95 Section 3-5.5.1.1 connection parameters are only 16 bits Also adds an option to not fully close the conncetion. This allows reconnection for slightly offspec devices.
1 parent a775b74 commit 1dd6785

File tree

5 files changed

+132
-27
lines changed

5 files changed

+132
-27
lines changed

include/odva_ethernetip/connection.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,17 @@ class Connection
9292
/**
9393
* Create the forward open request from the data in this connection object
9494
*/
95-
shared_ptr<ForwardOpenRequest> createForwardOpenRequest();
95+
shared_ptr<ForwardOpenRequest> createForwardOpenRequest()
96+
{
97+
// Maintains backwards compatability
98+
return createForwardOpenRequest(false);
99+
}
100+
101+
/**
102+
* Create the forward open request from the data in this connection object
103+
* @param use_legacy_forward_open_request use 16 bit connection parameters instead of news 32 bit parameters
104+
*/
105+
shared_ptr<ForwardOpenRequest> createForwardOpenRequest(bool use_legacy_forward_open_request);
96106

97107
/**
98108
* Create a forward close request from the data in this connection object

include/odva_ethernetip/forward_open_request.h

Lines changed: 87 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,21 @@ class ForwardOpenRequest : public Serializable
7777
EIP_USINT timeout_multiplyer;
7878
EIP_UDINT o_to_t_rpi;
7979
EIP_DWORD o_to_t_conn_params;
80+
EIP_WORD o_to_t_conn_params_legacy;
8081
EIP_UDINT t_to_o_rpi;
8182
EIP_DWORD t_to_o_conn_params;
83+
EIP_WORD t_to_o_conn_params_legacy;
8284
EIP_BYTE conn_type;
8385

86+
bool use_legacy_forward_open_request;
87+
88+
ForwardOpenRequest(bool use_legacy_forward_open_request)
89+
: use_legacy_forward_open_request(use_legacy_forward_open_request)
90+
{
91+
}
92+
8493
/**
85-
* Helper to calculate connection parameters
94+
* Helper to calculate connection parameters for current 32 bit connection parameters
8695
* @param size Maximum size of the messages in the connection in byte
8796
* @param variable if set to true, variable message sizes
8897
* @param priority Priority value for the connection
@@ -96,13 +105,35 @@ class ForwardOpenRequest : public Serializable
96105
| (type & 0x03) << 29 | (shared ? 0x80000000 : 0);
97106
}
98107

108+
/**
109+
* Helper to calculate connection parameters for legacy 16 bit connection parameters
110+
* @param size Maximum size of the messages in the connection in byte
111+
* @param variable if set to true, variable message sizes
112+
* @param priority Priority value for the connection
113+
* @param type Connection type / class info
114+
* @param shared If set to true, then a shared connection
115+
*/
116+
static EIP_WORD calcConnectionParamsLegacy(EIP_UINT size, bool variable, EIP_BYTE priority,
117+
EIP_BYTE type, bool shared)
118+
{
119+
return (size & 0x1FF) | (variable ? 0x200 : 0) | (priority & 0x03) << 10
120+
| (type & 0x03) << 13 | (shared ? 0x8000 : 0);
121+
}
122+
99123
/**
100124
* Shortcut to set the origin to target parameters.
101125
*/
102126
EIP_DWORD setOriginToTargetParams(EIP_UINT size, bool variable, EIP_BYTE priority,
103127
EIP_BYTE type, bool shared)
104128
{
105-
o_to_t_conn_params = calcConnectionParams(size, variable, priority, type, shared);
129+
if (use_legacy_forward_open_request)
130+
{
131+
o_to_t_conn_params_legacy = calcConnectionParamsLegacy(size, variable, priority, type, shared);
132+
}
133+
else
134+
{
135+
o_to_t_conn_params = calcConnectionParams(size, variable, priority, type, shared);
136+
}
106137
return 0;
107138
}
108139

@@ -112,7 +143,14 @@ class ForwardOpenRequest : public Serializable
112143
EIP_DWORD setTargetToOriginParams(EIP_UINT size, bool variable, EIP_BYTE priority,
113144
EIP_BYTE type, bool shared)
114145
{
115-
t_to_o_conn_params = calcConnectionParams(size, variable, priority, type, shared);
146+
if (use_legacy_forward_open_request)
147+
{
148+
t_to_o_conn_params_legacy = calcConnectionParamsLegacy(size, variable, priority, type, shared);
149+
}
150+
else
151+
{
152+
t_to_o_conn_params = calcConnectionParams(size, variable, priority, type, shared);
153+
}
116154
return 0;
117155
}
118156

@@ -131,21 +169,36 @@ class ForwardOpenRequest : public Serializable
131169
*/
132170
virtual size_t getLength() const
133171
{
134-
return sizeof(timeout_tick_size)
135-
+ sizeof(timeout_ticks)
136-
+ sizeof(o_to_t_connection_id)
137-
+ sizeof(t_to_o_connection_id)
138-
+ sizeof(connection_sn)
139-
+ sizeof(originator_vendor_id)
140-
+ sizeof(originator_sn)
141-
+ sizeof(timeout_multiplyer)
142-
+ sizeof(o_to_t_rpi)
143-
+ sizeof(o_to_t_conn_params)
144-
+ sizeof(t_to_o_rpi)
145-
+ sizeof(t_to_o_conn_params)
146-
+ sizeof(conn_type)
147-
+ 3 // reserved bytes
148-
+ path_.getLength();
172+
size_t ret = sizeof(timeout_tick_size);
173+
ret += sizeof(timeout_ticks);
174+
ret += sizeof(o_to_t_connection_id);
175+
ret += sizeof(t_to_o_connection_id);
176+
ret += sizeof(connection_sn);
177+
ret += sizeof(originator_vendor_id);
178+
ret += sizeof(originator_sn);
179+
ret += sizeof(timeout_multiplyer);
180+
ret += sizeof(o_to_t_rpi);
181+
if (use_legacy_forward_open_request)
182+
{
183+
ret += sizeof(o_to_t_conn_params_legacy);
184+
}
185+
else
186+
{
187+
ret += sizeof(o_to_t_conn_params);
188+
}
189+
ret += sizeof(t_to_o_rpi);
190+
if (use_legacy_forward_open_request)
191+
{
192+
ret += sizeof(t_to_o_conn_params_legacy);
193+
}
194+
else
195+
{
196+
ret += sizeof(t_to_o_conn_params);
197+
}
198+
ret += sizeof(conn_type);
199+
ret += 3; // reserved bytes
200+
ret += path_.getLength();
201+
return ret;
149202
}
150203

151204
/**
@@ -169,9 +222,23 @@ class ForwardOpenRequest : public Serializable
169222
writer.write(reserved);
170223
writer.write(reserved);
171224
writer.write(o_to_t_rpi);
172-
writer.write(o_to_t_conn_params);
225+
if (use_legacy_forward_open_request)
226+
{
227+
writer.write(o_to_t_conn_params_legacy);
228+
}
229+
else
230+
{
231+
writer.write(o_to_t_conn_params);
232+
}
173233
writer.write(t_to_o_rpi);
174-
writer.write(t_to_o_conn_params);
234+
if (use_legacy_forward_open_request)
235+
{
236+
writer.write(t_to_o_conn_params_legacy);
237+
}
238+
else
239+
{
240+
writer.write(t_to_o_conn_params);
241+
}
175242
writer.write(conn_type);
176243
path_.serialize(writer);
177244
return writer;

include/odva_ethernetip/session.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ class Session
8787
*/
8888
void close();
8989

90+
/**
91+
* Close the session without unregistering the session and just closing the port
92+
*/
93+
void closeWithoutUnregister();
94+
9095
/**
9196
* Get the ID number assigned to this session by the target
9297
* @return session ID number
@@ -153,7 +158,23 @@ class Session
153158
* @param t_to_o Target to origin connection info
154159
*/
155160
int createConnection(const EIP_CONNECTION_INFO_T& o_to_t,
156-
const EIP_CONNECTION_INFO_T& t_to_o);
161+
const EIP_CONNECTION_INFO_T& t_to_o)
162+
{
163+
// Maintains backwards compatability
164+
return createConnection(o_to_t, t_to_o, 0x5B, false);
165+
}
166+
167+
/**
168+
* Create an Ethernet/IP Connection for sending implicit messages
169+
* @param o_to_t Origin to target connection info
170+
* @param t_to_o Target to origin connection info
171+
* @param service Service code to send
172+
* @param use_legacy_forward_open_request use 16 bit connection parameters instead of news 32 bit parameters
173+
*/
174+
int createConnection(const EIP_CONNECTION_INFO_T& o_to_t,
175+
const EIP_CONNECTION_INFO_T& t_to_o,
176+
EIP_USINT service,
177+
bool use_legacy_forward_open_request);
157178

158179
/**
159180
* Close the given connection number

src/connection.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ void Connection::setConnectionPoints(EIP_USINT origin, EIP_USINT target)
5656
path_.addLogicalConnectionPoint(target);
5757
}
5858

59-
shared_ptr<ForwardOpenRequest> Connection::createForwardOpenRequest()
59+
shared_ptr<ForwardOpenRequest> Connection::createForwardOpenRequest(bool use_legacy_forward_open_request)
6060
{
61-
shared_ptr<ForwardOpenRequest> req = make_shared<ForwardOpenRequest> ();
61+
shared_ptr<ForwardOpenRequest> req = make_shared<ForwardOpenRequest> (use_legacy_forward_open_request);
6262

6363
req->originator_vendor_id = originator_vendor_id;
6464
req->originator_sn = originator_sn;

src/session.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ void Session::close()
158158

159159
CONSOLE_BRIDGE_logInform("Session closed");
160160

161+
closeWithoutUnregister();
162+
}
163+
164+
void Session::closeWithoutUnregister()
165+
{
161166
socket_->close();
162167
io_socket_->close();
163168
session_id_ = 0;
@@ -294,7 +299,9 @@ RRDataResponse Session::sendRRDataCommand(EIP_USINT service, const Path& path,
294299
}
295300

296301
int Session::createConnection(const EIP_CONNECTION_INFO_T& o_to_t,
297-
const EIP_CONNECTION_INFO_T& t_to_o)
302+
const EIP_CONNECTION_INFO_T& t_to_o,
303+
EIP_USINT service,
304+
bool use_legacy_forward_open_request)
298305
{
299306
Connection conn(o_to_t, t_to_o);
300307
conn.originator_vendor_id = my_vendor_id_;
@@ -303,8 +310,8 @@ int Session::createConnection(const EIP_CONNECTION_INFO_T& o_to_t,
303310
conn.o_to_t_connection_id = next_connection_id_++;
304311
conn.t_to_o_connection_id = next_connection_id_++;
305312

306-
shared_ptr<ForwardOpenRequest> req = conn.createForwardOpenRequest();
307-
RRDataResponse resp_data = sendRRDataCommand(0x5B, Path(0x06, 1), req);
313+
shared_ptr<ForwardOpenRequest> req = conn.createForwardOpenRequest(use_legacy_forward_open_request);
314+
RRDataResponse resp_data = sendRRDataCommand(service, Path(0x06, 1), req);
308315
ForwardOpenSuccess result;
309316
resp_data.getResponseDataAs(result);
310317
if (!conn.verifyForwardOpenResult(result))

0 commit comments

Comments
 (0)