io_scanner.cpp
Go to the documentation of this file.
00001 
00026 #include <iostream>
00027 #include <boost/bind.hpp>
00028 
00029 #include "odva_ethernetip/io_scanner.h"
00030 #include "odva_ethernetip/eip_types.h"
00031 #include "odva_ethernetip/serialization/buffer_reader.h"
00032 #include "odva_ethernetip/serialization/buffer_writer.h"
00033 #include "odva_ethernetip/encap_packet.h"
00034 #include "odva_ethernetip/cpf_packet.h"
00035 #include "odva_ethernetip/cpf_item.h"
00036 #include "odva_ethernetip/identity_item_data.h"
00037 
00038 using namespace boost::asio;
00039 using boost::asio::ip::udp;
00040 using std::cerr;
00041 using std::cout;
00042 using std::endl;
00043 
00044 namespace eip {
00045 
00046 using serialization::BufferReader;
00047 using serialization::BufferWriter;
00048 
00049 IOScanner::IOScanner(io_service& io_service, string hostname)
00050     : socket_(io_service), hostname_(hostname)
00051 {
00052   cout << "Opening UDP socket... ";
00053   socket_.open(udp::v4());
00054   socket_.async_receive_from(buffer(recv_buf_), device_endpoint_,
00055     boost::bind(&IOScanner::handleListIdentityResponse, this,
00056       boost::asio::placeholders::error,
00057       boost::asio::placeholders::bytes_transferred));
00058   cout << "done." << endl;
00059 }
00060 
00061 void IOScanner::sendListIdentityRequest()
00062 {
00063   cout << "Sending List Identity Request... ";
00064   udp::resolver r(socket_.get_io_service());
00065   udp::resolver::query q(udp::v4(), hostname_, "44818");
00066   udp::endpoint receiver_endpoint = *r.resolve(q);
00067 
00068   EncapPacket pkt(EIP_CMD_LIST_IDENTITY);
00069   char d[128];
00070   BufferWriter w(buffer(d));
00071   pkt.serialize(w);
00072   socket_.send_to(buffer(d, w.getByteCount()), receiver_endpoint);
00073   cout << "done." << endl;
00074 }
00075 
00076 void IOScanner::handleListIdentityResponse(const boost::system::error_code& ec,
00077   std::size_t num_bytes)
00078 {
00079   if (ec)
00080   {
00081     cerr << "Error receiving list identity response message" << endl;
00082     return;
00083   }
00084 
00085   try
00086   {
00087     BufferReader r(buffer(recv_buf_, num_bytes));
00088     EncapPacket pkt;
00089     pkt.deserialize(r);
00090     if (r.getByteCount() != num_bytes)
00091     {
00092       cerr << "Warning: packet received with " << num_bytes <<
00093         " bytes, but only " << r.getByteCount() << " bytes used" << endl;
00094     }
00095 
00096     if (pkt.getHeader().command != EIP_CMD_LIST_IDENTITY)
00097     {
00098       cerr << "Reply received with wrong command. Expected "
00099         << EIP_CMD_LIST_IDENTITY << ", received " << pkt.getHeader().command << endl;
00100       return;
00101     }
00102     if (pkt.getHeader().session_handle != 0)
00103     {
00104       cerr << "Warning: Non-zero session handle received: " << pkt.getHeader().session_handle << endl;
00105     }
00106     if (pkt.getHeader().status != 0)
00107     {
00108       cerr << "Warning: Non-zero status received: " << pkt.getHeader().status << endl;
00109     }
00110     if (pkt.getHeader().context[0] != 0 || pkt.getHeader().context[1] != 0)
00111     {
00112       cerr << "Warning: Non-zero sender context received: "
00113            << pkt.getHeader().context[0] << ", " << pkt.getHeader().context[1] << endl;
00114     }
00115     if (pkt.getHeader().options != 0)
00116     {
00117       cerr << "Warning: Non-zero options received: " << pkt.getHeader().options << endl;
00118     }
00119 
00120     CPFPacket payload;
00121     pkt.getPayloadAs(payload);
00122 
00123     if (payload.getItemCount() < 1)
00124     {
00125       cerr << "No items in list identity payload!" << endl;
00126       return;
00127     }
00128     if (payload.getItemCount() > 1)
00129     {
00130       cerr << "Warning: more than one item in list identity payload " << payload.getItemCount() << endl;
00131     }
00132 
00133     if (payload.getItems().at(0).getItemType() != EIP_ITEM_LIST_IDENTITY_RESPONSE)
00134     {
00135       cerr << "Error: Payload response received with the wrong item type. Expected: "
00136         << EIP_ITEM_LIST_IDENTITY_RESPONSE << ", received: " <<
00137         payload.getItems().at(0).getItemType() << endl;
00138       return;
00139     }
00140 
00141     IdentityItemData id;
00142     payload.getItems().at(0).getDataAs(id);
00143 
00144     cout << "=== Received ID Message ===" << endl;
00145     cout << "Encapsulation Protocol Version: " << (int)id.encap_protocol_version << endl;
00146     cout << "Address: " << inet_ntoa(id.sockaddr.sin_addr) << " : " << ntohs(id.sockaddr.sin_port) << endl;
00147     cout << "Vendor ID: " << (int)id.vendor_id << endl;
00148     cout << "Device Type: " << (int)id.device_type << endl;
00149     cout << "Product Code: " << (int)id.product_code << endl;
00150     cout << "Revision: " << (int)id.revision[0] << "." << (int)id.revision[1] << endl;
00151     cout << "Status: " << (int)id.status << endl;
00152     cout << "Serial Number: " << (int)id.serial_number << endl;
00153     cout << "Product Name: " << id.product_name << endl;
00154     cout << "State: " << (int)id.state << endl;
00155   }
00156   catch (std::length_error e)
00157   {
00158     printf("ERROR: Packet too short for identity response\n");
00159   }
00160 }
00161 
00162 void IOScanner::run()
00163 {
00164   sendListIdentityRequest();
00165   cout << "Waiting for responses." << endl;
00166   socket_.get_io_service().run();
00167 }
00168 
00169 } // namespace eip


odva_ethernetip
Author(s): Kareem Shehata
autogenerated on Sat Jun 8 2019 20:21:23