io_scanner.cpp
Go to the documentation of this file.
1 
26 #include <iostream>
27 #include <boost/bind.hpp>
28 
37 
38 using namespace boost::asio;
39 using boost::asio::ip::udp;
40 using std::cerr;
41 using std::cout;
42 using std::endl;
43 
44 namespace eip {
45 
46 using serialization::BufferReader;
47 using serialization::BufferWriter;
48 
49 IOScanner::IOScanner(io_service& io_service, string hostname)
50  : socket_(io_service), hostname_(hostname)
51 {
52  cout << "Opening UDP socket... ";
53  socket_.open(udp::v4());
54  socket_.async_receive_from(buffer(recv_buf_), device_endpoint_,
55  boost::bind(&IOScanner::handleListIdentityResponse, this,
56  boost::asio::placeholders::error,
57  boost::asio::placeholders::bytes_transferred));
58  cout << "done." << endl;
59 }
60 
62 {
63  cout << "Sending List Identity Request... ";
64  udp::resolver r(socket_.get_io_service());
65  udp::resolver::query q(udp::v4(), hostname_, "44818");
66  udp::endpoint receiver_endpoint = *r.resolve(q);
67 
69  char d[128];
70  BufferWriter w(buffer(d));
71  pkt.serialize(w);
72  socket_.send_to(buffer(d, w.getByteCount()), receiver_endpoint);
73  cout << "done." << endl;
74 }
75 
76 void IOScanner::handleListIdentityResponse(const boost::system::error_code& ec,
77  std::size_t num_bytes)
78 {
79  if (ec)
80  {
81  cerr << "Error receiving list identity response message" << endl;
82  return;
83  }
84 
85  try
86  {
87  BufferReader r(buffer(recv_buf_, num_bytes));
88  EncapPacket pkt;
89  pkt.deserialize(r);
90  if (r.getByteCount() != num_bytes)
91  {
92  cerr << "Warning: packet received with " << num_bytes <<
93  " bytes, but only " << r.getByteCount() << " bytes used" << endl;
94  }
95 
97  {
98  cerr << "Reply received with wrong command. Expected "
99  << EIP_CMD_LIST_IDENTITY << ", received " << pkt.getHeader().command << endl;
100  return;
101  }
102  if (pkt.getHeader().session_handle != 0)
103  {
104  cerr << "Warning: Non-zero session handle received: " << pkt.getHeader().session_handle << endl;
105  }
106  if (pkt.getHeader().status != 0)
107  {
108  cerr << "Warning: Non-zero status received: " << pkt.getHeader().status << endl;
109  }
110  if (pkt.getHeader().context[0] != 0 || pkt.getHeader().context[1] != 0)
111  {
112  cerr << "Warning: Non-zero sender context received: "
113  << pkt.getHeader().context[0] << ", " << pkt.getHeader().context[1] << endl;
114  }
115  if (pkt.getHeader().options != 0)
116  {
117  cerr << "Warning: Non-zero options received: " << pkt.getHeader().options << endl;
118  }
119 
120  CPFPacket payload;
121  pkt.getPayloadAs(payload);
122 
123  if (payload.getItemCount() < 1)
124  {
125  cerr << "No items in list identity payload!" << endl;
126  return;
127  }
128  if (payload.getItemCount() > 1)
129  {
130  cerr << "Warning: more than one item in list identity payload " << payload.getItemCount() << endl;
131  }
132 
133  if (payload.getItems().at(0).getItemType() != EIP_ITEM_LIST_IDENTITY_RESPONSE)
134  {
135  cerr << "Error: Payload response received with the wrong item type. Expected: "
136  << EIP_ITEM_LIST_IDENTITY_RESPONSE << ", received: " <<
137  payload.getItems().at(0).getItemType() << endl;
138  return;
139  }
140 
141  IdentityItemData id;
142  payload.getItems().at(0).getDataAs(id);
143 
144  cout << "=== Received ID Message ===" << endl;
145  cout << "Encapsulation Protocol Version: " << (int)id.encap_protocol_version << endl;
146  cout << "Address: " << inet_ntoa(id.sockaddr.sin_addr) << " : " << ntohs(id.sockaddr.sin_port) << endl;
147  cout << "Vendor ID: " << (int)id.vendor_id << endl;
148  cout << "Device Type: " << (int)id.device_type << endl;
149  cout << "Product Code: " << (int)id.product_code << endl;
150  cout << "Revision: " << (int)id.revision[0] << "." << (int)id.revision[1] << endl;
151  cout << "Status: " << (int)id.status << endl;
152  cout << "Serial Number: " << (int)id.serial_number << endl;
153  cout << "Product Name: " << id.product_name << endl;
154  cout << "State: " << (int)id.state << endl;
155  }
156  catch (std::length_error e)
157  {
158  printf("ERROR: Packet too short for identity response\n");
159  }
160 }
161 
163 {
165  cout << "Waiting for responses." << endl;
166  socket_.get_io_service().run();
167 }
168 
169 } // namespace eip
EncapHeader & getHeader()
Definition: encap_packet.h:78
Writer & serialize(Writer &writer) const
EIP_UINT command
Definition: encap_header.h:47
udp::endpoint device_endpoint_
Definition: io_scanner.h:72
Reader & deserialize(Reader &reader, size_t length)
EIP_DWORD context[2]
Definition: encap_header.h:51
udp::socket socket_
Definition: io_scanner.h:71
EIP_UDINT session_handle
Definition: encap_header.h:49
void getPayloadAs(Serializable &result)
Definition: connection.h:41
void handleListIdentityResponse(const boost::system::error_code &ec, std::size_t num_bytes)
Definition: io_scanner.cpp:76
void sendListIdentityRequest()
Definition: io_scanner.cpp:61
EIP_DWORD options
Definition: encap_header.h:52
string hostname_
Definition: io_scanner.h:70
boost::array< EIP_BYTE, 4 *1024 > recv_buf_
Definition: io_scanner.h:73
vector< CPFItem > & getItems()
Definition: cpf_packet.h:66
EIP_DWORD status
Definition: encap_header.h:50
EIP_UINT getItemCount() const
Definition: cpf_packet.h:57


odva_ethernetip
Author(s): Kareem Shehata
autogenerated on Mon Jun 10 2019 14:00:16