Skip to content

Commit e31f62d

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 e31f62d

File tree

5 files changed

+137
-27
lines changed

5 files changed

+137
-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: 92 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,26 @@ 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()
89+
: use_legacy_forward_open_request(false)
90+
{
91+
}
92+
93+
ForwardOpenRequest(bool use_legacy_forward_open_request)
94+
: use_legacy_forward_open_request(use_legacy_forward_open_request)
95+
{
96+
}
97+
8498
/**
85-
* Helper to calculate connection parameters
99+
* Helper to calculate connection parameters for current 32 bit connection parameters
86100
* @param size Maximum size of the messages in the connection in byte
87101
* @param variable if set to true, variable message sizes
88102
* @param priority Priority value for the connection
@@ -96,13 +110,35 @@ class ForwardOpenRequest : public Serializable
96110
| (type & 0x03) << 29 | (shared ? 0x80000000 : 0);
97111
}
98112

113+
/**
114+
* Helper to calculate connection parameters for legacy 16 bit connection parameters
115+
* @param size Maximum size of the messages in the connection in byte
116+
* @param variable if set to true, variable message sizes
117+
* @param priority Priority value for the connection
118+
* @param type Connection type / class info
119+
* @param shared If set to true, then a shared connection
120+
*/
121+
static EIP_WORD calcConnectionParamsLegacy(EIP_UINT size, bool variable, EIP_BYTE priority,
122+
EIP_BYTE type, bool shared)
123+
{
124+
return (size & 0x1FF) | (variable ? 0x200 : 0) | (priority & 0x03) << 10
125+
| (type & 0x03) << 13 | (shared ? 0x8000 : 0);
126+
}
127+
99128
/**
100129
* Shortcut to set the origin to target parameters.
101130
*/
102131
EIP_DWORD setOriginToTargetParams(EIP_UINT size, bool variable, EIP_BYTE priority,
103132
EIP_BYTE type, bool shared)
104133
{
105-
o_to_t_conn_params = calcConnectionParams(size, variable, priority, type, shared);
134+
if (use_legacy_forward_open_request)
135+
{
136+
o_to_t_conn_params_legacy = calcConnectionParamsLegacy(size, variable, priority, type, shared);
137+
}
138+
else
139+
{
140+
o_to_t_conn_params = calcConnectionParams(size, variable, priority, type, shared);
141+
}
106142
return 0;
107143
}
108144

@@ -112,7 +148,14 @@ class ForwardOpenRequest : public Serializable
112148
EIP_DWORD setTargetToOriginParams(EIP_UINT size, bool variable, EIP_BYTE priority,
113149
EIP_BYTE type, bool shared)
114150
{
115-
t_to_o_conn_params = calcConnectionParams(size, variable, priority, type, shared);
151+
if (use_legacy_forward_open_request)
152+
{
153+
t_to_o_conn_params_legacy = calcConnectionParamsLegacy(size, variable, priority, type, shared);
154+
}
155+
else
156+
{
157+
t_to_o_conn_params = calcConnectionParams(size, variable, priority, type, shared);
158+
}
116159
return 0;
117160
}
118161

@@ -131,21 +174,36 @@ class ForwardOpenRequest : public Serializable
131174
*/
132175
virtual size_t getLength() const
133176
{
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();
177+
size_t ret = sizeof(timeout_tick_size);
178+
ret += sizeof(timeout_ticks);
179+
ret += sizeof(o_to_t_connection_id);
180+
ret += sizeof(t_to_o_connection_id);
181+
ret += sizeof(connection_sn);
182+
ret += sizeof(originator_vendor_id);
183+
ret += sizeof(originator_sn);
184+
ret += sizeof(timeout_multiplyer);
185+
ret += sizeof(o_to_t_rpi);
186+
if (use_legacy_forward_open_request)
187+
{
188+
ret += sizeof(o_to_t_conn_params_legacy);
189+
}
190+
else
191+
{
192+
ret += sizeof(o_to_t_conn_params);
193+
}
194+
ret += sizeof(t_to_o_rpi);
195+
if (use_legacy_forward_open_request)
196+
{
197+
ret += sizeof(t_to_o_conn_params_legacy);
198+
}
199+
else
200+
{
201+
ret += sizeof(t_to_o_conn_params);
202+
}
203+
ret += sizeof(conn_type);
204+
ret += 3; // reserved bytes
205+
ret += path_.getLength();
206+
return ret;
149207
}
150208

151209
/**
@@ -169,9 +227,23 @@ class ForwardOpenRequest : public Serializable
169227
writer.write(reserved);
170228
writer.write(reserved);
171229
writer.write(o_to_t_rpi);
172-
writer.write(o_to_t_conn_params);
230+
if (use_legacy_forward_open_request)
231+
{
232+
writer.write(o_to_t_conn_params_legacy);
233+
}
234+
else
235+
{
236+
writer.write(o_to_t_conn_params);
237+
}
173238
writer.write(t_to_o_rpi);
174-
writer.write(t_to_o_conn_params);
239+
if (use_legacy_forward_open_request)
240+
{
241+
writer.write(t_to_o_conn_params_legacy);
242+
}
243+
else
244+
{
245+
writer.write(t_to_o_conn_params);
246+
}
175247
writer.write(conn_type);
176248
path_.serialize(writer);
177249
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)