From a11802c1690a2ee7b4c7da7e218a200547a9881c Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 15 Oct 2016 11:34:58 +0200 Subject: Fix zmq epgm:// input and mpeg enryption --- src/ConfigParser.cpp | 112 ++++++++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 59 deletions(-) (limited to 'src/ConfigParser.cpp') diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index bb1e0e0..747fa39 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -107,8 +107,13 @@ typedef DWORD32 uint32_t; using namespace std; +static void setup_subchannel_from_ptree(DabSubchannel* subchan, + const boost::property_tree::ptree &pt, + std::shared_ptr ensemble, + const string& subchanuid); + /* a helper class to parse hexadecimal ids */ -int hexparse(std::string input) +static int hexparse(std::string input) { int value; if (input.find("0x") == 0) { @@ -125,7 +130,7 @@ int hexparse(std::string input) return value; } -uint16_t get_announcement_flag_from_ptree( +static uint16_t get_announcement_flag_from_ptree( boost::property_tree::ptree& pt ) { @@ -556,10 +561,44 @@ void parse_ptree( } } -void setup_subchannel_from_ptree(DabSubchannel* subchan, - boost::property_tree::ptree &pt, +static dab_input_zmq_config_t setup_zmq_input( + const boost::property_tree::ptree &pt, + const std::string& subchanuid) +{ + using boost::property_tree::ptree_error; + + dab_input_zmq_config_t zmqconfig; + + try { + zmqconfig.buffer_size = pt.get("zmq-buffer"); + } + catch (ptree_error &e) { + stringstream ss; + ss << "Subchannel " << subchanuid << ": " << "no zmq-buffer defined!"; + throw runtime_error(ss.str()); + } + try { + zmqconfig.prebuffering = pt.get("zmq-prebuffering"); + } + catch (ptree_error &e) { + stringstream ss; + ss << "Subchannel " << subchanuid << ": " << "no zmq-prebuffer defined!"; + throw runtime_error(ss.str()); + } + + zmqconfig.curve_encoder_keyfile = pt.get("encoder-key",""); + zmqconfig.curve_secret_keyfile = pt.get("secret-key",""); + zmqconfig.curve_public_keyfile = pt.get("public-key",""); + + zmqconfig.enable_encryption = pt.get("encryption", 0); + + return zmqconfig; +} + +static void setup_subchannel_from_ptree(DabSubchannel* subchan, + const boost::property_tree::ptree &pt, std::shared_ptr ensemble, - string subchanuid) + const string& subchanuid) { using boost::property_tree::ptree; using boost::property_tree::ptree_error; @@ -626,43 +665,24 @@ void setup_subchannel_from_ptree(DabSubchannel* subchan, #if defined(HAVE_INPUT_ZEROMQ) } else if (proto == "tcp" || - proto == "epmg" || + proto == "epgm" || proto == "ipc") { input_is_old_style = false; - dab_input_zmq_config_t zmqconfig; - - try { - zmqconfig.buffer_size = pt.get("zmq-buffer"); - } - catch (ptree_error &e) { - stringstream ss; - ss << "ZMQ Subchannel with uid " << subchanuid << - " has no zmq-buffer defined!"; - throw runtime_error(ss.str()); - } - try { - zmqconfig.prebuffering = pt.get("zmq-prebuffering"); - } - catch (ptree_error &e) { - stringstream ss; - ss << "ZMQ Subchannel with uid " << subchanuid << - " has no zmq-buffer defined!"; - throw runtime_error(ss.str()); - } - zmqconfig.enable_encryption = false; + auto zmqconfig = setup_zmq_input(pt, subchanuid); DabInputZmqMPEG* inzmq = new DabInputZmqMPEG(subchanuid, zmqconfig); rcs.enrol(inzmq); subchan->input = inzmq; - if (proto == "epmg") { - etiLog.level(warn) << "Using untested epmg:// zeromq input"; + if (proto == "epgm") { + etiLog.level(warn) << "Using untested epgm:// zeromq input"; } else if (proto == "ipc") { etiLog.level(warn) << "Using untested ipc:// zeromq input"; } + #endif // defined(HAVE_INPUT_ZEROMQ) } else { stringstream ss; @@ -685,37 +705,11 @@ void setup_subchannel_from_ptree(DabSubchannel* subchan, #if defined(HAVE_INPUT_ZEROMQ) } else if (proto == "tcp" || - proto == "epmg" || + proto == "epgm" || proto == "ipc") { input_is_old_style = false; - dab_input_zmq_config_t zmqconfig; - - try { - zmqconfig.buffer_size = pt.get("zmq-buffer"); - } - catch (ptree_error &e) { - stringstream ss; - ss << "ZMQ Subchannel with uid " << subchanuid << - " has no zmq-buffer defined!"; - throw runtime_error(ss.str()); - } - - try { - zmqconfig.prebuffering = pt.get("zmq-prebuffering"); - } - catch (ptree_error &e) { - stringstream ss; - ss << "ZMQ Subchannel with uid " << subchanuid << - " has no zmq-buffer defined!"; - throw runtime_error(ss.str()); - } - - zmqconfig.curve_encoder_keyfile = pt.get("encoder-key",""); - zmqconfig.curve_secret_keyfile = pt.get("secret-key",""); - zmqconfig.curve_public_keyfile = pt.get("public-key",""); - - zmqconfig.enable_encryption = pt.get("encryption", 0); + auto zmqconfig = setup_zmq_input(pt, subchanuid); DabInputZmqAAC* inzmq = new DabInputZmqAAC(subchanuid, zmqconfig); @@ -723,8 +717,8 @@ void setup_subchannel_from_ptree(DabSubchannel* subchan, rcs.enrol(inzmq); subchan->input = inzmq; - if (proto == "epmg") { - etiLog.level(warn) << "Using untested epmg:// zeromq input"; + if (proto == "epgm") { + etiLog.level(warn) << "Using untested epgm:// zeromq input"; } else if (proto == "ipc") { etiLog.level(warn) << "Using untested ipc:// zeromq input"; -- cgit v1.2.3 From 32bdfb274ec20318dd7d45fb62cd6e51323453f7 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 28 Oct 2016 23:44:15 +0200 Subject: Replace NULL by nullptr --- src/ConfigParser.cpp | 4 ++-- src/DabMultiplexer.cpp | 6 +++--- src/DabMux.cpp | 4 ++-- src/Dmb.cpp | 10 +++++----- src/InetAddress.cpp | 4 ++-- src/ManagementServer.cpp | 2 +- src/ReedSolomon.cpp | 6 +++--- src/dabInputDabplusFifo.cpp | 4 ++-- src/dabInputDabplusFile.cpp | 10 +++++----- src/dabInputDmbFile.cpp | 14 +++++++------- src/dabInputEnhancedPacketFile.cpp | 4 ++-- src/dabInputFifo.cpp | 20 ++++++++++---------- src/dabInputFile.cpp | 8 ++++---- src/dabInputMpegFile.cpp | 4 ++-- src/dabInputPacketFile.cpp | 12 ++++++------ src/dabInputRawFifo.cpp | 10 +++++----- src/dabInputRawFile.cpp | 4 ++-- src/dabInputZmq.cpp | 2 +- src/utils.cpp | 4 ++-- 19 files changed, 66 insertions(+), 66 deletions(-) (limited to 'src/ConfigParser.cpp') diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 747fa39..93e6068 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -117,10 +117,10 @@ static int hexparse(std::string input) { int value; if (input.find("0x") == 0) { - value = strtoll(input.c_str() + 2, NULL, 16); + value = strtoll(input.c_str() + 2, nullptr, 16); } else { - value = strtoll(input.c_str(), NULL, 10); + value = strtoll(input.c_str(), nullptr, 10); } if (errno == ERANGE) { diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp index 90d3d02..c789763 100644 --- a/src/DabMultiplexer.cpp +++ b/src/DabMultiplexer.cpp @@ -162,7 +162,7 @@ void DabMultiplexer::prepare() * Ideally, we must be able to restart transmission s.t. the receiver * synchronisation is preserved. */ - gettimeofday(&mnsc_time, NULL); + gettimeofday(&mnsc_time, nullptr); #if HAVE_OUTPUT_EDI edi_time = chrono::system_clock::now(); @@ -212,7 +212,7 @@ void DabMultiplexer::prepare_subchannels() void DabMultiplexer::prepare_services_components() { set ids; - dabProtection* protection = NULL; + dabProtection* protection = nullptr; vector::iterator component; vector::iterator subchannel; @@ -301,7 +301,7 @@ void DabMultiplexer::prepare_services_components() void DabMultiplexer::prepare_data_inputs() { - dabProtection* protection = NULL; + dabProtection* protection = nullptr; vector::iterator subchannel; // Prepare and check the data inputs diff --git a/src/DabMux.cpp b/src/DabMux.cpp index aefa701..c962818 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -189,7 +189,7 @@ int main(int argc, char *argv[]) const int sigs[] = {SIGHUP, SIGQUIT, SIGINT, SIGTERM}; for (int i = 0; i < 4; i++) { - if (sigaction(sigs[i], &sa, NULL) == -1) { + if (sigaction(sigs[i], &sa, nullptr) == -1) { perror("sigaction"); return EXIT_FAILURE; } @@ -399,7 +399,7 @@ int main(int argc, char *argv[]) throw MuxInitException(); } - if (output == NULL) { + if (output == nullptr) { etiLog.level(error) << "Unable to init output " << uri; diff --git a/src/Dmb.cpp b/src/Dmb.cpp index e168b63..92688ea 100644 --- a/src/Dmb.cpp +++ b/src/Dmb.cpp @@ -45,7 +45,7 @@ Dmb::Dmb(bool reverse) : interleaver(12, 17), encoder(204, 188) { - buffer = NULL; + buffer = nullptr; bufferSize = 0; setReverse(reverse); } @@ -53,7 +53,7 @@ encoder(204, 188) Dmb::~Dmb() { - if (buffer != NULL) { + if (buffer != nullptr) { delete[] buffer; } } @@ -93,7 +93,7 @@ int Dmb::encode( char* output = reinterpret_cast(dataOut); if (bufferSize < sizeIn + 204) { - if (buffer != NULL) { + if (buffer != nullptr) { delete[] buffer; } unsigned char* oldBuffer = buffer; @@ -263,9 +263,9 @@ int Dmb::sync(void* dataIn, unsigned long sizeIn) char* sync = input; unsigned long size = sizeIn; - while (sync != NULL) { + while (sync != nullptr) { sync = (char*)memchr(sync, 0x47, size); - if (sync != NULL) { + if (sync != nullptr) { int offset = sync - input; if (offset % 12 != 0) { offset = ((offset / 12) * 12) + 12; diff --git a/src/InetAddress.cpp b/src/InetAddress.cpp index 90cdd06..d92e1b9 100644 --- a/src/InetAddress.cpp +++ b/src/InetAddress.cpp @@ -44,8 +44,8 @@ int inetErrNo = 0; -const char *inetErrMsg = NULL; -const char *inetErrDesc = NULL; +const char *inetErrMsg = nullptr; +const char *inetErrDesc = nullptr; /** diff --git a/src/ManagementServer.cpp b/src/ManagementServer.cpp index dd4da89..f946fd0 100644 --- a/src/ManagementServer.cpp +++ b/src/ManagementServer.cpp @@ -343,7 +343,7 @@ input_state_t InputStat::determineState(void) { boost::mutex::scoped_lock lock(m_mutex); - time_t now = time(NULL); + time_t now = time(nullptr); input_state_t state; /* if the last event was more that INPUT_COUNTER_RESET_TIME diff --git a/src/ReedSolomon.cpp b/src/ReedSolomon.cpp index 69e1191..7508747 100644 --- a/src/ReedSolomon.cpp +++ b/src/ReedSolomon.cpp @@ -47,7 +47,7 @@ ReedSolomon::ReedSolomon(int N, int K, bool reverse, int gfpoly, int firstRoot, rsData = init_rs_char(symsize, gfpoly, firstRoot, primElem, nroots, pad); - if (rsData == NULL) { + if (rsData == nullptr) { std::stringstream ss; ss << "Invalid Reed-Solomon parameters! " << "N=" << N << " ; K=" << K << " ; pad=" << pad; @@ -79,7 +79,7 @@ int ReedSolomon::encode(void* data, void* fec, unsigned long size) memcpy(buffer, input, myK); memcpy(&buffer[myK], output, myN - myK); - ret = decode_rs_char(rsData, buffer, NULL, 0); + ret = decode_rs_char(rsData, buffer, nullptr, 0); if ((ret != 0) && (ret != -1)) { memcpy(input, buffer, myK); memcpy(output, &buffer[myK], myN - myK); @@ -100,7 +100,7 @@ int ReedSolomon::encode(void* data, unsigned long size) int ret = 0; if (reverse) { - ret = decode_rs_char(rsData, input, NULL, 0); + ret = decode_rs_char(rsData, input, nullptr, 0); } else { encode_rs_char(rsData, input, &input[myK]); } diff --git a/src/dabInputDabplusFifo.cpp b/src/dabInputDabplusFifo.cpp index 81f373b..94aec13 100644 --- a/src/dabInputDabplusFifo.cpp +++ b/src/dabInputDabplusFifo.cpp @@ -68,7 +68,7 @@ int dabInputDabplusFifoInit(void** args) dabInputDabplusFifoData* data = new dabInputDabplusFifoData; dabInputFifoInit(&data->fifoData); - data->buffer = NULL; + data->buffer = nullptr; data->bufferSize = 0; data->bufferIndex = 0; data->bufferOffset = 0; @@ -100,7 +100,7 @@ int dabInputDabplusFifoRead(void* args, void* buffer, int size) dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; if (data->bufferSize != (size_t)size * 5) { - if (data->buffer != NULL) { + if (data->buffer != nullptr) { delete[] data->buffer; } data->buffer = new uint8_t[size * 5]; diff --git a/src/dabInputDabplusFile.cpp b/src/dabInputDabplusFile.cpp index 396a376..64b7f07 100644 --- a/src/dabInputDabplusFile.cpp +++ b/src/dabInputDabplusFile.cpp @@ -40,8 +40,8 @@ struct dabInputOperations dabInputDabplusFileOperations = { dabInputDabplusFileOpen, dabInputSetbuf, dabInputDabplusFileRead, - NULL, - NULL, + nullptr, + nullptr, dabInputDabplusFileReadFrame, dabInputSetbitrate, dabInputDabplusFileClose, @@ -54,7 +54,7 @@ int dabInputDabplusFileInit(void** args) { dabInputDabplusFileData* data = new dabInputDabplusFileData; data->file = -1; - data->buffer = NULL; + data->buffer = nullptr; data->bufferSize = 0; data->bufferIndex = 0; @@ -80,7 +80,7 @@ int dabInputDabplusFileRead(void* args, void* buffer, int size) { dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; if (data->bufferSize != (size_t)size * 5) { - if (data->buffer == NULL) { + if (data->buffer == nullptr) { delete[] data->buffer; } data->buffer = new uint8_t[size * 5]; @@ -158,7 +158,7 @@ int dabInputDabplusFileClose(void* args) int dabInputDabplusFileClean(void** args) { dabInputDabplusFileData* data = (dabInputDabplusFileData*)*args; - if (data->buffer != NULL) { + if (data->buffer != nullptr) { delete[] data->buffer; } delete data; diff --git a/src/dabInputDmbFile.cpp b/src/dabInputDmbFile.cpp index 423d644..17bd72d 100644 --- a/src/dabInputDmbFile.cpp +++ b/src/dabInputDmbFile.cpp @@ -42,14 +42,14 @@ struct dabInputOperations dabInputDmbFileOperations = { dabInputDmbFileInit, dabInputDmbFileOpen, dabInputSetbuf, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, dabInputDmbFileRead, dabInputSetbitrate, dabInputDmbFileClose, dabInputDmbFileClean, - NULL + nullptr }; @@ -58,7 +58,7 @@ int dabInputDmbFileInit(void** args) dabInputDmbFileData* input = new dabInputDmbFileData; memset(&input->stats, 0, sizeof(input->stats)); input->stats.id = dabInputFifoData::nb++; - input->file = NULL; + input->file = nullptr; input->bufferLength = 0; input->dmb = new Dmb(); *args = input; @@ -73,7 +73,7 @@ int dabInputDmbFileOpen(void* args, const char* inputName) dabInputDmbFileData* input = (dabInputDmbFileData*)args; input->file = fopen(inputName, "r"); - if (input->file == NULL) { + if (input->file == nullptr) { perror(inputName); returnCode = -1; } @@ -138,7 +138,7 @@ int dabInputDmbFileClose(void* args) { dabInputDmbFileData* input = (dabInputDmbFileData*)args; - if (input->file != NULL) { + if (input->file != nullptr) { if (fclose(input->file)) { perror(""); return -1; diff --git a/src/dabInputEnhancedPacketFile.cpp b/src/dabInputEnhancedPacketFile.cpp index 1b5c8bc..3b12e0b 100644 --- a/src/dabInputEnhancedPacketFile.cpp +++ b/src/dabInputEnhancedPacketFile.cpp @@ -29,8 +29,8 @@ struct dabInputOperations dabInputEnhancedPacketFileOperations = { dabInputFileOpen, dabInputSetbuf, dabInputFileRead, - NULL, - NULL, + nullptr, + nullptr, dabInputPacketFileRead, dabInputSetbitrate, dabInputFileClose, diff --git a/src/dabInputFifo.cpp b/src/dabInputFifo.cpp index 3e35c20..7e07731 100644 --- a/src/dabInputFifo.cpp +++ b/src/dabInputFifo.cpp @@ -61,9 +61,9 @@ int dabInputFifoInit(void** args) data->curSize = 0; data->head = 0; data->tail = 0; - data->buffer = NULL; - data->packetData = NULL; - data->enhancedPacketData = NULL; + data->buffer = nullptr; + data->packetData = nullptr; + data->enhancedPacketData = nullptr; data->packetLength = 0; data->enhancedPacketLength = 0; data->enhancedPacketWaiting = 0; @@ -145,7 +145,7 @@ int dabInputFifoOpen(void* args, const char* filename) return -1; } #else - if (pthread_create(&data->thread, NULL, dabInputFifoThread, data)) { + if (pthread_create(&data->thread, nullptr, dabInputFifoThread, data)) { perror("Can't create FIFO child"); return -1; } @@ -166,7 +166,7 @@ int dabInputFifoSetbuf(void* args, int size) sem_wait(&data->semBuffer); #endif } - if (data->buffer != NULL) { + if (data->buffer != nullptr) { delete data->buffer; } if (size == 0) { @@ -367,7 +367,7 @@ int dabInputFifoClean(void** args) } #else if (data->thread != (pthread_t)NULL) { - if (pthread_join(data->thread, NULL)) { + if (pthread_join(data->thread, nullptr)) { etiLog.log(debug, "ERROR: FIFO child thread had not exit normally\n"); } } @@ -382,12 +382,12 @@ int dabInputFifoClean(void** args) sem_destroy(&data->semFull); sem_destroy(&data->semBuffer); #endif - if (data->packetData != NULL) { + if (data->packetData != nullptr) { delete[] data->packetData; } - if (data->enhancedPacketData != NULL) { + if (data->enhancedPacketData != nullptr) { for (int i = 0; i < 12; ++i) { - if (data->enhancedPacketData[i] != NULL) { + if (data->enhancedPacketData[i] != nullptr) { delete[] data->enhancedPacketData[i]; } } @@ -505,7 +505,7 @@ void* dabInputFifoThread(void* args) sem_post(&data->semBuffer); #endif } - return NULL; + return nullptr; } diff --git a/src/dabInputFile.cpp b/src/dabInputFile.cpp index 30ab37d..2847caa 100644 --- a/src/dabInputFile.cpp +++ b/src/dabInputFile.cpp @@ -38,7 +38,7 @@ int dabInputFileInit(void** args) data->parity = false; data->packetLength = 0; data->packetData = new unsigned char[96]; - data->enhancedPacketData = NULL; + data->enhancedPacketData = nullptr; data->enhancedPacketLength = 0; data->enhancedPacketWaiting = 0; @@ -79,12 +79,12 @@ int dabInputFileClose(void* args) int dabInputFileClean(void** args) { dabInputFileData* data = (dabInputFileData*)*args; - if (data->packetData != NULL) { + if (data->packetData != nullptr) { delete[] data->packetData; } - if (data->enhancedPacketData != NULL) { + if (data->enhancedPacketData != nullptr) { for (int i = 0; i < 12; ++i) { - if (data->enhancedPacketData[i] != NULL) { + if (data->enhancedPacketData[i] != nullptr) { delete[] data->enhancedPacketData[i]; } } diff --git a/src/dabInputMpegFile.cpp b/src/dabInputMpegFile.cpp index 724ad54..804ea29 100644 --- a/src/dabInputMpegFile.cpp +++ b/src/dabInputMpegFile.cpp @@ -37,8 +37,8 @@ struct dabInputOperations dabInputMpegFileOperations = { dabInputFileOpen, dabInputSetbuf, dabInputFileRead, - NULL, - NULL, + nullptr, + nullptr, dabInputMpegFileRead, dabInputMpegSetbitrate, dabInputFileClose, diff --git a/src/dabInputPacketFile.cpp b/src/dabInputPacketFile.cpp index 3ff4e56..867d9fc 100644 --- a/src/dabInputPacketFile.cpp +++ b/src/dabInputPacketFile.cpp @@ -59,8 +59,8 @@ struct dabInputOperations dabInputPacketFileOperations = { dabInputFileOpen, dabInputSetbuf, dabInputFileRead, - NULL, - NULL, + nullptr, + nullptr, dabInputPacketFileRead, dabInputSetbitrate, dabInputFileClose, @@ -114,7 +114,7 @@ int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, dataBuffer[22] = 0x60; dataBuffer[23] = 0x4b; length = 24; - } else if (data->enhancedPacketData != NULL) { + } else if (data->enhancedPacketData != nullptr) { if (data->enhancedPacketLength + data->packetLength > (12 * 188)) { memset(dataBuffer, 0, 22); @@ -131,7 +131,7 @@ int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, length = data->packetLength; data->packetLength = 0; } - if (data->enhancedPacketData != NULL) { + if (data->enhancedPacketData != nullptr) { indexCol = data->enhancedPacketLength / 12; indexRow = data->enhancedPacketLength % 12; // TODO Check if always 0 for (int j = 0; j < length; ++j) { @@ -179,7 +179,7 @@ int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, data->packetLength = length; continue; } - if (data->enhancedPacketData != NULL) { + if (data->enhancedPacketData != nullptr) { if (data->enhancedPacketLength + length > (12 * 188)) { memcpy(data->packetData, header, 3); ops->read(args, &data->packetData[3], length - 3); @@ -203,7 +203,7 @@ int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, "read %i out of %i bytes\n", nbBytes, length - 3); break; } - if (data->enhancedPacketData != NULL) { + if (data->enhancedPacketData != nullptr) { indexCol = data->enhancedPacketLength / 12; indexRow = data->enhancedPacketLength % 12; // TODO Check if always 0 for (int j = 0; j < length; ++j) { diff --git a/src/dabInputRawFifo.cpp b/src/dabInputRawFifo.cpp index 0da9727..cc6268b 100644 --- a/src/dabInputRawFifo.cpp +++ b/src/dabInputRawFifo.cpp @@ -40,8 +40,8 @@ struct dabInputOperations dabInputRawFifoOperations = { dabInputRawFifoOpen, dabInputRawFifoSetbuf, dabInputRawFifoRead, - NULL, - NULL, + nullptr, + nullptr, dabInputRawFifoReadFrame, dabInputSetbitrate, dabInputRawFifoClose, @@ -54,7 +54,7 @@ int dabInputRawFifoInit(void** args) { dabInputRawFifoData* data = new dabInputRawFifoData; data->file = -1; - data->buffer = NULL; + data->buffer = nullptr; data->bufferSize = 0; data->bufferOffset = 0; @@ -97,7 +97,7 @@ int dabInputRawFifoSetbuf(void* args, int size) } if (data->bufferSize != (size_t)size) { - if (data->buffer != NULL) { + if (data->buffer != nullptr) { delete[] data->buffer; } data->buffer = new uint8_t[size]; @@ -174,7 +174,7 @@ int dabInputRawFifoClose(void* args) int dabInputRawFifoClean(void** args) { dabInputRawFifoData* data = (dabInputRawFifoData*)*args; - if (data->buffer != NULL) { + if (data->buffer != nullptr) { delete[] data->buffer; } delete data; diff --git a/src/dabInputRawFile.cpp b/src/dabInputRawFile.cpp index 88ffa2a..be33a45 100644 --- a/src/dabInputRawFile.cpp +++ b/src/dabInputRawFile.cpp @@ -32,8 +32,8 @@ struct dabInputOperations dabInputRawFileOperations = { dabInputFileOpen, dabInputSetbuf, dabInputFileRead, - NULL, - NULL, + nullptr, + nullptr, dabInputRawFileRead, dabInputSetbitrate, dabInputFileClose, diff --git a/src/dabInputZmq.cpp b/src/dabInputZmq.cpp index 70fd0c8..1591939 100644 --- a/src/dabInputZmq.cpp +++ b/src/dabInputZmq.cpp @@ -213,7 +213,7 @@ void DabInputZmqBase::rebind() m_zmq_sock_bound_to = m_inputUri; try { - m_zmq_sock.setsockopt(ZMQ_SUBSCRIBE, NULL, 0); + m_zmq_sock.setsockopt(ZMQ_SUBSCRIBE, nullptr, 0); } catch (zmq::error_t& err) { std::ostringstream os; diff --git a/src/utils.cpp b/src/utils.cpp index 02fbc3f..c776b0b 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -38,7 +38,7 @@ static int dab_time_millis = 0; void update_dab_time() { if (dab_time_seconds == 0) { - dab_time_seconds = time(NULL); + dab_time_seconds = time(nullptr); } else { dab_time_millis+= 24; if (dab_time_millis >= 1000) { @@ -566,7 +566,7 @@ void printEnsemble(const shared_ptr ensemble) etiLog.log(info, " mode: %u", ensemble->mode); if (ensemble->lto_auto) { - time_t now = time(NULL); + time_t now = time(nullptr); struct tm* ltime = localtime(&now); time_t now2 = timegm(ltime); etiLog.log(info, " lto: %2.1f hours", 0.5 * (now2 - now) / 1800); -- cgit v1.2.3 From 471e7ee279d633a7b48e73ece42677574a74ad39 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 29 Oct 2016 00:08:42 +0200 Subject: Modernize a few bits and pieces --- src/ConfigParser.cpp | 4 ++-- src/DabMultiplexer.cpp | 2 +- src/DabMux.cpp | 4 ++-- src/ManagementServer.cpp | 2 +- src/MuxElements.cpp | 10 +++++----- src/dabInputZmq.cpp | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/ConfigParser.cpp') diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 93e6068..0ba1d78 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -393,7 +393,7 @@ void parse_ptree( ptree pt_subchans = pt.get_child("subchannels"); for (ptree::iterator it = pt_subchans.begin(); it != pt_subchans.end(); ++it) { string subchanuid = it->first; - DabSubchannel* subchan = new DabSubchannel(subchanuid); + auto subchan = new DabSubchannel(subchanuid); ensemble->subchannels.push_back(subchan); @@ -466,7 +466,7 @@ void parse_ptree( int packet_datagroup = pt_comp.get("datagroup", false); uint8_t component_type = hexparse(pt_comp.get("type", "0")); - DabComponent* component = new DabComponent(componentuid); + auto component = new DabComponent(componentuid); component->serviceId = service->id; component->subchId = subchannel->id; diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp index c789763..4a3234e 100644 --- a/src/DabMultiplexer.cpp +++ b/src/DabMultiplexer.cpp @@ -773,7 +773,7 @@ void DabMultiplexer::mux_frame(std::vector >& outputs currentFrame++; } -void DabMultiplexer::print_info(void) +void DabMultiplexer::print_info() { // Print settings before starting etiLog.log(info, "--- Multiplex configuration ---"); diff --git a/src/DabMux.cpp b/src/DabMux.cpp index c962818..046b149 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -188,8 +188,8 @@ int main(int argc, char *argv[]) sa.sa_handler = &signalHandler; const int sigs[] = {SIGHUP, SIGQUIT, SIGINT, SIGTERM}; - for (int i = 0; i < 4; i++) { - if (sigaction(sigs[i], &sa, nullptr) == -1) { + for (int sig : sigs) { + if (sigaction(sig, &sa, nullptr) == -1) { perror("sigaction"); return EXIT_FAILURE; } diff --git a/src/ManagementServer.cpp b/src/ManagementServer.cpp index f946fd0..c44738a 100644 --- a/src/ManagementServer.cpp +++ b/src/ManagementServer.cpp @@ -339,7 +339,7 @@ std::string InputStat::encodeStateJSON() return ss.str(); } -input_state_t InputStat::determineState(void) +input_state_t InputStat::determineState() { boost::mutex::scoped_lock lock(m_mutex); diff --git a/src/MuxElements.cpp b/src/MuxElements.cpp index 773ec17..db59078 100644 --- a/src/MuxElements.cpp +++ b/src/MuxElements.cpp @@ -71,7 +71,7 @@ std::string AnnouncementCluster::tostring() const return ss.str(); } -bool AnnouncementCluster::is_active(void) +bool AnnouncementCluster::is_active() { if (m_deferred_start_time) { @@ -415,7 +415,7 @@ const string DabComponent::get_parameter(const string& parameter) const subchannel_type_t DabService::getType(std::shared_ptr ensemble) const { vector::iterator subchannel; - vector::iterator component = + auto component = getComponent(ensemble->components, id); if (component == ensemble->components.end()) { throw std::runtime_error("No component found for service"); @@ -647,17 +647,17 @@ unsigned short DabSubchannel::getSizeCu() const return 0; } -unsigned short DabSubchannel::getSizeByte(void) const +unsigned short DabSubchannel::getSizeByte() const { return bitrate * 3; } -unsigned short DabSubchannel::getSizeWord(void) const +unsigned short DabSubchannel::getSizeWord() const { return (bitrate * 3) >> 2; } -unsigned short DabSubchannel::getSizeDWord(void) const +unsigned short DabSubchannel::getSizeDWord() const { return (bitrate * 3) >> 3; } diff --git a/src/dabInputZmq.cpp b/src/dabInputZmq.cpp index 1591939..790a961 100644 --- a/src/dabInputZmq.cpp +++ b/src/dabInputZmq.cpp @@ -387,7 +387,7 @@ int DabInputZmqMPEG::readFromSocket(size_t framesize) } else if (m_enable_input) { // copy the input frame blockwise into the frame_buffer - uint8_t* framedata = new uint8_t[framesize]; + auto framedata = new uint8_t[framesize]; memcpy(framedata, data, framesize); m_frame_buffer.push_back(framedata); } @@ -467,7 +467,7 @@ int DabInputZmqAAC::readFromSocket(size_t framesize) for (uint8_t* framestart = data; framestart < &data[5*framesize]; framestart += framesize) { - uint8_t* audioframe = new uint8_t[framesize]; + auto audioframe = new uint8_t[framesize]; memcpy(audioframe, framestart, framesize); m_frame_buffer.push_back(audioframe); } -- cgit v1.2.3 From e7ad2e1fab9c51189fdc8b4f2d81f625da9dd422 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sat, 29 Oct 2016 22:09:13 +0200 Subject: Modernise PRBS generator and remove code for cmd line parser --- configure.ac | 6 - src/ConfigParser.cpp | 14 +- src/DabMux.cpp | 10 - src/Makefile.am | 5 +- src/ParserCmdline.cpp | 771 -------------------------------------------------- src/ParserCmdline.h | 54 ---- src/dabInputFifo.cpp | 5 + src/dabInputFifo.h | 13 +- src/dabInputPrbs.cpp | 122 +++----- src/dabInputPrbs.h | 48 ++-- src/prbs.c | 140 --------- src/prbs.cpp | 144 ++++++++++ src/prbs.h | 74 ++--- src/utils.cpp | 160 ----------- 14 files changed, 265 insertions(+), 1301 deletions(-) delete mode 100644 src/ParserCmdline.cpp delete mode 100644 src/ParserCmdline.h delete mode 100644 src/prbs.c create mode 100644 src/prbs.cpp (limited to 'src/ConfigParser.cpp') diff --git a/configure.ac b/configure.ac index 09ca8c1..6297365 100644 --- a/configure.ac +++ b/configure.ac @@ -115,12 +115,6 @@ AC_ARG_ENABLE([input_file], AS_IF([test "x$enable_input_file" = "xyes"], [AC_DEFINE(HAVE_INPUT_FILE, [1], [Define if FILE input is enabled])]) -# PRBS -AC_ARG_ENABLE([input_prbs], - [AS_HELP_STRING([--enable-input-prbs], [Enable PRBS input])], - [], [enable_input_prbs=no]) -AS_IF([test "x$enable_input_prbs" = "xyes"], - [AC_DEFINE(HAVE_INPUT_PRBS, [1], [Define if PRBS input is enabled])]) # TEST AC_ARG_ENABLE([input_test], [AS_HELP_STRING([--enable-input-test], [Enable TEST input])], diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 0ba1d78..8e5fed1 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -3,7 +3,7 @@ 2011, 2012 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2014, 2015 + Copyright (C) 2016 Matthias P. Braendli, matthias.braendli@mpb.li http://www.opendigitalradio.org @@ -742,6 +742,12 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan, #endif // defined(HAVE_INPUT_UDP) #endif // defined(HAVE_FORMAT_BRIDGE) } + } else if (type == "data" and proto == "prbs") { + input_is_old_style = false; + + subchan->input = new DabInputPrbs(); + subchan->type = subchannel_type_t::DataDmb; + subchan->bitrate = DEFAULT_DATA_BITRATE; } else if (type == "data") { // TODO default proto should be udp:// if (0) { @@ -749,10 +755,6 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan, } else if (proto == "udp") { operations = dabInputUdpOperations; #endif -#if defined(HAVE_INPUT_PRBS) && defined(HAVE_FORMAT_RAW) - } else if (proto == "prbs") { - operations = dabInputPrbsOperations; -#endif #if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_RAW) } else if (proto == "file") { operations = dabInputRawFileOperations; @@ -761,7 +763,7 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan, operations = dabInputRawFifoOperations; } else { stringstream ss; - ss << "Subchannel with uid " << subchanuid << + ss << "Subchannel with uid " << subchanuid << ": Invalid protocol for data input (" << proto << ")" << endl; throw runtime_error(ss.str()); diff --git a/src/DabMux.cpp b/src/DabMux.cpp index 046b149..f72ea8d 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -125,7 +125,6 @@ typedef DWORD32 uint32_t; #include "DabMux.h" #include "MuxElements.h" #include "utils.h" -#include "ParserCmdline.h" #include "ConfigParser.h" #include "ManagementServer.h" #include "Log.h" @@ -252,18 +251,9 @@ int main(int argc, char *argv[]) throw MuxInitException(e.what()); } } -#if ENABLE_CMDLINE_OPTIONS - else { - if (!parse_cmdline(argv, argc, outputs, ensemble, &enableTist, &FICL, - &factumAnalyzer, &limit)) { - throw MuxInitException(); - } - } -#else else { throw MuxInitException("No configuration file specified"); } -#endif int mgmtserverport = pt.get("general.managementport", pt.get("general.statsserverport", 0) ); diff --git a/src/Makefile.am b/src/Makefile.am index ef43a97..dfcdb12 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ # (Communications Research Center Canada) # Pascal Charest # -# Copyright (C) 2014, Matthias P. Braendli, http://mpb.li +# Copyright (C) 2016, Matthias P. Braendli, http://opendigitalradio.org # # This file is part of ODR-DabMux. @@ -87,7 +87,6 @@ odr_dabmux_SOURCES =DabMux.cpp DabMux.h \ Log.h Log.cpp \ ManagementServer.h ManagementServer.cpp \ MuxElements.cpp MuxElements.h \ - ParserCmdline.cpp ParserCmdline.h \ PcDebug.h \ ReedSolomon.h ReedSolomon.cpp \ RemoteControl.cpp RemoteControl.h \ @@ -114,7 +113,7 @@ odr_dabmux_SOURCES =DabMux.cpp DabMux.h \ fig/FIGCarousel.cpp fig/FIGCarousel.h \ fig/TransitionHandler.h \ mpeg.h mpeg.c \ - prbs.h prbs.c \ + prbs.h prbs.cpp \ utils.cpp utils.h \ zmq.hpp \ fec/char.h fec/rs-common.h \ diff --git a/src/ParserCmdline.cpp b/src/ParserCmdline.cpp deleted file mode 100644 index 8ce6f7a..0000000 --- a/src/ParserCmdline.cpp +++ /dev/null @@ -1,771 +0,0 @@ -/* - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, - 2011, 2012 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - - Includes modifications - 2012, Matthias P. Braendli, matthias.braendli@mpb.li - - The command-line parser reads the parameters given on the command - line, and builds an ensemble. - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux 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. - - ODR-DabMux 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 ODR-DabMux. If not, see . -*/ -#include "ParserCmdline.h" - -#if ENABLE_CMDLINE_OPTIONS - -#include -#include -#include -#include "dabOutput/dabOutput.h" -#include "dabInput.h" -#include "utils.h" -#include "dabInputFile.h" -#include "dabInputFifo.h" -#include "dabInputMpegFile.h" -#include "dabInputMpegFifo.h" -#include "dabInputDabplusFile.h" -#include "dabInputDabplusFifo.h" -#include "dabInputPacketFile.h" -#include "dabInputEnhancedPacketFile.h" -#include "dabInputEnhancedFifo.h" -#include "dabInputUdp.h" -#include "dabInputBridgeUdp.h" -#include "dabInputSlip.h" -#include "dabInputTest.h" -#include "dabInputPrbs.h" -#include "dabInputRawFile.h" -#include "dabInputRawFifo.h" -#include "dabInputDmbFile.h" -#include "dabInputDmbUdp.h" -#include "DabMux.h" - - -#ifdef _WIN32 -# pragma warning ( disable : 4103 ) -# include "Eti.h" -# pragma warning ( default : 4103 ) -#else -# include "Eti.h" -#endif - - -#ifdef _WIN32 -# include -# include -# include -# include -# include // For types... -typedef u_char uint8_t; -typedef WORD uint16_t; -typedef DWORD32 uint32_t; - -# ifndef __MINGW32__ -# include "xgetopt.h" -# endif -# define read _read -# define snprintf _snprintf -# define sleep(a) Sleep((a) * 1000) -#else -# include -# include -# include -# include -# include -#endif - -using namespace std; - -bool parse_cmdline(char **argv, - int argc, - vector &outputs, - dabEnsemble* ensemble, - bool* enableTist, - unsigned* FICL, - bool* factumAnalyzer, - unsigned long* limit - ) -{ - vector::iterator output; - vector::iterator subchannel = ensemble->subchannels.end(); - vector::iterator component = ensemble->components.end(); - vector::iterator service = ensemble->services.end(); - dabProtection* protection = NULL; - - // Yes, this is ugly, but it suppresses warnings - dabInputOperations operations = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL - }; - - // Default ensemble parameters: - ensemble->lto = 0; - ensemble->lto_auto = true; // Transmit local time by default - ensemble->mode = 1; // Default TM=1 - - // Parse command line - int scids_temp = 0; - - const char* error_at = ""; - int success; - - char* progName = strrchr(argv[0], '/'); - if (progName == NULL) { - progName = argv[0]; - } else { - ++progName; - } - - while (1) { - int c = getopt(argc, argv, - "A:B:CD:E:F:L:M:O:P:STVa:b:c:de:f:g:hi:kl:m:n:op:rst:y:z"); - if (c == -1) { - break; - } - switch (c) { - case 'O': - char* proto; - - proto = strstr(optarg, "://"); - if (proto == NULL) { - etiLog.log(error, - "No protocol defined for output\n"); - goto EXIT; - } else { - *proto = 0; // terminate optarg - outputs.push_back(new dabOutput(optarg, proto + 3)); - output = outputs.end() - 1; - } - - subchannel = ensemble->subchannels.end(); - protection = NULL; - component = ensemble->components.end(); - service = ensemble->services.end(); - break; - case 'S': - ensemble->services.push_back(new DabService("?")); - - subchannel = ensemble->subchannels.end(); - protection = NULL; - component = ensemble->components.end(); - service = ensemble->services.end() - 1; - output = outputs.end(); - - (*service)->label.setLabel("Service", "Serv"); - (*service)->id = DEFAULT_SERVICE_ID + ensemble->services.size(); - (*service)->pty = 0; - (*service)->language = 0; - scids_temp = 0; - - break; - case 'C': - if (service == ensemble->services.end()) { - etiLog.log(error, "You must define a service" - " before using option -%c\n", c); - printUsage(progName); - goto EXIT; - } - - ensemble->components.push_back(new DabComponent("?")); - - component = ensemble->components.end() - 1; - subchannel = ensemble->subchannels.end(); - protection = NULL; - output = outputs.end(); - - (*component)->label.setLabel("Component", "Comp"); - (*component)->serviceId = (*service)->id; - (*component)->subchId = (*(ensemble->subchannels.end() - 1))->id; - (*component)->SCIdS = scids_temp++; - break; - case 'A': - case 'B': - case 'D': - case 'E': - case 'F': - case 'M': - case 'P': - case 'T': - if (optarg == NULL && c != 'T') { - etiLog.log(error, - "Missing parameter for option -%c\n", c); - printUsage(progName); - goto EXIT; - } - - ensemble->subchannels.push_back(new DabSubchannel); - - subchannel = ensemble->subchannels.end() - 1; - protection = &(*subchannel)->protection; - component = ensemble->components.end(); - service = ensemble->services.end(); - output = outputs.end(); - - if (c != 'T') { - (*subchannel)->inputName = optarg; - } else { - (*subchannel)->inputName = NULL; - } - if (0) { -#if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_MPEG) - } else if (c == 'A') { - (*subchannel)->inputProto = "file"; - (*subchannel)->type = Audio; - (*subchannel)->bitrate = 0; - operations = dabInputMpegFileOperations; -#endif // defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_MPEG) -#if defined(HAVE_FORMAT_DABPLUS) - } else if (c == 'F') { - (*subchannel)->type = Audio; - (*subchannel)->bitrate = 32; - - char* proto; - - proto = strstr(optarg, "://"); - if (proto == NULL) { - (*subchannel)->inputProto = "file"; - } else { - (*subchannel)->inputProto = optarg; - (*subchannel)->inputName = proto + 3; - *proto = 0; - } - - if (0) { -#if defined(HAVE_INPUT_FILE) - } else if (strcmp((*subchannel)->inputProto, "file") == 0) { - operations = dabInputDabplusFileOperations; -#endif // defined(HAVE_INPUT_FILE) - } else { - etiLog.log(error, - "Invalid protocol for DAB+ input (%s)\n", - (*subchannel)->inputProto); - printUsage(progName); - goto EXIT; - } -#endif // defined(HAVE_FORMAT_DABPLUS) - } else if (c == 'B') { - char* proto; - - proto = strstr(optarg, "://"); - if (proto == NULL) { - (*subchannel)->inputProto = "udp"; - } else { - (*subchannel)->inputProto = optarg; - (*subchannel)->inputName = proto + 3; - *proto = 0; - } - if (0) { -#if defined(HAVE_FORMAT_BRIDGE) -#if defined(HAVE_INPUT_UDP) - } else if (strcmp((*subchannel)->inputProto, "udp") == 0) { - operations = dabInputBridgeUdpOperations; -#endif // defined(HAVE_INPUT_UDP) -#endif // defined(HAVE_FORMAT_BRIDGE) - } - } else if (c == 'D') { - char* proto; - - proto = strstr(optarg, "://"); - if (proto == NULL) { - (*subchannel)->inputProto = "udp"; - } else { - (*subchannel)->inputProto = optarg; - (*subchannel)->inputName = proto + 3; - *proto = 0; - } - if (0) { -#if defined(HAVE_INPUT_UDP) - } else if (strcmp((*subchannel)->inputProto, "udp") == 0) { - operations = dabInputUdpOperations; -#endif -#if defined(HAVE_INPUT_PRBS) && defined(HAVE_FORMAT_RAW) - } else if (strcmp((*subchannel)->inputProto, "prbs") == 0) { - operations = dabInputPrbsOperations; -#endif -#if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_RAW) - } else if (strcmp((*subchannel)->inputProto, "file") == 0) { - operations = dabInputRawFileOperations; -#endif - } else if (strcmp((*subchannel)->inputProto, "fifo") == 0) { - operations = dabInputRawFifoOperations; - } else { - etiLog.log(error, - "Invalid protocol for data input (%s)\n", - (*subchannel)->inputProto); - printUsage(progName); - goto EXIT; - } - - (*subchannel)->type = DataDmb; - (*subchannel)->bitrate = DEFAULT_DATA_BITRATE; -#if defined(HAVE_INPUT_TEST) && defined(HAVE_FORMAT_RAW) - } else if (c == 'T') { - (*subchannel)->inputProto = "test"; - (*subchannel)->type = DataDmb; - (*subchannel)->bitrate = DEFAULT_DATA_BITRATE; - operations = dabInputTestOperations; -#endif // defined(HAVE_INPUT_TEST)) && defined(HAVE_FORMAT_RAW) -#ifdef HAVE_FORMAT_PACKET - } else if (c == 'P') { - (*subchannel)->inputProto = "file"; - (*subchannel)->type = Packet; - (*subchannel)->bitrate = DEFAULT_PACKET_BITRATE; -#ifdef HAVE_INPUT_FILE - operations = dabInputPacketFileOperations; -#elif defined(HAVE_INPUT_FIFO) - operations = dabInputFifoOperations; -#else -# pragma error("Must defined at least one packet input") -#endif // defined(HAVE_INPUT_FILE) -#ifdef HAVE_FORMAT_EPM - } else if (c == 'E') { - (*subchannel)->inputProto = "file"; - (*subchannel)->type = Packet; - (*subchannel)->bitrate = DEFAULT_PACKET_BITRATE; - operations = dabInputEnhancedPacketFileOperations; -#endif // defined(HAVE_FORMAT_EPM) -#endif // defined(HAVE_FORMAT_PACKET) -#ifdef HAVE_FORMAT_DMB - } else if (c == 'M') { - char* proto; - - proto = strstr(optarg, "://"); - if (proto == NULL) { - (*subchannel)->inputProto = "udp"; - } else { - (*subchannel)->inputProto = optarg; - (*subchannel)->inputName = proto + 3; - *proto = 0; - } - if (strcmp((*subchannel)->inputProto, "udp") == 0) { - operations = dabInputDmbUdpOperations; - } else if (strcmp((*subchannel)->inputProto, "file") == 0) { - operations = dabInputDmbFileOperations; - } else { - etiLog.log(error, - "Invalid protocol for DMB input (%s)\n", - (*subchannel)->inputProto); - printUsage(progName); - goto EXIT; - } - - (*subchannel)->type = DataDmb; - (*subchannel)->bitrate = DEFAULT_DATA_BITRATE; -#endif - } else { - etiLog.log(error, - "Service '%c' not yet coded!\n", c); - goto EXIT; - } - (*subchannel)->input = new DabInputCompatible(operations); - - for (int i = 0; i < 64; ++i) { // Find first free subchannel - subchannel = getSubchannel(ensemble->subchannels, i); - if (subchannel == ensemble->subchannels.end()) { - subchannel = ensemble->subchannels.end() - 1; - (*subchannel)->id = i; - break; - } - } - (*subchannel)->startAddress = 0; - - if (c == 'A') { - protection->form = UEP; - protection->level = 2; - protection->uep.tableIndex = 0; - } else { - protection->form = EEP; - protection->level = 2; - protection->eep.profile = EEP_A; - } - break; - case 'L': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -L\n"); - printUsage(progName); - goto EXIT; - } - if (service == ensemble->services.end()) { - ensemble->label.setLabel(optarg); - } else if (component != ensemble->components.end()) { - (*component)->label.setLabel(optarg); - } else { // Service - (*service)->label.setLabel(optarg); - } - break; - case 'V': - goto EXIT; - case 'l': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -l\n"); - printUsage(progName); - goto EXIT; - } - - if (service == ensemble->services.end()) { - success = ensemble->label.setLabel(ensemble->label.text(), optarg); - error_at = "Ensemble"; - } - else if (component != ensemble->components.end()) { - success = (*component)->label.setLabel(ensemble->label.text(), optarg); - error_at = "Component"; - } - else { - success = (*service)->label.setLabel(ensemble->label.text(), optarg); - error_at = "Service"; - } - - switch (success) - { - case 0: - break; - case -1: - etiLog.level(error) << error_at << " short label " << - optarg << " is not subset of label '" << - ensemble->label.text() << "'"; - goto EXIT; - case -2: - etiLog.level(error) << error_at << " short label " << - optarg << " is too long (max 8 characters)"; - goto EXIT; - case -3: - etiLog.level(error) << error_at << " label " << - ensemble->label.text() << " is too long (max 16 characters)"; - goto EXIT; - default: - etiLog.level(error) << error_at << " short label definition: program error !"; - abort(); - } - break; - case 'i': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -i\n"); - printUsage(progName); - goto EXIT; - } - if (component != ensemble->components.end()) { - (*component)->subchId = strtoul(optarg, NULL, 0); - } else if (subchannel != ensemble->subchannels.end()) { - (*subchannel)->id = strtoul(optarg, NULL, 0); - } else if (service != ensemble->services.end()) { - (*service)->id = strtoul(optarg, NULL, 0); - if ((*service)->id == 0) { - etiLog.log(error, - "Service id 0 is invalid\n"); - goto EXIT; - } - } else { - ensemble->id = strtoul(optarg, NULL, 0); - } - break; - case 'b': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -b\n"); - printUsage(progName); - goto EXIT; - } - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "You must define a subchannel first!\n"); - printUsage(progName); - goto EXIT; - } - (*subchannel)->bitrate = strtoul(optarg, NULL, 0); - if (((*subchannel)->bitrate & 0x7) != 0) { - (*subchannel)->bitrate += 8; - (*subchannel)->bitrate &= ~0x7; - etiLog.log(warn, - "bitrate must be multiple of 8 -> ceiling to %i\n", - (*subchannel)->bitrate); - } - break; - case 'c': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -c\n"); - printUsage(progName); - goto EXIT; - } - ensemble->ecc = strtoul(optarg, NULL, 0); - break; -#if defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE) - case 'k': - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "You must define a subchannel first!\n"); - printUsage(progName); - goto EXIT; - } - switch ((*subchannel)->type) { -#ifdef HAVE_FORMAT_PACKET - case Packet: - if ( ((DabInputCompatible*)(*subchannel)->input)->getOpts() == dabInputPacketFileOperations) { - operations = dabInputFifoOperations; -#ifdef HAVE_FORMAT_EPM - } else if ( ((DabInputCompatible*)(*subchannel)->input)->getOpts() == dabInputEnhancedPacketFileOperations) { - operations = dabInputEnhancedFifoOperations; -#endif // defined(HAVE_FORMAT_EPM) - } else { - etiLog.log(error, - "Error, wrong packet subchannel operations!\n"); - goto EXIT; - } - delete (*subchannel)->input; - (*subchannel)->input = new DabInputCompatible(operations); - (*subchannel)->inputProto = "fifo"; - break; -#endif // defined(HAVE_FORMAT_PACKET) -#ifdef HAVE_FORMAT_MPEG - case Audio: - if ( ((DabInputCompatible*)(*subchannel)->input)->getOpts() == dabInputMpegFileOperations) { - operations = dabInputMpegFifoOperations; - } else if (((DabInputCompatible*)(*subchannel)->input)->getOpts() == - dabInputDabplusFileOperations) { - operations = dabInputDabplusFifoOperations; - } else { - etiLog.log(error, - "Error, wrong audio subchannel operations!\n"); - goto EXIT; - } - delete (*subchannel)->input; - (*subchannel)->input = new DabInputCompatible(operations); - (*subchannel)->inputProto = "fifo"; - break; -#endif // defined(HAVE_FORMAT_MPEG) - default: - etiLog.log(error, - "sorry, non-blocking input file is " - "only valid with audio or packet services\n"); - goto EXIT; - } - break; -#endif // defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE) - case 'p': - int level; - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -p\n"); - printUsage(progName); - goto EXIT; - } - if (subchannel == ensemble->subchannels.end()) { - etiLog.log(error, - "You must define a subchannel first!\n"); - printUsage(progName); - goto EXIT; - } - level = strtoul(optarg, NULL, 0) - 1; - if (protection->form == UEP) { - if ((level < 0) || (level > 4)) { - etiLog.log(error, - "UEP protection level must be between " - "1 to 5 inclusively (current = %i)\n", level); - goto EXIT; - } - } - else if (protection->form == EEP) { - if ((level < 0) || (level > 3)) { - etiLog.log(error, - "EEP protection level must be between " - "1 to 4 inclusively (current = %i)\n", level); - goto EXIT; - } - } - protection->level = level; - break; - case 'm': - if (optarg) { - ensemble->mode = strtoul(optarg, NULL, 0); - if ((ensemble->mode < 1) || (ensemble->mode > 4)) { - etiLog.log(error, - "Mode must be between 1-4\n"); - goto EXIT; - } - if (ensemble->mode == 4) - ensemble->mode = 0; - if (ensemble->mode == 3) { - *FICL = 32; - } else { - *FICL = 24; - } - } else { - etiLog.log(error, - "Missing parameter for option -m\n"); - printUsage(progName); - goto EXIT; - } - break; - case 'n': - if (optarg) { - *limit = strtoul(optarg, NULL, 0); - } else { - etiLog.log(error, - "Missing parameter for option -n\n"); - printUsage(progName); - goto EXIT; - } - break; - case 'o': - etiLog.register_backend(new LogToSyslog()); // TODO don't leak the LogToSyslog backend - break; - case 't': - if (optarg == NULL) { - etiLog.log(error, - "Missing parameter for option -t\n"); - printUsage(progName); - goto EXIT; - } - if (component == ensemble->components.end()) { - etiLog.log(error, - "You must define a component before setting " - "service type!\n"); - printUsage(progName); - goto EXIT; - } - (*component)->type = strtoul(optarg, NULL, 0); - break; - case 'a': - if (component == ensemble->components.end()) { - etiLog.log(error, - "You must define a component before setting " - "packet address!\n"); - printUsage(progName); - goto EXIT; - } - if (!(*component)->isPacketComponent(ensemble->subchannels)) { - etiLog.log(error, "address\n"); - printUsage(progName); - goto EXIT; - } - (*component)->packet.address = strtoul(optarg, NULL, 0); - break; - case 'd': - if (component == ensemble->components.end()) { - etiLog.log(error, - "You must define a component before setting " - "datagroup!\n"); - printUsage(progName); - goto EXIT; - } - if (!(*component)->isPacketComponent(ensemble->subchannels)) { - etiLog.log(error, "datagroup\n"); - printUsage(progName); - goto EXIT; - } - (*component)->packet.datagroup = true; - break; - case 'f': - if (component == ensemble->components.end()) { - etiLog.log(error, - "You must define a component first!\n"); - printUsage(progName); - goto EXIT; - } - if (!(*component)->isPacketComponent(ensemble->subchannels)) { - etiLog.log(error, "application type\n"); - printUsage(progName); - goto EXIT; - } - (*component)->packet.appType = strtoul(optarg, NULL, 0); - break; - case 'g': - if (service == ensemble->services.end()) { - etiLog.log(error, "You must define a service" - " before using option -%c\n", c); - printUsage(progName); - goto EXIT; - } - (*service)->language = strtoul(optarg, NULL, 0); - break; - case 's': - { - /* - struct timeval tv; - gettimeofday(&tv, NULL); - unsigned _8ms = (tv.tv_usec / 1000) / 8; - unsigned _1ms = (tv.tv_usec - (_8ms * 8000)) / 1000; - unsigned _4us = 20; - unsigned _488ns = 0; - unsigned _61ns = 0; - timestamp = (((((((_8ms << 3) | _1ms) << 8) | _4us) << 3) | _488ns) << 8) | _61ns; - */ - *enableTist = true; - } - break; - case 'y': - if (service == ensemble->services.end()) { - etiLog.log(error, "You must define a service" - " before using option -%c\n", c); - printUsage(progName); - goto EXIT; - } - (*service)->pty = strtoul(optarg, NULL, 0); - break; - case 'z': - *factumAnalyzer = true; - break; - case 'r': - etiLog.log(info, - "Enabling throttled output using simul, one frame every 24ms\n"); - outputs.push_back(new dabOutput("simul", "simul")); - output = outputs.end() - 1; - - subchannel = ensemble->subchannels.end(); - protection = NULL; - component = ensemble->components.end(); - service = ensemble->services.end(); - break; - case '?': - case 'h': - printUsage(progName, stdout); - goto EXIT; - default: - etiLog.log(error, "Option '%c' not coded yet\n", c); - goto EXIT; - } - } - if (optind < argc) { - etiLog.log(error, "Too much parameters:"); - while (optind < argc) { - etiLog.log(error, " %s", argv[optind++]); - } - etiLog.log(error, "\n"); - printUsage(progName); - goto EXIT; - } - - return true; -EXIT: - return false; -} - -#endif // ENABLE_CMDLINE_OPTIONS - diff --git a/src/ParserCmdline.h b/src/ParserCmdline.h deleted file mode 100644 index 1c4545b..0000000 --- a/src/ParserCmdline.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, - 2011, 2012 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - - Includes modifications - 2012, Matthias P. Braendli, matthias.braendli@mpb.li - - The command-line parser reads the parameters given on the command - line, and builds an ensemble. - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux 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. - - ODR-DabMux 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 ODR-DabMux. If not, see . -*/ -#ifndef _PARSER_CMDLINE -#define _PARSER_CMDLINE - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include "MuxElements.h" - -#define ENABLE_CMDLINE_OPTIONS 0 - -#if ENABLE_CMDLINE_OPTIONS - -bool parse_cmdline(char **argv, - int argc, - std::vector &outputs, - dabEnsemble* ensemble, - bool* enableTist, - unsigned* FICL, - bool* factumAnalyzer, - unsigned long* limit - ); - -#endif - -#endif diff --git a/src/dabInputFifo.cpp b/src/dabInputFifo.cpp index 7e07731..6fa3aad 100644 --- a/src/dabInputFifo.cpp +++ b/src/dabInputFifo.cpp @@ -1,6 +1,11 @@ /* Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org */ /* This file is part of ODR-DabMux. diff --git a/src/dabInputFifo.h b/src/dabInputFifo.h index e5f5206..99edac6 100644 --- a/src/dabInputFifo.h +++ b/src/dabInputFifo.h @@ -1,6 +1,11 @@ /* Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org */ /* This file is part of ODR-DabMux. @@ -19,19 +24,18 @@ along with ODR-DabMux. If not, see . */ -#ifndef DAB_INPUT_FIFO_H -#define DAB_INPUT_FIFO_H +#pragma once #ifdef HAVE_CONFIG_H -# include "config.h" +# include "config.h" #endif + #include "dabInputFile.h" #include "Log.h" #ifdef _WIN32 # include - # define sem_t HANDLE # define O_NONBLOCK 0 #else @@ -97,4 +101,3 @@ void* dabInputFifoThread(void* args); # endif #endif -#endif // DAB_INPUT_FIFO_H diff --git a/src/dabInputPrbs.cpp b/src/dabInputPrbs.cpp index 8d8c0d9..f34c427 100644 --- a/src/dabInputPrbs.cpp +++ b/src/dabInputPrbs.cpp @@ -1,6 +1,13 @@ /* Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org + + Pseudo-Random Bit Sequence generator for test purposes. */ /* This file is part of ODR-DabMux. @@ -21,126 +28,65 @@ #include "dabInputPrbs.h" +#include +#include #include #include #include +#include +using namespace std; -#ifdef HAVE_FORMAT_RAW -# ifdef HAVE_INPUT_PRBS - - -struct dabInputOperations dabInputPrbsOperations = { - dabInputPrbsInit, - dabInputPrbsOpen, - NULL, - dabInputPrbsRead, - NULL, - NULL, - dabInputPrbsReadFrame, - dabInputPrbsBitrate, - dabInputPrbsClose, - dabInputPrbsClean, - dabInputPrbsRewind, -}; - - -int dabInputPrbsInit(void** args) -{ - prbs_data* data = new prbs_data; - - memset(data, 0, sizeof(*data)); - - *args = data; - return 0; -} - - -int dabInputPrbsOpen(void* args, const char* name) +int DabInputPrbs::open(const string name) { - prbs_data* data = (prbs_data*)args; - - if (*name != ':') { - etiLog.log(error, - "Sorry, PRBS address format is prbs://:polynomial.\n"); - errno = EINVAL; - return -1; + if (name[0] != ':') { + throw invalid_argument( + "Invalid PRBS address format. Must be prbs://:polynomial."); } - long polynomial = strtol(++name, (char **)NULL, 10); + const string poly_str = name.substr(1); + + long polynomial = strtol(poly_str.c_str(), (char **)NULL, 10); if ((polynomial == LONG_MIN) || (polynomial == LONG_MAX)) { - etiLog.log(error, "can't convert polynomial number %s\n", name); - errno = EINVAL; - return -1; + stringstream ss; + ss << "Can't convert polynomial number " << poly_str; + throw invalid_argument(ss.str()); } + if (polynomial == 0) { - etiLog.log(error, "you must specify a polynomial number\n"); - errno = EINVAL; - return -1; + throw invalid_argument("No polynomial given for PRBS input"); } - - data->polynomial = polynomial; - data->accum = 0; - gen_prbs_table(data); - gen_weight_table(data); - dabInputPrbsRewind(args); + + m_prbs.setup(polynomial); + rewind(); return 0; } - -int dabInputPrbsRead(void* args, void* buffer, int size) +int DabInputPrbs::readFrame(void* buffer, int size) { - prbs_data* data = (prbs_data*)args; - unsigned char* cbuffer = reinterpret_cast(buffer); + unsigned char* cbuffer = reinterpret_cast(buffer); - for(int i = 0; i < size; ++i) { - data->accum = update_prbs(args); - *(cbuffer++) = (unsigned char)(data->accum & 0xff); + for (int i = 0; i < size; ++i) { + cbuffer[i] = m_prbs.step(); } return size; } - -int dabInputPrbsReadFrame(dabInputOperations* ops, void* args, - void* buffer, int size) -{ - return ops->read(args, buffer, size); -} - - -int dabInputPrbsBitrate(dabInputOperations* ops, void* args, int bitrate) +int DabInputPrbs::setBitrate(int bitrate) { return bitrate; } - -int dabInputPrbsClose(void* args) +int DabInputPrbs::close() { return 0; } - -int dabInputPrbsClean(void** args) +int DabInputPrbs::rewind() { - delete (prbs_data*)(*args); + m_prbs.rewind(); return 0; } - -int dabInputPrbsRewind(void* args) -{ - prbs_data* data = (prbs_data*)args; - - while (data->accum < data->polynomial) { - data->accum <<= 1; - data->accum |= 1; - } - - return 0; -} - - -# endif -#endif diff --git a/src/dabInputPrbs.h b/src/dabInputPrbs.h index 22c088c..9cde7e2 100644 --- a/src/dabInputPrbs.h +++ b/src/dabInputPrbs.h @@ -1,6 +1,13 @@ /* Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org + + Pseudo-Random Bit Sequence generator for test purposes. */ /* This file is part of ODR-DabMux. @@ -19,38 +26,27 @@ along with ODR-DabMux. If not, see . */ -#ifndef DAB_INPUT_PRBS_H -#define DAB_INPUT_PRBS_H - +#pragma once #ifdef HAVE_CONFIG_H -# include "config.h" +# include "config.h" #endif -#include "dabInput.h" -#include "prbs.h" - -#include +#include -#ifdef HAVE_FORMAT_RAW -# ifdef HAVE_INPUT_PRBS - - -extern struct dabInputOperations dabInputPrbsOperations; - -int dabInputPrbsInit(void** args); -int dabInputPrbsOpen(void* args, const char* name); -int dabInputPrbsRead(void* args, void* buffer, int size); -int dabInputPrbsReadFrame(dabInputOperations* ops, void* args, - void* buffer, int size); -int dabInputPrbsBitrate(dabInputOperations* ops, void* args, int bitrate); -int dabInputPrbsClose(void* args); -int dabInputPrbsClean(void** args); -int dabInputPrbsRewind(void* args); +#include "dabInput.h" +#include "prbs.h" +class DabInputPrbs : public DabInputBase { + public: + virtual int open(const std::string name); + virtual int readFrame(void* buffer, int size); + virtual int setBitrate(int bitrate); + virtual int close(); -# endif -#endif + private: + virtual int rewind(); + PrbsGenerator m_prbs; +}; -#endif // DAB_INPUT_PRBS_H diff --git a/src/prbs.c b/src/prbs.c deleted file mode 100644 index c29a830..0000000 --- a/src/prbs.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right - of Canada (Communications Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux 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. - - ODR-DabMux 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 ODR-DabMux. If not, see . - */ - -#include "prbs.h" - -#include -#include -#include - - -/* - * Generate a parity check for a 32-bit word. - */ -unsigned long parity_check(unsigned long prbs_accum) -{ - unsigned long mask=1UL, parity=0UL; - int i; - for (i = 0; i < 32; ++i) { - parity ^= ((prbs_accum & mask) != 0UL); - mask <<= 1; - } - return parity; -} - -/* - * Generate a table of matrix products to update a 32-bit PRBS generator. - */ -void gen_prbs_table(void* args) -{ - prbs_data* data = (prbs_data*)args; - int i; - for (i = 0; i < 4; ++i) { - int j; - for (j = 0; j < 256; ++j) { - unsigned long prbs_accum = ((unsigned long)j << (i * 8)); - int k; - for (k = 0; k < 8; ++k) { - prbs_accum = (prbs_accum << 1) - ^ parity_check(prbs_accum & data->polynomial); - } - data->prbs_table[i][j] = (prbs_accum & 0xff); - } - } -} - -/* - * Update a 32-bit PRBS generator eight bits at a time. - */ -unsigned long update_prbs(void* args) -{ - prbs_data* data = (prbs_data*)args; - unsigned char acc_lsb = 0; - int i; - for (i = 0; i < 4; ++i ) { - acc_lsb ^= data->prbs_table [i] [ (data->accum >> (i * 8) ) & 0xff ]; - } - return (data->accum << 8) ^ ((unsigned long)acc_lsb); -} - -/* - * Generate the weight table. - */ -void gen_weight_table(void* args) -{ - prbs_data* data = (prbs_data*)args; - int i; - for (i = 0; i < 256; ++i) { - unsigned char mask=1U, ones_count = 0U; - int j; - for (j = 0; j < 8; ++j) { - ones_count += ((i & mask) != 0U); - mask = mask << 1; - } - data->weight[i] = ones_count; - } -} - -/* - * Count the number of errors in a block of received data. - */ -unsigned long error_count(void* args, unsigned char *rx_data, - int rx_data_length) -{ - prbs_data* data = (prbs_data*)args; - unsigned long error_count = 0U; - unsigned long prbs_accum = 0U; - int i; - - /* seed the PRBS accumulator */ - for (i = 0; i < 4; ++i) { - prbs_accum = (prbs_accum << 8) ^ (rx_data[i] ^ data->polarity_mask); - } - - /* check the received data */ - for (i = 0; i < rx_data_length; ++i) { - unsigned char error_pattern = (unsigned char) - ((prbs_accum >> 24) - ^ (rx_data[i] ^ data->polarity_mask)); - if (error_pattern != 0U) { - error_count += data->weight[error_pattern]; - } - prbs_accum = update_prbs(data); - } - return error_count; -} - -void gen_sequence(void* args, unsigned char *tx_data, int tx_data_length, - unsigned long polynomial) -{ - prbs_data* data = (prbs_data*)args; - unsigned long prbs_accum = 0U; - - while (prbs_accum < polynomial) { - prbs_accum <<= 1; - prbs_accum |= 1; - } - - while (tx_data_length-- > 0) { - prbs_accum = update_prbs(data); - *(tx_data++) = (unsigned char)(prbs_accum & 0xff); - } -} diff --git a/src/prbs.cpp b/src/prbs.cpp new file mode 100644 index 0000000..0ac3187 --- /dev/null +++ b/src/prbs.cpp @@ -0,0 +1,144 @@ +/* + Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right + of Canada (Communications Research Center Canada) + */ +/* + This file is part of ODR-DabMux. + + ODR-DabMux 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. + + ODR-DabMux 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 ODR-DabMux. If not, see . + */ + +#include "prbs.h" + +#include +#include + + +/* + * Generate a parity check for a 32-bit word. + */ +static unsigned long parity_check(unsigned long prbs_accum) +{ + unsigned long mask=1UL, parity=0UL; + int i; + for (i = 0; i < 32; ++i) { + parity ^= ((prbs_accum & mask) != 0UL); + mask <<= 1; + } + return parity; +} + +void PrbsGenerator::setup(long polynomial) +{ + this->polynomial = polynomial; + this->accum = 0; + gen_prbs_table(); + gen_weight_table(); +} + +uint8_t PrbsGenerator::step() +{ + accum = update_prbs(); + return accum & 0xff; +} + +void PrbsGenerator::rewind() +{ + while (accum < polynomial) { + accum <<= 1; + accum |= 1; + } +} + +void PrbsGenerator::gen_prbs_table() +{ + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 256; ++j) { + unsigned long prbs_accum = ((unsigned long)j << (i * 8)); + for (int k = 0; k < 8; ++k) { + prbs_accum = (prbs_accum << 1) + ^ parity_check(prbs_accum & polynomial); + } + + prbs_table[i][j] = (prbs_accum & 0xff); + } + } +} + +unsigned long PrbsGenerator::update_prbs() +{ + unsigned char acc_lsb = 0; + int i; + for (i = 0; i < 4; ++i ) { + acc_lsb ^= prbs_table [i] [ (accum >> (i * 8) ) & 0xff ]; + } + return (accum << 8) ^ ((unsigned long)acc_lsb); +} + +void PrbsGenerator::gen_weight_table() +{ + for (int i = 0; i < 256; ++i) { + unsigned char mask = 1U; + unsigned char ones_count = 0U; + + for (int j = 0; j < 8; ++j) { + ones_count += ((i & mask) != 0U); + mask = mask << 1; + } + weight[i] = ones_count; + } +} + +size_t PrbsGenerator::error_count( + unsigned char *rx_data, + int rx_data_length) +{ + unsigned long error_count = 0U; + unsigned long prbs_accum = 0U; + + /* seed the PRBS accumulator */ + for (int i = 0; i < 4; ++i) { + prbs_accum = (prbs_accum << 8) ^ (rx_data[i] ^ polarity_mask); + } + + /* check the received data */ + for (int i = 0; i < rx_data_length; ++i) { + unsigned char error_pattern = (unsigned char) + ((prbs_accum >> 24) + ^ (rx_data[i] ^ polarity_mask)); + if (error_pattern != 0U) { + error_count += weight[error_pattern]; + } + prbs_accum = update_prbs(); + } + return error_count; +} + +void PrbsGenerator::gen_sequence( + unsigned char *tx_data, + int tx_data_length, + unsigned long polynomial) +{ + unsigned long prbs_accum = 0U; + + while (prbs_accum < polynomial) { + prbs_accum <<= 1; + prbs_accum |= 1; + } + + while (tx_data_length-- > 0) { + prbs_accum = update_prbs(); + *(tx_data++) = (unsigned char)(prbs_accum & 0xff); + } +} diff --git a/src/prbs.h b/src/prbs.h index c039a6e..5b6b7c2 100644 --- a/src/prbs.h +++ b/src/prbs.h @@ -19,43 +19,53 @@ along with ODR-DabMux. If not, see . */ -#ifndef _PRBS -#define _PRBS +#pragma once + +#include +#include #ifdef HAVE_CONFIG_H # include "config.h" #endif +class PrbsGenerator { + public: + void setup(long polynomial); -#ifdef __cplusplus -extern "C" { // } -#endif + uint8_t step(void); -typedef struct { - // table of matrix products used to update a 32-bit PRBS generator - unsigned long prbs_table [4] [256]; - // table of weights for 8-bit bytes - unsigned char weight[256]; - // PRBS polynomial generator - unsigned long polynomial; - // PRBS generator polarity mask - unsigned char polarity_mask; - // PRBS accumulator - unsigned long accum; -} prbs_data; - - -unsigned long parity_check(unsigned long prbs_accum); -void gen_prbs_table(void* args); -unsigned long update_prbs(void* args); -void gen_weight_table(void* args); -unsigned long error_count(void* args, unsigned char *rx_data, - int rx_data_length); -void gen_sequence(void* args, unsigned char *tx_data, int tx_data_length, - unsigned long polynomial); - -#ifdef __cplusplus -} -#endif + void rewind(void); + + private: + /* Generate a table of matrix products to update a 32-bit PRBS + * generator. */ + void gen_prbs_table(void); + + /* Update a 32-bit PRBS generator eight bits at a time. */ + unsigned long update_prbs(void); + + /* Generate the weight table. */ + void gen_weight_table(void); + + /* Count the number of errors in a block of received data. */ + size_t error_count( + unsigned char *rx_data, + int rx_data_length); + + void gen_sequence( + unsigned char *tx_data, + int tx_data_length, + unsigned long polynomial); + + // table of matrix products used to update a 32-bit PRBS generator + unsigned long prbs_table [4] [256]; + // table of weights for 8-bit bytes + unsigned char weight[256]; + // PRBS polynomial generator + unsigned long polynomial; + // PRBS generator polarity mask + unsigned char polarity_mask; + // PRBS accumulator + unsigned long accum; +}; -#endif // _PRBS diff --git a/src/utils.cpp b/src/utils.cpp index c776b0b..9976e88 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -102,9 +102,7 @@ void header_message() "http://opendigitalradio.org\n\n"); std::cerr << "Input URLs supported:" << std::endl << -#if defined(HAVE_INPUT_PRBS) " prbs" << -#endif #if defined(HAVE_INPUT_TEST) " test" << #endif @@ -166,163 +164,6 @@ void header_message() } -#if ENABLE_CMDLINE_OPTIONS -void printUsage(char *name, FILE* out) -{ - fprintf(out, "NAME\n"); - fprintf(out, " %s - A software DAB multiplexer\n", name); - fprintf(out, "\nSYNOPSYS\n"); - fprintf(out, " You can use either a configuration file, or the command line arguments\n"); - fprintf(out, " With external configuration file:\n"); - fprintf(out, " %s [-e] configuration.mux\n", name); - fprintf(out, " See doc/example.config for an example format for the configuration file\n"); - fprintf(out, " With command line arguments:\n"); - fprintf(out, " %s" - " [ensemble]" - " [subchannel1 subchannel2 ...]" - " [service1 component1 [component2 ...] service2 ...]" - " [output1 ...]" - " [-h]" - " [-m mode]" - " [-n nbFrames]" - " [-o]" - " [-s]" - " [-V]" - " [-z]" - "\n", - name); - fprintf(out, "\n Where ensemble =" - " [-i ensembleId]" - " [-L label]" - " [-l sLabel]" - "\n"); - fprintf(out, "\n Where subchannel =" - " -(A | B | D | E | F | M | P | T) inputName" - " [-b bitrate]" - " [-i subchannelId]" - " [-k]" - " [-p protection]" - "\n"); - fprintf(out, "\n Where service =" - " -S" - " [-g language]" - " [-i serviceId]" - " [-L label]" - " [-l sLabel]" - " [-y PTy]" - "\n"); - fprintf(out, "\n Where component =" - " -C" - " [-a address]" - " [-d]" - " [-f figType]" - " [-i subchannelId]" - " [-L label]" - " [-l sLabel]" - " [-t type]" - "\n"); - fprintf(out, "\nDESCRIPTION\n"); - fprintf(out, - " %s is a software multiplexer that generates an ETI stream from\n" - " audio and data streams. Because of its software based architecture,\n" - " many typical DAB services can be generated and multiplexed on a single\n" - " PC platform with live or pre-recorded sources.\n" - "\n" - " A DAB multiplex configuration is composed of one ensemble. An ensemble\n" - " is the entity that receivers tune to and process. An ensemble contains\n" - " several services. A service is the listener-selectable output. Each\n" - " service contains one mandatory service component which is called pri-\n" - " mary component. An audio primary component define a program service\n" - " while a data primary component define a data service. Service can con-\n" - " tain additional components which are called secondary components. Maxi-\n" - " mum total number of components is 12 for program services and 11 for\n" - " data services. A service component is a link to one subchannel (of Fast\n" - " Information Data Channel). A subchannel is the physical space used\n" - " within the common interleaved frame.\n" - "\n" - " __________________________________________________\n" - " | Ensemble | ENSEMBLE\n" - " |__________________________________________________|\n" - " | | |\n" - " | | |\n" - " _______V______ _______V______ _______V______\n" - " | Service 1 | | Service 2 | | Service 3 | SERVICES\n" - " |______________| |______________| |______________|\n" - " | | | | |______ |\n" - " | | | | | |\n" - " __V__ __V__ __V__ __V__ __V__ __V__\n" - " | SC1 | | SC2 | | SC3 | | SC4 | | SC5 | | SC6 | SERVICE\n" - " |_____| |_____| |_____| |_____| |_____| |_____| COMPONENTS\n" - " | | _____| | | ____|\n" - " | | | | | |\n" - " __V________V__V______________V________V___V_______ COMMON\n" - " | SubCh1 | SubCh9 | ... | SubCh3 | SubCh60 | ... | INTERLEAVED\n" - " |________|________|_______|________|_________|_____| FRAME\n" - " Figure 1: An example of a DAB multiplex configuration\n", - name); - - fprintf(out, "\nGENERAL OPTIONS\n"); - fprintf(out, " -h : get this help\n"); - fprintf(out, " -m : DAB mode (default: 2)\n"); - fprintf(out, " -n nbFrames : number of frames to produce\n"); - fprintf(out, " -o : enable logging to syslog\n"); - fprintf(out, " -r : throttle the output rate to one ETI frame every 24ms\n"); - fprintf(out, " -V : print version information and " - "exit\n"); - fprintf(out, " -z : write SCCA field for Factum ETI" - " analyzer\n"); - fprintf(out, "\nINPUT OPTIONS\n"); - fprintf(out, " -A : set audio service\n"); - fprintf(out, " -B : set CRC-Bridge data service\n"); - fprintf(out, " -D : set data service\n"); - fprintf(out, " -E : set enhanced packet service\n"); - fprintf(out, " -F : set DAB+ service\n"); - fprintf(out, " -M : set DMB service\n"); - fprintf(out, " -P : set packet service\n"); - fprintf(out, " -T : set test service\n"); - fprintf(out, " inputName : name of file for audio and " - "packet service and Udp input address for data service " - "([address]:port)\n"); - fprintf(out, " -a : packet address (default: 0x%x " - "(%i))\n", DEFAULT_PACKET_ADDRESS, DEFAULT_PACKET_ADDRESS); - fprintf(out, " -b bitrate : bitrate (in kbits/s) of the " - "subchannel (default: audio 1st frame, data %i, packet %i)\n", - DEFAULT_DATA_BITRATE, DEFAULT_PACKET_BITRATE); - fprintf(out, " -c : set the extendend country code ECC " - "(default: %u (0x%2x)\n", DEFAULT_ENSEMBLE_ECC, DEFAULT_ENSEMBLE_ECC); - fprintf(out, " -d : turn on datagroups in packet " - "mode\n"); - fprintf(out, " -f figType : user application type in FIG " - "0/13 for packet mode\n"); - fprintf(out, " -g language : Primary service component " - "language: english=9, french=15\n"); - fprintf(out, " -i id : service|subchannel|" - "serviceComponent id (default: )\n"); - fprintf(out, " -k : set non-blocking file input " - "(audio and packet only)\n"); - fprintf(out, " -L label : label of service " - " (default: CRC-Audio)\n"); - fprintf(out, " -l sLabel : short label flag of service " - " (default: 0xf040)\n"); - fprintf(out, " -p protection : protection level (default: 3)\n"); - fprintf(out, " -s : enable TIST, synchronized on 1PPS at level 2.\n"); - fprintf(out, " This also transmits time using the MNSC.\n"); - fprintf(out, " -t type : audio/data service component type" - " (default: 0)\n"); - fprintf(out, " audio: foreground=0, " - "background=1, multi-channel=2\n"); - fprintf(out, " data: unspecified=0, TMC=1, " - "EWS=2, ITTS=3, paging=4, TDC=5, DMB=24, IP=59, MOT=60, " - "proprietary=61\n"); - fprintf(out, " -y PTy : Primary service component program" - " type international code\n"); - fprintf(out, "\nOUTPUT OPTIONS\n"); - fprintf(out, " -O output : name of the output in format " - "scheme://[address][:port][/name]\n" - " where scheme is (raw|udp|tcp|file|fifo|simul)\n" - ); -} -#else // no command line options void printUsage(char *name, FILE* out) { fprintf(out, "NAME\n"); @@ -371,7 +212,6 @@ void printUsage(char *name, FILE* out) " Figure 1: An example of a DAB multiplex configuration\n", name); } -#endif void printOutputs(const vector >& outputs) { -- cgit v1.2.3