summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DabMod.cpp57
-rw-r--r--src/Log.cpp62
-rw-r--r--src/Log.h143
-rw-r--r--src/Makefile.am3
-rw-r--r--src/Makefile.in20
-rw-r--r--src/OutputUHD.cpp42
-rw-r--r--src/OutputUHD.h14
7 files changed, 325 insertions, 16 deletions
diff --git a/src/DabMod.cpp b/src/DabMod.cpp
index 2960642..0d899d1 100644
--- a/src/DabMod.cpp
+++ b/src/DabMod.cpp
@@ -29,6 +29,7 @@
#include "porting.h"
+#include "Log.h"
#include "DabModulator.h"
#include "InputMemory.h"
#include "OutputFile.h"
@@ -190,6 +191,8 @@ int main(int argc, char* argv[])
InputMemory* input = NULL;
ModOutput* output = NULL;
+ Logger logger;
+
signal(SIGINT, signalHandler);
// Set timezone to UTC
@@ -303,6 +306,26 @@ int main(int argc, char* argv[])
read_ini(configuration_file, pt);
+ // log parameters:
+ if (pt.get("log.syslog", 0) == 1) {
+ LogToSyslog* log_syslog = new LogToSyslog();
+ logger.register_backend(log_syslog);
+ }
+
+ if (pt.get("log.filelog", 0) == 1) {
+ try {
+ std::string logfilename = pt.get<std::string>("fileoutput.filename");
+ LogToFile* log_file = new LogToFile(logfilename);
+ logger.register_backend(log_file);
+ }
+ catch (std::exception &e) {
+ std::cerr << "Error: " << e.what() << "\n";
+ std::cerr << " Configuration enables file log, but does not specify log filename\n";
+ goto END_MAIN;
+ }
+ }
+
+
// modulator parameters:
gainMode = (GainMode)pt.get("modulator.gainmode", 0);
dabMode = pt.get("modulator.mode", dabMode);
@@ -386,11 +409,14 @@ int main(int argc, char* argv[])
}
}
+ logger(info, "starting up");
+
// When using offset, enable frame muting
uhd_mute_no_timestamps = (modconf.use_offset_file || modconf.use_offset_fixed);
if (!(modconf.use_offset_file || modconf.use_offset_fixed)) {
fprintf(stderr, "No Modulator offset defined, setting to 0\n");
+ logger(debug, "No Modulator offset defined, setting to 0");
modconf.use_offset_fixed = true;
modconf.offset_fixed = 0;
}
@@ -417,10 +443,12 @@ int main(int argc, char* argv[])
fprintf(stderr, "\n");
printUsage(argv[0]);
ret = -1;
+ logger(error, "Received invalid command line arguments");
goto END_MAIN;
}
if (!useFileOutput && !useUHDOutput) {
+ logger(error, "Output not specified");
fprintf(stderr, "Must specify output !");
goto END_MAIN;
}
@@ -450,6 +478,7 @@ int main(int argc, char* argv[])
inputFile = fopen(inputName, "r");
if (inputFile == NULL) {
fprintf(stderr, "Unable to open input file!\n");
+ logger(error, "Unable to open input file!");
perror(inputName);
ret = -1;
goto END_MAIN;
@@ -465,7 +494,17 @@ int main(int argc, char* argv[])
else if (useUHDOutput) {
fprintf(stderr, "Using UHD output\n");
amplitude /= 32000.0f;
- output = new OutputUHD(outputDevice, outputRate, uhdFrequency, uhdTxGain, uhd_enable_sync, uhd_mute_no_timestamps);
+ try {
+ output = new OutputUHD(outputDevice, outputRate,
+ uhdFrequency, uhdTxGain,
+ uhd_enable_sync, uhd_mute_no_timestamps,
+ logger);
+ }
+ catch (std::exception& e) {
+ logger(error, "UHD initialisation failed");
+ goto END_MAIN;
+ }
+
}
flowgraph = new Flowgraph();
@@ -496,6 +535,7 @@ int main(int argc, char* argv[])
if (fread(&sync, sizeof(sync), 1, inputFile) != 1) {
fprintf(stderr, "Unable to read sync in input file!\n");
+ logger(error, "Unable to read sync in input file!");
perror(inputName);
ret = -1;
goto END_MAIN;
@@ -511,6 +551,7 @@ int main(int argc, char* argv[])
if (fread(data.getData(), 6144 - sizeof(sync), 1, inputFile)
!= 1) {
fprintf(stderr, "Unable to seek in input file!\n");
+ logger(error, "Unable to seek in input file!");
ret = -1;
goto END_MAIN;
}
@@ -521,6 +562,7 @@ int main(int argc, char* argv[])
nbFrames = sync;
if (fread(&frameSize, sizeof(frameSize), 1, inputFile) != 1) {
fprintf(stderr, "Unable to read frame size in input file!\n");
+ logger(error, "Unable to read frame size in input file!");
perror(inputName);
ret = -1;
goto END_MAIN;
@@ -541,6 +583,7 @@ int main(int argc, char* argv[])
if (fread(data.getData(), frameSize - 4, 1, inputFile)
!= 1) {
fprintf(stderr, "Unable to seek in input file!\n");
+ logger(error, "Unable to seek in input file!");
ret = -1;
goto END_MAIN;
}
@@ -550,6 +593,7 @@ int main(int argc, char* argv[])
if (fread(&sync, sizeof(sync), 1, inputFile) != 1) {
fprintf(stderr, "Unable to read nb frame in input file!\n");
+ logger(error, "Unable to read nb frame in input file!");
perror(inputName);
ret = -1;
goto END_MAIN;
@@ -560,6 +604,7 @@ int main(int argc, char* argv[])
if (fread(data.getData(), frameSize - 4, 1, inputFile)
!= 1) {
fprintf(stderr, "Unable to seek in input file!\n");
+ logger(error, "Unable to seek in input file!");
ret = -1;
goto END_MAIN;
}
@@ -571,7 +616,8 @@ int main(int argc, char* argv[])
sync >>= 8;
sync &= 0xffffff;
if (fread((uint8_t*)&sync + 3, 1, 1, inputFile) != 1) {
- fprintf(stderr, "Unable to read in input file!\n");
+ fprintf(stderr, "Unable to read from input file!\n");
+ logger(error, "Unable to read from input file!");
ret = 1;
goto END_MAIN;
}
@@ -586,6 +632,7 @@ int main(int argc, char* argv[])
if (fread(data.getData(), 6144 - sizeof(sync), 1, inputFile)
!= 1) {
fprintf(stderr, "Unable to seek in input file!\n");
+ logger(error, "Unable to seek in input file!");
ret = -1;
goto END_MAIN;
}
@@ -595,6 +642,7 @@ int main(int argc, char* argv[])
}
fprintf(stderr, "Bad input file format!\n");
+ logger(error, "Bad input file format!");
ret = -1;
goto END_MAIN;
@@ -612,6 +660,7 @@ START:
break;
default:
fprintf(stderr, "unknown\n");
+ logger(error, "Input file format unknown!");
ret = -1;
goto END_MAIN;
}
@@ -633,6 +682,7 @@ START:
if (fread(&frameSize, sizeof(frameSize), 1, inputFile)
!= 1) {
PDEBUG("End of file!\n");
+ logger(error, "Reached end of file!");
goto END_MAIN;
}
}
@@ -644,6 +694,7 @@ START:
frameSize);
perror(inputName);
ret = -1;
+ logger(error, "Unable to read from input file!");
goto END_MAIN;
}
memset(&((uint8_t*)data.getData())[frameSize], 0x55, 6144 - frameSize);
@@ -686,5 +737,7 @@ END_MAIN:
fclose(inputFile);
}
+ logger(info, "Terminating");
+
return ret;
}
diff --git a/src/Log.cpp b/src/Log.cpp
new file mode 100644
index 0000000..8d04c58
--- /dev/null
+++ b/src/Log.cpp
@@ -0,0 +1,62 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+ Her Majesty the Queen in Right of Canada (Communications Research
+ Center Canada)
+
+ Includes modifications for which no copyright is claimed
+ 2012, Matthias P. Braendli, matthias.braendli@mpb.li
+ */
+/*
+ This file is part of CRC-DADMOD.
+
+ CRC-DADMOD is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ CRC-DADMOD is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with CRC-DADMOD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <list>
+#include <stdarg.h>
+
+#include "Log.h"
+#include "porting.h"
+
+
+Logger::Logger() {
+}
+
+void
+Logger::register_backend(LogBackend* backend) {
+ backends.push_back(backend);
+ //log(info, "Registered new logger " + backend->get_name());
+}
+
+void
+Logger::operator()(log_level_t level, const char* fmt, ...) {
+ va_list arg_ptr;
+
+ va_start(arg_ptr, fmt);
+ for (std::list<LogBackend*>::iterator it = backends.begin(); it != backends.end(); it++) {
+ (*it)->log(level, fmt, arg_ptr);
+ }
+ va_end(arg_ptr);
+}
+
+void
+Logger::log(log_level_t level, const char* fmt, ...) {
+ va_list arg_ptr;
+
+ va_start(arg_ptr, fmt);
+ for (std::list<LogBackend*>::iterator it = backends.begin(); it != backends.end(); it++) {
+ (*it)->log(level, fmt, arg_ptr);
+ }
+ va_end(arg_ptr);
+}
diff --git a/src/Log.h b/src/Log.h
new file mode 100644
index 0000000..dc686fc
--- /dev/null
+++ b/src/Log.h
@@ -0,0 +1,143 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+ Her Majesty the Queen in Right of Canada (Communications Research
+ Center Canada)
+
+ Includes modifications for which no copyright is claimed
+ 2012, Matthias P. Braendli, matthias.braendli@mpb.li
+ */
+/*
+ This file is part of CRC-DADMOD.
+
+ CRC-DADMOD is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ CRC-DADMOD is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with CRC-DADMOD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _LOG_H
+#define _LOG_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string>
+#include <syslog.h>
+#include <iostream>
+#include <fstream>
+#include <list>
+#include <stdexcept>
+
+#include <stdarg.h>
+
+#include "porting.h"
+
+#define SYSLOG_IDENT "CRC-DABMOD"
+#define SYSLOG_FACILITY LOG_LOCAL0
+
+enum log_level_t {debug = 0, info, warn, error, alert, emerg};
+
+class LogBackend {
+ public:
+ virtual void log(log_level_t level, const char* fmt, ...) = 0;
+ virtual std::string get_name() = 0;
+};
+
+class LogToSyslog : public LogBackend {
+ public:
+ LogToSyslog() {
+ name = "SYSLOG";
+ openlog(SYSLOG_IDENT, LOG_PID, SYSLOG_FACILITY);
+ }
+
+ ~LogToSyslog() {
+ closelog();
+ }
+
+ void log(log_level_t level, const char* fmt, ...) {
+ va_list arg_ptr;
+
+ int syslog_level = LOG_EMERG;
+ switch (level) {
+ case debug: syslog_level = LOG_DEBUG; break;
+ case alert: syslog_level = LOG_ALERT; break;
+ case info: syslog_level = LOG_INFO; break;
+ case warn: syslog_level = LOG_WARNING; break;
+ case error: syslog_level = LOG_ERR; break;
+ case emerg: syslog_level = LOG_EMERG; break;
+ }
+
+ va_start(arg_ptr, fmt);
+ syslog(level, fmt, arg_ptr);
+ va_end(arg_ptr);
+ }
+
+ std::string get_name() { return name; };
+
+ private:
+ std::string name;
+};
+
+class LogToFile : public LogBackend {
+ public:
+ LogToFile(std::string filename) {
+ name = "FILE";
+ log_filename = filename;
+ log_stream.open(filename.c_str(), std::ios::app);
+ if (!log_stream.is_open()) {
+ throw new std::runtime_error("Cannot open log file !");
+ }
+ }
+
+ ~LogToFile() {
+ if (log_stream.is_open()) {
+ log_stream.close();
+ }
+ }
+
+ void log(log_level_t level, const char* fmt, ...) {
+ va_list arg_ptr;
+ char message[200];
+
+ const char* log_level_text[] = {"DEBUG", "INFO", "WARN", "ERROR", "ALERT", "EMERG"};
+
+ va_start(arg_ptr, fmt);
+ snprintf(message, 200, fmt, arg_ptr);
+ log_stream << "CRC-DABMOD: " << log_level_text[(size_t)level] << ": " << message << std::endl;
+ va_end(arg_ptr);
+ }
+
+ std::string get_name() { return name; };
+
+ private:
+ std::string name;
+ std::string log_filename;
+ std::ofstream log_stream;
+};
+
+class Logger {
+ public:
+ Logger();
+
+ void register_backend(LogBackend* backend);
+
+ void log(log_level_t level, std::string message) { operator()(level, "%s", message.c_str()); }
+ void log(log_level_t level, const char* fmt, ...);
+
+ void operator()(log_level_t level, const char* fmt, ...);
+
+ private:
+ std::list<LogBackend*> backends;
+};
+
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index c82842c..c546e1d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -75,7 +75,8 @@ crc_dabmod_SOURCES = DabMod.cpp \
GuardIntervalInserter.cpp GuardIntervalInserter.h \
Resampler.cpp Resampler.h \
ConvEncoder.cpp ConvEncoder.h \
- TimeInterleaver.cpp TimeInterleaver.h
+ TimeInterleaver.cpp TimeInterleaver.h \
+ Log.cpp Log.h
nodist_crc_dabmod_SOURCES =$(FFT_SRC)
dist_bin_SCRIPTS =crc-dwap.py
diff --git a/src/Makefile.in b/src/Makefile.in
index 6620494..f56fb98 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -99,7 +99,7 @@ am_crc_dabmod_OBJECTS = crc_dabmod-DabMod.$(OBJEXT) \
crc_dabmod-GuardIntervalInserter.$(OBJEXT) \
crc_dabmod-Resampler.$(OBJEXT) \
crc_dabmod-ConvEncoder.$(OBJEXT) \
- crc_dabmod-TimeInterleaver.$(OBJEXT)
+ crc_dabmod-TimeInterleaver.$(OBJEXT) crc_dabmod-Log.$(OBJEXT)
am__objects_1 = crc_dabmod-kiss_fft.$(OBJEXT) \
crc_dabmod-kiss_fftr.$(OBJEXT) \
crc_dabmod-kiss_fftsimd.$(OBJEXT)
@@ -293,7 +293,8 @@ crc_dabmod_SOURCES = DabMod.cpp \
GuardIntervalInserter.cpp GuardIntervalInserter.h \
Resampler.cpp Resampler.h \
ConvEncoder.cpp ConvEncoder.h \
- TimeInterleaver.cpp TimeInterleaver.h
+ TimeInterleaver.cpp TimeInterleaver.h \
+ Log.cpp Log.h
nodist_crc_dabmod_SOURCES = $(FFT_SRC)
dist_bin_SCRIPTS = crc-dwap.py
@@ -430,6 +431,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc_dabmod-GainControl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc_dabmod-GuardIntervalInserter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc_dabmod-InputMemory.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc_dabmod-Log.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc_dabmod-ModCodec.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc_dabmod-ModFormat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc_dabmod-ModInput.Po@am__quote@
@@ -1072,6 +1074,20 @@ crc_dabmod-TimeInterleaver.obj: TimeInterleaver.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(crc_dabmod_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o crc_dabmod-TimeInterleaver.obj `if test -f 'TimeInterleaver.cpp'; then $(CYGPATH_W) 'TimeInterleaver.cpp'; else $(CYGPATH_W) '$(srcdir)/TimeInterleaver.cpp'; fi`
+crc_dabmod-Log.o: Log.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(crc_dabmod_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT crc_dabmod-Log.o -MD -MP -MF $(DEPDIR)/crc_dabmod-Log.Tpo -c -o crc_dabmod-Log.o `test -f 'Log.cpp' || echo '$(srcdir)/'`Log.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/crc_dabmod-Log.Tpo $(DEPDIR)/crc_dabmod-Log.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Log.cpp' object='crc_dabmod-Log.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(crc_dabmod_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o crc_dabmod-Log.o `test -f 'Log.cpp' || echo '$(srcdir)/'`Log.cpp
+
+crc_dabmod-Log.obj: Log.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(crc_dabmod_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT crc_dabmod-Log.obj -MD -MP -MF $(DEPDIR)/crc_dabmod-Log.Tpo -c -o crc_dabmod-Log.obj `if test -f 'Log.cpp'; then $(CYGPATH_W) 'Log.cpp'; else $(CYGPATH_W) '$(srcdir)/Log.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/crc_dabmod-Log.Tpo $(DEPDIR)/crc_dabmod-Log.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Log.cpp' object='crc_dabmod-Log.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(crc_dabmod_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o crc_dabmod-Log.obj `if test -f 'Log.cpp'; then $(CYGPATH_W) 'Log.cpp'; else $(CYGPATH_W) '$(srcdir)/Log.cpp'; fi`
+
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp
index 3fb23d5..971f33b 100644
--- a/src/OutputUHD.cpp
+++ b/src/OutputUHD.cpp
@@ -26,6 +26,7 @@
#include "OutputUHD.h"
#include "PcDebug.h"
+#include "Log.h"
#include <iostream>
#include <assert.h>
@@ -38,8 +39,10 @@
typedef std::complex<float> complexf;
OutputUHD::OutputUHD(const char* device, unsigned sampleRate,
- double frequency, int txgain, bool enableSync, bool muteNoTimestamps) :
+ double frequency, int txgain, bool enableSync, bool muteNoTimestamps,
+ Logger& logger) :
ModOutput(ModFormat(1), ModFormat(0)),
+ myLogger(logger),
mySampleRate(sampleRate),
myTxGain(txgain),
myFrequency(frequency),
@@ -57,7 +60,12 @@ OutputUHD::OutputUHD(const char* device, unsigned sampleRate,
//create a usrp device
MDEBUG("OutputUHD:Creating the usrp device with: %s...\n",
myDevice.c_str());
- myUsrp = uhd::usrp::multi_usrp::make(myDevice);
+ //try {
+ myUsrp = uhd::usrp::multi_usrp::make(myDevice);
+ /*}
+ catch (std::exception &e) {
+ fprintf(stderr, "FLABBER FLABBER FLABBER\n");
+ }*/
MDEBUG("OutputUHD:Using device: %s...\n", myUsrp->get_pp_string().c_str());
if (enable_sync) {
@@ -97,6 +105,7 @@ OutputUHD::OutputUHD(const char* device, unsigned sampleRate,
if (clock_gettime(CLOCK_REALTIME, &now)) {
fprintf(stderr, "errno: %d\n", errno);
perror("OutputUHD:Error: could not get time: ");
+ myLogger(error, "OutputUHD: could not get time");
}
else {
seconds = now.tv_sec;
@@ -107,6 +116,7 @@ OutputUHD::OutputUHD(const char* device, unsigned sampleRate,
if (clock_gettime(CLOCK_REALTIME, &now)) {
fprintf(stderr, "errno: %d\n", errno);
perror("OutputUHD:Error: could not get time: ");
+ myLogger(error, "OutputUHD: could not get time");
break;
}
}
@@ -129,6 +139,7 @@ OutputUHD::OutputUHD(const char* device, unsigned sampleRate,
uwd.myUsrp = myUsrp;
#else
fprintf(stderr, "OutputUHD: UHD initialisation disabled at compile-time\n");
+ myLogger(error, "OutputUHD: UHD initialisation disabled at compile-time");
#endif
uwd.frame0.ts.timestamp_valid = false;
@@ -167,6 +178,7 @@ int OutputUHD::process(Buffer* dataIn, Buffer* dataOut)
// OutputUHD::process
if (first_run) {
fprintf(stderr, "OutUHD.process:Initialising...\n");
+ myLogger(debug, "OutputUHD: UHD initialising...");
uwd.bufsize = dataIn->getLength();
uwd.frame0.buf = malloc(uwd.bufsize);
@@ -186,6 +198,7 @@ int OutputUHD::process(Buffer* dataIn, Buffer* dataOut)
lastLen = uwd.bufsize;
first_run = false;
fprintf(stderr, "OutUHD.process:Initialising complete.\n");
+ myLogger(debug, "OutputUHD: UHD initialising complete");
}
else {
@@ -194,6 +207,7 @@ int OutputUHD::process(Buffer* dataIn, Buffer* dataOut)
fprintf(stderr,
"OutUHD.process:AAAAH PANIC input length changed from %zu to %zu !\n",
lastLen, dataIn->getLength());
+ myLogger(emerg, "OutputUHD: Fatal error, input length changed !");
throw std::runtime_error("Non-constant input length!");
}
//fprintf(stderr, "OutUHD.process:Waiting for barrier\n");
@@ -291,6 +305,7 @@ void UHDWorker::process(struct UHDWorkerData *uwd)
// Check for ref_lock
if (! uwd->myUsrp->get_mboard_sensor("ref_locked", 0).to_bool()) {
fprintf(stderr, "UHDWorker: RefLock lost !\n");
+ uwd->logger->log(alert, "OutputUHD: External reference clock lock lost !");
}
usrp_time = uwd->myUsrp->get_time_now().get_real_secs();
@@ -305,6 +320,8 @@ void UHDWorker::process(struct UHDWorkerData *uwd)
*/
fprintf(stderr, "UHDOut: Throwing sample %d away: incomplete timestamp %zu + %f\n",
frame->fct, tx_second, pps_offset);
+ uwd->logger->log(info, "OutputUHD: Throwing sample %d away: incomplete timestamp %zu + %f\n",
+ frame->fct, tx_second, pps_offset);
usleep(20000);
goto loopend;
}
@@ -335,6 +352,7 @@ void UHDWorker::process(struct UHDWorkerData *uwd)
"* Timestamp way too far in the future! offset: %f\n",
md.time_spec.get_real_secs() - usrp_time);
fprintf(stderr, "* Aborting\n");
+ uwd->logger->log(error, "OutputUHD: timestamp is way to far in the future, aborting");
throw std::runtime_error("Timestamp error. Aborted.");
}
#endif
@@ -425,29 +443,35 @@ void UHDWorker::process(struct UHDWorkerData *uwd)
//std::cerr << std::endl << "Waiting for async burst ACK... " << std::flush;
uhd::async_metadata_t async_md;
if (uwd->myUsrp->get_device()->recv_async_msg(async_md, 0)) {
- std::string PREFIX = "### asyncronous UHD message : ";
+ std::string uhd_async_message = "Received UHD message ";
+ bool failure = true;
switch (async_md.event_code) {
case uhd::async_metadata_t::EVENT_CODE_BURST_ACK:
+ failure = false;
break;
case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW:
- std::cerr << PREFIX << "Underflow" << std::endl;
+ uhd_async_message += "Underflow";
break;
case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR:
- std::cerr << PREFIX << "Packet loss between host and device." << std::endl;
+ uhd_async_message += "Packet loss between host and device.";
break;
case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR:
- std::cerr << PREFIX << "Packet had time that was late." << std::endl;
+ uhd_async_message += "Packet had time that was late.";
break;
case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET:
- std::cerr << PREFIX << "Underflow occurred inside a packet." << std::endl;
+ uhd_async_message += "Underflow occurred inside a packet.";
break;
case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST:
- std::cerr << PREFIX << "Packet loss within a burst." << std::endl;
+ uhd_async_message += "Packet loss within a burst.";
break;
default:
- std::cerr << PREFIX << "unknown event code" << std::endl;
+ uhd_async_message += "unknown event code";
break;
}
+
+ if (failure) {
+ uwd->logger->log(alert, uhd_async_message);
+ }
}
/*
diff --git a/src/OutputUHD.h b/src/OutputUHD.h
index d460af4..23d0e4c 100644
--- a/src/OutputUHD.h
+++ b/src/OutputUHD.h
@@ -45,6 +45,7 @@ DESCRIPTION:
#include <boost/thread/barrier.hpp>
#include <boost/shared_ptr.hpp>
+#include "Log.h"
#include "ModOutput.h"
#include "EtiReader.h"
#include "TimestampDecoder.h"
@@ -100,6 +101,9 @@ struct UHDWorkerData {
// A barrier to synchronise the two threads
shared_ptr<barrier> sync_barrier;
+
+ // The common logger
+ Logger* logger;
};
@@ -134,8 +138,13 @@ class UHDWorker {
class OutputUHD: public ModOutput {
public:
- OutputUHD(const char* device, unsigned sampleRate, double frequency, int txgain,
- bool enableSync, bool muteNoTimestamps);
+ OutputUHD(const char* device,
+ unsigned sampleRate,
+ double frequency,
+ int txgain,
+ bool enableSync,
+ bool muteNoTimestamps,
+ Logger& logger);
~OutputUHD();
int process(Buffer* dataIn, Buffer* dataOut);
@@ -147,6 +156,7 @@ class OutputUHD: public ModOutput {
}
protected:
+ Logger& myLogger;
EtiReader *myEtiReader;
std::string myDevice;
unsigned mySampleRate;