summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--etiinput.cpp197
-rw-r--r--etiinput.h49
-rw-r--r--etisnoop.cpp44
4 files changed, 283 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index c0a3a52..334077b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
CC=g++
-SOURCES=etisnoop.cpp dabplussnoop.cpp lib_crc.c firecode.c faad_decoder.cpp wavfile.c
-HEADERS=dabplussnoop.h lib_crc.h firecode.h faad_decoder.h wavfile.h
+SOURCES=etisnoop.cpp dabplussnoop.cpp lib_crc.c firecode.c faad_decoder.cpp wavfile.c etiinput.cpp
+HEADERS=dabplussnoop.h lib_crc.h firecode.h faad_decoder.h wavfile.h etiinput.h
all: etisnoop
diff --git a/etiinput.cpp b/etiinput.cpp
new file mode 100644
index 0000000..ea3241f
--- /dev/null
+++ b/etiinput.cpp
@@ -0,0 +1,197 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+ Her Majesty the Queen in Right of Canada (Communications Research
+ Center Canada)
+
+ Copyrigth (C) 2014
+ Matthias P. Braendli, matthias.braendli@mpb.li
+
+ Taken from ODR-DabMod
+
+ Supported file formats: RAW, FRAMED, STREAMED
+ Supports re-sync to RAW ETI file
+ */
+/*
+ This file is part of ODR-DabMod.
+
+ ODR-DabMod 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-DabMod 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-DabMod. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "etiinput.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h> /* Definition of AT_* constants */
+#include <sys/stat.h>
+
+int identify_eti_format(FILE* inputFile, int *streamType)
+{
+ *streamType = ETI_STREAM_TYPE_NONE;
+
+ struct stat inputFileStat;
+ fstat(fileno(inputFile), &inputFileStat);
+ size_t inputfilelength_ = inputFileStat.st_size;
+
+ int nbframes_;
+
+ 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");
+ perror("");
+ 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");
+ perror("");
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ nbFrames = sync;
+ if (fread(&frameSize, sizeof(frameSize), 1, inputFile) != 1) {
+ fprintf(stderr, "Unable to read frame size in input file!\n");
+ perror("");
+ 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");
+ perror("");
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ if (fread(&sync, sizeof(sync), 1, inputFile) != 1) {
+ fprintf(stderr, "Unable to read nb frame in input file!\n");
+ perror("");
+ 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");
+ perror("");
+ return -1;
+ }
+ }
+ 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");
+ perror("");
+ 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");
+ perror("");
+ return -1;
+ }
+ }
+ return 0;
+ }
+ }
+
+ fprintf(stderr, "Bad input file format!\n");
+ return -1;
+}
+
+int get_eti_frame(FILE* inputfile, int stream_type, void* buf)
+{
+ // Initialise buffer
+ memset(buf, 0x55, 6144);
+
+ uint16_t frameSize;
+ if (stream_type == ETI_STREAM_TYPE_RAW) {
+ frameSize = 6144;
+ }
+ else {
+ if (fread(&frameSize, sizeof(frameSize), 1, inputfile) != 1) {
+ // EOF
+ return 0;
+ }
+ }
+
+ if (frameSize > 6144) { // there might be a better limit
+ printf("Wrong frame size %u in ETI file!\n", frameSize);
+ return -1;
+ }
+
+ int read_bytes = fread(buf, 1, frameSize, inputfile);
+ if (read_bytes != frameSize) {
+ // A short read of a frame (i.e. reading an incomplete frame)
+ // is not tolerated. Input files must not contain incomplete frames
+ printf("Incomplete frame in ETI file!\n");
+ return -1;
+ }
+
+ // We have added padding, so we always return 6144 bytes
+ return 6144;
+}
+
diff --git a/etiinput.h b/etiinput.h
new file mode 100644
index 0000000..d8b7691
--- /dev/null
+++ b/etiinput.h
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+ Her Majesty the Queen in Right of Canada (Communications Research
+ Center Canada)
+
+ Copyrigth (C) 2014
+ Matthias P. Braendli, matthias.braendli@mpb.li
+
+ Taken from ODR-DabMod
+
+ Supported file formats: RAW, FRAMED, STREAMED
+ Supports re-sync to RAW ETI file
+ */
+/*
+ This file is part of ODR-DabMod.
+
+ ODR-DabMod 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-DabMod 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-DabMod. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdio.h>
+
+#ifndef _ETIINPUT_H_
+#define _ETIINPUT_H_
+
+
+#define ETI_STREAM_TYPE_NONE 0
+#define ETI_STREAM_TYPE_RAW 1
+#define ETI_STREAM_TYPE_STREAMED 2
+#define ETI_STREAM_TYPE_FRAMED 3
+
+/* Identify the stream type, and return 0 on success, -1 on failure */
+int identify_eti_format(FILE* inputfile, int *stream_type);
+
+/* Read the next ETI frame into buf, which must be at least 6144 bytes big
+ * Return number of bytes read, or zero if EOF */
+int get_eti_frame(FILE* inputfile, int stream_type, void* buf);
+
+#endif
+
diff --git a/etisnoop.cpp b/etisnoop.cpp
index 4688ca9..1baea7d 100644
--- a/etisnoop.cpp
+++ b/etisnoop.cpp
@@ -40,6 +40,7 @@
#include "lib_crc.h"
#include "dabplussnoop.h"
+#include "etiinput.h"
struct FIG {
unsigned short int type;
@@ -59,7 +60,7 @@ struct FIG0_13_shortAppInfo {
using namespace std;
struct eti_analyse_config_t {
- int etifd;
+ FILE* etifd;
bool ignore_error;
std::map<int, DabPlusSnoop> streams_to_decode;
bool analyse_fic_carousel;
@@ -170,15 +171,15 @@ int main(int argc, char *argv[])
}
}
- int etifd;
+ FILE* etifd;
if (file_name == "-") {
printf("Analysing stdin\n");
- etifd = STDIN_FILENO;
+ etifd = stdin;
}
else {
- etifd = open(file_name.c_str(), O_RDONLY);
- if (etifd == -1) {
+ etifd = fopen(file_name.c_str(), "r");
+ if (etifd == NULL) {
perror("File open failed");
return 1;
}
@@ -191,7 +192,7 @@ int main(int argc, char *argv[])
.analyse_fic_carousel = analyse_fic_carousel
};
eti_analyse(config);
- close(etifd);
+ fclose(etifd);
}
int eti_analyse(eti_analyse_config_t& config)
@@ -206,10 +207,34 @@ int eti_analyse(eti_analyse_config_t& config)
unsigned short int sad[64],stl[64];
char sdesc[256];
- while (1) {
+ bool running = true;
- int ret = read(config.etifd, p, ETINIPACKETSIZE);
- if (ret != ETINIPACKETSIZE) {
+ int stream_type = ETI_STREAM_TYPE_NONE;
+ if (identify_eti_format(config.etifd, &stream_type) == -1) {
+ printf("Could not identify stream type\n");
+
+ running = false;
+ }
+ else {
+ printf("Identified ETI type ");
+ if (stream_type == ETI_STREAM_TYPE_RAW)
+ printf("RAW\n");
+ else if (stream_type == ETI_STREAM_TYPE_STREAMED)
+ printf("STREAMED\n");
+ else if (stream_type == ETI_STREAM_TYPE_FRAMED)
+ printf("FRAMED\n");
+ else
+ printf("?\n");
+ }
+
+ while (running) {
+
+ int ret = get_eti_frame(config.etifd, stream_type, p);
+ if (ret == -1) {
+ fprintf(stderr, "ETI file read error\n");
+ break;
+ }
+ else if (ret == 0) {
fprintf(stderr, "End of ETI\n");
break;
}
@@ -226,6 +251,7 @@ int eti_analyse(eti_analyse_config_t& config)
desc = "Error";
printbuf("ERR", 1, p, 1, desc);
if (!config.ignore_error) {
+ printf("Aborting because of SYNC error\n");
break;
}
}