From 6603a0b62b22cefbc1ceed00739230e6ccc4a8d9 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli (think)" Date: Wed, 15 Aug 2012 16:32:54 +0200 Subject: crc-dabmod: added syslog support --- src/DabMod.cpp | 57 +++++++++++++++++++++- src/Log.cpp | 62 +++++++++++++++++++++++ src/Log.h | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Makefile.am | 3 +- src/Makefile.in | 20 +++++++- src/OutputUHD.cpp | 42 ++++++++++++---- src/OutputUHD.h | 14 +++++- 7 files changed, 325 insertions(+), 16 deletions(-) create mode 100644 src/Log.cpp create mode 100644 src/Log.h (limited to 'src') 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("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 . + */ + +#include +#include + +#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::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::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 . + */ + +#ifndef _LOG_H +#define _LOG_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#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 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 #include @@ -38,8 +39,10 @@ typedef std::complex 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 #include +#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 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; -- cgit v1.2.3