Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "PingProcess.h"
- #include "Ping.h"
- #include "System.h"
- #include <Logging_Controller.h>
- PingProcess::PingProcess ( Ping *parent )
- : m_stop(false)
- {
- m_timer = 0;
- m_resolver = 0;
- m_reply_buffer = 0;
- m_num_replies = 0;
- m_num_timeout = 0;
- m_socket = 0;
- m_camera_availability = -1;
- this->parent = parent;
- try
- {
- KSVC_TRACE ( PING_SERVICE ) << "Created new ping process";
- } catch (...) {}
- }
- PingProcess::~PingProcess()
- {
- boost::unique_lock<boost::mutex> locker(m_synclock);
- m_stop = true;
- if(m_socket)
- {
- m_socket->cancel();
- m_socket->close();
- delete m_socket;
- m_socket = 0;
- }
- if(m_timer)
- {
- m_timer->cancel();
- delete m_timer;
- m_timer = 0;
- }
- delete m_reply_buffer;
- m_reply_buffer = 0;
- delete m_resolver;
- m_resolver = 0;
- try
- {
- KSVC_LOG_INF ( PING_SERVICE ) << "Ping process for host " << m_destination.address() << " is destoyed";
- } catch (...) {}
- }
- /*
- PingProcess::PingProcess ( const PingProcess& other )
- {
- }
- PingProcess& PingProcess::operator= ( const PingProcess& other )
- {
- }
- bool PingProcess::operator== ( const PingProcess& other ) const
- {
- }*/
- bool PingProcess::Init()
- {
- m_reply_buffer = new boost::asio::streambuf;
- m_timer = new boost::asio::deadline_timer ( parent->m_io_service );
- m_socket = new boost::asio::ip::icmp::socket ( parent->m_io_service, boost::asio::ip::icmp::v4() );
- Configuration::Instance().SetCameraAvailability ( UUID, -1 );
- m_camera_availability = -1;
- return true;
- }
- void PingProcess::StartSend()
- {
- boost::unique_lock<boost::mutex> locker(m_synclock);
- if(!m_socket || m_stop)
- {
- return;
- }
- std::string body ( "KSVD testing ICMP request" );
- // Create an ICMP header for an echo request.
- icmp_header echo_request;
- echo_request.type ( icmp_header::echo_request );
- echo_request.code ( 0 );
- echo_request.identifier ( m_ping_process_id );
- // int32 == 2^32-1
- if ( m_sequence_number >= 2147483647 )
- m_sequence_number = 0;
- echo_request.sequence_number ( ++m_sequence_number );
- compute_checksum ( echo_request, body.begin(), body.end() );
- // Encode the request packet.
- boost::asio::streambuf request_buffer;
- std::ostream os ( &request_buffer );
- os << echo_request << body;
- // Send the request.
- m_time_sent = posix_time::microsec_clock::universal_time();
- m_socket->send_to ( request_buffer.data(), m_destination );
- // Wait up to five seconds for a reply.
- m_num_replies = 0;
- m_timer->expires_at ( m_time_sent + boost::posix_time::seconds ( timeout_to_read_reply ) );
- m_timer->async_wait ( boost::bind ( &PingProcess::HandleTimeout, this ) );
- //KSVC_TRACE ( PING_SERVICE ) << "In func: " << __FUNCTION__;
- }
- void PingProcess::StartReceive()
- {
- boost::unique_lock<boost::mutex> locker(m_synclock);
- if ( 0 == m_socket || m_stop)
- {
- return;
- }
- // Discard any data already in the buffer.
- m_reply_buffer->consume ( m_reply_buffer->size() );
- // Wait for a reply. We prepare the buffer to receive up to 64KB.
- m_socket->async_receive ( m_reply_buffer->prepare ( 65536 ), boost::bind ( &PingProcess::HandleReceive, this, _2 ) );
- //KSVC_TRACE ( PING_SERVICE ) << "In func: " << __FUNCTION__;
- }
- void PingProcess::HandleTimeout()
- {
- boost::unique_lock<boost::mutex> locker(m_synclock);
- if ( 0 == m_timer || m_stop )
- {
- return;
- }
- if ( m_num_replies == 0 )
- {
- // just warn if pong does't returned
- try
- {
- KSVC_LOG_WAR ( PING_SERVICE ) << "Request timed out for host " << m_destination.address();
- } catch (...) {}
- // the host is considered unreachable here
- if ( ( m_num_timeout++ ) >= timeout_to_fail )
- {
- SetCameraUnavailable ( UUID );
- }
- } else {
- // we are changing the status only if there is no answer N times in a row
- m_num_timeout = 0;
- // Pong has arrived so update status
- if ( m_camera_availability == 0 || m_camera_availability == -1 )
- {
- SetCameraAvailable ( UUID );
- }
- }
- // Requests must be sent no less than one second apart.
- m_timer->expires_at ( m_time_sent + boost::posix_time::seconds ( timeout_to_send_request ) );
- m_timer->async_wait ( boost::bind ( &PingProcess::StartSend, this ) );
- //KSVC_TRACE ( PING_SERVICE ) << "In func: " << __FUNCTION__;
- }
- void PingProcess::HandleReceive ( std::size_t length )
- {
- boost::unique_lock<boost::mutex> locker(m_synclock);
- if ( 0 == m_socket || 0 == m_reply_buffer || m_stop)
- return;
- // The actual number of bytes received is committed to the buffer so that we
- // can extract it using a std::istream object.
- m_reply_buffer->commit ( length );
- // Decode the reply packet.
- std::istream is ( m_reply_buffer );
- ipv4_header ipv4_hdr;
- icmp_header icmp_hdr;
- is >> ipv4_hdr >> icmp_hdr;
- // We can receive all ICMP packets received by the host, so we need to
- // filter out only the echo replies that match the our identifier and
- // expected sequence number.
- if ( is && icmp_hdr.type() == icmp_header::echo_reply
- && icmp_hdr.identifier() == m_ping_process_id
- && icmp_hdr.sequence_number() == m_sequence_number )
- {
- // If this is the first reply, interrupt the five second timeout.
- if ( m_num_replies++ == 0 )
- m_timer->cancel();
- // Print out some information about the reply packet.
- boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
- try
- {
- KSVC_LOG_INF ( PING_SERVICE ) << length - ipv4_hdr.header_length()
- << " bytes from " << ipv4_hdr.source_address()
- << ": icmp_seq=" << icmp_hdr.sequence_number()
- << ", ttl=" << ipv4_hdr.time_to_live()
- << ", time=" << ( now - m_time_sent ).total_milliseconds() << " ms";
- } catch (...) {}
- }
- StartReceive();
- //KSVC_TRACE ( PING_SERVICE ) << "In func: " << __FUNCTION__;
- }
- bool PingProcess::Query ( std::string destination )
- {
- boost::asio::ip::icmp::resolver::query query ( boost::asio::ip::icmp::v4(), destination.c_str(), "" );
- m_resolver = new boost::asio::ip::icmp::resolver ( parent->m_io_service );
- m_destination = *( m_resolver->resolve ( query ) );
- StartSend();
- StartReceive();
- return true;
- }
- /*short unsigned int PingProcess::GetIdentidier()
- {
- #if defined ( BOOST_WINDOWS )
- return static_cast < unsigned short > ( ::GetCurrentProcessId() );
- #else
- return static_cast < unsigned short > ( ::getpid() );
- #endif
- }*/
- void PingProcess::SetUUID ( std::string uuid )
- {
- UUID = uuid;
- }
- void PingProcess::SetCameraUnavailable ( std::string uuid )
- {
- m_num_timeout = 0;
- //boost::property_tree::ptree tree;
- Configuration& conf = Configuration::Instance();
- conf.SetCameraAvailability ( uuid, false );
- m_camera_availability = 0;
- //tree.put ( ".is_available", "false" );
- //conf.SetCameraSettings ( G_SYSTEM_USER, "system", uuid.c_str(), tree, true );
- try
- {
- KSVC_LOG_INF ( PING_SERVICE ) << "Host " << m_destination.address() << " has changed status to not available";
- } catch (...) {}
- }
- void PingProcess::SetCameraAvailable ( std::string uuid )
- {
- m_num_timeout = 0;
- Configuration& conf = Configuration::Instance();
- conf.SetCameraAvailability ( uuid, 1 );
- m_camera_availability = 1;
- try
- {
- KSVC_LOG_INF ( PING_SERVICE ) << "Host " << m_destination.address() << " has changed status to available";
- } catch (...) {}
- }
- void PingProcess::SetPingProcessID ( int ID )
- {
- m_ping_process_id = ID;
- }
- std::string PingProcess::GetIP()
- {
- return m_destination.address().to_string();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement