aboutsummaryrefslogtreecommitdiffstats
path: root/src/OutputUHD.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/OutputUHD.h')
-rw-r--r--src/OutputUHD.h93
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