mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-11-03 21:40:52 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			186 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "PollingTransceiver.hpp"
 | 
						|
 | 
						|
#include <exception>
 | 
						|
 | 
						|
#include <QObject>
 | 
						|
#include <QString>
 | 
						|
#include <QTimer>
 | 
						|
 | 
						|
#include "moc_PollingTransceiver.cpp"
 | 
						|
 | 
						|
namespace
 | 
						|
{
 | 
						|
  unsigned const polls_to_stabilize {3};
 | 
						|
}
 | 
						|
 | 
						|
PollingTransceiver::PollingTransceiver (int poll_interval, QObject * parent)
 | 
						|
  : TransceiverBase {parent}
 | 
						|
  , interval_ {poll_interval * 1000}
 | 
						|
  , poll_timer_ {nullptr}
 | 
						|
  , retries_ {0}
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void PollingTransceiver::start_timer ()
 | 
						|
{
 | 
						|
  if (interval_)
 | 
						|
    {
 | 
						|
      if (!poll_timer_)
 | 
						|
        {
 | 
						|
          poll_timer_ = new QTimer {this}; // pass ownership to
 | 
						|
                                           // QObject which handles
 | 
						|
                                           // destruction for us
 | 
						|
 | 
						|
          connect (poll_timer_, &QTimer::timeout, this,
 | 
						|
                   &PollingTransceiver::handle_timeout);
 | 
						|
        }
 | 
						|
      poll_timer_->start (interval_);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      stop_timer ();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void PollingTransceiver::stop_timer ()
 | 
						|
{
 | 
						|
  if (poll_timer_)
 | 
						|
    {
 | 
						|
      poll_timer_->stop ();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void PollingTransceiver::do_post_start ()
 | 
						|
{
 | 
						|
  start_timer ();
 | 
						|
  if (!next_state_.online ())
 | 
						|
    {
 | 
						|
      // remember that we are expecting to go online
 | 
						|
      next_state_.online (true);
 | 
						|
      retries_ = polls_to_stabilize;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void PollingTransceiver::do_post_stop ()
 | 
						|
{
 | 
						|
  // not much point waiting for rig to go offline since we are ceasing
 | 
						|
  // polls
 | 
						|
  stop_timer ();
 | 
						|
}
 | 
						|
 | 
						|
void PollingTransceiver::do_post_frequency (Frequency f, MODE m)
 | 
						|
{
 | 
						|
  // take care not to set the expected next mode to unknown since some
 | 
						|
  // callers use mode == unknown to signify that they do not know the
 | 
						|
  // mode and don't care
 | 
						|
  if (next_state_.frequency () != f || (m != UNK && next_state_.mode () != m))
 | 
						|
    {
 | 
						|
      // update expected state with new frequency and set poll count
 | 
						|
      next_state_.frequency (f);
 | 
						|
      if (m != UNK)
 | 
						|
        {
 | 
						|
          next_state_.mode (m);
 | 
						|
        }
 | 
						|
      retries_ = polls_to_stabilize;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void PollingTransceiver::do_post_tx_frequency (Frequency f, MODE)
 | 
						|
{
 | 
						|
  if (next_state_.tx_frequency () != f)
 | 
						|
    {
 | 
						|
      // update expected state with new TX frequency and set poll
 | 
						|
      // count
 | 
						|
      next_state_.tx_frequency (f);
 | 
						|
      next_state_.split (f); // setting non-zero TX frequency means split
 | 
						|
      retries_ = polls_to_stabilize;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void PollingTransceiver::do_post_mode (MODE m)
 | 
						|
{
 | 
						|
  // we don't ever expect mode to goto to unknown
 | 
						|
  if (m != UNK && next_state_.mode () != m)
 | 
						|
    {
 | 
						|
      // update expected state with new mode and set poll count
 | 
						|
      next_state_.mode (m);
 | 
						|
      retries_ = polls_to_stabilize;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void PollingTransceiver::do_post_ptt (bool p)
 | 
						|
{
 | 
						|
  if (next_state_.ptt () != p)
 | 
						|
    {
 | 
						|
      // update expected state with new PTT and set poll count
 | 
						|
      next_state_.ptt (p);
 | 
						|
      retries_ = polls_to_stabilize;
 | 
						|
      //retries_ = 0;             // fast feedback on PTT
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
bool PollingTransceiver::do_pre_update ()
 | 
						|
{
 | 
						|
  // if we are holding off a change then withhold the signal
 | 
						|
  if (retries_ && state () != next_state_)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
void PollingTransceiver::handle_timeout ()
 | 
						|
{
 | 
						|
  QString message;
 | 
						|
  bool force_signal {false};
 | 
						|
 | 
						|
  // we must catch all exceptions here since we are called by Qt and
 | 
						|
  // inform our parent of the failure via the offline() message
 | 
						|
  try
 | 
						|
    {
 | 
						|
      do_poll ();              // tell sub-classes to update our state
 | 
						|
 | 
						|
      // Signal new state if it what we expected or, hasn't become
 | 
						|
      // what we expected after polls_to_stabilize polls. Unsolicited
 | 
						|
      // changes will be signalled immediately unless they intervene
 | 
						|
      // in a expected sequence where they will be delayed.
 | 
						|
      if (retries_)
 | 
						|
        {
 | 
						|
          --retries_;
 | 
						|
          if (state () == next_state_ || !retries_)
 | 
						|
            {
 | 
						|
              // the expected state has arrived or there are no more
 | 
						|
              // retries
 | 
						|
              force_signal = true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
      else if (state () != last_signalled_state_)
 | 
						|
        {
 | 
						|
          // here is the normal passive polling path where state has
 | 
						|
          // changed asynchronously
 | 
						|
          force_signal = true;
 | 
						|
        }
 | 
						|
 | 
						|
      if (force_signal)
 | 
						|
        {
 | 
						|
          // reset everything, record and signal the current state
 | 
						|
          retries_ = 0;
 | 
						|
          next_state_ = state ();
 | 
						|
          last_signalled_state_ = state ();
 | 
						|
          update_complete (true);
 | 
						|
        }
 | 
						|
    }
 | 
						|
  catch (std::exception const& e)
 | 
						|
    {
 | 
						|
      message = e.what ();
 | 
						|
    }
 | 
						|
  catch (...)
 | 
						|
    {
 | 
						|
      message = tr ("Unexpected rig error");
 | 
						|
    }
 | 
						|
  if (!message.isEmpty ())
 | 
						|
    {
 | 
						|
      offline (message);
 | 
						|
    }
 | 
						|
}
 |