241 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			241 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								#include "TransceiverBase.hpp"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <exception>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <QString>
							 | 
						||
| 
								 | 
							
								#include <QTimer>
							 | 
						||
| 
								 | 
							
								#include <QThread>
							 | 
						||
| 
								 | 
							
								#include <QDebug>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "moc_TransceiverBase.cpp"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  auto const unexpected = TransceiverBase::tr ("Unexpected rig error");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::start (unsigned sequence_number) noexcept
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  QString message;
							 | 
						||
| 
								 | 
							
								  try
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      may_update u {this, true};
							 | 
						||
| 
								 | 
							
								      shutdown ();
							 | 
						||
| 
								 | 
							
								      startup ();
							 | 
						||
| 
								 | 
							
								      last_sequence_number_ = sequence_number;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  catch (std::exception const& e)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      message = e.what ();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  catch (...)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      message = unexpected;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  if (!message.isEmpty ())
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      offline (message);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::set (TransceiverState const& s,
							 | 
						||
| 
								 | 
							
								                           unsigned sequence_number) noexcept
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  TRACE_CAT ("TransceiverBase", "#:" << sequence_number << s);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  QString message;
							 | 
						||
| 
								 | 
							
								  try
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      may_update u {this, true};
							 | 
						||
| 
								 | 
							
								      bool was_online {requested_.online ()};
							 | 
						||
| 
								 | 
							
								      if (!s.online () && was_online)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          shutdown ();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      else if (s.online () && !was_online)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          shutdown ();
							 | 
						||
| 
								 | 
							
								          startup ();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      if (requested_.online ())
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          bool ptt_on {false};
							 | 
						||
| 
								 | 
							
								          bool ptt_off {false};
							 | 
						||
| 
								 | 
							
								          if (s.ptt () != requested_.ptt ())
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              ptt_on = s.ptt ();
							 | 
						||
| 
								 | 
							
								              ptt_off = !s.ptt ();
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          if (ptt_off)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              do_ptt (false);
							 | 
						||
| 
								 | 
							
								              do_post_ptt (false);
							 | 
						||
| 
								 | 
							
								              QThread::msleep (100); // some rigs cannot process CAT
							 | 
						||
| 
								 | 
							
								                                     // commands while switching from
							 | 
						||
| 
								 | 
							
								                                     // Tx to Rx
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          if (s.frequency ()    // ignore bogus zero frequencies
							 | 
						||
| 
								 | 
							
								              && ((s.frequency () != requested_.frequency () // and QSY
							 | 
						||
| 
								 | 
							
								                   || (s.mode () != UNK && s.mode () != requested_.mode ())) // or mode change
							 | 
						||
| 
								 | 
							
								                  || ptt_off))       // or just returned to rx
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              do_frequency (s.frequency (), s.mode (), ptt_off);
							 | 
						||
| 
								 | 
							
								              do_post_frequency (s.frequency (), s.mode ());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								              // record what actually changed
							 | 
						||
| 
								 | 
							
								              requested_.frequency (actual_.frequency ());
							 | 
						||
| 
								 | 
							
								              requested_.mode (actual_.mode ());
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          if (!s.tx_frequency () || s.tx_frequency () > 10000) // ignore bogus startup values
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              if ((s.tx_frequency () != requested_.tx_frequency () // and QSY
							 | 
						||
| 
								 | 
							
								                   || (s.mode () != UNK && s.mode () != requested_.mode ())) // or mode change
							 | 
						||
| 
								 | 
							
								                  // || s.split () != requested_.split ())) // or split change
							 | 
						||
| 
								 | 
							
								                  || (s.tx_frequency () && ptt_on)) // or about to tx split
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                  do_tx_frequency (s.tx_frequency (), s.mode (), ptt_on);
							 | 
						||
| 
								 | 
							
								                  do_post_tx_frequency (s.tx_frequency (), s.mode ());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                  // record what actually changed
							 | 
						||
| 
								 | 
							
								                  requested_.tx_frequency (actual_.tx_frequency ());
							 | 
						||
| 
								 | 
							
								                  requested_.split (actual_.split ());
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          if (ptt_on)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              do_ptt (true);
							 | 
						||
| 
								 | 
							
								              do_post_ptt (true);
							 | 
						||
| 
								 | 
							
								              QThread::msleep (100); // some rigs cannot process CAT
							 | 
						||
| 
								 | 
							
								                                     // commands while switching from
							 | 
						||
| 
								 | 
							
								                                     // Rx to Tx
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // record what actually changed
							 | 
						||
| 
								 | 
							
								          requested_.ptt (actual_.ptt ());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      last_sequence_number_ = sequence_number;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  catch (std::exception const& e)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      message = e.what ();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  catch (...)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      message = unexpected;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  if (!message.isEmpty ())
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      offline (message);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::startup ()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  Q_EMIT resolution (do_start ());
							 | 
						||
| 
								 | 
							
								  do_post_start ();
							 | 
						||
| 
								 | 
							
								  actual_.online (true);
							 | 
						||
| 
								 | 
							
								  requested_.online (true);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::shutdown ()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  may_update u {this};
							 | 
						||
| 
								 | 
							
								  if (requested_.online ())
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      try
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          // try and ensure PTT isn't left set
							 | 
						||
| 
								 | 
							
								          do_ptt (false);
							 | 
						||
| 
								 | 
							
								          do_post_ptt (false);
							 | 
						||
| 
								 | 
							
								          if (requested_.split ())
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								              // try and reset split mode
							 | 
						||
| 
								 | 
							
								              do_tx_frequency (0, UNK, true);
							 | 
						||
| 
								 | 
							
								              do_post_tx_frequency (0, UNK);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      catch (...)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          // don't care about exceptions
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  do_stop ();
							 | 
						||
| 
								 | 
							
								  do_post_stop ();
							 | 
						||
| 
								 | 
							
								  actual_.online (false);
							 | 
						||
| 
								 | 
							
								  requested_.online (false);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::stop () noexcept
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  QString message;
							 | 
						||
| 
								 | 
							
								  try
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      shutdown ();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  catch (std::exception const& e)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      message = e.what ();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  catch (...)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      message = unexpected;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  if (!message.isEmpty ())
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      offline (message);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  else
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      Q_EMIT finished ();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::update_rx_frequency (Frequency rx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  actual_.frequency (rx);
							 | 
						||
| 
								 | 
							
								  requested_.frequency (rx);    // track rig changes
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::update_other_frequency (Frequency tx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  actual_.tx_frequency (tx);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::update_split (bool state)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  actual_.split (state);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::update_mode (MODE m)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  actual_.mode (m);
							 | 
						||
| 
								 | 
							
								  requested_.mode (m);    // track rig changes
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::update_PTT (bool state)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  actual_.ptt (state);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::update_complete (bool force_signal)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  if ((do_pre_update () && actual_ != last_) || force_signal)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      Q_EMIT update (actual_, last_sequence_number_);
							 | 
						||
| 
								 | 
							
								      last_ = actual_;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void TransceiverBase::offline (QString const& reason)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  Q_EMIT failure (reason);
							 | 
						||
| 
								 | 
							
								  try
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      shutdown ();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  catch (...)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      // don't care
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |