diff options
Diffstat (limited to 'src/OutputUHD.h')
-rw-r--r-- | src/OutputUHD.h | 93 |
1 files changed, 71 insertions, 22 deletions
diff --git a/src/OutputUHD.h b/src/OutputUHD.h index d002e98..633de04 100644 --- a/src/OutputUHD.h +++ b/src/OutputUHD.h @@ -2,7 +2,7 @@ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2014 + Copyright (C) 2014, 2015 Matthias P. Braendli, matthias.braendli@mpb.li http://opendigitalradio.org @@ -50,6 +50,7 @@ DESCRIPTION: #include <boost/thread/thread.hpp> #include <boost/thread/barrier.hpp> #include <boost/shared_ptr.hpp> +#include <boost/atomic.hpp> #include <list> #include <string> @@ -83,9 +84,20 @@ struct UHDWorkerFrameData { struct frame_timestamp ts; }; +struct fct_discontinuity_error : public std::exception +{ + const char* what () const throw () + { + return "FCT discontinuity detected"; + } +}; + enum refclk_lock_loss_behaviour_t { CRASH, IGNORE }; struct UHDWorkerData { + boost::atomic<bool> running; + bool failed_due_to_fct; + #if FAKE_UHD == 0 uhd::usrp::multi_usrp::sptr myUsrp; #endif @@ -109,6 +121,9 @@ struct UHDWorkerData { // If we want to verify loss of refclk bool check_refclk_loss; + // If we want to check for the gps_fixtype sensor + bool check_gpsfix; + // muting set by remote control bool muting; @@ -118,9 +133,6 @@ struct UHDWorkerData { // What to do when the reference clock PLL loses lock refclk_lock_loss_behaviour_t refclk_lock_loss_behaviour; - // The common logger - Logger* logger; - // What transmission mode we're using defines by how // much the FCT should increment for each // transmission frame. @@ -130,31 +142,44 @@ struct UHDWorkerData { class UHDWorker { public: - UHDWorker () { - running = false; - } - void start(struct UHDWorkerData *uhdworkerdata) { - running = true; uwd = uhdworkerdata; - uhd_thread = boost::thread(&UHDWorker::process, this); + + uwd->running = true; + uwd->failed_due_to_fct = false; + uhd_thread = boost::thread(&UHDWorker::process_errhandler, this); } void stop() { - running = false; + uwd->running = false; uhd_thread.interrupt(); uhd_thread.join(); } - void process(); + private: + // Asynchronous message statistics + int num_underflows; + int num_late_packets; + bool fct_discontinuity; + int expected_next_fct; + uhd::tx_metadata_t md; + time_t tx_second; + double pps_offset; + double last_pps; + + void print_async_metadata(const struct UHDWorkerFrameData *frame); + + void handle_frame(const struct UHDWorkerFrameData *frame); + void tx_frame(const struct UHDWorkerFrameData *frame); - private: struct UHDWorkerData *uwd; - bool running; boost::thread uhd_thread; uhd::tx_streamer::sptr myTxStream; + + void process(); + void process_errhandler(); }; /* This structure is used as initial configuration for OutputUHD */ @@ -171,7 +196,8 @@ struct OutputUHDConfig { double txgain; bool enableSync; bool muteNoTimestamps; - unsigned dabMode; + unsigned dabMode; + unsigned maxGPSHoldoverTime; /* allowed values : auto, int, sma, mimo */ std::string refclk_src; @@ -190,9 +216,7 @@ struct OutputUHDConfig { class OutputUHD: public ModOutput, public RemoteControllable { public: - OutputUHD( - OutputUHDConfig& config, - Logger& logger); + OutputUHD(const OutputUHDConfig& config); ~OutputUHD(); int process(Buffer* dataIn, Buffer* dataOut); @@ -218,13 +242,16 @@ class OutputUHD: public ModOutput, public RemoteControllable { protected: - Logger& myLogger; + OutputUHD(const OutputUHD& other); + OutputUHD& operator=(const OutputUHD& other); + EtiReader *myEtiReader; OutputUHDConfig myConf; uhd::usrp::multi_usrp::sptr myUsrp; boost::shared_ptr<boost::barrier> mySyncBarrier; UHDWorker worker; bool first_run; + bool gps_fix_verified; struct UHDWorkerData uwd; int activebuffer; @@ -232,14 +259,36 @@ class OutputUHD: public ModOutput, public RemoteControllable { bool myMuting; private: - // methods - void SetDelayBuffer(unsigned int dabMode); + // Resize the internal delay buffer according to the dabMode and + // the sample rate. + void SetDelayBuffer(unsigned int dabMode); // data int myStaticDelayUs; // static delay in microseconds - int myTFDurationMs; // TF duration in milliseconds + int myTFDurationMs; // TF duration in milliseconds std::vector<complexf> myDelayBuf; size_t lastLen; + + // GPS Fix check variables + int num_checks_without_gps_fix; + struct timespec first_gps_fix_check; + struct timespec last_gps_fix_check; + struct timespec time_last_frame; + boost::packaged_task<bool> gps_fix_pt; + boost::unique_future<bool> gps_fix_future; + boost::thread gps_fix_task; + + // Wait time in seconds to get fix + static const int initial_gps_fix_wait = 60; + + // Interval for checking the GPS at runtime + static const double gps_fix_check_interval = 10.0; // seconds + + void check_gps(); + + void set_usrp_time(); + + void initial_gps_check(); }; #endif // HAVE_OUTPUT_UHD |