26 #include <boost/bind.hpp> 27 #include <boost/shared_ptr.hpp> 28 #include <boost/make_shared.hpp> 29 #include <boost/random/mersenne_twister.hpp> 30 #include <boost/random/uniform_int_distribution.hpp> 41 using boost::shared_ptr;
42 using boost::make_shared;
49 using serialization::BufferReader;
50 using serialization::BufferWriter;
54 : socket_(socket), io_socket_(io_socket), session_id_(0),
55 my_vendor_id_(vendor_id), my_serial_num_(serial_num)
58 boost::random::mt19937 gen;
59 gen.seed(std::time(0));
60 boost::random::uniform_int_distribution<> dist(0, 0xFFFF);
84 cout <<
"Resolving hostname and connecting socket" << endl;
89 cout <<
"Creating and sending the registration message" << endl;
90 shared_ptr<RegisterSessionData> reg_data = make_shared<RegisterSessionData>();
99 catch (std::length_error ex)
103 cerr <<
"Could not parse response when registering session: " << ex.what() << endl;
104 throw std::runtime_error(
"Invalid response received registering session");
106 catch (std::logic_error ex)
110 cerr <<
"Error in registration response: " << ex.what() << endl;
111 throw std::runtime_error(
"Error in registration response");
116 cerr <<
"Warning: Registration message received with wrong size. Expected " 117 << reg_data->getLength() <<
" bytes, received " 121 bool response_valid =
false;
125 response_valid =
true;
127 catch (std::length_error ex)
129 cerr <<
"Warning: Registration message too short, ignoring" << endl;
131 catch (std::logic_error ex)
133 cerr <<
"Warning: could not parse registration response: " << ex.what() << endl;
138 cerr <<
"Error: Wrong Ethernet Industrial Protocol Version. " 140 << reg_data->protocol_version << endl;
143 throw std::runtime_error(
"Received wrong Ethernet IP Protocol Version on registration");
145 if (response_valid && reg_data->options != 0)
147 cerr <<
"Warning: Registration message included non-zero options flags: " 148 << reg_data->options << endl;
152 cout <<
"Successfully opened session ID " <<
session_id_ << endl;
158 cout <<
"Closing session" << endl;
164 cout <<
"Session closed" << endl;
173 cout <<
"Sending Command" << endl;
176 cout <<
"Waiting for response" << endl;
178 cout <<
"Received response of " << n <<
" bytes" << endl;
184 if (reader.getByteCount() != n)
186 cerr <<
"Warning: packet received with " << n <<
187 " bytes, but only " << reader.getByteCount() <<
" bytes used" << endl;
199 cerr <<
"Reply received with wrong command. Expected " 201 throw std::logic_error(
"Reply received with wrong command");
205 cerr <<
"Warning: Zero session handle received on registration: " 207 throw std::logic_error(
"Zero session handle received on registration");
211 cerr <<
"Warning: reply received with wrong session ID. Expected " 213 throw std::logic_error(
"Wrong session ID received for command");
217 cerr <<
"Warning: Non-zero status received: " << pkt.
getHeader().
status << endl;
221 cerr <<
"Warning: Non-zero sender context received: " 226 cerr <<
"Warning: Non-zero options received: " << pkt.
getHeader().
options << endl;
231 EIP_USINT attribute_id, Serializable& result)
233 shared_ptr<Serializable> no_data;
235 Path(class_id, instance_id, attribute_id), no_data);
244 Path(class_id, instance_id, attribute_id), data);
248 shared_ptr<Serializable> data)
250 cout <<
"Creating RR Data Request" << endl;
251 shared_ptr<RRDataRequest> req_data =
252 make_shared<RRDataRequest> (service, path, data);
261 catch (std::length_error ex)
263 cerr <<
"Response packet to RR command too short: " << ex.what() << endl;
264 throw std::runtime_error(
"Packet response to RR Data Command too short");
266 catch (std::logic_error ex)
268 cerr <<
"Invalid response to RR command: " << ex.what() << endl;
269 throw std::runtime_error(
"Invalid packet response to RR Data Command");
277 catch (std::length_error ex)
279 cerr <<
"Response data to RR command too short: " << ex.what() << endl;
280 throw std::runtime_error(
"Response data to RR Command too short");
282 catch (std::logic_error ex)
284 cerr <<
"Invalid data to RR command: " << ex.what() << endl;
285 throw std::runtime_error(
"Invalid data in response to RR command");
291 cerr <<
"Warning: Wrong service code returned for RR Data command. Expected: " 292 << (int)service <<
" but received " << (
int)resp_data.
getServiceCode() << endl;
297 cerr <<
"RR Data Command failed with status " << (int)resp_data.
getGeneralStatus() << endl;
298 throw std::runtime_error(
"RR Data Command Failed");
319 cerr <<
"Received invalid response to forward open request" << endl;
320 throw std::logic_error(
"Forward Open Response Invalid");
329 shared_ptr<ForwardCloseRequest> req =
connections_[n].createForwardCloseRequest();
335 cerr <<
"Received invalid response to forward close request" << endl;
336 throw std::logic_error(
"Forward Close Response Invalid");
352 if (reader.getByteCount() != n)
354 cerr <<
"Warning: IO packet received with " << n <<
355 " bytes, but only " << reader.getByteCount() <<
" bytes used" << endl;
EIP_USINT getServiceCode() const
EIP_BYTE recv_buffer_[4 *1024]
EncapHeader & getHeader()
shared_ptr< Socket > io_socket_
CPFPacket receiveIOPacket()
RRDataResponse sendRRDataCommand(EIP_USINT service, const Path &path, shared_ptr< Serializable > data)
shared_ptr< ForwardOpenRequest > createForwardOpenRequest()
EIP_UDINT t_to_o_connection_id
void closeConnection(size_t n)
bool verifyForwardOpenResult(const ForwardOpenSuccess &result)
Reader & deserialize(Reader &reader, size_t length)
void open(string hostname, string port="44818", string io_port="2222")
virtual Reader & deserialize(Reader &reader, size_t length)
void check_packet(EncapPacket &pkt, EIP_UINT exp_cmd)
void sendIOPacket(CPFPacket &pkt)
#define EIP_PROTOCOL_VERSION
EIP_UDINT o_to_t_connection_id
EIP_UDINT next_connection_id_
void getPayloadAs(Serializable &result)
vector< Connection > connections_
void setSingleAttributeSerializable(EIP_USINT class_id, EIP_USINT instance_id, EIP_USINT attribute_id, shared_ptr< Serializable > data)
int createConnection(const EIP_CONNECTION_INFO_T &o_to_t, const EIP_CONNECTION_INFO_T &t_to_o)
EIP_UINT next_connection_sn_
void getResponseDataAs(Serializable &result)
Session(shared_ptr< Socket > socket, shared_ptr< Socket > io_socket, EIP_UINT vendor_id=DEFAULT_VENDOR_ID, EIP_UDINT serial_num=DEFAULT_SERIAL_NUM)
void getSingleAttributeSerializable(EIP_USINT class_id, EIP_USINT instance_id, EIP_USINT attribute_id, Serializable &result)
EIP_USINT getGeneralStatus() const
EIP_UINT originator_vendor_id
EncapPacket sendCommand(EncapPacket &req)
shared_ptr< Socket > socket_