io_scanner.cpp
Go to the documentation of this file.
1 
26 #include <iostream>
27 #include <boost/bind.hpp>
28 #include <console_bridge/console.h>
29 
39 
40 using namespace boost::asio;
41 using boost::asio::ip::udp;
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  CONSOLE_BRIDGE_logInform("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  CONSOLE_BRIDGE_logInform("done.");
59 }
60 
62 {
63  CONSOLE_BRIDGE_logInform("Sending List Identity Request... ");
64  udp::resolver r(GET_IO_SERVICE(&socket_));
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  CONSOLE_BRIDGE_logInform("done.");
74 }
75 
76 void IOScanner::handleListIdentityResponse(const boost::system::error_code& ec,
77  std::size_t num_bytes)
78 {
79  if (ec)
80  {
81  CONSOLE_BRIDGE_logError("Error receiving list identity response message");
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  CONSOLE_BRIDGE_logWarn("Packet received with %zu bytes, but only %zu bytes used", num_bytes, r.getByteCount());
93  }
94 
96  {
97  CONSOLE_BRIDGE_logError("Reply received with wrong command. Expected %u, received %u", EIP_CMD_LIST_IDENTITY,
98  pkt.getHeader().command);
99  return;
100  }
101  if (pkt.getHeader().session_handle != 0)
102  {
103  CONSOLE_BRIDGE_logWarn("Non-zero session handle received: %zu", pkt.getHeader().session_handle);
104  }
105  if (pkt.getHeader().status != 0)
106  {
107  CONSOLE_BRIDGE_logWarn("Non-zero status received: %zu", pkt.getHeader().status);
108  }
109  if (pkt.getHeader().context[0] != 0 || pkt.getHeader().context[1] != 0)
110  {
111  CONSOLE_BRIDGE_logWarn("Non-zero sender context received: %zu, %zu", pkt.getHeader().context[0],
112  pkt.getHeader().context[1]);
113  }
114  if (pkt.getHeader().options != 0)
115  {
116  CONSOLE_BRIDGE_logWarn("Non-zero options received: %zu", pkt.getHeader().options);
117  }
118 
119  CPFPacket payload;
120  pkt.getPayloadAs(payload);
121 
122  if (payload.getItemCount() < 1)
123  {
124  CONSOLE_BRIDGE_logError("No items in list identity payload!");
125  return;
126  }
127  if (payload.getItemCount() > 1)
128  {
129  CONSOLE_BRIDGE_logWarn("More than one item in list identity payload %u", payload.getItemCount());
130  }
131 
132  if (payload.getItems().at(0).getItemType() != EIP_ITEM_LIST_IDENTITY_RESPONSE)
133  {
134  CONSOLE_BRIDGE_logError("Error: Payload response received with the wrong item type. Expected: %zu, received %zu",
135  EIP_ITEM_LIST_IDENTITY_RESPONSE, payload.getItems().at(0).getItemType());
136  return;
137  }
138 
139  IdentityItemData id;
140  payload.getItems().at(0).getDataAs(id);
141 
142  CONSOLE_BRIDGE_logInform("=== Received ID Message ===");
143  CONSOLE_BRIDGE_logInform("Encapsulation Protocol Version: %d", (int)id.encap_protocol_version);
144  CONSOLE_BRIDGE_logInform("Address: %d : %d", inet_ntoa(id.sockaddr.sin_addr), ntohs(id.sockaddr.sin_port));
145  CONSOLE_BRIDGE_logInform("Vendor ID: %d", (int)id.vendor_id);
146  CONSOLE_BRIDGE_logInform("Device Type: %d", (int)id.device_type);
147  CONSOLE_BRIDGE_logInform("Product Code: %d", (int)id.product_code);
148  CONSOLE_BRIDGE_logInform("Revision: %d.%d", (int)id.revision[0], (int)id.revision[1]);
149  CONSOLE_BRIDGE_logInform("Status: %d", (int)id.status);
150  CONSOLE_BRIDGE_logInform("Serial Number: %d", (int)id.serial_number);
151  CONSOLE_BRIDGE_logInform("Product Name: %s", id.product_name.c_str());
152  CONSOLE_BRIDGE_logInform("State: %d", (int)id.state);
153  }
154  catch (std::length_error e)
155  {
156  printf("ERROR: Packet too short for identity response\n");
157  }
158 }
159 
161 {
163  CONSOLE_BRIDGE_logInform("Waiting for responses.");
164  GET_IO_SERVICE(&socket_).run();
165 }
166 
167 } // namespace eip
eip::CPFPacket
Definition: cpf_packet.h:49
eip_types.h
eip::EncapPacket::serialize
Writer & serialize(Writer &writer) const
Definition: encap_packet.cpp:49
eip::IOScanner::hostname_
string hostname_
Definition: io_scanner.h:70
eip::EncapHeader::options
EIP_DWORD options
Definition: encap_header.h:52
eip
Definition: connection.h:41
eip::serialization::BufferWriter
Definition: buffer_writer.h:44
eip::EncapHeader::context
EIP_DWORD context[2]
Definition: encap_header.h:51
eip::IOScanner::socket_
udp::socket socket_
Definition: io_scanner.h:71
eip::CPFPacket::getItems
vector< CPFItem > & getItems()
Definition: cpf_packet.h:66
io_scanner.h
eip::EncapHeader::status
EIP_DWORD status
Definition: encap_header.h:50
eip::IOScanner::handleListIdentityResponse
void handleListIdentityResponse(const boost::system::error_code &ec, std::size_t num_bytes)
Definition: io_scanner.cpp:76
eip::EncapPacket::getHeader
EncapHeader & getHeader()
Definition: encap_packet.h:78
eip::EncapHeader::session_handle
EIP_UDINT session_handle
Definition: encap_header.h:49
buffer_writer.h
EIP_CMD_LIST_IDENTITY
@ EIP_CMD_LIST_IDENTITY
Definition: eip_types.h:63
cpf_item.h
eip::IOScanner::recv_buf_
boost::array< EIP_BYTE, 4 *1024 > recv_buf_
Definition: io_scanner.h:73
eip::IOScanner::device_endpoint_
udp::endpoint device_endpoint_
Definition: io_scanner.h:72
eip::IOScanner::run
void run()
Definition: io_scanner.cpp:160
eip::EncapPacket::getPayloadAs
void getPayloadAs(Serializable &result)
Definition: encap_packet.cpp:44
eip::EncapHeader::command
EIP_UINT command
Definition: encap_header.h:47
eip::serialization::BufferReader::getByteCount
virtual size_t getByteCount()
Definition: buffer_reader.h:118
eip::CPFPacket::getItemCount
EIP_UINT getItemCount() const
Definition: cpf_packet.h:57
eip::serialization::BufferWriter::getByteCount
size_t getByteCount()
Definition: buffer_writer.h:90
eip::IdentityItemData
Definition: identity_item_data.h:46
buffer_reader.h
socket.h
GET_IO_SERVICE
#define GET_IO_SERVICE(s)
Definition: socket.h:35
encap_packet.h
eip::serialization::BufferReader
Definition: buffer_reader.h:45
eip::EncapPacket::deserialize
Reader & deserialize(Reader &reader, size_t length)
Definition: encap_packet.cpp:77
cpf_packet.h
eip::IOScanner::sendListIdentityRequest
void sendListIdentityRequest()
Definition: io_scanner.cpp:61
eip::EncapPacket
Definition: encap_packet.h:50
EIP_ITEM_LIST_IDENTITY_RESPONSE
@ EIP_ITEM_LIST_IDENTITY_RESPONSE
Definition: eip_types.h:87
identity_item_data.h


odva_ethernetip
Author(s): Kareem Shehata
autogenerated on Wed Mar 2 2022 00:38:56