--- /dev/null
+/*
+ The software in this package is distributed under the GNU General
+ Public License version 2 (with a special exception described below).
+
+ A copy of GNU General Public License (GPL) is included in this distribution,
+ in the file COPYING.GPL.
+
+ As a special exception, if other files instantiate templates or use macros
+ or inline functions from this file, or you compile this file and link it
+ with other works to produce a work based on this file, this file
+ does not by itself cause the resulting work to be covered
+ by the GNU General Public License.
+
+ However the source code for this file must still be made available
+ in accordance with section (3) of the GNU General Public License.
+
+ This exception does not invalidate any other reasons why a work based
+ on this file might be covered by the GNU General Public License.
+ */
+
+#include "host/pingrotate.h"
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+
+#include "host/pingerfactory.h"
+
+using namespace std;
+using boost::asio::io_service;
+using boost::function;
+
+//-----------------------------------------------------------------------------
+// PingRotate
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief Parameterized constructor.
+ *
+ * @param io_serv The @c io_service object.
+ * @param network_interface The name of the network interface from where to
+ * dispatch the pings.
+ * @param protocol_rotation_list A list of protocols to be used to ping the
+ * host. The protocols will be used in the order they are in the list.
+ */
+PingRotate::PingRotate(
+ io_service &io_serv,
+ const string &network_interface,
+ PingProtocolList protocol_rotation_list
+) :
+ IoService( io_serv ),
+ NetworkInterfaceName( network_interface ),
+ ProtocolList( protocol_rotation_list ),
+ Ping(),
+ PingDoneCallback()
+{
+ BOOST_ASSERT( !network_interface.empty() );
+ BOOST_ASSERT( 0 < protocol_rotation_list.size() );
+
+ get_next_ping_protocol();
+}
+
+/**
+ * @brief Destructor.
+ */
+PingRotate::~PingRotate()
+{
+}
+
+/**
+ * @brief Ping a destination address from an available local source.
+ *
+ * @param destination_ip The address of the host to ping.
+ * @param destination_port The port at the destination host to ping.
+ * @param done_handler Done handler will be called on successful ping or timeout.
+ *
+ * @return void.
+ */
+void PingRotate::ping(
+ const string &destination_ip,
+ const uint16_t destination_port,
+ function<void(bool)> ping_done_callback
+)
+{
+ BOOST_ASSERT( !destination_ip.empty() );
+
+ PingDoneCallback = ping_done_callback;
+
+ Ping->ping(
+ destination_ip,
+ destination_port,
+ boost::bind(&PingRotate::ping_done_handler, this, _1)
+ );
+}
+
+void PingRotate::ping_done_handler( bool ping_success )
+{
+ PingDoneCallback( ping_success );
+
+ if ( can_change_ping_protocol() )
+ {
+ get_next_ping_protocol();
+ }
+}
+
+void PingRotate::get_next_ping_protocol()
+{
+ if ( 1 <= ProtocolList.size() )
+ {
+ PingProtocol ping_protocol = ProtocolList.front();
+
+ ProtocolList.pop_front();
+ ProtocolList.push_back( ping_protocol );
+
+ Ping = PingerFactory::createPinger( ping_protocol, IoService, NetworkInterfaceName );
+ }
+}
+
+bool PingRotate::can_change_ping_protocol() const
+{
+ return true;
+}
--- /dev/null
+/*
+ The software in this package is distributed under the GNU General
+ Public License version 2 (with a special exception described below).
+
+ A copy of GNU General Public License (GPL) is included in this distribution,
+ in the file COPYING.GPL.
+
+ As a special exception, if other files instantiate templates or use macros
+ or inline functions from this file, or you compile this file and link it
+ with other works to produce a work based on this file, this file
+ does not by itself cause the resulting work to be covered
+ by the GNU General Public License.
+
+ However the source code for this file must still be made available
+ in accordance with section (3) of the GNU General Public License.
+
+ This exception does not invalidate any other reasons why a work based
+ on this file might be covered by the GNU General Public License.
+ */
+
+#ifndef PIN_GROTATE_H
+#define PIN_GROTATE_H
+
+#include <stdint.h>
+
+#include <string>
+
+#include <boost/asio.hpp>
+#include <boost/function.hpp>
+
+#include "host/pinger.h"
+#include "host/pingprotocol.h"
+
+//-----------------------------------------------------------------------------
+// PingRotate
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief This class is a wrapper to the Pingers, and serves to alternate
+ * between protocols.
+ * Scope: one object per host.
+ */
+class PingRotate : public Pinger
+{
+public:
+ PingRotate(
+ boost::asio::io_service &io_serv,
+ const std::string &network_interface,
+ PingProtocolList protocol_rotation_list
+ );
+ virtual ~PingRotate();
+
+ virtual void ping(
+ const std::string &destination_ip,
+ const uint16_t destination_port,
+ boost::function<void(bool)> ping_done_callback
+ );
+
+private:
+ //
+ // Methods
+ //
+
+ void ping_done_handler( bool ping_success );
+ void get_next_ping_protocol();
+ bool can_change_ping_protocol() const;
+
+ //
+ // Attributes
+ //
+
+ /// The IO service object, which has the loop event
+ boost::asio::io_service &IoService;
+ /// The network interface name
+ std::string NetworkInterfaceName;
+ /// The list of protocols to ping
+ PingProtocolList ProtocolList;
+ /// Internal boost pinger object
+ PingerItem Ping;
+ /// The callback function
+ boost::function<void(bool)> PingDoneCallback;
+};
+
+#endif // PING_ROTATE_H