summaryrefslogtreecommitdiffstats
path: root/src/InputFileReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/InputFileReader.cpp')
-rw-r--r--src/InputFileReader.cpp266
1 files changed, 266 insertions, 0 deletions
diff --git a/src/InputFileReader.cpp b/src/InputFileReader.cpp
new file mode 100644
index 0000000..1be1ad7
--- /dev/null
+++ b/src/InputFileReader.cpp
@@ -0,0 +1,266 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+ Her Majesty the Queen in Right of Canada (Communications Research
+ Center Canada)
+
+ Copyrigth (C) 2013
+ Matthias P. Braendli, matthias.braendli@mpb.li
+
+
+ Input module for reading the ETI data from file or pipe.
+
+ Supported formats: RAW, FRAMED, STREAMED
+ Supports re-sync to RAW ETI
+ */
+/*
+ This file is part of CRC-DADMOD.
+
+ CRC-DADMOD is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ CRC-DADMOD is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with CRC-DADMOD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string>
+#include <cstdio>
+#include <cstring>
+#include <errno.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include "porting.h"
+#include "InputReader.h"
+#include "PcDebug.h"
+
+int InputFileReader::Open(std::string filename)
+{
+ filename_ = filename;
+ inputfile_ = fopen(filename_.c_str(), "r");
+ if (inputfile_ == NULL) {
+ fprintf(stderr, "Unable to open input file!\n");
+ logger_.level(error) << "Unable to open input file!";
+ perror(filename_.c_str());
+ return -1;
+ }
+
+ return IdentifyType();
+}
+
+int InputFileReader::Rewind()
+{
+ rewind(inputfile_);
+ return IdentifyType();
+}
+
+int InputFileReader::IdentifyType()
+{
+ EtiStreamType streamType = ETI_STREAM_TYPE_NONE;
+
+ struct stat inputFileStat;
+ fstat(fileno(inputfile_), &inputFileStat);
+ inputfilelength_ = inputFileStat.st_size;
+
+ uint32_t sync;
+ uint32_t nbFrames;
+ uint16_t frameSize;
+
+ char discard_buffer[6144];
+
+ if (fread(&sync, sizeof(sync), 1, inputfile_) != 1) {
+ fprintf(stderr, "Unable to read sync in input file!\n");
+ logger_.level(error) << "Unable to read sync in input file!";
+ perror(filename_.c_str());
+ return -1;
+ }
+ if ((sync == 0x49c5f8ff) || (sync == 0xb63a07ff)) {
+ streamType = ETI_STREAM_TYPE_RAW;
+ if (inputfilelength_ > 0) {
+ nbframes_ = inputfilelength_ / 6144;
+ }
+ else {
+ nbframes_ = ~0;
+ }
+ if (fseek(inputfile_, -sizeof(sync), SEEK_CUR) != 0) {
+ // if the seek fails, consume the rest of the frame
+ if (fread(discard_buffer, 6144 - sizeof(sync), 1, inputfile_)
+ != 1) {
+ fprintf(stderr, "Unable to read from input file!\n");
+ logger_.level(error) << "Unable to read from input file!";
+ perror(filename_.c_str());
+ return -1;
+ }
+ }
+ this->streamtype_ = streamType;
+ return 0;
+ }
+
+ nbFrames = sync;
+ if (fread(&frameSize, sizeof(frameSize), 1, inputfile_) != 1) {
+ fprintf(stderr, "Unable to read frame size in input file!\n");
+ logger_.level(error) << "Unable to read frame size in input file!";
+ perror(filename_.c_str());
+ return -1;
+ }
+ sync >>= 16;
+ sync &= 0xffff;
+ sync |= ((uint32_t)frameSize) << 16;
+
+ if ((sync == 0x49c5f8ff) || (sync == 0xb63a07ff)) {
+ streamType = ETI_STREAM_TYPE_STREAMED;
+ frameSize = nbFrames & 0xffff;
+ if (inputfilelength_ > 0) {
+ nbframes_ = inputfilelength_ / (frameSize + 2);
+ }
+ else {
+ nbframes_ = ~0;
+ }
+ if (fseek(inputfile_, -6, SEEK_CUR) != 0) {
+ // if the seek fails, consume the rest of the frame
+ if (fread(discard_buffer, frameSize - 4, 1, inputfile_)
+ != 1) {
+ fprintf(stderr, "Unable to read from input file!\n");
+ logger_.level(error) << "Unable to read from input file!";
+ perror(filename_.c_str());
+ return -1;
+ }
+ }
+ this->streamtype_ = streamType;
+ return 0;
+ }
+
+ if (fread(&sync, sizeof(sync), 1, inputfile_) != 1) {
+ fprintf(stderr, "Unable to read nb frame in input file!\n");
+ logger_.level(error) << "Unable to read nb frame in input file!";
+ perror(filename_.c_str());
+ return -1;
+ }
+ if ((sync == 0x49c5f8ff) || (sync == 0xb63a07ff)) {
+ streamType = ETI_STREAM_TYPE_FRAMED;
+ if (fseek(inputfile_, -6, SEEK_CUR) != 0) {
+ // if the seek fails, consume the rest of the frame
+ if (fread(discard_buffer, frameSize - 4, 1, inputfile_)
+ != 1) {
+ fprintf(stderr, "Unable to read from input file!\n");
+ logger_.level(error) << "Unable to read from input file!";
+ perror(filename_.c_str());
+ return -1;
+ }
+ }
+ this->streamtype_ = streamType;
+ nbframes_ = ~0;
+ return 0;
+ }
+
+ // Search for the sync marker byte by byte
+ for (size_t i = 10; i < 6144 + 10; ++i) {
+ sync >>= 8;
+ sync &= 0xffffff;
+ if (fread((uint8_t*)&sync + 3, 1, 1, inputfile_) != 1) {
+ fprintf(stderr, "Unable to read from input file!\n");
+ logger_.level(error) << "Unable to read from input file!";
+ perror(filename_.c_str());
+ return -1;
+ }
+ if ((sync == 0x49c5f8ff) || (sync == 0xb63a07ff)) {
+ streamType = ETI_STREAM_TYPE_RAW;
+ if (inputfilelength_ > 0) {
+ nbframes_ = (inputfilelength_ - i) / 6144;
+ }
+ else {
+ nbframes_ = ~0;
+ }
+ if (fseek(inputfile_, -sizeof(sync), SEEK_CUR) != 0) {
+ if (fread(discard_buffer, 6144 - sizeof(sync), 1, inputfile_)
+ != 1) {
+ fprintf(stderr, "Unable to read from input file!\n");
+ logger_.level(error) << "Unable to read from input file!";
+ perror(filename_.c_str());
+ return -1;
+ }
+ }
+ this->streamtype_ = streamType;
+ return 0;
+ }
+ }
+
+ fprintf(stderr, "Bad input file format!\n");
+ logger_.level(error) << "Bad input file format!";
+ return -1;
+}
+
+void InputFileReader::PrintInfo()
+{
+ fprintf(stderr, "Input file format: ");
+ switch (streamtype_) {
+ case ETI_STREAM_TYPE_RAW:
+ fprintf(stderr, "raw");
+ break;
+ case ETI_STREAM_TYPE_STREAMED:
+ fprintf(stderr, "streamed");
+ break;
+ case ETI_STREAM_TYPE_FRAMED:
+ fprintf(stderr, "framed");
+ break;
+ default:
+ fprintf(stderr, "unkown!");
+ break;
+ }
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Input file length: %zu\n", inputfilelength_);
+ if (~nbframes_ != 0) {
+ fprintf(stderr, "Input file nb frames: %lu\n", nbframes_);
+ }
+ else {
+ fprintf(stderr, "Input file nb frames: endless\n");
+ }
+}
+
+int InputFileReader::GetNextFrame(void* buffer)
+{
+ uint16_t frameSize;
+
+ if (streamtype_ == ETI_STREAM_TYPE_RAW) {
+ frameSize = 6144;
+ }
+ else {
+ if (fread(&frameSize, sizeof(frameSize), 1, inputfile_) != 1) {
+ PDEBUG("End of file!\n");
+ logger_.level(error) << "Reached end of file!";
+ return 0;
+ }
+ }
+ if (frameSize > 6144) { // there might be a better limit
+ logger_.level(error) << "Wrong frame size " << frameSize << " in ETI file!";
+ fprintf(stderr, "Wrong frame size %u in ETI file!\n", frameSize);
+ return -1;
+ }
+
+ PDEBUG("Frame size: %u\n", frameSize);
+
+ if (fread(buffer, frameSize, 1, inputfile_) != 1) {
+ // A short read of a frame (i.e. reading an incomplete frame)
+ // is not tolerated. Input files must not contain incomplete frames
+ fprintf(stderr,
+ "Unable to read a complete frame of %u data bytes from input file!\n",
+ frameSize);
+
+ perror(filename_.c_str());
+ logger_.level(error) << "Unable to read from input file!";
+ return -1;
+ }
+
+ memset(&((uint8_t*)buffer)[frameSize], 0x55, 6144 - frameSize);
+
+ return 6144;
+}