Advertisement
abagrintsev

PingProcess.cpp (new)

Sep 3rd, 2015
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.42 KB | None | 0 0
  1. #include "PingProcess.h"
  2. #include "Ping.h"
  3. #include "System.h"
  4. #include <Logging_Controller.h>
  5.  
  6. PingProcess::PingProcess ( Ping *parent )
  7.   : m_stop(false)
  8. {
  9.     m_timer = 0;
  10.     m_resolver = 0;
  11.     m_reply_buffer = 0;
  12.     m_num_replies = 0;
  13.     m_num_timeout = 0;
  14.     m_socket = 0;
  15.     m_camera_availability = -1;
  16.  
  17.     this->parent = parent;
  18.    
  19.     try
  20.     {
  21.         KSVC_TRACE ( PING_SERVICE ) << "Created new ping process";
  22.     } catch (...) {}
  23.        
  24. }
  25.  
  26. PingProcess::~PingProcess()
  27. {  
  28.   boost::unique_lock<boost::mutex> locker(m_synclock);
  29.   m_stop = true;
  30.   if(m_socket)
  31.   {
  32.     m_socket->cancel();
  33.     m_socket->close();
  34.     delete m_socket;
  35.     m_socket = 0;
  36.   }
  37.   if(m_timer)
  38.   {
  39.     m_timer->cancel();
  40.     delete m_timer;
  41.     m_timer = 0;
  42.   }
  43.     delete m_reply_buffer;
  44.     m_reply_buffer = 0;
  45.     delete m_resolver;
  46.     m_resolver = 0;
  47.    
  48.     try
  49.     {
  50.         KSVC_LOG_INF ( PING_SERVICE ) << "Ping process for host " << m_destination.address() << " is destoyed";
  51.     } catch (...) {}
  52. }
  53.  
  54. /*
  55.  
  56. PingProcess::PingProcess ( const PingProcess& other )
  57. {
  58.  
  59. }
  60.  
  61. PingProcess& PingProcess::operator= ( const PingProcess& other )
  62. {
  63.  
  64. }
  65.  
  66. bool PingProcess::operator== ( const PingProcess& other ) const
  67. {
  68.  
  69. }*/
  70.  
  71. bool PingProcess::Init()
  72. {
  73.     m_reply_buffer = new boost::asio::streambuf;
  74.     m_timer = new boost::asio::deadline_timer ( parent->m_io_service );
  75.     m_socket = new boost::asio::ip::icmp::socket ( parent->m_io_service, boost::asio::ip::icmp::v4() );
  76.     Configuration::Instance().SetCameraAvailability ( UUID, -1 );
  77.     m_camera_availability = -1;
  78.    
  79.     return true;
  80. }
  81.  
  82.  
  83. void PingProcess::StartSend()
  84. {
  85.   boost::unique_lock<boost::mutex> locker(m_synclock);
  86.     if(!m_socket || m_stop)
  87.     {
  88.         return;
  89.     }
  90.    
  91.     std::string body ( "KSVD testing ICMP request" );
  92.    
  93.     // Create an ICMP header for an echo request.
  94.     icmp_header echo_request;
  95.     echo_request.type ( icmp_header::echo_request );
  96.     echo_request.code ( 0 );
  97.     echo_request.identifier ( m_ping_process_id );
  98.    
  99.     // int32 == 2^32-1
  100.     if ( m_sequence_number >= 2147483647 )
  101.         m_sequence_number = 0;
  102.    
  103.     echo_request.sequence_number ( ++m_sequence_number );
  104.     compute_checksum ( echo_request, body.begin(), body.end() );
  105.    
  106.     // Encode the request packet.
  107.     boost::asio::streambuf request_buffer;
  108.     std::ostream os ( &request_buffer );
  109.     os << echo_request << body;
  110.    
  111.     // Send the request.
  112.     m_time_sent = posix_time::microsec_clock::universal_time();
  113.     m_socket->send_to ( request_buffer.data(), m_destination );
  114.    
  115.     // Wait up to five seconds for a reply.
  116.     m_num_replies = 0;
  117.     m_timer->expires_at ( m_time_sent + boost::posix_time::seconds ( timeout_to_read_reply ) );
  118.     m_timer->async_wait ( boost::bind ( &PingProcess::HandleTimeout, this ) );
  119.    
  120.     //KSVC_TRACE ( PING_SERVICE ) << "In func: " << __FUNCTION__;
  121. }
  122.  
  123. void PingProcess::StartReceive()
  124. {
  125.   boost::unique_lock<boost::mutex> locker(m_synclock);
  126.     if ( 0 == m_socket || m_stop)
  127.     {
  128.         return;
  129.     }
  130.    
  131.     // Discard any data already in the buffer.
  132.     m_reply_buffer->consume ( m_reply_buffer->size() );
  133.    
  134.     // Wait for a reply. We prepare the buffer to receive up to 64KB.
  135.     m_socket->async_receive ( m_reply_buffer->prepare ( 65536 ), boost::bind ( &PingProcess::HandleReceive, this, _2 ) );
  136.    
  137.     //KSVC_TRACE ( PING_SERVICE ) << "In func: " << __FUNCTION__;
  138. }
  139.  
  140. void PingProcess::HandleTimeout()
  141. {
  142.   boost::unique_lock<boost::mutex> locker(m_synclock);
  143.     if ( 0 == m_timer || m_stop )
  144.     {
  145.         return;
  146.     }
  147.    
  148.     if ( m_num_replies == 0 )
  149.     {
  150.         // just warn if pong does't returned
  151.         try
  152.         {
  153.             KSVC_LOG_WAR ( PING_SERVICE ) << "Request timed out for host " << m_destination.address();
  154.         } catch (...) {}
  155.            
  156.         // the host is considered unreachable here
  157.         if ( ( m_num_timeout++ ) >= timeout_to_fail )
  158.         {
  159.             SetCameraUnavailable ( UUID );
  160.         }
  161.     } else {
  162.    
  163.         // we are changing the status only if there is no answer N times in a row
  164.         m_num_timeout = 0;
  165.        
  166.         // Pong has arrived so update status
  167.         if ( m_camera_availability == 0 || m_camera_availability == -1 )
  168.         {
  169.             SetCameraAvailable ( UUID );
  170.         }
  171.     }  
  172.  
  173.     // Requests must be sent no less than one second apart.
  174.     m_timer->expires_at ( m_time_sent + boost::posix_time::seconds ( timeout_to_send_request ) );
  175.     m_timer->async_wait ( boost::bind ( &PingProcess::StartSend, this ) );
  176.    
  177.     //KSVC_TRACE ( PING_SERVICE ) << "In func: " << __FUNCTION__;
  178. }
  179.  
  180. void PingProcess::HandleReceive ( std::size_t length )
  181. {
  182.   boost::unique_lock<boost::mutex> locker(m_synclock);
  183.     if ( 0 == m_socket || 0 == m_reply_buffer || m_stop)
  184.         return;
  185.    
  186.     // The actual number of bytes received is committed to the buffer so that we
  187.     // can extract it using a std::istream object.
  188.     m_reply_buffer->commit ( length );
  189.    
  190.     // Decode the reply packet.
  191.     std::istream is ( m_reply_buffer );
  192.     ipv4_header ipv4_hdr;
  193.     icmp_header icmp_hdr;
  194.     is >> ipv4_hdr >> icmp_hdr;
  195.    
  196.     // We can receive all ICMP packets received by the host, so we need to
  197.     // filter out only the echo replies that match the our identifier and
  198.     // expected sequence number.
  199.     if ( is && icmp_hdr.type() == icmp_header::echo_reply
  200.         && icmp_hdr.identifier() == m_ping_process_id
  201.         && icmp_hdr.sequence_number() == m_sequence_number )
  202.     {
  203.         // If this is the first reply, interrupt the five second timeout.
  204.         if ( m_num_replies++ == 0 )
  205.             m_timer->cancel();
  206.        
  207.         // Print out some information about the reply packet.
  208.         boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
  209.        
  210.         try
  211.         {
  212.             KSVC_LOG_INF ( PING_SERVICE ) << length - ipv4_hdr.header_length()
  213.                 << " bytes from " << ipv4_hdr.source_address()
  214.                 << ": icmp_seq=" << icmp_hdr.sequence_number()
  215.                 << ", ttl=" << ipv4_hdr.time_to_live()
  216.                 << ", time=" << ( now - m_time_sent ).total_milliseconds() << " ms";
  217.         } catch (...) {}
  218.     }
  219.    
  220.     StartReceive();
  221.     //KSVC_TRACE ( PING_SERVICE ) << "In func: " << __FUNCTION__;
  222. }
  223.  
  224. bool PingProcess::Query ( std::string destination )
  225. {
  226.     boost::asio::ip::icmp::resolver::query query ( boost::asio::ip::icmp::v4(), destination.c_str(), "" );
  227.     m_resolver = new boost::asio::ip::icmp::resolver ( parent->m_io_service );
  228.     m_destination = *( m_resolver->resolve ( query ) );
  229.    
  230.     StartSend();
  231.     StartReceive();
  232.  
  233.     return true;
  234. }
  235.  
  236. /*short unsigned int PingProcess::GetIdentidier()
  237. {
  238.     #if defined ( BOOST_WINDOWS )
  239.     return static_cast < unsigned short > ( ::GetCurrentProcessId() );
  240.     #else
  241.     return static_cast < unsigned short > ( ::getpid() );
  242.     #endif
  243. }*/
  244.  
  245. void PingProcess::SetUUID ( std::string uuid )
  246. {
  247.     UUID = uuid;
  248. }
  249.  
  250. void PingProcess::SetCameraUnavailable ( std::string uuid )
  251. {
  252.     m_num_timeout = 0;
  253.    
  254.     //boost::property_tree::ptree tree;
  255.     Configuration& conf = Configuration::Instance();
  256.     conf.SetCameraAvailability ( uuid, false );
  257.     m_camera_availability = 0;
  258.     //tree.put ( ".is_available", "false" );
  259.     //conf.SetCameraSettings ( G_SYSTEM_USER, "system", uuid.c_str(), tree, true );
  260.    
  261.     try
  262.     {
  263.         KSVC_LOG_INF ( PING_SERVICE ) << "Host " << m_destination.address() << " has changed status to not available";
  264.     } catch (...) {}   
  265. }
  266.  
  267. void PingProcess::SetCameraAvailable ( std::string uuid )
  268. {
  269.     m_num_timeout = 0;
  270.     Configuration& conf = Configuration::Instance();
  271.     conf.SetCameraAvailability ( uuid, 1 );
  272.     m_camera_availability = 1;
  273.    
  274.     try
  275.     {
  276.         KSVC_LOG_INF ( PING_SERVICE ) << "Host " << m_destination.address() << " has changed status to available";
  277.     } catch (...) {}
  278. }
  279.  
  280. void PingProcess::SetPingProcessID ( int ID )
  281. {
  282.     m_ping_process_id = ID;
  283. }
  284.  
  285. std::string PingProcess::GetIP()
  286. {
  287.     return m_destination.address().to_string();
  288. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement