aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias (think) <matthias@mpb.li>2012-07-11 11:49:12 +0200
committerMatthias (think) <matthias@mpb.li>2012-07-11 11:49:12 +0200
commitbbab73a63b8c7b50e8a8cb228999d45024fad984 (patch)
tree81a822aa9bd33cae8a5fb8ade4faa83b652316d9 /src
downloaddabmux-bbab73a63b8c7b50e8a8cb228999d45024fad984.tar.gz
dabmux-bbab73a63b8c7b50e8a8cb228999d45024fad984.tar.bz2
dabmux-bbab73a63b8c7b50e8a8cb228999d45024fad984.zip
added unmodified mmbtools
Diffstat (limited to 'src')
-rw-r--r--src/DabMux.cpp3549
-rw-r--r--src/Dmb.cpp280
-rw-r--r--src/Dmb.h81
-rw-r--r--src/Eti.cpp70
-rw-r--r--src/Eti.h96
-rw-r--r--src/InetAddress.cpp259
-rw-r--r--src/InetAddress.h91
-rw-r--r--src/Interleaver.cpp143
-rw-r--r--src/Interleaver.h56
-rw-r--r--src/Makefile.am66
-rw-r--r--src/Makefile.in1146
-rw-r--r--src/PcDebug.h76
-rw-r--r--src/ReedSolomon.cpp105
-rw-r--r--src/ReedSolomon.h52
-rw-r--r--src/TcpLog.cpp330
-rw-r--r--src/TcpLog.h69
-rw-r--r--src/TcpServer.cpp243
-rw-r--r--src/TcpServer.h84
-rw-r--r--src/TcpSocket.cpp366
-rw-r--r--src/TcpSocket.h97
-rw-r--r--src/UdpSocket.cpp455
-rw-r--r--src/UdpSocket.h126
-rw-r--r--src/bridge.c515
-rw-r--r--src/bridge.h112
-rw-r--r--src/crc.c266
-rw-r--r--src/crc.h59
-rw-r--r--src/dabInput.cpp51
-rw-r--r--src/dabInput.h52
-rw-r--r--src/dabInputBridgeUdp.cpp124
-rw-r--r--src/dabInputBridgeUdp.h49
-rw-r--r--src/dabInputDabplusFifo.cpp186
-rw-r--r--src/dabInputDabplusFifo.h54
-rw-r--r--src/dabInputDabplusFile.cpp176
-rw-r--r--src/dabInputDabplusFile.h62
-rw-r--r--src/dabInputDmbFile.cpp161
-rw-r--r--src/dabInputDmbFile.h49
-rw-r--r--src/dabInputDmbUdp.cpp191
-rw-r--r--src/dabInputDmbUdp.h49
-rw-r--r--src/dabInputEnhancedFifo.cpp64
-rw-r--r--src/dabInputEnhancedFifo.h46
-rw-r--r--src/dabInputEnhancedPacketFile.cpp53
-rw-r--r--src/dabInputEnhancedPacketFile.h47
-rw-r--r--src/dabInputFifo.cpp513
-rw-r--r--src/dabInputFifo.h101
-rw-r--r--src/dabInputFile.cpp104
-rw-r--r--src/dabInputFile.h49
-rw-r--r--src/dabInputMpegFifo.cpp47
-rw-r--r--src/dabInputMpegFifo.h37
-rw-r--r--src/dabInputMpegFile.cpp201
-rw-r--r--src/dabInputMpegFile.h42
-rw-r--r--src/dabInputPacketFile.cpp263
-rw-r--r--src/dabInputPacketFile.h46
-rw-r--r--src/dabInputPrbs.cpp146
-rw-r--r--src/dabInputPrbs.h56
-rw-r--r--src/dabInputRawFifo.cpp193
-rw-r--r--src/dabInputRawFifo.h63
-rw-r--r--src/dabInputRawFile.cpp59
-rw-r--r--src/dabInputRawFile.h45
-rw-r--r--src/dabInputSlip.cpp408
-rw-r--r--src/dabInputSlip.h52
-rw-r--r--src/dabInputTest.cpp105
-rw-r--r--src/dabInputTest.h50
-rw-r--r--src/dabInputUdp.cpp189
-rw-r--r--src/dabInputUdp.h59
-rw-r--r--src/dabOutput.cpp1112
-rw-r--r--src/dabOutput.h72
-rw-r--r--src/dabUtils.cpp52
-rw-r--r--src/dabUtils.h35
-rw-r--r--src/mpeg.c221
-rw-r--r--src/mpeg.h82
-rw-r--r--src/prbs.c140
-rw-r--r--src/prbs.h61
72 files changed, 14809 insertions, 0 deletions
diff --git a/src/DabMux.cpp b/src/DabMux.cpp
new file mode 100644
index 0000000..59278f9
--- /dev/null
+++ b/src/DabMux.cpp
@@ -0,0 +1,3549 @@
+/*
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2011 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <cstdio>
+#include <cstring>
+#include <errno.h>
+
+using namespace std;
+#include <vector>
+#include <set>
+#include <functional>
+#include <algorithm>
+
+#ifdef _WIN32
+# include <time.h>
+# include <process.h>
+# include <io.h>
+# include <conio.h>
+# include <winsock2.h> // 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 <netinet/in.h>
+# include <unistd.h>
+# include <sys/time.h>
+# include <sys/wait.h>
+# include <sys/socket.h>
+# include <sys/ioctl.h>
+# include <sys/times.h>
+
+# include <linux/if_packet.h>
+# include <linux/netdevice.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#ifdef _WIN32
+# pragma warning ( disable : 4103 )
+# include "Eti.h"
+# pragma warning ( default : 4103 )
+#else
+# include "Eti.h"
+#endif
+#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 "dabOutput.h"
+#include "crc.h"
+#include "UdpSocket.h"
+#include "InetAddress.h"
+#include "dabUtils.h"
+#include "PcDebug.h"
+
+
+// DAB Mode
+#define DEFAULT_DAB_MODE 2
+
+// Taille de la trame de donnee, sous-canal 3, nb de paquets de 64bits,
+// STL3 * 8 = x kbytes par trame ETI
+
+// Data bitrate in kbits/s. Must be 64 kb/s multiple.
+#define DEFAULT_DATA_BITRATE 384
+#define DEFAULT_PACKET_BITRATE 32
+
+// Etiquettes des sous-canaux et de l'ensemble, 16 characteres incluant les
+// espaces
+#define DEFAULT_ENSEMBLE_LABEL "CRC-Dr.Radio"
+#define DEFAULT_ENSEMBLE_SHORT_LABEL 0xe000
+#define DEFAULT_ENSEMBLE_ID 0xc000
+#define DEFAULT_ENSEMBLE_ECC 0xa1
+
+//Numeros des sous-canaux
+#define DEFAULT_SERVICE_ID 50
+#define DEFAULT_PACKET_ADDRESS 0
+
+
+struct dabOutput {
+ const char* outputProto;
+ const char* outputName;
+ void* data;
+ dabOutputOperations operations;
+};
+
+
+struct dabLabel {
+ char text[16];
+ uint16_t flag;
+};
+
+
+struct dabService;
+struct dabComponent;
+struct dabSubchannel;
+struct dabEnsemble {
+ uint16_t id;
+ uint8_t ecc;
+ dabLabel label;
+ uint8_t mode;
+ vector<dabService*> services;
+ vector<dabComponent*> components;
+ vector<dabSubchannel*> subchannels;
+};
+
+
+struct dabProtectionShort {
+ unsigned char tableSwitch;
+ unsigned char tableIndex;
+};
+
+
+struct dabProtectionLong {
+ unsigned char option;
+};
+
+
+struct dabProtection {
+ unsigned char level;
+ unsigned char form;
+ union {
+ dabProtectionShort shortForm;
+ dabProtectionLong longForm;
+ };
+};
+
+
+struct dabSubchannel {
+ const char* inputProto;
+ const char* inputName;
+ void* data;
+ dabInputOperations operations;
+ unsigned char id;
+ unsigned char type;
+ uint16_t startAddress;
+ uint16_t bitrate;
+ dabProtection protection;
+};
+
+
+class SubchannelId : public std::binary_function <dabSubchannel*, int, bool> {
+public:
+ bool operator()(const dabSubchannel* subchannel, const int id) const {
+ return subchannel->id == id;
+ }
+};
+
+
+vector<dabSubchannel*>::iterator getSubchannel(
+ vector<dabSubchannel*>& subchannels, int id)
+{
+ return find_if(
+ subchannels.begin(),
+ subchannels.end(),
+ bind2nd(SubchannelId(), id)
+ );
+}
+
+
+struct dabAudioComponent {
+};
+
+
+struct dabDataComponent {
+};
+
+
+struct dabFidcComponent {
+};
+
+
+struct dabPacketComponent {
+ uint16_t id;
+ uint16_t address;
+ uint16_t appType;
+ bool datagroup;
+};
+
+
+struct dabComponent {
+ dabLabel label;
+ uint32_t serviceId;
+ uint8_t subchId;
+ uint8_t type;
+ uint8_t SCIdS;
+ union {
+ dabAudioComponent audio;
+ dabDataComponent data;
+ dabFidcComponent fidc;
+ dabPacketComponent packet;
+ };
+
+ bool isPacketComponent(vector<dabSubchannel*>& subchannels)
+ {
+ if (subchId > 63) {
+ etiLog.printHeader(TcpLog::ERR,
+ "You must define subchannel id in the "
+ "packet component before defining packet ");
+ return false;
+ }
+ if (getSubchannel(subchannels, subchId) == subchannels.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Invalid subchannel id in the packet component "
+ "for defining packet ");
+ return false;
+ }
+ if ((*getSubchannel(subchannels, subchId))->type != 3) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Invalid component type for defining packet ");
+ return false;
+ }
+ return true;
+ }
+};
+
+
+vector<dabComponent*>::iterator getComponent(
+ vector<dabComponent*>& components,
+ uint32_t serviceId,
+ vector<dabComponent*>::iterator current)
+{
+ if (current == components.end()) {
+ current = components.begin();
+ } else {
+ ++current;
+ }
+
+ while (current != components.end()) {
+ if ((*current)->serviceId == serviceId) {
+ return current;
+ }
+ ++current;
+ }
+
+ return components.end();
+}
+
+
+vector<dabComponent*>::iterator getComponent(
+ vector<dabComponent*>& components,
+ uint32_t serviceId) {
+ return getComponent(components, serviceId, components.end());
+}
+
+
+struct dabService {
+ dabLabel label;
+ uint32_t id;
+ unsigned char pty;
+ unsigned char language;
+ bool program;
+
+ unsigned char getType(dabEnsemble* ensemble)
+ {
+ vector<dabSubchannel*>::iterator subchannel;
+ vector<dabComponent*>::iterator component =
+ getComponent(ensemble->components, id);
+ if (component == ensemble->components.end()) {
+ return 4;
+ }
+ subchannel = getSubchannel(ensemble->subchannels, (*component)->subchId);
+ if (subchannel == ensemble->subchannels.end()) {
+ return 8;
+ }
+
+ return (*subchannel)->type;
+ }
+ unsigned char nbComponent(vector<dabComponent*>& components)
+ {
+ int nb = 0;
+ vector<dabComponent*>::iterator current;
+
+ for (current = components.begin(); current != components.end();
+ ++current) {
+ if ((*current)->serviceId == id) {
+ ++nb;
+ }
+ }
+ return nb;
+ }
+};
+
+
+vector<dabService*>::iterator getService(
+ dabComponent* component,
+ vector<dabService*>& services)
+{
+ vector<dabService*>::iterator service;
+
+ for (service = services.begin(); service != services.end(); ++service) {
+ if ((*service)->id == component->serviceId) {
+ break;
+ }
+ }
+
+ return service;
+}
+
+
+/******************************************************************************
+ ***************** Definitions des stuctures des FIGs **********************
+ ******************************************************************************/
+struct FIGtype0 {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:5;
+ uint8_t PD:1;
+ uint8_t OE:1;
+ uint8_t CN:1;
+} PACKED;
+
+
+struct FIGtype0_0 {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:5;
+ uint8_t PD:1;
+ uint8_t OE:1;
+ uint8_t CN:1;
+
+ uint16_t EId;
+ uint8_t CIFcnt_hight:5;
+ uint8_t Al:1;
+ uint8_t Change:2;
+ uint8_t CIFcnt_low:8;
+} PACKED;
+
+
+struct FIGtype0_2 {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:5;
+ uint8_t PD:1;
+ uint8_t OE:1;
+ uint8_t CN:1;
+} PACKED;
+
+
+struct FIGtype0_2_Service {
+ uint16_t SId;
+ uint8_t NbServiceComp:4;
+ uint8_t CAId:3;
+ uint8_t Local_flag:1;
+} PACKED;
+
+
+struct FIGtype0_2_Service_data {
+ uint32_t SId;
+ uint8_t NbServiceComp:4;
+ uint8_t CAId:3;
+ uint8_t Local_flag:1;
+} PACKED;
+
+
+struct FIGtype0_2_audio_component {
+ uint8_t ASCTy:6;
+ uint8_t TMid:2;
+ uint8_t CA_flag:1;
+ uint8_t PS:1;
+ uint8_t SubChId:6;
+} PACKED;
+
+
+struct FIGtype0_2_data_component {
+ uint8_t DSCTy:6;
+ uint8_t TMid:2;
+ uint8_t CA_flag:1;
+ uint8_t PS:1;
+ uint8_t SubChId:6;
+} PACKED;
+
+
+struct FIGtype0_2_packet_component {
+ uint8_t SCId_high:6;
+ uint8_t TMid:2;
+ uint8_t CA_flag:1;
+ uint8_t PS:1;
+ uint8_t SCId_low:6;
+ void setSCId(uint16_t SCId) {
+ SCId_high = SCId >> 6;
+ SCId_low = SCId & 0x3f;
+ }
+} PACKED;
+
+
+struct FIGtype0_3_header {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:5;
+ uint8_t PD:1;
+ uint8_t OE:1;
+ uint8_t CN:1;
+} PACKED;
+
+
+/* Warning: When bit SCCA_flag is unset(0), the multiplexer R&S does not send
+ * the SCCA field. But, in the Factum ETI analyzer, if this field is not there,
+ * it is an error.
+ */
+struct FIGtype0_3_data {
+ uint8_t SCId_high;
+ uint8_t SCCA_flag:1;
+ uint8_t rfa:3;
+ uint8_t SCId_low:4;
+ uint8_t DSCTy:6;
+ uint8_t rfu:1;
+ uint8_t DG_flag:1;
+ uint8_t Packet_address_high:2;
+ uint8_t SubChId:6;
+ uint8_t Packet_address_low;
+ uint16_t SCCA;
+ void setSCId(uint16_t SCId) {
+ SCId_high = SCId >> 4;
+ SCId_low = SCId & 0xf;
+ }
+ void setPacketAddress(uint16_t address) {
+ Packet_address_high = address >> 8;
+ Packet_address_low = address & 0xff;
+ }
+} PACKED;
+
+
+struct FIGtype0_8_short {
+ uint8_t SCIdS:4;
+ uint8_t rfa_1:3;
+ uint8_t ext:1;
+ uint8_t Id:6;
+ uint8_t MscFic:1;
+ uint8_t LS:1;
+ uint8_t rfa_2;
+} PACKED;
+
+
+struct FIGtype0_8_long {
+ uint8_t SCIdS:4;
+ uint8_t rfa_1:3;
+ uint8_t ext:1;
+ uint8_t SCId_high:4;
+ uint8_t rfa:3;
+ uint8_t LS:1;
+ uint8_t SCId_low;
+ uint8_t rfa_2;
+ void setSCId(uint16_t id) {
+ SCId_high = id >> 8;
+ SCId_low = id & 0xff;
+ }
+ uint16_t getSCid() {
+ return (SCId_high << 8) | SCId_low;
+ }
+} PACKED;
+
+
+struct FIGtype0_9 {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:5;
+ uint8_t PD:1;
+ uint8_t OE:1;
+ uint8_t CN:1;
+
+ uint8_t ensembleLto:6;
+ uint8_t lto:1;
+ uint8_t ext:1;
+ uint8_t ensembleEcc;
+ uint8_t tableId;
+} PACKED;
+
+
+struct FIGtype0_10 {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:5;
+ uint8_t PD:1;
+ uint8_t OE:1;
+ uint8_t CN:1;
+
+ uint8_t MJD_high:7;
+ uint8_t RFU:1;
+ uint8_t MJD_med;
+ uint8_t Hours_high:3;
+ uint8_t UTC:1;
+ uint8_t ConfInd:1;
+ uint8_t LSI:1;
+ uint8_t MJD_low:2;
+ uint8_t Minutes:6;
+ uint8_t Hours_low:2;
+ void setMJD(uint32_t date) {
+ MJD_high = (date >> 10) & 0x7f;
+ MJD_med = (date >> 2) & 0xff;
+ MJD_low = date & 0x03;
+ }
+ void setHours(uint16_t hours) {
+ Hours_high = (hours >> 2) & 0x07;
+ Hours_low = hours & 0x03;
+ }
+} PACKED;
+
+
+struct FIGtype0_17_programme {
+ uint16_t SId;
+ uint8_t NFC:2;
+ uint8_t Rfa:2;
+ uint8_t CC:1;
+ uint8_t L:1;
+ uint8_t PS:1;
+ uint8_t SD:1;
+} PACKED;
+
+
+struct FIGtype0_1 {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:5;
+ uint8_t PD:1;
+ uint8_t OE:1;
+ uint8_t CN:1;
+} PACKED;
+
+
+struct FIG_01_SubChannel_ShortF {
+ uint8_t StartAdress_high:2;
+ uint8_t SubChId:6;
+ uint8_t StartAdress_low:8;
+ uint8_t TableIndex:6;
+ uint8_t TableSwitch:1;
+ uint8_t Short_Long_form:1;
+} PACKED;
+
+
+struct FIG_01_SubChannel_LongF {
+ uint8_t StartAdress_high:2;
+ uint8_t SubChId:6;
+ uint8_t StartAdress_low:8;
+ uint8_t Sub_ChannelSize_high:2;
+ uint8_t ProtectionLevel:2;
+ uint8_t Option:3;
+ uint8_t Short_Long_form:1;
+ uint8_t Sub_ChannelSize_low:8;
+} PACKED;
+
+
+struct FIG0_13_shortAppInfo {
+ uint16_t SId;
+ uint8_t No:4;
+ uint8_t SCIdS:4;
+} PACKED;
+
+
+struct FIG0_13_longAppInfo {
+ uint32_t SId;
+ uint8_t No:4;
+ uint8_t SCIdS:4;
+} PACKED;
+
+
+struct FIG0_13_app {
+ uint8_t typeHigh;
+ uint8_t length:5;
+ uint8_t typeLow:3;
+ void setType(uint16_t type) {
+ typeHigh = type >> 3;
+ typeLow = type & 0x1f;
+ }
+} PACKED;
+
+
+struct FIGtype1_0 {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:3;
+ uint8_t OE:1;
+ uint8_t Charset:4;
+
+ uint16_t EId;
+} PACKED;
+
+
+struct FIGtype1_1 {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:3;
+ uint8_t OE:1;
+ uint8_t Charset:4;
+
+ uint16_t Sld;
+} PACKED;
+
+
+struct FIGtype1_5 {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:3;
+ uint8_t OE:1;
+ uint8_t Charset:4;
+ uint32_t SId;
+} PACKED;
+
+
+struct FIGtype1_4_programme {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:3;
+ uint8_t OE:1;
+ uint8_t Charset:4;
+ uint8_t SCIdS:4;
+ uint8_t rfa:3;
+ uint8_t PD:1;
+ uint16_t SId;
+} PACKED;
+
+
+struct FIGtype1_4_data {
+ uint8_t Length:5;
+ uint8_t FIGtypeNumber:3;
+ uint8_t Extension:3;
+ uint8_t OE:1;
+ uint8_t Charset:4;
+ uint8_t SCIdS:4;
+ uint8_t rfa:3;
+ uint8_t PD:1;
+ uint32_t SId;
+} PACKED;
+
+
+#ifdef _WIN32
+# pragma pack(pop)
+#endif
+
+static unsigned char Padding_FIB[] = {
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/******************************************************************************
+ ************* Tables pour l'identification des fichiers mp2 ****************
+ *****************************************************************************/
+const unsigned short Bit_Rate_SpecifiedTable[16] = {
+ 0, 32, 48, 56, 64, 80, 96, 112,
+ 128, 160, 192, 224, 256, 320, 384, 0
+};
+
+
+const unsigned short Sub_Channel_SizeTable[64] = {
+ 16, 21, 24, 29, 35, 24, 29, 35,
+ 42, 52, 29, 35, 42, 52, 32, 42,
+ 48, 58, 70, 40, 52, 58, 70, 84,
+ 48, 58, 70, 84, 104, 58, 70, 84,
+ 104, 64, 84, 96, 116, 140, 80, 104,
+ 116, 140, 168, 96, 116, 140, 168, 208,
+ 116, 140, 168, 208, 232, 128, 168, 192,
+ 232, 280, 160, 208, 280, 192, 280, 416
+};
+
+
+const unsigned char ProtectionLevelTable[64] = {
+ 4, 3, 2, 1, 0, 4, 3, 2,
+ 1, 0, 4, 3, 2, 1, 4, 3,
+ 2, 1, 0, 4, 3, 2, 1, 0,
+ 4, 3, 2, 1, 0, 4, 3, 2,
+ 1, 4, 3, 2, 1, 0, 4, 3,
+ 2, 1, 0, 4, 3, 2, 1, 0,
+ 4, 3, 2, 1, 0, 4, 3, 2,
+ 1, 0, 4, 3, 1, 4, 2, 0
+};
+
+
+const unsigned short BitRateTable[64] = {
+ 32, 32, 32, 32, 32, 48, 48, 48,
+ 48, 48, 56, 56, 56, 56, 64, 64,
+ 64, 64, 64, 80, 80, 80, 80, 80,
+ 96, 96, 96, 96, 96, 112, 112, 112,
+ 112, 128, 128, 128, 128, 128, 160, 160,
+ 160, 160, 160, 192, 192, 192, 192, 192,
+ 224, 224, 224, 224, 224, 256, 256, 256,
+ 256, 256, 320, 320, 320, 384, 384, 384
+};
+
+
+unsigned short getSizeByte(dabSubchannel* subchannel)
+{
+ return subchannel->bitrate * 3;
+}
+
+
+unsigned short getSizeWord(dabSubchannel* subchannel)
+{
+ return (subchannel->bitrate * 3) >> 2;
+}
+
+
+unsigned short getSizeDWord(dabSubchannel* subchannel)
+{
+ return (subchannel->bitrate * 3) >> 3;
+}
+
+
+unsigned short getSizeCu(dabSubchannel* subchannel)
+{
+ if (subchannel->protection.form == 0) {
+ return Sub_Channel_SizeTable[subchannel->
+ protection.shortForm.tableIndex];
+ } else {
+ dabProtectionLong* protection =
+ &subchannel->protection.longForm;
+ switch (protection->option) {
+ case 0:
+ switch (subchannel->protection.level) {
+ case 0:
+ return (subchannel->bitrate * 12) >> 3;
+ break;
+ case 1:
+ return subchannel->bitrate;
+ break;
+ case 2:
+ return (subchannel->bitrate * 6) >> 3;
+ break;
+ case 3:
+ return (subchannel->bitrate >> 1);
+ break;
+ default: // Should not happens
+ etiLog.print(TcpLog::ERR, "Bad protection level on "
+ "subchannel\n");
+ return 0;
+ }
+ break;
+ case 1:
+ switch (subchannel->protection.level) {
+ case 0:
+ return (subchannel->bitrate * 27) >> 5;
+ break;
+ case 1:
+ return (subchannel->bitrate * 21) >> 5;
+ break;
+ case 2:
+ return (subchannel->bitrate * 18) >> 5;
+ break;
+ case 3:
+ return (subchannel->bitrate * 15) >> 5;
+ break;
+ default: // Should not happens
+ etiLog.print(TcpLog::ERR,
+ "Bad protection level on subchannel\n");
+ return 0;
+ }
+ break;
+ default:
+ etiLog.print(TcpLog::ERR, "Invalid protection option\n");
+ return 0;
+ }
+ }
+ return 0;
+}
+
+
+time_t getDabTime()
+{
+ static time_t oldTime = 0;
+ static int offset = 0;
+ if (oldTime == 0) {
+ oldTime = time(NULL);
+ } else {
+ offset+= 24;
+ if (offset >= 1000) {
+ offset -= 1000;
+ ++oldTime;
+ }
+ }
+ return oldTime;
+}
+
+
+void printUsage(char *name, FILE* out = stderr)
+{
+ fprintf(out, "NAME\n");
+ fprintf(out, " %s - A software DAB multiplexer\n", name);
+ fprintf(out, "\nSYNOPSYS\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"
+ " | CRC-Ensemble | ENSEMBLE\n"
+ " |__________________________________________________|\n"
+ " | | |\n"
+ " | | |\n"
+ " _______V______ _______V______ _______V______\n"
+ " | CRC-Service1 | | CRC-Service2 | | CRC-Service3 | 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 : turn on TCP log on port 12222\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<n> : 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<n> : 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");
+ 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<n> : service|subchannel|"
+ "serviceComponent id <n> (default: <n>)\n");
+ fprintf(out, " -k : set non-blocking file input "
+ "(audio and packet only)\n");
+ fprintf(out, " -L label<n> : label of service <n>"
+ " (default: CRC-Audio<n>)\n");
+ fprintf(out, " -l sLabel<n> : short label flag of service <n>"
+ " (default: 0xf040)\n");
+ fprintf(out, " -p protection<n> : protection level (default: 3)\n");
+ fprintf(out, " -s : enable TIST, synchronized on 1PPS at level 2\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"
+ );
+}
+
+
+bool running = true;
+
+void signalHandler(int signum)
+{
+#ifdef _WIN32
+ etiLog.print(TcpLog::DBG, "\npid: %i\n", _getpid());
+#else
+ etiLog.print(TcpLog::DBG, "\npid: %i, ppid: %i\n", getpid(), getppid());
+#endif
+ etiLog.print(TcpLog::DBG, "Signal handler called with signal ");
+ switch (signum) {
+#ifndef _WIN32
+ case SIGHUP:
+ etiLog.print(TcpLog::DBG, "SIGHUP\n");
+ break;
+ case SIGQUIT:
+ etiLog.print(TcpLog::DBG, "SIGQUIT\n");
+ break;
+ case SIGPIPE:
+ etiLog.print(TcpLog::DBG, "SIGPIPE\n");
+ return;
+ break;
+#endif
+ case SIGINT:
+ etiLog.print(TcpLog::DBG, "SIGINT\n");
+ break;
+ case SIGTERM:
+ etiLog.print(TcpLog::DBG, "SIGTERM\n");
+ etiLog.print(TcpLog::DBG, "Exiting software\n");
+ exit(0);
+ break;
+ default:
+ etiLog.print(TcpLog::DBG, "number %i\n", signum);
+ }
+#ifndef _WIN32
+ killpg(0, SIGPIPE);
+#endif
+ running = false;
+}
+
+
+void printEnsemble(dabEnsemble* ensemble)
+{
+ char label[17];
+ memcpy(label, ensemble->label.text, 16);
+ label[16] = 0;
+
+ etiLog.printHeader(TcpLog::INFO, "Ensemble\n");
+ etiLog.printHeader(TcpLog::INFO, " id: 0x%lx (%lu)\n",
+ ensemble->id, ensemble->id);
+ etiLog.printHeader(TcpLog::INFO, " ecc: 0x%x (%u)\n",
+ ensemble->ecc, ensemble->ecc);
+ etiLog.printHeader(TcpLog::INFO, " label: %s\n", label);
+ etiLog.printHeader(TcpLog::INFO, " short label: ");
+ for (int i = 0; i < 32; ++i) {
+ if (ensemble->label.flag & 0x8000 >> i) {
+ etiLog.printHeader(TcpLog::INFO, "%c", ensemble->label.text[i]);
+ }
+ }
+ etiLog.printHeader(TcpLog::INFO, " (0x%x)\n", ensemble->label.flag);
+ etiLog.printHeader(TcpLog::INFO, " mode: %u\n", ensemble->mode);
+}
+
+
+void printSubchannels(vector<dabSubchannel*>& subchannels)
+{
+ vector<dabSubchannel*>::iterator subchannel;
+ int index = 0;
+
+ for (subchannel = subchannels.begin(); subchannel != subchannels.end();
+ ++subchannel) {
+ dabProtection* protection = &(*subchannel)->protection;
+ etiLog.printHeader(TcpLog::INFO, "Subchannel %i\n", index);
+ etiLog.printHeader(TcpLog::INFO, " input\n");
+ etiLog.printHeader(TcpLog::INFO, " protocol: %s\n",
+ (*subchannel)->inputProto);
+ etiLog.printHeader(TcpLog::INFO, " name: %s\n",
+ (*subchannel)->inputName);
+ etiLog.printHeader(TcpLog::INFO, " type: ");
+ switch ((*subchannel)->type) {
+ case 0:
+ etiLog.printHeader(TcpLog::INFO, "audio\n");
+ break;
+ case 1:
+ etiLog.printHeader(TcpLog::INFO, "data\n");
+ break;
+ case 2:
+ etiLog.printHeader(TcpLog::INFO, "fidc\n");
+ break;
+ case 3:
+ etiLog.printHeader(TcpLog::INFO, "packet\n");
+ break;
+ default:
+ etiLog.printHeader(TcpLog::INFO, "Unknown data type "
+ "(service->type)\n");
+ break;
+ }
+ etiLog.printHeader(TcpLog::INFO, " id: %i\n",
+ (*subchannel)->id);
+ etiLog.printHeader(TcpLog::INFO, " bitrate: %i\n",
+ (*subchannel)->bitrate);
+ etiLog.printHeader(TcpLog::INFO, " protection: ");
+ if (protection->form == 0) {
+ etiLog.printHeader(TcpLog::INFO, "UEP %i\n", protection->level + 1);
+ } else {
+ etiLog.printHeader(TcpLog::INFO, "EEP %i-%c\n",
+ protection->level + 1,
+ protection->longForm.option == 0 ? 'A' : 'B');
+ }
+ if (protection->form == 0) {
+ etiLog.printHeader(TcpLog::INFO,
+ " form: short\n switch: %i\n index: %i\n",
+ protection->shortForm.tableSwitch,
+ protection->shortForm.tableIndex);
+ } else {
+ etiLog.printHeader(TcpLog::INFO,
+ " form: long\n option: %i\n level: %i\n",
+ protection->longForm.option,
+ (*subchannel)->protection.level);
+ }
+ etiLog.printHeader(TcpLog::INFO, " SAD: %i\n",
+ (*subchannel)->startAddress);
+ etiLog.printHeader(TcpLog::INFO, " size (CU): %i\n",
+ getSizeCu(*subchannel));
+ ++index;
+ }
+}
+
+
+void printComponent(dabComponent* component)
+{
+ char label[17];
+ memcpy(label, component->label.text, 16);
+ label[16] = 0;
+ if (label[0] == 0) {
+ sprintf(label, "<none>");
+ }
+
+ etiLog.printHeader(TcpLog::INFO, " service id: %i\n",
+ component->serviceId);
+ etiLog.printHeader(TcpLog::INFO, " subchannel id: %i\n",
+ component->subchId);
+ etiLog.printHeader(TcpLog::INFO, " label: %s\n",
+ label);
+ etiLog.printHeader(TcpLog::INFO, " short label: ");
+ for (int i = 0; i < 32; ++i) {
+ if (component->label.flag & 0x8000 >> i) {
+ etiLog.printHeader(TcpLog::INFO, "%c", component->label.text[i]);
+ }
+ }
+ etiLog.printHeader(TcpLog::INFO, " (0x%x)\n", component->label.flag);
+ etiLog.printHeader(TcpLog::INFO, " service component type: 0x%x (%u)\n",
+ component->type, component->type);
+ etiLog.printHeader(TcpLog::INFO, " (packet) id: %u\n",
+ component->packet.id);
+ etiLog.printHeader(TcpLog::INFO, " (packet) address: %u\n",
+ component->packet.address);
+ etiLog.printHeader(TcpLog::INFO, " (packet) app type: %u\n",
+ component->packet.appType);
+ etiLog.printHeader(TcpLog::INFO, " (packet) datagroup: %u\n",
+ component->packet.datagroup);
+}
+
+
+void printComponents(vector<dabComponent*>& components)
+{
+ vector<dabComponent*>::const_iterator current;
+ unsigned int index = 0;
+
+ for (current = components.begin(); current != components.end(); ++current) {
+ etiLog.printHeader(TcpLog::INFO, "Component %i\n", index);
+ printComponent(*current);
+ ++index;
+ }
+}
+
+
+void printServices(vector<dabService*>& services)
+{
+ vector<dabService*>::const_iterator current;
+ int index = 0;
+
+ for (current = services.begin(); current != services.end(); ++current) {
+ char label[17];
+ memcpy(label, (*current)->label.text, 16);
+ label[16] = 0;
+
+ etiLog.printHeader(TcpLog::INFO, "Service %i\n", index);
+ etiLog.printHeader(TcpLog::INFO, " label: %s\n", label);
+ etiLog.printHeader(TcpLog::INFO, " short label: ");
+ for (int i = 0; i < 32; ++i) {
+ if ((*current)->label.flag & 0x8000 >> i) {
+ etiLog.printHeader(TcpLog::INFO, "%c", (*current)->label.text[i]);
+ }
+ }
+ etiLog.printHeader(TcpLog::INFO, " (0x%x)\n", (*current)->label.flag);
+ etiLog.printHeader(TcpLog::INFO, " id: 0x%lx (%lu)\n",
+ (*current)->id, (*current)->id);
+ etiLog.printHeader(TcpLog::INFO, " pty: 0x%x (%u)\n",
+ (*current)->pty, (*current)->pty);
+ etiLog.printHeader(TcpLog::INFO, " language: 0x%x (%u)\n",
+ (*current)->language, (*current)->language);
+ ++index;
+ }
+}
+
+
+void printOutputs(vector<dabOutput*>& outputs)
+{
+ vector<dabOutput*>::const_iterator output;
+ int index = 0;
+
+ for (output = outputs.begin(); output != outputs.end(); ++output) {
+ etiLog.printHeader(TcpLog::INFO, "Output %i\n", index);
+ etiLog.printHeader(TcpLog::INFO, " protocol: %s\n",
+ (*output)->outputProto);
+ etiLog.printHeader(TcpLog::INFO, " name: %s\n",
+ (*output)->outputName);
+ ++index;
+ }
+}
+
+
+int main(int argc, char *argv[])
+{
+ etiLog.printHeader(TcpLog::INFO,
+ "Welcome to %s %s, compiled at %s, %s\n\n",
+ PACKAGE_NAME, PACKAGE_VERSION, __DATE__, __TIME__);
+ etiLog.printHeader(TcpLog::INFO,
+ "Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011\n"
+ "Her Majesty the Queen in Right of Canada,\n"
+ "(Communications Research Centre Canada) All rights reserved.\n\n");
+ etiLog.printHeader(TcpLog::INFO, "Input URLs supported:");
+#if defined(HAVE_INPUT_PRBS)
+ etiLog.printHeader(TcpLog::INFO, " prbs");
+#endif
+#if defined(HAVE_INPUT_TEST)
+ etiLog.printHeader(TcpLog::INFO, " test");
+#endif
+#if defined(HAVE_INPUT_SLIP)
+ etiLog.printHeader(TcpLog::INFO, " slip");
+#endif
+#if defined(HAVE_INPUT_UDP)
+ etiLog.printHeader(TcpLog::INFO, " udp");
+#endif
+#if defined(HAVE_INPUT_FIFO)
+ etiLog.printHeader(TcpLog::INFO, " fifo");
+#endif
+#if defined(HAVE_INPUT_FILE)
+ etiLog.printHeader(TcpLog::INFO, " file");
+#endif
+ etiLog.printHeader(TcpLog::INFO, "\n");
+
+ etiLog.printHeader(TcpLog::INFO, "Inputs format supported:");
+#if defined(HAVE_FORMAT_RAW)
+ etiLog.printHeader(TcpLog::INFO, " raw");
+#endif
+#if defined(HAVE_FORMAT_BRIDGE)
+ etiLog.printHeader(TcpLog::INFO, " bridge");
+#endif
+#if defined(HAVE_FORMAT_MPEG)
+ etiLog.printHeader(TcpLog::INFO, " mpeg");
+#endif
+#if defined(HAVE_FORMAT_PACKET)
+ etiLog.printHeader(TcpLog::INFO, " packet");
+#endif
+#if defined(HAVE_FORMAT_DMB)
+ etiLog.printHeader(TcpLog::INFO, " dmb");
+#endif
+#if defined(HAVE_FORMAT_EPM)
+ etiLog.printHeader(TcpLog::INFO, " epm");
+#endif
+ etiLog.printHeader(TcpLog::INFO, "\n");
+
+ etiLog.printHeader(TcpLog::INFO, "Output URLs supported:");
+#if defined(HAVE_OUTPUT_FILE)
+ etiLog.printHeader(TcpLog::INFO, " file");
+#endif
+#if defined(HAVE_OUTPUT_FIFO)
+ etiLog.printHeader(TcpLog::INFO, " fifo");
+#endif
+#if defined(HAVE_OUTPUT_UDP)
+ etiLog.printHeader(TcpLog::INFO, " udp");
+#endif
+#if defined(HAVE_OUTPUT_TCP)
+ etiLog.printHeader(TcpLog::INFO, " tcp");
+#endif
+#if defined(HAVE_OUTPUT_RAW)
+ etiLog.printHeader(TcpLog::INFO, " raw");
+#endif
+#if defined(HAVE_OUTPUT_SIMUL)
+ etiLog.printHeader(TcpLog::INFO, " simul");
+#endif
+ etiLog.printHeader(TcpLog::INFO, "\n\n");
+
+ /* for (int signum = 1; signum < 16; ++signum) {
+ signal(signum, signalHandler);
+ }*/
+#ifndef _WIN32
+ signal(SIGHUP, signalHandler);
+ signal(SIGQUIT, signalHandler);
+#endif
+ signal(SIGINT, signalHandler);
+ signal(SIGTERM, signalHandler);
+ //signal(SIGPIPE, signalHandler);
+
+#ifdef _WIN32
+ if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST) == 0) {
+ etiLog.printHeader(TcpLog::WARNING, "Can't increase priority: %s\n",
+ strerror(errno));
+ }
+#else
+ if (setpriority(PRIO_PROCESS, 0, -20) == -1) {
+ etiLog.printHeader(TcpLog::WARNING, "Can't increase priority: %s\n",
+ strerror(errno));
+ }
+#endif
+ /*sched_param scheduler;
+ scheduler.sched_priority = 99; // sched_get_priority_max(SCHED_RR)
+ if (sched_setscheduler(0, SCHED_RR, &scheduler) == -1) {
+ etiLog.print(TcpLog::WARNING, "Can't increased priority: %s\n",
+ strerror(errno));
+ }*/
+
+ uint8_t watermarkData[128];
+ size_t watermarkSize = 0;
+ size_t watermarkPos = 0;
+ {
+ uint8_t buffer[sizeof(watermarkData) / 2];
+ snprintf((char*)buffer, sizeof(buffer),
+ "%s %s, compiled at %s, %s",
+ PACKAGE_NAME, PACKAGE_VERSION, __DATE__, __TIME__);
+ memset(watermarkData, 0, sizeof(watermarkData));
+ watermarkData[0] = 0x55; // Sync
+ watermarkData[1] = 0x55;
+ watermarkSize = 16;
+ for (unsigned i = 0; i < strlen((char*)buffer); ++i) {
+ for (int j = 0; j < 8; ++j) {
+ uint8_t bit = (buffer[watermarkPos >> 3] >> (7 - (watermarkPos & 0x07))) & 1;
+ watermarkData[watermarkSize >> 3] |= bit << (7 - (watermarkSize & 0x07));
+ ++watermarkSize;
+ bit = 1;
+ watermarkData[watermarkSize >> 3] |= bit << (7 - (watermarkSize & 0x07));
+ ++watermarkSize;
+ ++watermarkPos;
+ }
+ }
+ }
+ watermarkPos = 0;
+
+
+ dabEnsemble* ensemble = new dabEnsemble;
+ strncpy(ensemble->label.text, DEFAULT_ENSEMBLE_LABEL, 16);
+ ensemble->mode = DEFAULT_DAB_MODE;
+ ensemble->label.flag = DEFAULT_ENSEMBLE_SHORT_LABEL;
+ ensemble->id = DEFAULT_ENSEMBLE_ID;
+ ensemble->ecc = DEFAULT_ENSEMBLE_ECC;
+
+ vector<dabOutput*> outputs;
+ vector<dabService*>::iterator service = ensemble->services.end();
+ vector<dabService*>::iterator serviceProgramInd;
+ vector<dabService*>::iterator serviceDataInd;
+ vector<dabService*>::iterator servicePty;
+ vector<dabComponent*>::iterator component = ensemble->components.end();
+ vector<dabComponent*>::iterator componentIndicatorProgram;
+ vector<dabComponent*>::iterator componentIndicatorData;
+ vector<dabSubchannel*>::iterator subchannel = ensemble->subchannels.end();
+ vector<dabSubchannel*>::iterator subchannelIndicator;
+ vector<dabOutput*>::iterator output;
+ dabProtection* protection = NULL;
+
+ unsigned int currentFrame;
+ int returnCode = 0;
+ int result;
+ int cur;
+ unsigned char etiFrame[6144];
+ unsigned short index = 0;
+ //FIC Length, DAB Mode I, II, IV -> FICL = 24, DAB Mode III -> FICL = 32
+ unsigned FICL = (ensemble->mode == 3 ? 32 : 24);
+
+ unsigned long sync = 0x49C5F8;
+ unsigned short FLtmp = 0;
+ unsigned short nbBytesCRC = 0;
+ unsigned short CRCtmp = 0xFFFF;
+ unsigned short MSTsize = 0;
+
+ unsigned int insertFIG = 0;
+ unsigned int alterneFIB = 0;
+
+ bool factumAnalyzer = false;
+ unsigned long limit = 0;
+ time_t date;
+ unsigned timestamp = 0xffffff;
+
+
+ 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:st:y:z");
+ if (c == -1) {
+ break;
+ }
+ switch (c) {
+ case 'O':
+ outputs.push_back(new dabOutput);
+ output = outputs.end() - 1;
+
+ memset(*output, 0, sizeof(dabOutput));
+ (*output)->outputProto = NULL;
+ (*output)->outputName = NULL;
+ (*output)->data = NULL;
+ (*output)->operations = dabOutputDefaultOperations;
+
+ char* proto;
+
+ proto = strstr(optarg, "://");
+ if (proto == NULL) {
+ etiLog.printHeader(TcpLog::ERR,
+ "No protocol defined for output\n");
+ returnCode = -1;
+ goto EXIT;
+ } else {
+ (*output)->outputProto = optarg;
+ (*output)->outputName = proto + 3;
+ *proto = 0;
+ }
+ 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();
+
+ memset((*service)->label.text, 0, 16);
+ sprintf((*service)->label.text, "CRC-Service%i",
+ (int)ensemble->services.size());
+ (*service)->label.flag = 0xe01f;
+ (*service)->id = DEFAULT_SERVICE_ID + ensemble->services.size();
+ (*service)->pty = 0;
+ (*service)->language = 0;
+ currentFrame = 0; // Will be used temporaly for SCIdS
+
+ break;
+ case 'C':
+ if (service == ensemble->services.end()) {
+ etiLog.printHeader(TcpLog::ERR, "You must define a service"
+ " before using option -%c\n", c);
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ ensemble->components.push_back(new dabComponent);
+
+ component = ensemble->components.end() - 1;
+ subchannel = ensemble->subchannels.end();
+ protection = NULL;
+ output = outputs.end();
+
+ memset(*component, 0, sizeof(dabComponent));
+ memset((*component)->label.text, 0, 16);
+ (*component)->label.flag = 0xffff;
+ (*component)->serviceId = (*service)->id;
+ (*component)->subchId = (*(ensemble->subchannels.end() - 1))->id;
+ (*component)->SCIdS = currentFrame++;
+ break;
+ case 'A':
+ case 'B':
+ case 'D':
+ case 'E':
+ case 'F':
+ case 'M':
+ case 'P':
+ case 'T':
+ if (optarg == NULL && c != 'T') {
+ etiLog.printHeader(TcpLog::ERR,
+ "Missing parameter for option -%c\n", c);
+ printUsage(progName);
+ returnCode = -1;
+ 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 = 0;
+ (*subchannel)->bitrate = 0;
+ (*subchannel)->operations = dabInputMpegFileOperations;
+#endif // defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_MPEG)
+#if defined(HAVE_FORMAT_DABPLUS)
+ } else if (c == 'F') {
+ (*subchannel)->type = 0;
+ (*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) {
+ (*subchannel)->operations = dabInputDabplusFileOperations;
+#endif // defined(HAVE_INPUT_FILE)
+ } else {
+ etiLog.printHeader(TcpLog::ERR,
+ "Invalid protocol for DAB+ input (%s)\n",
+ (*subchannel)->inputProto);
+ printUsage(progName);
+ returnCode = -1;
+ 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) {
+ (*subchannel)->operations = dabInputBridgeUdpOperations;
+#endif // defined(HAVE_INPUT_UDP)
+#if defined(HAVE_INPUT_SLIP)
+ } else if (strcmp((*subchannel)->inputProto, "slip") == 0) {
+ (*subchannel)->operations = dabInputSlipOperations;
+#endif // defined(HAVE_INPUT_SLIP)
+#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) {
+ (*subchannel)->operations = dabInputUdpOperations;
+#endif
+#if defined(HAVE_INPUT_PRBS) && defined(HAVE_FORMAT_RAW)
+ } else if (strcmp((*subchannel)->inputProto, "prbs") == 0) {
+ (*subchannel)->operations = dabInputPrbsOperations;
+#endif
+#if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_RAW)
+ } else if (strcmp((*subchannel)->inputProto, "file") == 0) {
+ (*subchannel)->operations = dabInputRawFileOperations;
+#endif
+ } else if (strcmp((*subchannel)->inputProto, "fifo") == 0) {
+ (*subchannel)->operations = dabInputRawFifoOperations;
+ } else {
+ etiLog.printHeader(TcpLog::ERR,
+ "Invalid protocol for data input (%s)\n",
+ (*subchannel)->inputProto);
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ (*subchannel)->type = 1;
+ (*subchannel)->bitrate = DEFAULT_DATA_BITRATE;
+#if defined(HAVE_INPUT_TEST) && defined(HAVE_FORMAT_RAW)
+ } else if (c == 'T') {
+ (*subchannel)->inputProto = "test";
+ (*subchannel)->type = 1;
+ (*subchannel)->bitrate = DEFAULT_DATA_BITRATE;
+ (*subchannel)->operations = dabInputTestOperations;
+#endif // defined(HAVE_INPUT_TEST)) && defined(HAVE_FORMAT_RAW)
+#ifdef HAVE_FORMAT_PACKET
+ } else if (c == 'P') {
+ (*subchannel)->inputProto = "file";
+ (*subchannel)->type = 3;
+ (*subchannel)->bitrate = DEFAULT_PACKET_BITRATE;
+#ifdef HAVE_INPUT_FILE
+ (*subchannel)->operations = dabInputPacketFileOperations;
+#elif defined(HAVE_INPUT_FIFO)
+ (*subchannel)->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 = 3;
+ (*subchannel)->bitrate = DEFAULT_PACKET_BITRATE;
+ (*subchannel)->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) {
+ (*subchannel)->operations = dabInputDmbUdpOperations;
+ } else if (strcmp((*subchannel)->inputProto, "file") == 0) {
+ (*subchannel)->operations = dabInputDmbFileOperations;
+ } else {
+ etiLog.printHeader(TcpLog::ERR,
+ "Invalid protocol for DMB input (%s)\n",
+ (*subchannel)->inputProto);
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ (*subchannel)->type = 1;
+ (*subchannel)->bitrate = DEFAULT_DATA_BITRATE;
+#endif
+ } else {
+ etiLog.printHeader(TcpLog::ERR,
+ "Service '%c' not yet coded!\n", c);
+ returnCode = -1;
+ goto EXIT;
+ }
+ (*subchannel)->operations.init(&(*subchannel)->data);
+ 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 = 0;
+ protection->level = 2;
+ protection->shortForm.tableSwitch = 0;
+ protection->shortForm.tableIndex = 0;
+ } else {
+ protection->level = 2;
+ protection->form = 1;
+ protection->longForm.option = 0;
+ }
+ break;
+ case 'L':
+ if (optarg == NULL) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Missing parameter for option -L\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ if (service == ensemble->services.end()) {
+ memset(ensemble->label.text, 0, 16);
+ strncpy(ensemble->label.text, optarg, 16);
+ ensemble->label.flag = 0xff00;
+ } else if (component != ensemble->components.end()) {
+ memset((*component)->label.text, 0, 16);
+ strncpy((*component)->label.text, optarg, 16);
+ (*component)->label.flag = 0xff00;
+ } else { // Service
+ memset((*service)->label.text, 0, 16);
+ strncpy((*service)->label.text, optarg, 16);
+ (*service)->label.flag = 0xff00;
+ }
+ // TODO Check strlen before doing short label
+ // TODO Check if short label already set
+ break;
+ case 'V':
+ goto EXIT;
+ case 'l':
+ if (optarg == NULL) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Missing parameter for option -l\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ if (service == ensemble->services.end()) {
+ char* end;
+ ensemble->label.flag = strtoul(optarg, &end, 0);
+ if (*end != 0) {
+ end = optarg;
+ ensemble->label.flag = 0;
+ for (int i = 0; i < 32; ++i) {
+ if (*end == ensemble->label.text[i]) {
+ ensemble->label.flag |= 0x8000 >> i;
+ if (*(++end) == 0) {
+ break;
+ }
+ }
+ }
+ if (*end != 0) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Error at '%c' in ensemble short label '%s'!\n"
+ "Not in label '%s'!\n",
+ *end, optarg, ensemble->label.text);
+ returnCode = -1;
+ goto EXIT;
+ }
+ }
+ int count = 0;
+ for (int i = 0; i < 16; ++i) {
+ if (ensemble->label.flag & (1 << i)) {
+ ++count;
+ }
+ }
+ if (count > 8) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Ensemble short label too long!\n"
+ "Must be < 8 characters.\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+ } else if (component != ensemble->components.end()) {
+ char* end;
+ (*component)->label.flag = strtoul(optarg, &end, 0);
+ if (*end != 0) {
+ end = optarg;
+ (*component)->label.flag = 0;
+ for (int i = 0; i < 32; ++i) {
+ if (*end == (*component)->label.text[i]) {
+ (*component)->label.flag |= 0x8000 >> i;
+ if (*(++end) == 0) {
+ break;
+ }
+ }
+ }
+ if (*end != 0) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Error at '%c' in component short label '%s'!\n"
+ "Not in label '%s'!\n",
+ *end, optarg, (*component)->label.text);
+ returnCode = -1;
+ goto EXIT;
+ }
+ }
+ int count = 0;
+ for (int i = 0; i < 16; ++i) {
+ if ((*component)->label.flag & (1 << i)) {
+ ++count;
+ }
+ }
+ if (count > 8) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Service '%s' short label too long!\n"
+ "Must be < 8 characters.\n", (*component)->label.text);
+ returnCode = -1;
+ goto EXIT;
+ }
+ } else {
+ char* end;
+ (*service)->label.flag = strtoul(optarg, &end, 0);
+ if (*end != 0) {
+ end = optarg;
+ (*service)->label.flag = 0;
+ for (int i = 0; i < 32; ++i) {
+ if (*end == (*service)->label.text[i]) {
+ (*service)->label.flag |= 0x8000 >> i;
+ if (*(++end) == 0) {
+ break;
+ }
+ }
+ }
+ if (*end != 0) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Error at '%c' in service short label '%s'!\n"
+ "Not in label '%s'!\n",
+ *end, optarg, (*service)->label.text);
+ returnCode = -1;
+ goto EXIT;
+ }
+ }
+ int count = 0;
+ for (int i = 0; i < 16; ++i) {
+ if ((*service)->label.flag & (1 << i)) {
+ ++count;
+ }
+ }
+ if (count > 8) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Service '%s' short label too long!\n"
+ "Must be < 8 characters.\n", (*service)->label.text);
+ returnCode = -1;
+ goto EXIT;
+ }
+ }
+ break;
+ case 'i':
+ if (optarg == NULL) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Missing parameter for option -i\n");
+ printUsage(progName);
+ returnCode = -1;
+ 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.printHeader(TcpLog::ERR,
+ "Service id 0 is invalid\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+ } else {
+ ensemble->id = strtoul(optarg, NULL, 0);
+ }
+ break;
+ case 'b':
+ if (optarg == NULL) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Missing parameter for option -b\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ if (subchannel == ensemble->subchannels.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "You must define a subchannel first!\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ (*subchannel)->bitrate = strtoul(optarg, NULL, 0);
+ if (((*subchannel)->bitrate & 0x7) != 0) {
+ (*subchannel)->bitrate += 8;
+ (*subchannel)->bitrate &= ~0x7;
+ etiLog.printHeader(TcpLog::WARNING,
+ "bitrate must be multiple of 8 -> ceiling to %i\n",
+ (*subchannel)->bitrate);
+ }
+ break;
+ case 'c':
+ if (optarg == NULL) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Missing parameter for option -c\n");
+ printUsage(progName);
+ returnCode = -1;
+ 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.printHeader(TcpLog::ERR,
+ "You must define a subchannel first!\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ switch ((*subchannel)->type) {
+#ifdef HAVE_FORMAT_PACKET
+ case 3:
+ (*subchannel)->operations.clean(&(*subchannel)->data);
+ if ((*subchannel)->operations == dabInputPacketFileOperations) {
+ (*subchannel)->operations = dabInputFifoOperations;
+#ifdef HAVE_FORMAT_EPM
+ } else if ((*subchannel)->operations == dabInputEnhancedPacketFileOperations) {
+ (*subchannel)->operations = dabInputEnhancedFifoOperations;
+#endif // defined(HAVE_FORMAT_EPM)
+ } else {
+ etiLog.printHeader(TcpLog::ERR,
+ "Error, wrong packet subchannel operations!\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+ (*subchannel)->operations.init(&(*subchannel)->data);
+ (*subchannel)->inputProto = "fifo";
+ break;
+#endif // defined(HAVE_FORMAT_PACKET)
+#ifdef HAVE_FORMAT_MPEG
+ case 0:
+ (*subchannel)->operations.clean(&(*subchannel)->data);
+ if ((*subchannel)->operations == dabInputMpegFileOperations) {
+ (*subchannel)->operations = dabInputMpegFifoOperations;
+ } else if ((*subchannel)->operations ==
+ dabInputDabplusFileOperations) {
+ (*subchannel)->operations = dabInputDabplusFifoOperations;
+ } else {
+ etiLog.printHeader(TcpLog::ERR,
+ "Error, wrong audio subchannel operations!\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+ (*subchannel)->operations.init(&(*subchannel)->data);
+ (*subchannel)->inputProto = "fifo";
+ break;
+#endif // defined(HAVE_FORMAT_MPEG)
+ default:
+ etiLog.printHeader(TcpLog::ERR,
+ "sorry, non-blocking input file is "
+ "only valid with audio or packet services\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+ break;
+#endif // defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE)
+ case 'p':
+ int level;
+ if (optarg == NULL) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Missing parameter for option -P\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ if (subchannel == ensemble->subchannels.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "You must define a subchannel first!\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ level = strtoul(optarg, NULL, 0) - 1;
+ if (protection->form == 0) {
+ if ((level < 0) || (level > 4)) {
+ etiLog.printHeader(TcpLog::ERR,
+ "protection level must be between "
+ "1 to 5 inclusively (current = %i)\n", level);
+ returnCode = -1;
+ goto EXIT;
+ }
+ } else {
+ if ((level < 0) || (level > 3)) {
+ etiLog.printHeader(TcpLog::ERR,
+ "protection level must be between "
+ "1 to 4 inclusively (current = %i)\n", level);
+ returnCode = -1;
+ goto EXIT;
+ }
+ }
+ protection->level = level;
+ break;
+ case 'm':
+ if (optarg) {
+ ensemble->mode = strtoul(optarg, NULL, 0);
+ if ((ensemble->mode < 1) || (ensemble->mode > 4)) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Mode must be between 1-4\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+ if (ensemble->mode == 4)
+ ensemble->mode = 0;
+ if (ensemble->mode == 3) {
+ FICL = 32;
+ } else {
+ FICL = 24;
+ }
+ } else {
+ etiLog.printHeader(TcpLog::ERR,
+ "Missing parameter for option -m\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ break;
+ case 'n':
+ if (optarg) {
+ limit = strtoul(optarg, NULL, 0);
+ } else {
+ etiLog.printHeader(TcpLog::ERR,
+ "Missing parameter for option -n\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ break;
+ case 'o':
+ etiLog.open("createETI", 0, 12222);
+ break;
+ case 't':
+ if (optarg == NULL) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Missing parameter for option -t\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ if (component == ensemble->components.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "You must define a component before setting "
+ "service type!\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ (*component)->type = strtoul(optarg, NULL, 0);
+ break;
+ case 'a':
+ if (component == ensemble->components.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "You must define a component before setting "
+ "packet address!\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ if (!(*component)->isPacketComponent(ensemble->subchannels)) {
+ etiLog.printHeader(TcpLog::ERR, "address\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ (*component)->packet.address = strtoul(optarg, NULL, 0);
+ break;
+ case 'd':
+ if (component == ensemble->components.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "You must define a component before setting "
+ "datagroup!\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ if (!(*component)->isPacketComponent(ensemble->subchannels)) {
+ etiLog.printHeader(TcpLog::ERR, "datagroup\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ (*component)->packet.datagroup = true;
+ break;
+ case 'f':
+ if (component == ensemble->components.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "You must define a component first!\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ if (!(*component)->isPacketComponent(ensemble->subchannels)) {
+ etiLog.printHeader(TcpLog::ERR, "application type\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ (*component)->packet.appType = strtoul(optarg, NULL, 0);
+ break;
+ case 'g':
+ if (service == ensemble->services.end()) {
+ etiLog.printHeader(TcpLog::ERR, "You must define a service"
+ " before using option -%c\n", c);
+ printUsage(progName);
+ returnCode = -1;
+ 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;
+ }
+ break;
+ case 'y':
+ if (service == ensemble->services.end()) {
+ etiLog.printHeader(TcpLog::ERR, "You must define a service"
+ " before using option -%c\n", c);
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ (*service)->pty = strtoul(optarg, NULL, 0);
+ break;
+ case 'z':
+ factumAnalyzer = true;
+ break;
+ case '?':
+ returnCode = -1;
+ case 'h':
+ printUsage(progName, stdout);
+ goto EXIT;
+ default:
+ etiLog.printHeader(TcpLog::ERR, "Option '%c' not coded yet\n", c);
+ returnCode = -1;
+ goto EXIT;
+ }
+ }
+ if (optind < argc) {
+ etiLog.printHeader(TcpLog::ERR, "Too much parameters:");
+ while (optind < argc) {
+ etiLog.printHeader(TcpLog::ERR, " %s", argv[optind++]);
+ }
+ etiLog.printHeader(TcpLog::ERR, "\n");
+ printUsage(progName);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ if (outputs.size() == 0) {
+ etiLog.printHeader(TcpLog::WARNING, "no output defined\n");
+
+ outputs.push_back(new dabOutput);
+ output = outputs.end() - 1;
+
+ memset(*output, 0, sizeof(dabOutput));
+ (*output)->outputProto = "simul";
+ (*output)->outputName = NULL;
+ (*output)->data = NULL;
+ (*output)->operations = dabOutputDefaultOperations;
+
+ printf("Press enter to continue\n");
+ getchar();
+ }
+
+ // Check and adjust subchannels
+ {
+ set<unsigned char> ids;
+ for (subchannel = ensemble->subchannels.begin();
+ subchannel != ensemble->subchannels.end();
+ ++subchannel) {
+ if (ids.find((*subchannel)->id) != ids.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Subchannel %u is set more than once!\n",
+ (*subchannel)->id);
+ returnCode = -1;
+ goto EXIT;
+ }
+ }
+ }
+
+ // Check and adjust services and components
+ {
+ set<uint32_t> ids;
+ for (service = ensemble->services.begin();
+ service != ensemble->services.end();
+ ++service) {
+ if (ids.find((*service)->id) != ids.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Service id 0x%x (%u) is set more than once!\n",
+ (*service)->id, (*service)->id);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ // Get first component of this service
+ component = getComponent(ensemble->components, (*service)->id);
+ if (component == ensemble->components.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Service %u includes no component!\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ // Adjust service type from this first component
+ switch ((*service)->getType(ensemble)) {
+ case 0: // Audio
+ (*service)->program = true;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ (*service)->program = false;
+ break;
+ default:
+ etiLog.printHeader(TcpLog::ERR,
+ "Error, unknown service type: %u\n", (*service)->getType(ensemble));
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ // Adjust components type for DAB+
+ while (component != ensemble->components.end()) {
+ subchannel =
+ getSubchannel(ensemble->subchannels, (*component)->subchId);
+ if (subchannel == ensemble->subchannels.end()) {
+ etiLog.printHeader(TcpLog::ERR, "Error, service %u component "
+ "links to the invalid subchannel %u\n",
+ (*component)->serviceId, (*component)->subchId);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ protection = &(*subchannel)->protection;
+ switch ((*subchannel)->type) {
+ case 0: // Audio
+ {
+ if (protection->form != 0) {
+ (*component)->type = 0x3f; // DAB+
+ }
+ }
+ break;
+ case 1:
+ case 2:
+ case 3:
+ break;
+ default:
+ etiLog.printHeader(TcpLog::ERR,
+ "Error, unknown subchannel type\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+ component = getComponent(ensemble->components,
+ (*service)->id, component);
+ }
+ }
+ }
+
+
+ for (output = outputs.begin(); output != outputs.end() ; ++output) {
+#if defined(HAVE_OUTPUT_FILE)
+ if (strcmp((*output)->outputProto, "file") == 0) {
+ (*output)->operations = dabOutputFileOperations;
+#else // !defined(HAVE_OUTPUT_FILE)
+ if (0) {
+#endif // defined(HAVE_OUTPUT_FILE)
+#if defined(HAVE_OUTPUT_FIFO)
+ } else if (strcmp((*output)->outputProto, "fifo") == 0) {
+ (*output)->operations = dabOutputFifoOperations;
+#endif // !defined(HAVE_OUTPUT_FIFO)
+#if defined(HAVE_OUTPUT_RAW)
+ } else if (strcmp((*output)->outputProto, "raw") == 0) {
+ (*output)->operations = dabOutputRawOperations;
+#endif // defined(HAVE_OUTPUT_RAW)
+#if defined(HAVE_OUTPUT_UDP)
+ } else if (strcmp((*output)->outputProto, "udp") == 0) {
+ (*output)->operations = dabOutputUdpOperations;
+#endif // defined(HAVE_OUTPUT_UDP)
+#if defined(HAVE_OUTPUT_TCP)
+ } else if (strcmp((*output)->outputProto, "tcp") == 0) {
+ (*output)->operations = dabOutputTcpOperations;
+#endif // defined(HAVE_OUTPUT_TCP)
+#if defined(HAVE_OUTPUT_SIMUL)
+ } else if (strcmp((*output)->outputProto, "simul") == 0) {
+ (*output)->operations = dabOutputSimulOperations;
+#endif // defined(HAVE_OUTPUT_SIMUL)
+ } else {
+ etiLog.printHeader(TcpLog::ERR, "Output protcol unknown: %s\n",
+ (*output)->outputProto);
+ goto EXIT;
+ }
+
+ if ((*output)->operations.init(&(*output)->data) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Unable to init output %s://%s\n",
+ (*output)->outputProto, (*output)->outputName);
+ return -1;
+ }
+ if ((*output)->operations.open((*output)->data, (*output)->outputName)
+ == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Unable to open output %s://%s\n",
+ (*output)->outputProto, (*output)->outputName);
+ return -1;
+ }
+ }
+
+ //Relatif aux fichiers d'entre
+ for (subchannel = ensemble->subchannels.begin();
+ subchannel != ensemble->subchannels.end();
+ ++subchannel) {
+ protection = &(*subchannel)->protection;
+ if (subchannel == ensemble->subchannels.begin()) {
+ (*subchannel)->startAddress = 0;
+ } else {
+ (*subchannel)->startAddress = (*(subchannel - 1))->startAddress +
+ getSizeCu(*(subchannel - 1));
+ }
+ if ((*subchannel)->operations.open((*subchannel)->data,
+ (*subchannel)->inputName) == -1) {
+ perror((*subchannel)->inputName);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ // TODO Check errors
+ int result = (*subchannel)->operations.setBitrate(
+ &(*subchannel)->operations, (*subchannel)->data,
+ (*subchannel)->bitrate);
+ if (result <= 0) {
+ etiLog.printHeader(TcpLog::ERR, "can't set bitrate for source %s\n",
+ (*subchannel)->inputName);
+ returnCode = -1;
+ goto EXIT;
+ }
+ (*subchannel)->bitrate = result;
+
+ if (protection->form == 0) {
+ protection->form = 1;
+ for (int i = 0; i < 64; i++) {
+ if ((*subchannel)->bitrate == BitRateTable[i]) {
+ if (protection->level == ProtectionLevelTable[i]) {
+ protection->form = 0;
+ protection->shortForm.tableIndex = i;
+ }
+ }
+ }
+ }
+ }
+
+ if (ensemble->subchannels.size() == 0) {
+ etiLog.printHeader(TcpLog::ERR, "can't multiplexed no subchannel!\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ subchannel = ensemble->subchannels.end() - 1;
+ if ((*subchannel)->startAddress + getSizeCu((*subchannel)) > 864) {
+ etiLog.printHeader(TcpLog::ERR, "Total size in CU exceeds 864\n");
+ printSubchannels(ensemble->subchannels);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ // Init packet components SCId
+ cur = 0;
+ for (component = ensemble->components.begin();
+ component != ensemble->components.end();
+ ++component) {
+ subchannel = getSubchannel(ensemble->subchannels,
+ (*component)->subchId);
+ if (subchannel == ensemble->subchannels.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Subchannel %i does not exist for component "
+ "of service %i\n",
+ (*component)->subchId, (*component)->serviceId);
+ returnCode = -1;
+ goto EXIT;
+ }
+ if ((*subchannel)->type != 3) continue;
+
+ (*component)->packet.id = cur++;
+ }
+
+ //Initialisation a 0 des cases de la trame ETI
+ memset(etiFrame, 0, 6144);
+
+ // Print settings before starting
+ etiLog.printHeader(TcpLog::INFO, "\n--- Multiplex configuration ---\n");
+ printEnsemble(ensemble);
+
+ etiLog.printHeader(TcpLog::INFO, "\n--- Subchannels list ---\n");
+ printSubchannels(ensemble->subchannels);
+
+ etiLog.printHeader(TcpLog::INFO, "\n--- Services list ---\n");
+ printServices(ensemble->services);
+
+ etiLog.printHeader(TcpLog::INFO, "\n--- Components list ---\n");
+ printComponents(ensemble->components);
+
+ etiLog.printHeader(TcpLog::INFO, "\n--- Output list ---\n");
+ printOutputs(outputs);
+
+ etiLog.printHeader(TcpLog::INFO, "\n");
+
+
+ /***************************************************************************
+ ********** Boucle principale, chaque passage cree une trame ************
+ **************************************************************************/
+ serviceProgramInd = ensemble->services.end();
+ serviceDataInd = ensemble->services.end();
+ componentIndicatorProgram = ensemble->components.end();
+ componentIndicatorData = ensemble->components.end();
+ servicePty = ensemble->services.end();
+ subchannelIndicator = ensemble->subchannels.end();
+
+
+ for (currentFrame = 0; running; currentFrame++) {
+ if ((limit > 0) && (currentFrame >= limit)) {
+ break;
+ }
+ date = getDabTime();
+
+ //Initialisation a 0 des cases de la trame
+ memset(etiFrame, 0, 6144);
+
+ /**********************************************************************
+ ********** Section SYNC du ETI(NI, G703) *************************
+ **********************************************************************/
+
+ //declare une instance d'une structure eti_SYNC
+ eti_SYNC *etiSync = (eti_SYNC *) etiFrame;
+ //****** Section ERR ******//
+ // 1 octet
+ etiSync->ERR = 0xFF; //Indique qu'il n'y a pas d'erreur
+ //****** Section FSYNC *****//
+ // 3 octets, pour la synchronisation, alterne a chaque trame entre les
+ // deux symboles
+ sync ^= 0xffffff;
+ etiSync->FSYNC = sync;
+
+ /**********************************************************************
+ *********** Section LIDATA du ETI(NI, G703) **********************
+ **********************************************************************/
+
+ //****** Section FC ***************************************************/
+ // 4 octets
+ // declare une instance d une structure eti_FC et la place dans la trame
+ eti_FC *fc = (eti_FC *) & etiFrame[4];
+
+ //****** FCT **********************//
+ //Incremente a chaque trame, de 0 a 249, 1 octet
+ fc->FCT = currentFrame % 250;
+
+ //****** FICF ******//
+ //Fast Information Channel Flag, 1 bit, =1 si le FIC est present
+ fc->FICF = 1;
+
+ //****** NST ******//
+ //Number of Stream, 7 bits, 0-64, 0 si reconfiguration du multiplex
+ fc->NST = ensemble->subchannels.size();
+
+ //****** FP ******//
+ // Frame Phase, 3 bits, compteur sur 3 bits, permet au COFDM generator
+ // de savoir quand inserer le TII utilise egalement par le MNST
+ fc->FP = currentFrame & 0x7;
+
+ //****** MID ******//
+ //Mode Identity, 2 bits, 01 ModeI, 10 modeII, 11 ModeIII, 00 ModeIV
+ fc->MID = ensemble->mode; //mode 2 demande 3 FIB, 3*32octets = 96octets
+
+ //****** FL ******//
+ //Frame Length, 11 bits, nb of words(4 bytes) in STC, EOH and MST
+ // si NST=0, FL=1+FICL words, FICL=24 ou 32 selon le mode
+ //en word ( 4 bytes), +1 pour la partie EOH
+ FLtmp = 1 + FICL + (fc->NST);
+
+ for (subchannel = ensemble->subchannels.begin();
+ subchannel != ensemble->subchannels.end();
+ ++subchannel) {
+ //Taille d'une trame audio mp2 en paquet de 64 bits
+ FLtmp += getSizeWord(*subchannel);
+ }
+
+ fc->setFrameLength(FLtmp);
+ index = 8;
+
+ /******* Section STC **************************************************/
+ // Stream Characterization,
+ // number of channel * 4 octets = nb octets total
+ for (subchannel = ensemble->subchannels.begin();
+ subchannel != ensemble->subchannels.end();
+ ++subchannel) {
+ protection = &(*subchannel)->protection;
+ eti_STC *sstc = (eti_STC *) & etiFrame[index];
+
+ sstc->SCID = (*subchannel)->id;
+ sstc->startAddress_high = (*subchannel)->startAddress / 256;
+ sstc->startAddress_low = (*subchannel)->startAddress % 256;
+ //devrait changer selon le mode de protection desire
+ if (protection->form == 0) {
+ sstc->TPL = 0x10 |
+ ProtectionLevelTable[protection->shortForm.tableIndex];
+ } else {
+ sstc->TPL = 0x20 |
+ (protection->longForm.option << 2) |
+ (protection->level);
+ }
+ //Sub-channel Stream Length, multiple de 64 bits
+ sstc->STL_high = getSizeDWord(*subchannel) / 256;
+ sstc->STL_low = getSizeDWord(*subchannel) % 256;
+ index += 4;
+ }
+
+ /******* Section EOH **************************************************/
+ // End of Header 4 octets
+ eti_EOH *eoh = (eti_EOH *) & etiFrame[index];
+
+ //MNSC Multiplex Network Signalling Channel, 2 octets
+ eoh->MNSC = 0;
+
+ //CRC Cyclic Redundancy Checksum du FC, STC et MNSC, 2 octets
+ nbBytesCRC = 4 + ((fc->NST) * 4) + 2;
+
+ CRCtmp = 0xffff;
+ CRCtmp = crc16(CRCtmp, &etiFrame[4], nbBytesCRC);
+ CRCtmp ^= 0xffff;
+ eoh->CRC = htons(CRCtmp);
+
+ /******* Section MST **************************************************/
+ // Main Stream Data, si FICF=1 alors les 96 ou 128 premiers octets
+ // transportent le FIC selon le mode
+ index = ((fc->NST) + 2 + 1) * 4;
+
+ //Insertion du FIC
+ FIGtype0* fig0;
+ FIGtype0_0 *fig0_0;
+ FIGtype0_1 *figtype0_1;
+
+ FIG_01_SubChannel_ShortF *fig0_1subchShort;
+ FIG_01_SubChannel_LongF *fig0_1subchLong1;
+
+ FIGtype0_2 *fig0_2;
+
+ FIGtype0_2_Service *fig0_2serviceAudio;
+ FIGtype0_2_Service_data *fig0_2serviceData;
+ FIGtype0_2_audio_component* audio_description;
+ FIGtype0_2_data_component* data_description;
+ FIGtype0_2_packet_component* packet_description;
+
+ FIGtype0_3_header *fig0_3_header;
+ FIGtype0_3_data *fig0_3_data;
+ FIGtype0_9 *fig0_9;
+ FIGtype0_10 *fig0_10;
+ FIGtype0_17_programme *programme;
+
+ FIGtype1_0 *fig1_0;
+ FIGtype1_1 *fig1_1;
+ FIGtype1_5 *fig1_5;
+
+ tm* timeData;
+
+ unsigned char figSize = 0;
+
+ //Insertion du FIB 0
+ switch (insertFIG) {
+
+ case 0:
+ case 4:
+ // FIG type 0/0, Multiplex Configuration Info (MCI),
+ // Ensemble information
+ fig0_0 = (FIGtype0_0 *) & etiFrame[index];
+
+ fig0_0->FIGtypeNumber = 0;
+ fig0_0->Length = 5;
+ fig0_0->CN = 0;
+ fig0_0->OE = 0;
+ fig0_0->PD = 0;
+ fig0_0->Extension = 0;
+
+ fig0_0->EId = htons(ensemble->id);
+ fig0_0->Change = 0;
+ fig0_0->Al = 0;
+ fig0_0->CIFcnt_hight = (currentFrame / 250) % 20;
+ fig0_0->CIFcnt_low = (currentFrame % 250);
+ index = index + 6;
+ figSize += 6;
+
+ break;
+
+ case 1:
+ // FIG type 0/1, MIC, Sub-Channel Organization, une instance de la
+ // sous-partie par sous-canal
+ figtype0_1 = (FIGtype0_1 *) & etiFrame[index];
+
+ figtype0_1->FIGtypeNumber = 0;
+ figtype0_1->Length = 1;
+ figtype0_1->CN = 0;
+ figtype0_1->OE = 0;
+ figtype0_1->PD = 0;
+ figtype0_1->Extension = 1;
+ index = index + 2;
+ figSize += 2;
+
+ //Sous-partie du FIG type 0/1
+ if (subchannelIndicator == ensemble->subchannels.end()) {
+ subchannelIndicator = ensemble->subchannels.begin();
+ }
+ for (; subchannelIndicator != ensemble->subchannels.end();
+ ++subchannelIndicator) {
+ protection = &(*subchannelIndicator)->protection;
+
+ if ((protection->form == 0 && figSize > 27) ||
+ (protection->form != 0 && figSize > 26)) {
+ break;
+ }
+
+ if (protection->form == 0) {
+ fig0_1subchShort =
+ (FIG_01_SubChannel_ShortF*) &etiFrame[index];
+ fig0_1subchShort->SubChId = (*subchannelIndicator)->id;
+ fig0_1subchShort->StartAdress_high =
+ (*subchannelIndicator)->startAddress / 256;
+ fig0_1subchShort->StartAdress_low =
+ (*subchannelIndicator)->startAddress % 256;
+ fig0_1subchShort->Short_Long_form = 0;
+ fig0_1subchShort->TableSwitch = 0;
+ fig0_1subchShort->TableIndex =
+ protection->shortForm.tableIndex;
+
+ index = index + 3;
+ figSize += 3;
+ figtype0_1->Length += 3;
+ } else {
+ fig0_1subchLong1 =
+ (FIG_01_SubChannel_LongF*) &etiFrame[index];
+ fig0_1subchLong1->SubChId = (*subchannelIndicator)->id;
+ fig0_1subchLong1->StartAdress_high =
+ (*subchannelIndicator)->startAddress / 256;
+ fig0_1subchLong1->StartAdress_low =
+ (*subchannelIndicator)->startAddress % 256;
+ fig0_1subchLong1->Short_Long_form = 1;
+ fig0_1subchLong1->Option = protection->longForm.option;
+ fig0_1subchLong1->ProtectionLevel =
+ protection->level;
+ fig0_1subchLong1->Sub_ChannelSize_high =
+ getSizeCu(*subchannelIndicator) / 256;
+ fig0_1subchLong1->Sub_ChannelSize_low =
+ getSizeCu(*subchannelIndicator) % 256;
+
+ index = index + 4;
+ figSize += 4;
+ figtype0_1->Length += 4;
+ }
+ }
+ break;
+
+ case 2:
+ // FIG type 0/2, MCI, Service Organization, une instance de
+ // FIGtype0_2_Service par sous-canal
+ fig0_2 = NULL;
+ cur = 0;
+
+ if (serviceProgramInd == ensemble->services.end()) {
+ serviceProgramInd = ensemble->services.begin();
+ }
+ for (; serviceProgramInd != ensemble->services.end();
+ ++serviceProgramInd) {
+ if (!(*serviceProgramInd)->nbComponent(ensemble->components)) {
+ continue;
+ }
+ if ((*serviceProgramInd)->getType(ensemble) != 0) {
+ continue;
+ }
+
+ ++cur;
+
+ if (fig0_2 == NULL) {
+ fig0_2 = (FIGtype0_2 *) & etiFrame[index];
+
+ fig0_2->FIGtypeNumber = 0;
+ fig0_2->Length = 1;
+ fig0_2->CN = 0;
+ fig0_2->OE = 0;
+ fig0_2->PD = 0;
+ fig0_2->Extension = 2;
+ index = index + 2;
+ figSize += 2;
+ }
+
+ if (figSize + 3
+ + (*serviceProgramInd)->nbComponent(ensemble->components)
+ * 2 > 30) {
+ break;
+ }
+
+ fig0_2serviceAudio = (FIGtype0_2_Service*) &etiFrame[index];
+
+ fig0_2serviceAudio->SId = htons((*serviceProgramInd)->id);
+ fig0_2serviceAudio->Local_flag = 0;
+ fig0_2serviceAudio->CAId = 0;
+ fig0_2serviceAudio->NbServiceComp =
+ (*serviceProgramInd)->nbComponent(ensemble->components);
+ index += 3;
+ fig0_2->Length += 3;
+ figSize += 3;
+
+ int curCpnt = 0;
+ for (component = getComponent(ensemble->components,
+ (*serviceProgramInd)->id);
+ component != ensemble->components.end();
+ component = getComponent(ensemble->components,
+ (*serviceProgramInd)->id, component)) {
+ subchannel = getSubchannel(ensemble->subchannels,
+ (*component)->subchId);
+ if (subchannel == ensemble->subchannels.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Subchannel %i does not exist for component "
+ "of service %i\n",
+ (*component)->subchId, (*component)->serviceId);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ switch ((*subchannel)->type) {
+ case 0: // Audio
+ audio_description =
+ (FIGtype0_2_audio_component*)&etiFrame[index];
+ audio_description->TMid = 0;
+ audio_description->ASCTy = (*component)->type;
+ audio_description->SubChId = (*subchannel)->id;
+ audio_description->PS = ((curCpnt == 0) ? 1 : 0);
+ audio_description->CA_flag = 0;
+ break;
+ case 1: // Data
+ data_description =
+ (FIGtype0_2_data_component*)&etiFrame[index];
+ data_description->TMid = 1;
+ data_description->DSCTy = (*component)->type;
+ data_description->SubChId = (*subchannel)->id;
+ data_description->PS = ((curCpnt == 0) ? 1 : 0);
+ data_description->CA_flag = 0;
+ break;
+ case 3: // Packet
+ packet_description =
+ (FIGtype0_2_packet_component*)&etiFrame[index];
+ packet_description->TMid = 3;
+ packet_description->setSCId((*component)->packet.id);
+ packet_description->PS = ((curCpnt == 0) ? 1 : 0);
+ packet_description->CA_flag = 0;
+ break;
+ default:
+ etiLog.printHeader(TcpLog::ERR,
+ "Component type not supported\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+ index += 2;
+ fig0_2->Length += 2;
+ figSize += 2;
+ if (figSize > 30) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Sorry, no place left in FIG 0/2 to insert "
+ "component %i of program service %i.\n",
+ curCpnt, cur);
+ returnCode = -1;
+ goto EXIT;
+ }
+ ++curCpnt;
+ }
+ }
+ break;
+
+ case 3:
+ fig0_2 = NULL;
+ cur = 0;
+
+ if (serviceDataInd == ensemble->services.end()) {
+ serviceDataInd = ensemble->services.begin();
+ }
+ for (; serviceDataInd != ensemble->services.end();
+ ++serviceDataInd) {
+ if (!(*serviceDataInd)->nbComponent(ensemble->components)) {
+ continue;
+ }
+ unsigned char type = (*serviceDataInd)->getType(ensemble);
+ if ((type == 0) || (type == 2)) {
+ continue;
+ }
+
+ ++cur;
+
+ if (fig0_2 == NULL) {
+ fig0_2 = (FIGtype0_2 *) & etiFrame[index];
+
+ fig0_2->FIGtypeNumber = 0;
+ fig0_2->Length = 1;
+ fig0_2->CN = 0;
+ fig0_2->OE = 0;
+ fig0_2->PD = 1;
+ fig0_2->Extension = 2;
+ index = index + 2;
+ figSize += 2;
+ }
+
+ if (figSize + 5
+ + (*serviceDataInd)->nbComponent(ensemble->components)
+ * 2 > 30) {
+ break;
+ }
+
+ fig0_2serviceData =
+ (FIGtype0_2_Service_data*) &etiFrame[index];
+
+ fig0_2serviceData->SId = htonl((*serviceDataInd)->id);
+ fig0_2serviceData->Local_flag = 0;
+ fig0_2serviceData->CAId = 0;
+ fig0_2serviceData->NbServiceComp =
+ (*serviceDataInd)->nbComponent(ensemble->components);
+ fig0_2->Length += 5;
+ index += 5;
+ figSize += 5;
+
+ int curCpnt = 0;
+ for (component = getComponent(ensemble->components,
+ (*serviceDataInd)->id);
+ component != ensemble->components.end();
+ component = getComponent(ensemble->components,
+ (*serviceDataInd)->id, component)) {
+ subchannel = getSubchannel(ensemble->subchannels,
+ (*component)->subchId);
+ if (subchannel == ensemble->subchannels.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Subchannel %i does not exist for component "
+ "of service %i\n",
+ (*component)->subchId, (*component)->serviceId);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ switch ((*subchannel)->type) {
+ case 0: // Audio
+ audio_description =
+ (FIGtype0_2_audio_component*)&etiFrame[index];
+ audio_description->TMid = 0;
+ audio_description->ASCTy = (*component)->type;
+ audio_description->SubChId = (*subchannel)->id;
+ audio_description->PS = ((curCpnt == 0) ? 1 : 0);
+ audio_description->CA_flag = 0;
+ break;
+ case 1: // Data
+ data_description =
+ (FIGtype0_2_data_component*)&etiFrame[index];
+ data_description->TMid = 1;
+ data_description->DSCTy = (*component)->type;
+ data_description->SubChId = (*subchannel)->id;
+ data_description->PS = ((curCpnt == 0) ? 1 : 0);
+ data_description->CA_flag = 0;
+ break;
+ case 3: // Packet
+ packet_description =
+ (FIGtype0_2_packet_component*)&etiFrame[index];
+ packet_description->TMid = 3;
+ packet_description->setSCId((*component)->packet.id);
+ packet_description->PS = ((curCpnt == 0) ? 1 : 0);
+ packet_description->CA_flag = 0;
+ break;
+ default:
+ etiLog.printHeader(TcpLog::ERR,
+ "Component type not supported\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+ index += 2;
+ fig0_2->Length += 2;
+ figSize += 2;
+ if (figSize > 30) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Sorry, no place left in FIG 0/2 to insert "
+ "component %i of data service %i.\n",
+ curCpnt, cur);
+ returnCode = -1;
+ goto EXIT;
+ }
+ ++curCpnt;
+ }
+ }
+ break;
+
+ case 5:
+ fig0_3_header = NULL;
+
+ for (component = ensemble->components.begin();
+ component != ensemble->components.end();
+ ++component) {
+ subchannel = getSubchannel(ensemble->subchannels,
+ (*component)->subchId);
+ if (subchannel == ensemble->subchannels.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Subchannel %i does not exist for component "
+ "of service %i\n",
+ (*component)->subchId, (*component)->serviceId);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ if ((*subchannel)->type != 3) continue;
+
+ if (fig0_3_header == NULL) {
+ fig0_3_header = (FIGtype0_3_header*)&etiFrame[index];
+ fig0_3_header->FIGtypeNumber = 0;
+ fig0_3_header->Length = 1;
+ fig0_3_header->CN = 0;
+ fig0_3_header->OE = 0;
+ fig0_3_header->PD = 0;
+ fig0_3_header->Extension = 3;
+
+ index += 2;
+ figSize += 2;
+ }
+
+ /* Warning: When bit SCCA_flag is unset(0), the multiplexer
+ * R&S does not send the SCCA field. But, in the Factum ETI
+ * analyzer, if this field is not there, it is an error.
+ */
+ fig0_3_data = (FIGtype0_3_data*)&etiFrame[index];
+ fig0_3_data->setSCId((*component)->packet.id);
+ fig0_3_data->rfa = 0;
+ fig0_3_data->SCCA_flag = 0;
+ // if 0, datagroups are used
+ fig0_3_data->DG_flag = !(*component)->packet.datagroup;
+ fig0_3_data->rfu = 0;
+ fig0_3_data->DSCTy = (*component)->type;
+ fig0_3_data->SubChId = (*subchannel)->id;
+ fig0_3_data->setPacketAddress((*component)->packet.address);
+ if (factumAnalyzer) {
+ fig0_3_data->SCCA = 0;
+ }
+
+ fig0_3_header->Length += 5;
+ index += 5;
+ figSize += 5;
+ if (factumAnalyzer) {
+ fig0_3_header->Length += 2;
+ index += 2;
+ figSize += 2;
+ }
+
+ if (figSize > 30) {
+ etiLog.printHeader(TcpLog::ERR,
+ "can't add to Fic Fig 0/3, "
+ "too much packet service\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+ }
+ break;
+
+ case 7:
+ fig0 = NULL;
+ if (servicePty == ensemble->services.end()) {
+ servicePty = ensemble->services.begin();
+ }
+ for (; servicePty != ensemble->services.end();
+ ++servicePty) {
+ if ((*servicePty)->pty == 0 && (*servicePty)->language == 0) {
+ continue;
+ }
+ if (fig0 == NULL) {
+ fig0 = (FIGtype0*)&etiFrame[index];
+ fig0->FIGtypeNumber = 0;
+ fig0->Length = 1;
+ fig0->CN = 0;
+ fig0->OE = 0;
+ fig0->PD = 0;
+ fig0->Extension = 17;
+ index += 2;
+ figSize += 2;
+ }
+
+ if ((*servicePty)->language == 0) {
+ if (figSize + 4 > 30) {
+ break;
+ }
+ } else {
+ if (figSize + 5 > 30) {
+ break;
+ }
+ }
+
+ programme =
+ (FIGtype0_17_programme*)&etiFrame[index];
+ programme->SId = htons((*servicePty)->id);
+ programme->SD = 1;
+ programme->PS = 0;
+ programme->L = (*servicePty)->language != 0;
+ programme->CC = 0;
+ programme->Rfa = 0;
+ programme->NFC = 0;
+ if ((*servicePty)->language == 0) {
+ etiFrame[index + 3] = (*servicePty)->pty;
+ fig0->Length += 4;
+ index += 4;
+ figSize += 4;
+ } else {
+ etiFrame[index + 3] = (*servicePty)->language;
+ etiFrame[index + 4] = (*servicePty)->pty;
+ fig0->Length += 5;
+ index += 5;
+ figSize += 5;
+ }
+ }
+ break;
+ }
+
+ if (figSize > 30) {
+ etiLog.printHeader(TcpLog::ERR,
+ "FIG too big (%i > 30)\n", figSize);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ memcpy(&etiFrame[index], Padding_FIB, 30 - figSize);
+ index += 30 - figSize;
+
+ CRCtmp = 0xffff;
+ CRCtmp = crc16(CRCtmp, &etiFrame[(index - 30)], 30);
+ CRCtmp ^= 0xffff;
+ etiFrame[index++] = ((char *) &CRCtmp)[1];
+ etiFrame[index++] = ((char *) &CRCtmp)[0];
+
+ figSize = 0;
+ // Insertion du FIB 1
+ switch (alterneFIB) {
+ case 0: // FIG 0/8 program
+ fig0 = NULL;
+
+ if (componentIndicatorProgram == ensemble->components.end()) {
+ componentIndicatorProgram = ensemble->components.begin();
+ }
+ for (; componentIndicatorProgram != ensemble->components.end();
+ ++componentIndicatorProgram) {
+ service = getService(*componentIndicatorProgram,
+ ensemble->services);
+ subchannel = getSubchannel(ensemble->subchannels,
+ (*componentIndicatorProgram)->subchId);
+ if (subchannel == ensemble->subchannels.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Subchannel %i does not exist for component "
+ "of service %i\n",
+ (*componentIndicatorProgram)->subchId,
+ (*componentIndicatorProgram)->serviceId);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ if (!(*service)->program) continue;
+
+ if (fig0 == NULL) {
+ fig0 = (FIGtype0*)&etiFrame[index];
+ fig0->FIGtypeNumber = 0;
+ fig0->Length = 1;
+ fig0->CN = 0;
+ fig0->OE = 0;
+ fig0->PD = 0;
+ fig0->Extension = 8;
+ index += 2;
+ figSize += 2;
+ }
+
+ if ((*subchannel)->type == 3) { // Data packet
+ if (figSize > 30 - 5) {
+ break;
+ }
+ *((uint16_t*)&etiFrame[index]) =
+ htons((*componentIndicatorProgram)->serviceId);
+ fig0->Length += 2;
+ index += 2;
+ figSize += 2;
+
+ FIGtype0_8_long* definition =
+ (FIGtype0_8_long*)&etiFrame[index];
+ memset(definition, 0, 3);
+ definition->ext = 0; // no rfa
+ definition->SCIdS = (*componentIndicatorProgram)->SCIdS;
+ definition->LS = 1;
+ definition->setSCId((*componentIndicatorProgram)->packet.id);
+ fig0->Length += 3;
+ index += 3; // 8 minus rfa
+ figSize += 3;
+ } else { // Audio, data stream or FIDC
+ if (figSize > 30 - 4) {
+ break;
+ }
+ *((uint16_t*)&etiFrame[index]) =
+ htons((*componentIndicatorProgram)->serviceId);
+ fig0->Length += 2;
+ index += 2;
+ figSize += 2;
+
+ FIGtype0_8_short* definition =
+ (FIGtype0_8_short*)&etiFrame[index];
+ memset(definition, 0, 2);
+ definition->ext = 0; // no rfa
+ definition->SCIdS = (*componentIndicatorProgram)->SCIdS;
+ definition->LS = 0;
+ definition->MscFic = 0;
+ definition->Id = (*componentIndicatorProgram)->subchId;
+ fig0->Length += 2;
+ index += 2; // 4 minus rfa
+ figSize += 2;
+ }
+ }
+ break;
+
+ case 1: // FIG 0/8 data
+ fig0 = NULL;
+
+ if (componentIndicatorData == ensemble->components.end()) {
+ componentIndicatorData = ensemble->components.begin();
+ }
+ for (; componentIndicatorData != ensemble->components.end();
+ ++componentIndicatorData) {
+ service = getService(*componentIndicatorData,
+ ensemble->services);
+ subchannel = getSubchannel(ensemble->subchannels,
+ (*componentIndicatorData)->subchId);
+ if (subchannel == ensemble->subchannels.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Subchannel %i does not exist for component "
+ "of service %i\n",
+ (*componentIndicatorData)->subchId,
+ (*componentIndicatorData)->serviceId);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ if ((*service)->program) continue;
+
+ if (fig0 == NULL) {
+ fig0 = (FIGtype0*)&etiFrame[index];
+ fig0->FIGtypeNumber = 0;
+ fig0->Length = 1;
+ fig0->CN = 0;
+ fig0->OE = 0;
+ fig0->PD = 1;
+ fig0->Extension = 8;
+ index += 2;
+ figSize += 2;
+ }
+
+ if ((*subchannel)->type == 3) { // Data packet
+ if (figSize > 30 - 7) {
+ break;
+ }
+ *((uint32_t*)&etiFrame[index]) =
+ htonl((*componentIndicatorData)->serviceId);
+ fig0->Length += 4;
+ index += 4;
+ figSize += 4;
+
+ FIGtype0_8_long* definition =
+ (FIGtype0_8_long*)&etiFrame[index];
+ memset(definition, 0, 3);
+ definition->ext = 0; // no rfa
+ definition->SCIdS = (*componentIndicatorData)->SCIdS;
+ definition->LS = 1;
+ definition->setSCId((*componentIndicatorData)->packet.id);
+ fig0->Length += 3;
+ index += 3; // 8 minus rfa
+ figSize += 3;
+ } else { // Audio, data stream or FIDC
+ if (figSize > 30 - 6) {
+ break;
+ }
+ *((uint32_t*)&etiFrame[index]) =
+ htonl((*componentIndicatorData)->serviceId);
+ fig0->Length += 4;
+ index += 4;
+ figSize += 4;
+
+ FIGtype0_8_short* definition =
+ (FIGtype0_8_short*)&etiFrame[index];
+ memset(definition, 0, 2);
+ definition->ext = 0; // no rfa
+ definition->SCIdS = (*componentIndicatorData)->SCIdS;
+ definition->LS = 0;
+ definition->MscFic = 0;
+ definition->Id = (*componentIndicatorData)->subchId;
+ fig0->Length += 2;
+ index += 2; // 4 minus rfa
+ figSize += 2;
+ }
+ }
+ break;
+
+ case 3:
+ // FIG type 1/0, Service Information (SI), Ensemble Label
+ fig1_0 = (FIGtype1_0 *) & etiFrame[index];
+
+ fig1_0->Length = 21;
+ fig1_0->FIGtypeNumber = 1;
+ fig1_0->Extension = 0;
+ fig1_0->OE = 0;
+ fig1_0->Charset = 0;
+ fig1_0->EId = htons(ensemble->id);
+ index = index + 4;
+
+ memcpy(&etiFrame[index], ensemble->label.text, 16);
+ index = index + 16;
+
+ etiFrame[index++] = ((char *) &ensemble->label.flag)[1];
+ etiFrame[index++] = ((char *) &ensemble->label.flag)[0];
+
+ figSize += 22;
+ break;
+ case 5:
+ // FIG 0 / 13
+ fig0 = NULL;
+
+ for (component = ensemble->components.begin();
+ component != ensemble->components.end();
+ ++component) {
+ subchannel = getSubchannel(ensemble->subchannels,
+ (*component)->subchId);
+ if (subchannel == ensemble->subchannels.end()) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Subchannel %i does not exist for component "
+ "of service %i\n",
+ (*component)->subchId, (*component)->serviceId);
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ if ((*subchannel)->type != 3) continue;
+
+ if ((*component)->packet.appType != 0xffff) {
+ if (fig0 == NULL) {
+ fig0 = (FIGtype0*)&etiFrame[index];
+ fig0->FIGtypeNumber = 0;
+ fig0->Length = 1;
+ fig0->CN = 0;
+ fig0->OE = 0;
+ fig0->PD = 1;
+ fig0->Extension = 13;
+ index += 2;
+ figSize += 2;
+ }
+
+ FIG0_13_longAppInfo* info =
+ (FIG0_13_longAppInfo*)&etiFrame[index];
+ info->SId = htonl((*component)->serviceId);
+ info->SCIdS = (*component)->SCIdS;
+ info->No = 1;
+ index += 5;
+ figSize += 5;
+ fig0->Length += 5;
+
+ FIG0_13_app* app = (FIG0_13_app*)&etiFrame[index];
+ app->setType((*component)->packet.appType);
+ app->length = 0;
+ index += 2;
+ figSize += 2;
+ fig0->Length += 2;
+
+ if (figSize > 30) {
+ etiLog.printHeader(TcpLog::ERR,
+ "can't add to Fic Fig 0/13, "
+ "too much packet service\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+ }
+ }
+ break;
+ case 7:
+ //Time and country identifier
+ fig0_10 = (FIGtype0_10 *) & etiFrame[index];
+
+ fig0_10->FIGtypeNumber = 0;
+ fig0_10->Length = 5;
+ fig0_10->CN = 0;
+ fig0_10->OE = 0;
+ fig0_10->PD = 0;
+ fig0_10->Extension = 10;
+ index = index + 2;
+
+ timeData = localtime(&date);
+
+ fig0_10->RFU = 0;
+ fig0_10->setMJD(gregorian2mjd(timeData->tm_year + 1900,
+ timeData->tm_mon + 1,
+ timeData->tm_mday));
+ fig0_10->LSI = 0;
+ fig0_10->ConfInd = (watermarkData[watermarkPos >> 3] >>
+ (7 - (watermarkPos & 0x07))) & 1;
+ if (++watermarkPos == watermarkSize) {
+ watermarkPos = 0;
+ }
+ fig0_10->UTC = 0;
+ fig0_10->setHours(timeData->tm_hour);
+ fig0_10->Minutes = timeData->tm_min;
+ index = index + 4;
+ figSize += 6;
+
+ fig0_9 = (FIGtype0_9*)&etiFrame[index];
+ fig0_9->FIGtypeNumber = 0;
+ fig0_9->Length = 4;
+ fig0_9->CN = 0;
+ fig0_9->OE = 0;
+ fig0_9->PD = 0;
+ fig0_9->Extension = 9;
+
+ fig0_9->ext = 0;
+ fig0_9->lto = 0;
+ fig0_9->ensembleLto = 0;
+ fig0_9->ensembleEcc = ensemble->ecc;
+ fig0_9->tableId = 0x2;
+ index += 5;
+ figSize += 5;
+
+ break;
+ }
+
+ memcpy(&etiFrame[index], Padding_FIB, 30 - figSize);
+ index += 30 - figSize;
+
+ CRCtmp = 0xffff;
+ CRCtmp = crc16(CRCtmp, &etiFrame[(index - 30)], 30);
+ CRCtmp ^= 0xffff;
+ etiFrame[index++] = ((char *) &CRCtmp)[1];
+ etiFrame[index++] = ((char *) &CRCtmp)[0];
+
+
+ figSize = 0;
+ // Insertion FIB 2
+ if (alterneFIB < ensemble->services.size()) {
+ service = ensemble->services.begin() + alterneFIB;
+
+ // FIG type 1/1, SI, Service label, une instance par sous-canal
+ if ((*service)->getType(ensemble) == 0) {
+ fig1_1 = (FIGtype1_1 *) & etiFrame[index];
+
+ fig1_1->FIGtypeNumber = 1;
+ fig1_1->Length = 21;
+ fig1_1->Charset = 0;
+ fig1_1->OE = 0;
+ fig1_1->Extension = 1;
+
+ fig1_1->Sld = htons((*service)->id);
+ index += 4;
+ figSize += 4;
+ } else {
+ fig1_5 = (FIGtype1_5 *) & etiFrame[index];
+ fig1_5->FIGtypeNumber = 1;
+ fig1_5->Length = 23;
+ fig1_5->Charset = 0;
+ fig1_5->OE = 0;
+ fig1_5->Extension = 5;
+
+ fig1_5->SId = htonl((*service)->id);
+ index += 6;
+ figSize += 6;
+ }
+ memcpy(&etiFrame[index], (*service)->label.text, 16);
+ index += 16;
+ figSize += 16;
+
+ etiFrame[index++] = ((char *) &(*service)->label.flag)[1];
+ etiFrame[index++] = ((char *) &(*service)->label.flag)[0];
+ figSize += 2;
+ } else if (alterneFIB <
+ ensemble->services.size() + ensemble->components.size()) {
+ component = ensemble->components.begin() +
+ (alterneFIB - ensemble->services.size());
+ service = getService(*component, ensemble->services);
+ subchannel =
+ getSubchannel(ensemble->subchannels, (*component)->subchId);
+
+ if ((*component)->label.text[0] != 0) {
+ if ((*service)->getType(ensemble) == 0) { // Programme
+ FIGtype1_4_programme *fig1_4;
+ fig1_4 = (FIGtype1_4_programme*)&etiFrame[index];
+
+ fig1_4->FIGtypeNumber = 1;
+ fig1_4->Length = 22;
+ fig1_4->Charset = 0;
+ fig1_4->OE = 0;
+ fig1_4->Extension = 4;
+ fig1_4->PD = 0;
+ fig1_4->rfa = 0;
+ fig1_4->SCIdS = (*component)->SCIdS;
+
+ fig1_4->SId = htons((*service)->id);
+ index += 5;
+ figSize += 5;
+ } else { // Data
+ FIGtype1_4_data *fig1_4;
+ fig1_4 = (FIGtype1_4_data *) & etiFrame[index];
+ fig1_4->FIGtypeNumber = 1;
+ fig1_4->Length = 24;
+ fig1_4->Charset = 0;
+ fig1_4->OE = 0;
+ fig1_4->Extension = 4;
+ fig1_4->PD = 1;
+ fig1_4->rfa = 0;
+ fig1_4->SCIdS = (*component)->SCIdS;
+
+ fig1_4->SId = htonl((*service)->id);
+ index += 7;
+ figSize += 7;
+ }
+ memcpy(&etiFrame[index], (*component)->label.text, 16);
+ index += 16;
+ figSize += 16;
+
+ etiFrame[index++] = ((char *) &(*component)->label.flag)[1];
+ etiFrame[index++] = ((char *) &(*component)->label.flag)[0];
+ figSize += 2;
+ }
+ }
+ memcpy(&etiFrame[index], Padding_FIB, 30 - figSize);
+ index += 30 - figSize;
+
+ CRCtmp = 0xffff;
+ CRCtmp = crc16(CRCtmp, &etiFrame[(index - 30)], 30);
+ CRCtmp ^= 0xffff;
+ etiFrame[index++] = ((char *) &CRCtmp)[1];
+ etiFrame[index++] = ((char *) &CRCtmp)[0];
+
+ if (ensemble->mode == 3) {
+ memcpy(&etiFrame[index], Padding_FIB, 30);
+ index += 30;
+
+ CRCtmp = 0xffff;
+ CRCtmp = crc16(CRCtmp, &etiFrame[(index - 30)], 30);
+ CRCtmp ^= 0xffff;
+ etiFrame[index++] = ((char *) &CRCtmp)[1];
+ etiFrame[index++] = ((char *) &CRCtmp)[0];
+ }
+
+ if (ensemble->services.size() > 30) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Sorry, but this software currently can't write "
+ "Service Label of more than 30 services.\n");
+ returnCode = -1;
+ goto EXIT;
+ }
+
+ // compteur pour FIG 0/0
+ insertFIG = (insertFIG + 1) % 8;
+
+ // compteur pour inserer FIB a toutes les 30 trames
+ alterneFIB = (alterneFIB + 1) % 30;
+
+ /**********************************************************************
+ ****** Section de lecture de donnees *******************************
+ **********************************************************************/
+
+ //Lecture des donnees dans les fichiers d'entree
+ for (subchannel = ensemble->subchannels.begin();
+ subchannel != ensemble->subchannels.end();
+ ++subchannel) {
+ int sizeSubchannel = getSizeByte(*subchannel);
+ if ((*subchannel)->operations.lock != NULL) {
+ (*subchannel)->operations.lock((*subchannel)->data);
+ }
+ result = (*subchannel)->operations.readFrame(
+ &(*subchannel)->operations,
+ (*subchannel)->data, &etiFrame[index], sizeSubchannel);
+ if ((*subchannel)->operations.unlock != NULL) {
+ (*subchannel)->operations.unlock((*subchannel)->data);
+ }
+ if (result < 0) {
+ etiLog.print(TcpLog::INFO, "ETI frame number: %i\n", currentFrame);
+ }
+ index += sizeSubchannel;
+ }
+
+
+ index = (3 + fc->NST + FICL) * 4;
+ for (subchannel = ensemble->subchannels.begin();
+ subchannel != ensemble->subchannels.end();
+ ++subchannel) {
+ index += getSizeByte(*subchannel);
+ }
+
+ /******* Section EOF **************************************************/
+ // End of Frame, 4 octets
+ index = (FLtmp + 1 + 1) * 4;
+ eti_EOF *eof = (eti_EOF *) & etiFrame[index];
+
+ //CRC sur le Main Stream data (MST), sur 16 bits
+ index = ((fc->NST) + 2 + 1) * 4; //position du MST
+ MSTsize = ((FLtmp) - 1 - (fc->NST)) * 4; //nb d'octets de donnees
+
+ CRCtmp = 0xffff;
+ CRCtmp = crc16(CRCtmp, &etiFrame[index], MSTsize);
+ CRCtmp ^= 0xffff;
+ eof->CRC = htons(CRCtmp);
+
+ //RFU, Reserved for future use, 2 bytes, should be 0xFFFF
+ eof->RFU = htons(0xFFFF);
+
+ /******* Section TIST *************************************************/
+ // TimeStamps, 24 bits + 1 octet
+ index = (FLtmp + 2 + 1) * 4;
+ eti_TIST *tist = (eti_TIST *) & etiFrame[index];
+
+ tist->TIST = htonl(timestamp) | 0xff;
+ if (timestamp != 0xffffff) {
+ timestamp += 3 << 17;
+ if (timestamp > 0xf9ffff) {
+ timestamp -= 0xfa0000;
+ }
+ }
+
+ /**********************************************************************
+ *********** Section FRPD *****************************************
+ **********************************************************************/
+
+ //Donne le nombre total d'octets utils dans la trame
+ index = (FLtmp + 1 + 1 + 1 + 1) * 4;
+
+ for (output = outputs.begin() ; output != outputs.end(); ++output) {
+ if ((*output)->operations.write((*output)->data, etiFrame, index)
+ == -1) {
+ etiLog.print(TcpLog::ERR, "Can't write to output %s://%s\n",
+ (*output)->outputProto, (*output)->outputName);
+ }
+ }
+
+#ifdef DUMP_BRIDGE
+ dumpBytes(dumpData, sizeSubChannel, stderr);
+#endif // DUMP_BRIDGE
+
+ if (currentFrame % 100 == 0) {
+ etiLog.print(TcpLog::INFO, "ETI frame number %i \n", currentFrame);
+ }
+ }
+
+EXIT:
+ etiLog.print(TcpLog::DBG, "exiting...\n");
+ //fermeture des fichiers
+ for (subchannel = ensemble->subchannels.begin();
+ subchannel != ensemble->subchannels.end();
+ ++subchannel) {
+ (*subchannel)->operations.close((*subchannel)->data);
+ (*subchannel)->operations.clean(&(*subchannel)->data);
+ }
+ for (output = outputs.begin() ; output != outputs.end(); ++output) {
+ (*output)->operations.close((*output)->data);
+ (*output)->operations.clean(&(*output)->data);
+ }
+
+ for_each(ensemble->components.begin(), ensemble->components.end(), free);
+ for_each(ensemble->services.begin(), ensemble->services.end(), free);
+ for_each(ensemble->subchannels.begin(), ensemble->subchannels.end(), free);
+ for_each(outputs.begin(), outputs.end(), free);
+ ensemble->components.clear();
+ ensemble->services.clear();
+ ensemble->subchannels.clear();
+ free(ensemble);
+ outputs.clear();
+
+ UdpSocket::clean();
+
+ if (returnCode < 0) {
+ etiLog.print(TcpLog::EMERG, "...aborting\n");
+ } else {
+ etiLog.print(TcpLog::DBG, "...done\n");
+ }
+
+ return returnCode;
+}
diff --git a/src/Dmb.cpp b/src/Dmb.cpp
new file mode 100644
index 0000000..95742d0
--- /dev/null
+++ b/src/Dmb.cpp
@@ -0,0 +1,280 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right
+ of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Dmb.h"
+
+#include <string.h>
+
+
+#ifdef _WIN32
+# define bzero(a, b) memset((a), 0, (b))
+#endif // _WIN32
+
+
+DmbStats::DmbStats()
+{
+ reset();
+}
+
+
+void DmbStats::reset()
+{
+ memset(this, 0, sizeof(*this));
+}
+
+
+Dmb::Dmb(bool reverse) :
+interleaver(12, 17),
+encoder(204, 188)
+{
+ buffer = NULL;
+ bufferSize = 0;
+ setReverse(reverse);
+}
+
+
+Dmb::~Dmb()
+{
+ if (buffer != NULL) {
+ delete[] buffer;
+ }
+}
+
+
+void Dmb::setReverse(bool state)
+{
+ reverse = state;
+ reset();
+
+ interleaver.setReverse(state);
+ encoder.setReverse(state);
+ stats.reset();
+}
+
+
+void Dmb::reset()
+{
+ bufferOffset = 0;
+ bufferLength = 0;
+ inputOffset = 0;
+ outputOffset = 0;
+// padding = 0;
+}
+
+
+#include <stdio.h>
+int Dmb::encode(
+ void* dataIn,
+ unsigned long sizeIn,
+ void* dataOut,
+ unsigned long sizeOut
+ )
+{
+ int ret = 0;
+ char* input = reinterpret_cast<char*>(dataIn);
+ char* output = reinterpret_cast<char*>(dataOut);
+
+ if (bufferSize < sizeIn + 204) {
+ if (buffer != NULL) {
+ delete[] buffer;
+ }
+ unsigned char* oldBuffer = buffer;
+ bufferSize = sizeIn + 204;
+ buffer = new unsigned char[bufferSize];
+ memcpy(buffer, oldBuffer, bufferLength);
+ }
+
+ if (reverse) {
+// fprintf(stderr, "*** Decode ***\n");
+// fprintf(stderr, " sizeIn: %i\n", sizeIn);
+// fprintf(stderr, " inputOffset: %i\n", inputOffset);
+// fprintf(stderr, " bufferLength: %i\n", bufferLength);
+// fprintf(stderr, " bufferOffset: %i\n", bufferOffset);
+// fprintf(stderr, " outputOffset: %i\n", outputOffset);
+
+ if (inputOffset == 0) {
+ ++stats.dmbFrame;
+ stats.rcvBytes += sizeIn;
+ }
+
+ memcpy(&buffer[bufferLength], &input[inputOffset],
+ sizeIn - inputOffset);
+ interleaver.encode(&buffer[bufferLength], sizeIn - inputOffset);
+ bufferLength += sizeIn - inputOffset;
+ inputOffset += sizeIn - inputOffset;
+ while (bufferLength - bufferOffset >= 204) {
+ if (buffer[bufferOffset] != 0x47) {
+ int offset = sync(&buffer[bufferOffset],
+ bufferLength - bufferOffset);
+ if (offset == 0) {
+ bufferLength = 0;
+ bufferOffset = 0;
+ } else {
+ bufferOffset += offset;
+ }
+ } else {
+ if (outputOffset + 188 <= sizeOut) { // If enough place
+ int error = encoder.encode(&buffer[bufferOffset], 204);
+ if (error != -1) {
+// if (true) {
+ if (error > 0) {
+ stats.corBytes += error;
+ }
+ memcpy(&output[outputOffset], &buffer[bufferOffset],
+ 188);
+ if (((buffer[bufferOffset + 1] & 0x1f) == 0x1f) &&
+ (buffer[bufferOffset + 2] == 0xff)) {
+ stats.nulBytes += 188;
+ } else {
+ ret += 188;
+ stats.sndBytes += 188;
+ outputOffset += 188;
+ }
+ bufferOffset += 204;
+ ++stats.mpgFrame;
+ } else {
+// interleaver.reset();
+// padding = 0;
+// bufferLength = 0;
+// inputOffset = 0;
+// stats.errBytes += 188;
+ bufferOffset += 12;
+ stats.errBytes += 12;
+ ++stats.synFrame;
+ int offset = sync (&buffer[bufferOffset],
+ bufferLength - bufferOffset);
+ if (offset == 0) {
+ stats.errBytes += bufferLength - bufferOffset;
+ bufferOffset = 0;
+ bufferLength = 0;
+ } else {
+ stats.errBytes += offset;
+ bufferOffset += offset;
+ }
+ }
+ } else {
+ outputOffset = 0;
+ goto ENCODE_END;
+ }
+ }
+ }
+ memmove(buffer, &buffer[bufferOffset], bufferLength - bufferOffset);
+ bufferLength -= bufferOffset;
+ bufferOffset = 0;
+ if (ret == 0) {
+ inputOffset = 0;
+ } else {
+ outputOffset = 0;
+ }
+// fprintf(stderr, " ret: %i\n\n", ret);
+ } else {
+ if (sizeIn == 0) {
+ bzero(&output[outputOffset], sizeOut - outputOffset);
+ interleaver.encode(&output[outputOffset], sizeOut - outputOffset);
+ outputOffset = 0;
+ ++stats.dmbFrame;
+ stats.sndBytes += sizeOut;
+ goto ENCODE_END;
+ }
+
+ if (bufferLength == 204) { // If buffer is not empty
+ // If there's more data in buffer than place in output
+ if (204 - bufferOffset > sizeOut - outputOffset) {
+ memcpy(&output[outputOffset], &buffer[bufferOffset],
+ sizeOut - outputOffset);
+ bufferOffset += sizeOut - outputOffset;
+ outputOffset = 0;
+ ++stats.dmbFrame;
+ stats.sndBytes += sizeOut;
+ goto ENCODE_END;
+ }
+ memcpy(&output[outputOffset], &buffer[bufferOffset],
+ 204 - bufferOffset);
+ outputOffset += 204 - bufferOffset;
+ bufferOffset = 0;
+ bufferLength = 0;
+ }
+
+ while (true) {
+ // If there's not enought input data
+ if (sizeIn - inputOffset < 188 - bufferLength) {
+ memcpy(&buffer[bufferLength], &input[inputOffset],
+ sizeIn - inputOffset);
+ bufferLength += sizeIn - inputOffset;
+ ret = outputOffset;
+ inputOffset = 0;
+ goto ENCODE_END;
+ }
+ if (buffer[bufferLength] == 0x47) {
+ ++stats.mpgFrame;
+ }
+// fprintf(stderr, "++mpg: %i, sizeIn: %i, inputOffset: %i\n",
+// stats.mpgFrame, sizeIn, inputOffset);
+ stats.rcvBytes += 188;
+
+ memcpy(&buffer[bufferLength], &input[inputOffset],
+ 188 - bufferLength);
+ inputOffset += 188 - bufferLength;
+
+ encoder.encode(buffer, 188);
+ interleaver.encode(buffer, 204);
+ bufferLength = 204;
+
+ if (sizeOut - outputOffset < 204) {
+ memcpy(&output[outputOffset], buffer, sizeOut - outputOffset);
+ bufferOffset += sizeOut - outputOffset;
+ outputOffset = 0;
+ ++stats.dmbFrame;
+ stats.sndBytes += sizeOut;
+ goto ENCODE_END;
+ }
+ memcpy(&output[outputOffset], buffer, 204);
+ outputOffset += 204;
+ bufferLength = 0;
+ }
+ }
+
+ENCODE_END:
+ return ret;
+}
+
+
+int Dmb::sync(void* dataIn, unsigned long sizeIn)
+{
+ char* input = reinterpret_cast<char*>(dataIn);
+ char* sync = input;
+ unsigned long size = sizeIn;
+
+ while (sync != NULL) {
+ sync = (char*)memchr(sync, 0x47, size);
+ if (sync != NULL) {
+ int offset = sync - input;
+ if (offset % 12 != 0) {
+ offset = ((offset / 12) * 12) + 12;
+ sync = &input[offset];
+ size = sizeIn - offset;
+ } else {
+ return offset;
+ }
+ }
+ }
+ return 0;
+}
diff --git a/src/Dmb.h b/src/Dmb.h
new file mode 100644
index 0000000..13ce340
--- /dev/null
+++ b/src/Dmb.h
@@ -0,0 +1,81 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right
+ of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _DMB
+#define _DMB
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "Interleaver.h"
+#include "ReedSolomon.h"
+
+
+class DmbStats
+{
+public:
+ DmbStats();
+ void reset();
+
+ unsigned dmbFrame;
+ unsigned mpgFrame;
+ unsigned synFrame;
+ unsigned rcvBytes;
+ unsigned nulBytes;
+ unsigned sndBytes;
+ unsigned errBytes;
+ unsigned corBytes;
+};
+
+
+class Dmb
+{
+public:
+ Dmb(bool reverse = false);
+ Dmb(const Dmb& clone);
+ virtual ~Dmb();
+
+ void setReverse(bool state);
+ int encode(void* dataIn, unsigned long sizeIn, void* dataOut, unsigned long sizeOut);
+ void reset();
+ DmbStats getStats() { return stats; };
+
+private:
+ int sync(void* dataIn, unsigned long sizeIn);
+
+ Interleaver interleaver;
+ ReedSolomon encoder;
+ unsigned char* buffer;
+ unsigned bufferSize;
+ unsigned bufferOffset; // Encoded data written to output
+ unsigned bufferLength; // Encoded data
+ unsigned inputOffset;
+ unsigned outputOffset;
+// unsigned padding; // Padding data written
+
+ bool reverse;
+
+ DmbStats stats;
+};
+
+
+#endif // _DMB
diff --git a/src/Eti.cpp b/src/Eti.cpp
new file mode 100644
index 0000000..3dd11e2
--- /dev/null
+++ b/src/Eti.cpp
@@ -0,0 +1,70 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right
+ of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef _WIN32
+# pragma warning ( disable : 4103 )
+# include "Eti.h"
+# pragma warning ( default : 4103 )
+#else
+# include "Eti.h"
+#endif
+
+
+//definitions des structures des champs du ETI(NI, G703)
+
+
+unsigned short eti_FC::getFrameLength()
+{
+ return (unsigned short)((FL_high << 8) | FL_low);
+}
+
+
+void eti_FC::setFrameLength(uint16_t length)
+{
+ FL_high = (length >> 8) & 0x07;
+ FL_low = length & 0xff;
+}
+
+
+void eti_STC::setSTL(uint16_t length)
+{
+ STL_high = length >> 8;
+ STL_low = length & 0xff;
+}
+
+
+uint16_t eti_STC::getSTL()
+{
+ return (uint16_t)((STL_high << 8) + STL_low);
+}
+
+
+void eti_STC::setStartAddress(uint16_t address)
+{
+ startAddress_high = address >> 8;
+ startAddress_low = address & 0xff;
+}
+
+
+uint16_t eti_STC::getStartAddress()
+{
+ return (uint16_t)((startAddress_high << 8) + startAddress_low);
+}
diff --git a/src/Eti.h b/src/Eti.h
new file mode 100644
index 0000000..5580aaf
--- /dev/null
+++ b/src/Eti.h
@@ -0,0 +1,96 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right
+ of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ETI_
+#define ETI_
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef _WIN32
+# include <winsock2.h> // For types...
+typedef WORD uint16_t;
+typedef DWORD32 uint32_t;
+
+# define PACKED
+# pragma pack(push, 1)
+#else
+# include <stdint.h>
+
+# define PACKED __attribute__ ((packed))
+#endif
+
+
+//definitions des structures des champs du ETI(NI, G703)
+
+
+struct eti_SYNC {
+ uint32_t ERR:8;
+ uint32_t FSYNC:24;
+} PACKED;
+
+
+struct eti_FC {
+ uint32_t FCT:8;
+ uint32_t NST:7;
+ uint32_t FICF:1;
+ uint32_t FL_high:3;
+ uint32_t MID:2;
+ uint32_t FP:3;
+ uint32_t FL_low:8;
+ uint16_t getFrameLength();
+ void setFrameLength(uint16_t length);
+} PACKED;
+
+
+struct eti_STC {
+ uint32_t startAddress_high:2;
+ uint32_t SCID:6;
+ uint32_t startAddress_low:8;
+ uint32_t STL_high:2;
+ uint32_t TPL:6;
+ uint32_t STL_low:8;
+ void setSTL(uint16_t length);
+ uint16_t getSTL();
+ void setStartAddress(uint16_t address);
+ uint16_t getStartAddress();
+} PACKED;
+
+
+struct eti_EOH {
+ uint16_t MNSC;
+ uint16_t CRC;
+} PACKED;
+
+
+struct eti_EOF {
+ uint16_t CRC;
+ uint16_t RFU;
+} PACKED;
+
+
+struct eti_TIST {
+ uint32_t TIST;
+} PACKED;
+
+
+#endif // ETI_
diff --git a/src/InetAddress.cpp b/src/InetAddress.cpp
new file mode 100644
index 0000000..8915285
--- /dev/null
+++ b/src/InetAddress.cpp
@@ -0,0 +1,259 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
+ Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "InetAddress.h"
+#include <iostream>
+#include <stdio.h>
+
+#ifdef _WIN32
+#else
+# include <errno.h>
+# include <string.h>
+#endif
+
+#ifdef TRACE_ON
+# ifndef TRACE_CLASS
+# define TRACE_CLASS(clas, func) cout <<"-" <<(clas) <<"\t(" <<this <<")::" <<(func) <<endl
+# define TRACE_STATIC(clas, func) cout <<"-" <<(clas) <<"\t(static)::" <<(func) <<endl
+# endif
+#else
+# ifndef TRACE_CLASS
+# define TRACE_CLASS(clas, func)
+# define TRACE_STATIC(clas, func)
+# endif
+#endif
+
+
+int inetErrNo = 0;
+const char *inetErrMsg = NULL;
+const char *inetErrDesc = NULL;
+
+
+/**
+ * Constructs an IP address.
+ * @param port The port of this address
+ * @param name The name of this address
+ */
+InetAddress::InetAddress(int port, const char* name) {
+ TRACE_CLASS("InetAddress", "InetAddress(int, char)");
+ addr.sin_family = PF_INET;
+ addr.sin_addr.s_addr = htons(INADDR_ANY);
+ addr.sin_port = htons(port);
+ if (name)
+ setAddress(name);
+}
+
+
+/**
+ * Constructs a copy of inet
+ * @param inet The address to be copied
+ */
+InetAddress::InetAddress(const InetAddress &inet) {
+ TRACE_CLASS("InetAddress", "InetAddress(InetAddress)");
+ memcpy(&addr, &inet.addr, sizeof(addr));
+}
+
+
+/// Destructor
+InetAddress::~InetAddress() {
+ TRACE_CLASS("InetAddress" ,"~InetAddress()");
+}
+
+
+/// Returns the raw IP address of this InetAddress object.
+sockaddr *InetAddress::getAddress() {
+ TRACE_CLASS("InetAddress", "getAddress()");
+ return (sockaddr *)&addr;
+}
+
+
+/// Return the port of this address.
+int InetAddress::getPort()
+{
+ TRACE_CLASS("InetAddress", "getPort()");
+ return ntohs(addr.sin_port);
+}
+
+
+/**
+ * Returns the IP address string "%d.%d.%d.%d".
+ * @return IP address
+ */
+const char *InetAddress::getHostAddress() {
+ TRACE_CLASS("InetAddress", "getHostAddress()");
+ return inet_ntoa(addr.sin_addr);
+}
+
+
+/// Returns true if this address is multicast
+bool InetAddress::isMulticastAddress() {
+ TRACE_CLASS("InetAddress", "isMulticastAddress()");
+ return IN_MULTICAST(ntohl(addr.sin_addr.s_addr)); // a modifier
+}
+
+
+/**
+ * Set the port number
+ * @param port The new port number
+ */
+void InetAddress::setPort(int port)
+{
+ TRACE_CLASS("InetAddress", "setPort(int)");
+ addr.sin_port = htons(port);
+}
+
+
+/**
+ * Set the address
+ * @param name The new address name
+ * @return 0 if ok
+ * -1 if error
+ */
+int InetAddress::setAddress(const char *name)
+{
+ TRACE_CLASS("InetAddress", "setAddress(char*)");
+ if (name) {
+ if (atoi(name)) { // If it start with a number
+ if ((addr.sin_addr.s_addr = inet_addr(name)) == INADDR_NONE) {
+ addr.sin_addr.s_addr = htons(INADDR_ANY);
+ inetErrNo = 0;
+ inetErrMsg = "Invalid address";
+ inetErrDesc = name;
+ return -1;
+ }
+ } else { // Assume it's a real name
+ hostent *host = gethostbyname(name);
+ if (host) {
+ addr.sin_addr = *(in_addr *)(host->h_addr);
+ } else {
+ addr.sin_addr.s_addr = htons(INADDR_ANY);
+ inetErrNo = 0;
+ inetErrMsg = "Could not find address";
+ inetErrDesc = name;
+ return -1;
+ }
+ }
+ } else {
+ addr.sin_addr.s_addr = INADDR_ANY;
+ }
+ return 0;
+}
+
+
+void setInetError(const char* description)
+{
+ inetErrNo = 0;
+#ifdef _WIN32
+ inetErrNo = WSAGetLastError();
+ switch (inetErrNo) {
+ case WSANOTINITIALISED:
+ inetErrMsg = "WSANOTINITIALISED A successful WSAStartup must occur before using this function.";
+ break;
+ case WSAENETDOWN:
+ inetErrMsg = "WSAENETDOWN The network subsystem has failed.";
+ break;
+ case WSAEFAULT:
+ inetErrMsg = "WSAEFAULT The buf or from parameters are not part of the user address space, or the fromlen parameter is too small to accommodate the peer address.";
+ break;
+ case WSAEINTR:
+ inetErrMsg = "WSAEINTR The (blocking) call was canceled through WSACancelBlockingCall.";
+ break;
+ case WSAEINPROGRESS:
+ inetErrMsg = "WSAEINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.";
+ break;
+ case WSAEINVAL:
+ inetErrMsg = "WSAEINVAL The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, or (for byte stream-style sockets only) len was zero or negative.";
+ break;
+ case WSAEISCONN:
+ inetErrMsg = "WSAEISCONN The socket is connected. This function is not permitted with a connected socket, whether the socket is connection-oriented or connectionless.";
+ break;
+ case WSAENETRESET:
+ inetErrMsg = "WSAENETRESET The connection has been broken due to the \"keep-alive\" activity detecting a failure while the operation was in progress.";
+ break;
+ case WSAENOTSOCK:
+ inetErrMsg = "WSAENOTSOCK The descriptor is not a socket.";
+ break;
+ case WSAEOPNOTSUPP:
+ inetErrMsg = "WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, out-of-band data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.";
+ break;
+ case WSAESHUTDOWN:
+ inetErrMsg = "WSAESHUTDOWN The socket has been shut down; it is not possible to recvfrom on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.";
+ break;
+ case WSAEWOULDBLOCK:
+ inetErrMsg = "WSAEWOULDBLOCK The socket is marked as nonblocking and the recvfrom operation would block.";
+ break;
+ case WSAEMSGSIZE:
+ inetErrMsg = "WSAEMSGSIZE The message was too large to fit into the specified buffer and was truncated.";
+ break;
+ case WSAETIMEDOUT:
+ inetErrMsg = "WSAETIMEDOUT The connection has been dropped, because of a network failure or because the system on the other end went down without notice.";
+ break;
+ case WSAECONNRESET:
+ inetErrMsg = "WSAECONNRESET";
+ break;
+ case WSAEACCES:
+ inetErrMsg = "WSAEACCES The requested address is a broadcast address, but the appropriate flag was not set. Call setsockopt with the SO_BROADCAST parameter to allow the use of the broadcast address.";
+ break;
+ case WSAENOBUFS:
+ inetErrMsg = "WSAENOBUFS No buffer space is available.";
+ break;
+ case WSAENOTCONN:
+ inetErrMsg = "WSAENOTCONN The socket is not connected (connection-oriented sockets only)";
+ break;
+ case WSAEHOSTUNREACH:
+ inetErrMsg = "WSAEHOSTUNREACH The remote host cannot be reached from this host at this time.";
+ break;
+ case WSAECONNABORTED:
+ inetErrMsg = "WSAECONNABORTED The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.";
+ break;
+ case WSAEADDRNOTAVAIL:
+ inetErrMsg = "WSAEADDRNOTAVAIL The remote address is not a valid address, for example, ADDR_ANY.";
+ break;
+ case WSAEAFNOSUPPORT:
+ inetErrMsg = "WSAEAFNOSUPPORT Addresses in the specified family cannot be used with this socket.";
+ break;
+ case WSAEDESTADDRREQ:
+ inetErrMsg = "WSAEDESTADDRREQ A destination address is required.";
+ break;
+ case WSAENETUNREACH:
+ inetErrMsg = "WSAENETUNREACH The network cannot be reached from this host at this time.";
+ break;
+ case WSAEMFILE:
+ inetErrMsg = "No more socket descriptors are available.";
+ break;
+ case WSAEPROTONOSUPPORT:
+ inetErrMsg = "The specified protocol is not supported.";
+ break;
+ case WSAEPROTOTYPE:
+ inetErrMsg = "The specified protocol is the wrong type for this socket.";
+ break;
+ case WSAESOCKTNOSUPPORT:
+ inetErrMsg = "The specified socket type is not supported in this address family.";
+ break;
+ default:
+ inetErrMsg = "Unknown";
+ };
+#else
+ inetErrNo = errno;
+ inetErrMsg = strerror(inetErrNo);
+#endif
+ inetErrDesc = description;
+}
diff --git a/src/InetAddress.h b/src/InetAddress.h
new file mode 100644
index 0000000..f818cbf
--- /dev/null
+++ b/src/InetAddress.h
@@ -0,0 +1,91 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
+ Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _InetAddress
+#define _InetAddress
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+// General libraries
+#include <stdlib.h>
+// Linux librairies
+#ifndef _WIN32
+// # include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <unistd.h>
+# include <netdb.h>
+# include <arpa/inet.h>
+# include <pthread.h>
+# define SOCKET int
+# define INVALID_SOCKET -1
+# define closesocket ::close
+// Windows librairies
+#else
+# include <winsock.h>
+# ifdef _MSC_VER
+# pragma comment(lib, "wsock32.lib")
+# elif defined(__BORLANDC__)
+# pragma(lib, "mswsock.lib")
+# endif
+# ifndef IN_MULTICAST
+# define IN_MULTICAST(a) ((((unsigned long) (a)) & 0xf0000000) == 0xe0000000)
+# endif
+#endif
+// General definitions
+#define INVALID_PORT -1
+
+
+/// The last error number
+extern int inetErrNo;
+/// The last error message
+extern const char *inetErrMsg;
+/// The description of the last error
+extern const char *inetErrDesc;
+/// Set the number, message and description of the last error
+void setInetError(const char* description);
+
+
+/**
+ * This class represents an Internet Protocol (IP) address.
+ * @author Pascal Charest pascal.charest@crc.ca
+ */
+class InetAddress {
+ public:
+ InetAddress(int port = 0, const char* name = NULL);
+ InetAddress(const InetAddress &addr);
+ ~InetAddress();
+
+ sockaddr *getAddress();
+ const char *getHostAddress();
+ int getPort();
+ int setAddress(const char *name);
+ void setPort(int port);
+ bool isMulticastAddress();
+
+ private:
+ sockaddr_in addr;
+};
+
+
+#endif
diff --git a/src/Interleaver.cpp b/src/Interleaver.cpp
new file mode 100644
index 0000000..0b23b8d
--- /dev/null
+++ b/src/Interleaver.cpp
@@ -0,0 +1,143 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right
+ of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Interleaver.h"
+
+#include <string.h>
+
+#ifdef _WIN32
+# define bzero(a, b) memset((a), 0, (b))
+#endif // _WIN32
+
+
+Interleaver::Interleaver(unsigned short I, unsigned short M, bool reverse)
+{
+ this->I = I;
+ this->M = M;
+ this->N = I * M;
+ this->memSize = (this->N * I) - 1;
+ this->mem = new char[memSize];
+ setReverse(reverse);
+}
+
+
+Interleaver::~Interleaver()
+{
+ delete []mem;
+}
+
+
+void Interleaver::setReverse(bool state)
+{
+ reverse = state;
+ reset();
+}
+
+
+void Interleaver::reset()
+{
+ j = 0;
+ index = 0;
+ bzero(mem, memSize);
+}
+
+
+void Interleaver::encode(void* data, unsigned long size)
+{
+ encode(data, data, size);
+}
+
+
+void Interleaver::encode(const void* inData, void* outData, unsigned long size)
+{
+ const char* input = reinterpret_cast<const char *>(inData);
+ char* output = reinterpret_cast<char *>(outData);
+ unsigned long i;
+
+ if (reverse) {
+ for (i = 0; i < size; ++i) {
+ mem[(index + ((I - 1 - j) * N)) % memSize] = *input;
+ *output = mem[index];
+ ++input;
+ ++output;
+ if (++j == I) {
+ j = 0;
+ }
+ if (++index == memSize) {
+ index = 0;
+ }
+ }
+ } else {
+ for (i = 0; i < size; ++i) {
+ if (j) {
+ mem[(index + (j * N)) % memSize] = *input;
+ *output = mem[index];
+ } else {
+ *output = *input;
+ }
+ ++input;
+ ++output;
+ if (++j == I) {
+ j = 0;
+ }
+ if (++index == memSize) {
+ index = 0;
+ }
+ }
+ }
+}
+
+
+unsigned long Interleaver::sync(void* data, unsigned long size, char padding)
+{
+ char* input = reinterpret_cast<char *>(data);
+ unsigned long index;
+
+ if (reverse) {
+ for (index = 0; index < size; ++index) {
+ mem[(index + ((I - 1 - j) * N)) % memSize] = padding;
+ *input = mem[index];
+ ++input;
+ if (++index == memSize) {
+ index = 0;
+ }
+ if (++j == I) {
+ j = 0;
+ break;
+ }
+ }
+ } else {
+ for (index = 0; index < size; ++index) {
+ mem[(index + (j * N)) % memSize] = padding;
+ *input = mem[index];
+ ++input;
+ if (++index == memSize) {
+ index = 0;
+ }
+ if (++j == I) {
+ j = 0;
+ break;
+ }
+ }
+ }
+
+ return index;
+}
diff --git a/src/Interleaver.h b/src/Interleaver.h
new file mode 100644
index 0000000..ad5cccf
--- /dev/null
+++ b/src/Interleaver.h
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right
+ of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _INTERLEAVER
+#define _INTERLEAVER
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+class Interleaver
+{
+public:
+ Interleaver(unsigned short I, unsigned short M, bool reverse = false);
+ Interleaver(Interleaver& clone);
+ virtual ~Interleaver();
+
+ void setReverse(bool state);
+ void encode(void* data, unsigned long size);
+ void encode(const void* inData, void* outData, unsigned long size);
+ unsigned long sync(void* data, unsigned long size, char padding = 0);
+ void reset();
+ void flush(char padding = 0);
+
+private:
+ unsigned short I;
+ unsigned short M;
+ unsigned long N;
+ unsigned long j;
+ unsigned long index;
+ unsigned long memSize;
+ char* mem;
+ bool reverse;
+};
+
+
+#endif // _INTERLEAVER
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..956e0f4
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,66 @@
+# Copyright (C) 2008, 2009 Her Majesty the Queen in Right of Canada
+# (Communications Research Center Canada)
+
+# This file is part of CRC-DabMux.
+#
+# CRC-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.
+#
+# CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+
+bin_PROGRAMS =CRC-DabMux CRC-BridgeTest
+
+FEC_FLAGS =
+FEC_LIBS =-lfec
+
+CRC_DabMux_CPPFLAGS =-I$(FARSYNC_DIR)
+CRC_DabMux_LDADD =$(FEC_LIBS) -lpthread
+CRC_DabMux_SOURCES =DabMux.cpp \
+ dabInput.h dabInput.cpp \
+ dabInputBridgeUdp.h dabInputBridgeUdp.cpp \
+ dabInputDabplusFifo.h dabInputDabplusFifo.cpp \
+ dabInputDabplusFile.h dabInputDabplusFile.cpp \
+ dabInputDmbFile.h dabInputDmbFile.cpp \
+ dabInputDmbUdp.h dabInputDmbUdp.cpp \
+ dabInputEnhancedFifo.h dabInputEnhancedFifo.cpp \
+ dabInputEnhancedPacketFile.h dabInputEnhancedPacketFile.cpp \
+ dabInputFifo.h dabInputFifo.cpp \
+ dabInputFile.h dabInputFile.cpp \
+ dabInputMpegFifo.h dabInputMpegFifo.cpp \
+ dabInputMpegFile.h dabInputMpegFile.cpp \
+ dabInputPacketFile.h dabInputPacketFile.cpp \
+ dabInputPrbs.h dabInputPrbs.cpp \
+ dabInputRawFile.h dabInputRawFile.cpp \
+ dabInputRawFifo.h dabInputRawFifo.cpp \
+ dabInputSlip.h dabInputSlip.cpp \
+ dabInputTest.h dabInputTest.cpp \
+ dabInputUdp.h dabInputUdp.cpp \
+ dabOutput.h dabOutput.cpp \
+ bridge.h bridge.c \
+ \
+ Eti.h Eti.cpp \
+ TcpLog.h TcpLog.cpp \
+ UdpSocket.h UdpSocket.cpp \
+ InetAddress.h InetAddress.cpp \
+ prbs.h prbs.c \
+ crc.h crc.c \
+ dabUtils.h dabUtils.cpp \
+ PcDebug.h \
+ Dmb.h Dmb.cpp \
+ Interleaver.h Interleaver.cpp \
+ ReedSolomon.h ReedSolomon.cpp \
+ mpeg.h mpeg.c \
+ TcpServer.h TcpServer.cpp \
+ TcpSocket.h TcpSocket.cpp
+
+CRC_BridgeTest_CFLAGS =-DBRIDGE_TEST
+CRC_BridgeTest_SOURCES =bridge.c \
+ crc.c crc.h
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..e3689b0
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,1146 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 2008, 2009 Her Majesty the Queen in Right of Canada
+# (Communications Research Center Canada)
+
+# This file is part of CRC-DabMux.
+#
+# CRC-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.
+#
+# CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+bin_PROGRAMS = CRC-DabMux$(EXEEXT) CRC-BridgeTest$(EXEEXT)
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_CRC_BridgeTest_OBJECTS = CRC_BridgeTest-bridge.$(OBJEXT) \
+ CRC_BridgeTest-crc.$(OBJEXT)
+CRC_BridgeTest_OBJECTS = $(am_CRC_BridgeTest_OBJECTS)
+CRC_BridgeTest_LDADD = $(LDADD)
+CRC_BridgeTest_LINK = $(CCLD) $(CRC_BridgeTest_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_CRC_DabMux_OBJECTS = CRC_DabMux-DabMux.$(OBJEXT) \
+ CRC_DabMux-dabInput.$(OBJEXT) \
+ CRC_DabMux-dabInputBridgeUdp.$(OBJEXT) \
+ CRC_DabMux-dabInputDabplusFifo.$(OBJEXT) \
+ CRC_DabMux-dabInputDabplusFile.$(OBJEXT) \
+ CRC_DabMux-dabInputDmbFile.$(OBJEXT) \
+ CRC_DabMux-dabInputDmbUdp.$(OBJEXT) \
+ CRC_DabMux-dabInputEnhancedFifo.$(OBJEXT) \
+ CRC_DabMux-dabInputEnhancedPacketFile.$(OBJEXT) \
+ CRC_DabMux-dabInputFifo.$(OBJEXT) \
+ CRC_DabMux-dabInputFile.$(OBJEXT) \
+ CRC_DabMux-dabInputMpegFifo.$(OBJEXT) \
+ CRC_DabMux-dabInputMpegFile.$(OBJEXT) \
+ CRC_DabMux-dabInputPacketFile.$(OBJEXT) \
+ CRC_DabMux-dabInputPrbs.$(OBJEXT) \
+ CRC_DabMux-dabInputRawFile.$(OBJEXT) \
+ CRC_DabMux-dabInputRawFifo.$(OBJEXT) \
+ CRC_DabMux-dabInputSlip.$(OBJEXT) \
+ CRC_DabMux-dabInputTest.$(OBJEXT) \
+ CRC_DabMux-dabInputUdp.$(OBJEXT) \
+ CRC_DabMux-dabOutput.$(OBJEXT) CRC_DabMux-bridge.$(OBJEXT) \
+ CRC_DabMux-Eti.$(OBJEXT) CRC_DabMux-TcpLog.$(OBJEXT) \
+ CRC_DabMux-UdpSocket.$(OBJEXT) \
+ CRC_DabMux-InetAddress.$(OBJEXT) CRC_DabMux-prbs.$(OBJEXT) \
+ CRC_DabMux-crc.$(OBJEXT) CRC_DabMux-dabUtils.$(OBJEXT) \
+ CRC_DabMux-Dmb.$(OBJEXT) CRC_DabMux-Interleaver.$(OBJEXT) \
+ CRC_DabMux-ReedSolomon.$(OBJEXT) CRC_DabMux-mpeg.$(OBJEXT) \
+ CRC_DabMux-TcpServer.$(OBJEXT) CRC_DabMux-TcpSocket.$(OBJEXT)
+CRC_DabMux_OBJECTS = $(am_CRC_DabMux_OBJECTS)
+am__DEPENDENCIES_1 =
+CRC_DabMux_DEPENDENCIES = $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+ -o $@
+SOURCES = $(CRC_BridgeTest_SOURCES) $(CRC_DabMux_SOURCES)
+DIST_SOURCES = $(CRC_BridgeTest_SOURCES) $(CRC_DabMux_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_HOST = @BUILD_HOST@
+BUILD_TARGET = @BUILD_TARGET@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FARSYNC_DIR = @FARSYNC_DIR@
+GETOPT = @GETOPT@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+WSOCK32 = @WSOCK32@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+FEC_FLAGS =
+FEC_LIBS = -lfec
+CRC_DabMux_CPPFLAGS = -I$(FARSYNC_DIR)
+CRC_DabMux_LDADD = $(FEC_LIBS) -lpthread
+CRC_DabMux_SOURCES = DabMux.cpp \
+ dabInput.h dabInput.cpp \
+ dabInputBridgeUdp.h dabInputBridgeUdp.cpp \
+ dabInputDabplusFifo.h dabInputDabplusFifo.cpp \
+ dabInputDabplusFile.h dabInputDabplusFile.cpp \
+ dabInputDmbFile.h dabInputDmbFile.cpp \
+ dabInputDmbUdp.h dabInputDmbUdp.cpp \
+ dabInputEnhancedFifo.h dabInputEnhancedFifo.cpp \
+ dabInputEnhancedPacketFile.h dabInputEnhancedPacketFile.cpp \
+ dabInputFifo.h dabInputFifo.cpp \
+ dabInputFile.h dabInputFile.cpp \
+ dabInputMpegFifo.h dabInputMpegFifo.cpp \
+ dabInputMpegFile.h dabInputMpegFile.cpp \
+ dabInputPacketFile.h dabInputPacketFile.cpp \
+ dabInputPrbs.h dabInputPrbs.cpp \
+ dabInputRawFile.h dabInputRawFile.cpp \
+ dabInputRawFifo.h dabInputRawFifo.cpp \
+ dabInputSlip.h dabInputSlip.cpp \
+ dabInputTest.h dabInputTest.cpp \
+ dabInputUdp.h dabInputUdp.cpp \
+ dabOutput.h dabOutput.cpp \
+ bridge.h bridge.c \
+ \
+ Eti.h Eti.cpp \
+ TcpLog.h TcpLog.cpp \
+ UdpSocket.h UdpSocket.cpp \
+ InetAddress.h InetAddress.cpp \
+ prbs.h prbs.c \
+ crc.h crc.c \
+ dabUtils.h dabUtils.cpp \
+ PcDebug.h \
+ Dmb.h Dmb.cpp \
+ Interleaver.h Interleaver.cpp \
+ ReedSolomon.h ReedSolomon.cpp \
+ mpeg.h mpeg.c \
+ TcpServer.h TcpServer.cpp \
+ TcpSocket.h TcpSocket.cpp
+
+CRC_BridgeTest_CFLAGS = -DBRIDGE_TEST
+CRC_BridgeTest_SOURCES = bridge.c \
+ crc.c crc.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cpp .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+CRC-BridgeTest$(EXEEXT): $(CRC_BridgeTest_OBJECTS) $(CRC_BridgeTest_DEPENDENCIES)
+ @rm -f CRC-BridgeTest$(EXEEXT)
+ $(CRC_BridgeTest_LINK) $(CRC_BridgeTest_OBJECTS) $(CRC_BridgeTest_LDADD) $(LIBS)
+CRC-DabMux$(EXEEXT): $(CRC_DabMux_OBJECTS) $(CRC_DabMux_DEPENDENCIES)
+ @rm -f CRC-DabMux$(EXEEXT)
+ $(CXXLINK) $(CRC_DabMux_OBJECTS) $(CRC_DabMux_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_BridgeTest-bridge.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_BridgeTest-crc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-DabMux.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-Dmb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-Eti.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-InetAddress.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-Interleaver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-ReedSolomon.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-TcpLog.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-TcpServer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-TcpSocket.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-UdpSocket.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-bridge.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-crc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInput.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputBridgeUdp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputDabplusFifo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputDabplusFile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputDmbFile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputDmbUdp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputEnhancedFifo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputEnhancedPacketFile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputFifo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputFile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputMpegFifo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputMpegFile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputPacketFile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputPrbs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputRawFifo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputRawFile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputSlip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputTest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabInputUdp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabOutput.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-dabUtils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-mpeg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRC_DabMux-prbs.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+CRC_BridgeTest-bridge.o: bridge.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CRC_BridgeTest_CFLAGS) $(CFLAGS) -MT CRC_BridgeTest-bridge.o -MD -MP -MF $(DEPDIR)/CRC_BridgeTest-bridge.Tpo -c -o CRC_BridgeTest-bridge.o `test -f 'bridge.c' || echo '$(srcdir)/'`bridge.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_BridgeTest-bridge.Tpo $(DEPDIR)/CRC_BridgeTest-bridge.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bridge.c' object='CRC_BridgeTest-bridge.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CRC_BridgeTest_CFLAGS) $(CFLAGS) -c -o CRC_BridgeTest-bridge.o `test -f 'bridge.c' || echo '$(srcdir)/'`bridge.c
+
+CRC_BridgeTest-bridge.obj: bridge.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CRC_BridgeTest_CFLAGS) $(CFLAGS) -MT CRC_BridgeTest-bridge.obj -MD -MP -MF $(DEPDIR)/CRC_BridgeTest-bridge.Tpo -c -o CRC_BridgeTest-bridge.obj `if test -f 'bridge.c'; then $(CYGPATH_W) 'bridge.c'; else $(CYGPATH_W) '$(srcdir)/bridge.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_BridgeTest-bridge.Tpo $(DEPDIR)/CRC_BridgeTest-bridge.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bridge.c' object='CRC_BridgeTest-bridge.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CRC_BridgeTest_CFLAGS) $(CFLAGS) -c -o CRC_BridgeTest-bridge.obj `if test -f 'bridge.c'; then $(CYGPATH_W) 'bridge.c'; else $(CYGPATH_W) '$(srcdir)/bridge.c'; fi`
+
+CRC_BridgeTest-crc.o: crc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CRC_BridgeTest_CFLAGS) $(CFLAGS) -MT CRC_BridgeTest-crc.o -MD -MP -MF $(DEPDIR)/CRC_BridgeTest-crc.Tpo -c -o CRC_BridgeTest-crc.o `test -f 'crc.c' || echo '$(srcdir)/'`crc.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_BridgeTest-crc.Tpo $(DEPDIR)/CRC_BridgeTest-crc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crc.c' object='CRC_BridgeTest-crc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CRC_BridgeTest_CFLAGS) $(CFLAGS) -c -o CRC_BridgeTest-crc.o `test -f 'crc.c' || echo '$(srcdir)/'`crc.c
+
+CRC_BridgeTest-crc.obj: crc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CRC_BridgeTest_CFLAGS) $(CFLAGS) -MT CRC_BridgeTest-crc.obj -MD -MP -MF $(DEPDIR)/CRC_BridgeTest-crc.Tpo -c -o CRC_BridgeTest-crc.obj `if test -f 'crc.c'; then $(CYGPATH_W) 'crc.c'; else $(CYGPATH_W) '$(srcdir)/crc.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_BridgeTest-crc.Tpo $(DEPDIR)/CRC_BridgeTest-crc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crc.c' object='CRC_BridgeTest-crc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CRC_BridgeTest_CFLAGS) $(CFLAGS) -c -o CRC_BridgeTest-crc.obj `if test -f 'crc.c'; then $(CYGPATH_W) 'crc.c'; else $(CYGPATH_W) '$(srcdir)/crc.c'; fi`
+
+CRC_DabMux-bridge.o: bridge.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT CRC_DabMux-bridge.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-bridge.Tpo -c -o CRC_DabMux-bridge.o `test -f 'bridge.c' || echo '$(srcdir)/'`bridge.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-bridge.Tpo $(DEPDIR)/CRC_DabMux-bridge.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bridge.c' object='CRC_DabMux-bridge.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o CRC_DabMux-bridge.o `test -f 'bridge.c' || echo '$(srcdir)/'`bridge.c
+
+CRC_DabMux-bridge.obj: bridge.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT CRC_DabMux-bridge.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-bridge.Tpo -c -o CRC_DabMux-bridge.obj `if test -f 'bridge.c'; then $(CYGPATH_W) 'bridge.c'; else $(CYGPATH_W) '$(srcdir)/bridge.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-bridge.Tpo $(DEPDIR)/CRC_DabMux-bridge.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bridge.c' object='CRC_DabMux-bridge.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o CRC_DabMux-bridge.obj `if test -f 'bridge.c'; then $(CYGPATH_W) 'bridge.c'; else $(CYGPATH_W) '$(srcdir)/bridge.c'; fi`
+
+CRC_DabMux-prbs.o: prbs.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT CRC_DabMux-prbs.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-prbs.Tpo -c -o CRC_DabMux-prbs.o `test -f 'prbs.c' || echo '$(srcdir)/'`prbs.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-prbs.Tpo $(DEPDIR)/CRC_DabMux-prbs.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='prbs.c' object='CRC_DabMux-prbs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o CRC_DabMux-prbs.o `test -f 'prbs.c' || echo '$(srcdir)/'`prbs.c
+
+CRC_DabMux-prbs.obj: prbs.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT CRC_DabMux-prbs.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-prbs.Tpo -c -o CRC_DabMux-prbs.obj `if test -f 'prbs.c'; then $(CYGPATH_W) 'prbs.c'; else $(CYGPATH_W) '$(srcdir)/prbs.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-prbs.Tpo $(DEPDIR)/CRC_DabMux-prbs.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='prbs.c' object='CRC_DabMux-prbs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o CRC_DabMux-prbs.obj `if test -f 'prbs.c'; then $(CYGPATH_W) 'prbs.c'; else $(CYGPATH_W) '$(srcdir)/prbs.c'; fi`
+
+CRC_DabMux-crc.o: crc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT CRC_DabMux-crc.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-crc.Tpo -c -o CRC_DabMux-crc.o `test -f 'crc.c' || echo '$(srcdir)/'`crc.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-crc.Tpo $(DEPDIR)/CRC_DabMux-crc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crc.c' object='CRC_DabMux-crc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o CRC_DabMux-crc.o `test -f 'crc.c' || echo '$(srcdir)/'`crc.c
+
+CRC_DabMux-crc.obj: crc.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT CRC_DabMux-crc.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-crc.Tpo -c -o CRC_DabMux-crc.obj `if test -f 'crc.c'; then $(CYGPATH_W) 'crc.c'; else $(CYGPATH_W) '$(srcdir)/crc.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-crc.Tpo $(DEPDIR)/CRC_DabMux-crc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crc.c' object='CRC_DabMux-crc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o CRC_DabMux-crc.obj `if test -f 'crc.c'; then $(CYGPATH_W) 'crc.c'; else $(CYGPATH_W) '$(srcdir)/crc.c'; fi`
+
+CRC_DabMux-mpeg.o: mpeg.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT CRC_DabMux-mpeg.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-mpeg.Tpo -c -o CRC_DabMux-mpeg.o `test -f 'mpeg.c' || echo '$(srcdir)/'`mpeg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-mpeg.Tpo $(DEPDIR)/CRC_DabMux-mpeg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mpeg.c' object='CRC_DabMux-mpeg.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o CRC_DabMux-mpeg.o `test -f 'mpeg.c' || echo '$(srcdir)/'`mpeg.c
+
+CRC_DabMux-mpeg.obj: mpeg.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT CRC_DabMux-mpeg.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-mpeg.Tpo -c -o CRC_DabMux-mpeg.obj `if test -f 'mpeg.c'; then $(CYGPATH_W) 'mpeg.c'; else $(CYGPATH_W) '$(srcdir)/mpeg.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-mpeg.Tpo $(DEPDIR)/CRC_DabMux-mpeg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mpeg.c' object='CRC_DabMux-mpeg.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o CRC_DabMux-mpeg.obj `if test -f 'mpeg.c'; then $(CYGPATH_W) 'mpeg.c'; else $(CYGPATH_W) '$(srcdir)/mpeg.c'; fi`
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+CRC_DabMux-DabMux.o: DabMux.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-DabMux.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-DabMux.Tpo -c -o CRC_DabMux-DabMux.o `test -f 'DabMux.cpp' || echo '$(srcdir)/'`DabMux.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-DabMux.Tpo $(DEPDIR)/CRC_DabMux-DabMux.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DabMux.cpp' object='CRC_DabMux-DabMux.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-DabMux.o `test -f 'DabMux.cpp' || echo '$(srcdir)/'`DabMux.cpp
+
+CRC_DabMux-DabMux.obj: DabMux.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-DabMux.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-DabMux.Tpo -c -o CRC_DabMux-DabMux.obj `if test -f 'DabMux.cpp'; then $(CYGPATH_W) 'DabMux.cpp'; else $(CYGPATH_W) '$(srcdir)/DabMux.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-DabMux.Tpo $(DEPDIR)/CRC_DabMux-DabMux.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='DabMux.cpp' object='CRC_DabMux-DabMux.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-DabMux.obj `if test -f 'DabMux.cpp'; then $(CYGPATH_W) 'DabMux.cpp'; else $(CYGPATH_W) '$(srcdir)/DabMux.cpp'; fi`
+
+CRC_DabMux-dabInput.o: dabInput.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInput.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInput.Tpo -c -o CRC_DabMux-dabInput.o `test -f 'dabInput.cpp' || echo '$(srcdir)/'`dabInput.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInput.Tpo $(DEPDIR)/CRC_DabMux-dabInput.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInput.cpp' object='CRC_DabMux-dabInput.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInput.o `test -f 'dabInput.cpp' || echo '$(srcdir)/'`dabInput.cpp
+
+CRC_DabMux-dabInput.obj: dabInput.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInput.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInput.Tpo -c -o CRC_DabMux-dabInput.obj `if test -f 'dabInput.cpp'; then $(CYGPATH_W) 'dabInput.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInput.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInput.Tpo $(DEPDIR)/CRC_DabMux-dabInput.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInput.cpp' object='CRC_DabMux-dabInput.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInput.obj `if test -f 'dabInput.cpp'; then $(CYGPATH_W) 'dabInput.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInput.cpp'; fi`
+
+CRC_DabMux-dabInputBridgeUdp.o: dabInputBridgeUdp.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputBridgeUdp.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputBridgeUdp.Tpo -c -o CRC_DabMux-dabInputBridgeUdp.o `test -f 'dabInputBridgeUdp.cpp' || echo '$(srcdir)/'`dabInputBridgeUdp.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputBridgeUdp.Tpo $(DEPDIR)/CRC_DabMux-dabInputBridgeUdp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputBridgeUdp.cpp' object='CRC_DabMux-dabInputBridgeUdp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputBridgeUdp.o `test -f 'dabInputBridgeUdp.cpp' || echo '$(srcdir)/'`dabInputBridgeUdp.cpp
+
+CRC_DabMux-dabInputBridgeUdp.obj: dabInputBridgeUdp.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputBridgeUdp.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputBridgeUdp.Tpo -c -o CRC_DabMux-dabInputBridgeUdp.obj `if test -f 'dabInputBridgeUdp.cpp'; then $(CYGPATH_W) 'dabInputBridgeUdp.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputBridgeUdp.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputBridgeUdp.Tpo $(DEPDIR)/CRC_DabMux-dabInputBridgeUdp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputBridgeUdp.cpp' object='CRC_DabMux-dabInputBridgeUdp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputBridgeUdp.obj `if test -f 'dabInputBridgeUdp.cpp'; then $(CYGPATH_W) 'dabInputBridgeUdp.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputBridgeUdp.cpp'; fi`
+
+CRC_DabMux-dabInputDabplusFifo.o: dabInputDabplusFifo.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputDabplusFifo.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputDabplusFifo.Tpo -c -o CRC_DabMux-dabInputDabplusFifo.o `test -f 'dabInputDabplusFifo.cpp' || echo '$(srcdir)/'`dabInputDabplusFifo.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputDabplusFifo.Tpo $(DEPDIR)/CRC_DabMux-dabInputDabplusFifo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputDabplusFifo.cpp' object='CRC_DabMux-dabInputDabplusFifo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputDabplusFifo.o `test -f 'dabInputDabplusFifo.cpp' || echo '$(srcdir)/'`dabInputDabplusFifo.cpp
+
+CRC_DabMux-dabInputDabplusFifo.obj: dabInputDabplusFifo.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputDabplusFifo.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputDabplusFifo.Tpo -c -o CRC_DabMux-dabInputDabplusFifo.obj `if test -f 'dabInputDabplusFifo.cpp'; then $(CYGPATH_W) 'dabInputDabplusFifo.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputDabplusFifo.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputDabplusFifo.Tpo $(DEPDIR)/CRC_DabMux-dabInputDabplusFifo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputDabplusFifo.cpp' object='CRC_DabMux-dabInputDabplusFifo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputDabplusFifo.obj `if test -f 'dabInputDabplusFifo.cpp'; then $(CYGPATH_W) 'dabInputDabplusFifo.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputDabplusFifo.cpp'; fi`
+
+CRC_DabMux-dabInputDabplusFile.o: dabInputDabplusFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputDabplusFile.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputDabplusFile.Tpo -c -o CRC_DabMux-dabInputDabplusFile.o `test -f 'dabInputDabplusFile.cpp' || echo '$(srcdir)/'`dabInputDabplusFile.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputDabplusFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputDabplusFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputDabplusFile.cpp' object='CRC_DabMux-dabInputDabplusFile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputDabplusFile.o `test -f 'dabInputDabplusFile.cpp' || echo '$(srcdir)/'`dabInputDabplusFile.cpp
+
+CRC_DabMux-dabInputDabplusFile.obj: dabInputDabplusFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputDabplusFile.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputDabplusFile.Tpo -c -o CRC_DabMux-dabInputDabplusFile.obj `if test -f 'dabInputDabplusFile.cpp'; then $(CYGPATH_W) 'dabInputDabplusFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputDabplusFile.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputDabplusFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputDabplusFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputDabplusFile.cpp' object='CRC_DabMux-dabInputDabplusFile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputDabplusFile.obj `if test -f 'dabInputDabplusFile.cpp'; then $(CYGPATH_W) 'dabInputDabplusFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputDabplusFile.cpp'; fi`
+
+CRC_DabMux-dabInputDmbFile.o: dabInputDmbFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputDmbFile.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputDmbFile.Tpo -c -o CRC_DabMux-dabInputDmbFile.o `test -f 'dabInputDmbFile.cpp' || echo '$(srcdir)/'`dabInputDmbFile.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputDmbFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputDmbFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputDmbFile.cpp' object='CRC_DabMux-dabInputDmbFile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputDmbFile.o `test -f 'dabInputDmbFile.cpp' || echo '$(srcdir)/'`dabInputDmbFile.cpp
+
+CRC_DabMux-dabInputDmbFile.obj: dabInputDmbFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputDmbFile.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputDmbFile.Tpo -c -o CRC_DabMux-dabInputDmbFile.obj `if test -f 'dabInputDmbFile.cpp'; then $(CYGPATH_W) 'dabInputDmbFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputDmbFile.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputDmbFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputDmbFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputDmbFile.cpp' object='CRC_DabMux-dabInputDmbFile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputDmbFile.obj `if test -f 'dabInputDmbFile.cpp'; then $(CYGPATH_W) 'dabInputDmbFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputDmbFile.cpp'; fi`
+
+CRC_DabMux-dabInputDmbUdp.o: dabInputDmbUdp.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputDmbUdp.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputDmbUdp.Tpo -c -o CRC_DabMux-dabInputDmbUdp.o `test -f 'dabInputDmbUdp.cpp' || echo '$(srcdir)/'`dabInputDmbUdp.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputDmbUdp.Tpo $(DEPDIR)/CRC_DabMux-dabInputDmbUdp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputDmbUdp.cpp' object='CRC_DabMux-dabInputDmbUdp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputDmbUdp.o `test -f 'dabInputDmbUdp.cpp' || echo '$(srcdir)/'`dabInputDmbUdp.cpp
+
+CRC_DabMux-dabInputDmbUdp.obj: dabInputDmbUdp.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputDmbUdp.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputDmbUdp.Tpo -c -o CRC_DabMux-dabInputDmbUdp.obj `if test -f 'dabInputDmbUdp.cpp'; then $(CYGPATH_W) 'dabInputDmbUdp.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputDmbUdp.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputDmbUdp.Tpo $(DEPDIR)/CRC_DabMux-dabInputDmbUdp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputDmbUdp.cpp' object='CRC_DabMux-dabInputDmbUdp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputDmbUdp.obj `if test -f 'dabInputDmbUdp.cpp'; then $(CYGPATH_W) 'dabInputDmbUdp.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputDmbUdp.cpp'; fi`
+
+CRC_DabMux-dabInputEnhancedFifo.o: dabInputEnhancedFifo.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputEnhancedFifo.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputEnhancedFifo.Tpo -c -o CRC_DabMux-dabInputEnhancedFifo.o `test -f 'dabInputEnhancedFifo.cpp' || echo '$(srcdir)/'`dabInputEnhancedFifo.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputEnhancedFifo.Tpo $(DEPDIR)/CRC_DabMux-dabInputEnhancedFifo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputEnhancedFifo.cpp' object='CRC_DabMux-dabInputEnhancedFifo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputEnhancedFifo.o `test -f 'dabInputEnhancedFifo.cpp' || echo '$(srcdir)/'`dabInputEnhancedFifo.cpp
+
+CRC_DabMux-dabInputEnhancedFifo.obj: dabInputEnhancedFifo.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputEnhancedFifo.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputEnhancedFifo.Tpo -c -o CRC_DabMux-dabInputEnhancedFifo.obj `if test -f 'dabInputEnhancedFifo.cpp'; then $(CYGPATH_W) 'dabInputEnhancedFifo.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputEnhancedFifo.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputEnhancedFifo.Tpo $(DEPDIR)/CRC_DabMux-dabInputEnhancedFifo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputEnhancedFifo.cpp' object='CRC_DabMux-dabInputEnhancedFifo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputEnhancedFifo.obj `if test -f 'dabInputEnhancedFifo.cpp'; then $(CYGPATH_W) 'dabInputEnhancedFifo.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputEnhancedFifo.cpp'; fi`
+
+CRC_DabMux-dabInputEnhancedPacketFile.o: dabInputEnhancedPacketFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputEnhancedPacketFile.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputEnhancedPacketFile.Tpo -c -o CRC_DabMux-dabInputEnhancedPacketFile.o `test -f 'dabInputEnhancedPacketFile.cpp' || echo '$(srcdir)/'`dabInputEnhancedPacketFile.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputEnhancedPacketFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputEnhancedPacketFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputEnhancedPacketFile.cpp' object='CRC_DabMux-dabInputEnhancedPacketFile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputEnhancedPacketFile.o `test -f 'dabInputEnhancedPacketFile.cpp' || echo '$(srcdir)/'`dabInputEnhancedPacketFile.cpp
+
+CRC_DabMux-dabInputEnhancedPacketFile.obj: dabInputEnhancedPacketFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputEnhancedPacketFile.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputEnhancedPacketFile.Tpo -c -o CRC_DabMux-dabInputEnhancedPacketFile.obj `if test -f 'dabInputEnhancedPacketFile.cpp'; then $(CYGPATH_W) 'dabInputEnhancedPacketFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputEnhancedPacketFile.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputEnhancedPacketFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputEnhancedPacketFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputEnhancedPacketFile.cpp' object='CRC_DabMux-dabInputEnhancedPacketFile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputEnhancedPacketFile.obj `if test -f 'dabInputEnhancedPacketFile.cpp'; then $(CYGPATH_W) 'dabInputEnhancedPacketFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputEnhancedPacketFile.cpp'; fi`
+
+CRC_DabMux-dabInputFifo.o: dabInputFifo.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputFifo.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputFifo.Tpo -c -o CRC_DabMux-dabInputFifo.o `test -f 'dabInputFifo.cpp' || echo '$(srcdir)/'`dabInputFifo.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputFifo.Tpo $(DEPDIR)/CRC_DabMux-dabInputFifo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputFifo.cpp' object='CRC_DabMux-dabInputFifo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputFifo.o `test -f 'dabInputFifo.cpp' || echo '$(srcdir)/'`dabInputFifo.cpp
+
+CRC_DabMux-dabInputFifo.obj: dabInputFifo.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputFifo.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputFifo.Tpo -c -o CRC_DabMux-dabInputFifo.obj `if test -f 'dabInputFifo.cpp'; then $(CYGPATH_W) 'dabInputFifo.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputFifo.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputFifo.Tpo $(DEPDIR)/CRC_DabMux-dabInputFifo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputFifo.cpp' object='CRC_DabMux-dabInputFifo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputFifo.obj `if test -f 'dabInputFifo.cpp'; then $(CYGPATH_W) 'dabInputFifo.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputFifo.cpp'; fi`
+
+CRC_DabMux-dabInputFile.o: dabInputFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputFile.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputFile.Tpo -c -o CRC_DabMux-dabInputFile.o `test -f 'dabInputFile.cpp' || echo '$(srcdir)/'`dabInputFile.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputFile.cpp' object='CRC_DabMux-dabInputFile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputFile.o `test -f 'dabInputFile.cpp' || echo '$(srcdir)/'`dabInputFile.cpp
+
+CRC_DabMux-dabInputFile.obj: dabInputFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputFile.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputFile.Tpo -c -o CRC_DabMux-dabInputFile.obj `if test -f 'dabInputFile.cpp'; then $(CYGPATH_W) 'dabInputFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputFile.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputFile.cpp' object='CRC_DabMux-dabInputFile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputFile.obj `if test -f 'dabInputFile.cpp'; then $(CYGPATH_W) 'dabInputFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputFile.cpp'; fi`
+
+CRC_DabMux-dabInputMpegFifo.o: dabInputMpegFifo.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputMpegFifo.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputMpegFifo.Tpo -c -o CRC_DabMux-dabInputMpegFifo.o `test -f 'dabInputMpegFifo.cpp' || echo '$(srcdir)/'`dabInputMpegFifo.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputMpegFifo.Tpo $(DEPDIR)/CRC_DabMux-dabInputMpegFifo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputMpegFifo.cpp' object='CRC_DabMux-dabInputMpegFifo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputMpegFifo.o `test -f 'dabInputMpegFifo.cpp' || echo '$(srcdir)/'`dabInputMpegFifo.cpp
+
+CRC_DabMux-dabInputMpegFifo.obj: dabInputMpegFifo.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputMpegFifo.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputMpegFifo.Tpo -c -o CRC_DabMux-dabInputMpegFifo.obj `if test -f 'dabInputMpegFifo.cpp'; then $(CYGPATH_W) 'dabInputMpegFifo.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputMpegFifo.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputMpegFifo.Tpo $(DEPDIR)/CRC_DabMux-dabInputMpegFifo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputMpegFifo.cpp' object='CRC_DabMux-dabInputMpegFifo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputMpegFifo.obj `if test -f 'dabInputMpegFifo.cpp'; then $(CYGPATH_W) 'dabInputMpegFifo.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputMpegFifo.cpp'; fi`
+
+CRC_DabMux-dabInputMpegFile.o: dabInputMpegFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputMpegFile.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputMpegFile.Tpo -c -o CRC_DabMux-dabInputMpegFile.o `test -f 'dabInputMpegFile.cpp' || echo '$(srcdir)/'`dabInputMpegFile.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputMpegFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputMpegFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputMpegFile.cpp' object='CRC_DabMux-dabInputMpegFile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputMpegFile.o `test -f 'dabInputMpegFile.cpp' || echo '$(srcdir)/'`dabInputMpegFile.cpp
+
+CRC_DabMux-dabInputMpegFile.obj: dabInputMpegFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputMpegFile.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputMpegFile.Tpo -c -o CRC_DabMux-dabInputMpegFile.obj `if test -f 'dabInputMpegFile.cpp'; then $(CYGPATH_W) 'dabInputMpegFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputMpegFile.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputMpegFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputMpegFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputMpegFile.cpp' object='CRC_DabMux-dabInputMpegFile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputMpegFile.obj `if test -f 'dabInputMpegFile.cpp'; then $(CYGPATH_W) 'dabInputMpegFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputMpegFile.cpp'; fi`
+
+CRC_DabMux-dabInputPacketFile.o: dabInputPacketFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputPacketFile.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputPacketFile.Tpo -c -o CRC_DabMux-dabInputPacketFile.o `test -f 'dabInputPacketFile.cpp' || echo '$(srcdir)/'`dabInputPacketFile.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputPacketFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputPacketFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputPacketFile.cpp' object='CRC_DabMux-dabInputPacketFile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputPacketFile.o `test -f 'dabInputPacketFile.cpp' || echo '$(srcdir)/'`dabInputPacketFile.cpp
+
+CRC_DabMux-dabInputPacketFile.obj: dabInputPacketFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputPacketFile.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputPacketFile.Tpo -c -o CRC_DabMux-dabInputPacketFile.obj `if test -f 'dabInputPacketFile.cpp'; then $(CYGPATH_W) 'dabInputPacketFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputPacketFile.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputPacketFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputPacketFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputPacketFile.cpp' object='CRC_DabMux-dabInputPacketFile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputPacketFile.obj `if test -f 'dabInputPacketFile.cpp'; then $(CYGPATH_W) 'dabInputPacketFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputPacketFile.cpp'; fi`
+
+CRC_DabMux-dabInputPrbs.o: dabInputPrbs.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputPrbs.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputPrbs.Tpo -c -o CRC_DabMux-dabInputPrbs.o `test -f 'dabInputPrbs.cpp' || echo '$(srcdir)/'`dabInputPrbs.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputPrbs.Tpo $(DEPDIR)/CRC_DabMux-dabInputPrbs.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputPrbs.cpp' object='CRC_DabMux-dabInputPrbs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputPrbs.o `test -f 'dabInputPrbs.cpp' || echo '$(srcdir)/'`dabInputPrbs.cpp
+
+CRC_DabMux-dabInputPrbs.obj: dabInputPrbs.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputPrbs.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputPrbs.Tpo -c -o CRC_DabMux-dabInputPrbs.obj `if test -f 'dabInputPrbs.cpp'; then $(CYGPATH_W) 'dabInputPrbs.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputPrbs.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputPrbs.Tpo $(DEPDIR)/CRC_DabMux-dabInputPrbs.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputPrbs.cpp' object='CRC_DabMux-dabInputPrbs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputPrbs.obj `if test -f 'dabInputPrbs.cpp'; then $(CYGPATH_W) 'dabInputPrbs.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputPrbs.cpp'; fi`
+
+CRC_DabMux-dabInputRawFile.o: dabInputRawFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputRawFile.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputRawFile.Tpo -c -o CRC_DabMux-dabInputRawFile.o `test -f 'dabInputRawFile.cpp' || echo '$(srcdir)/'`dabInputRawFile.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputRawFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputRawFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputRawFile.cpp' object='CRC_DabMux-dabInputRawFile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputRawFile.o `test -f 'dabInputRawFile.cpp' || echo '$(srcdir)/'`dabInputRawFile.cpp
+
+CRC_DabMux-dabInputRawFile.obj: dabInputRawFile.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputRawFile.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputRawFile.Tpo -c -o CRC_DabMux-dabInputRawFile.obj `if test -f 'dabInputRawFile.cpp'; then $(CYGPATH_W) 'dabInputRawFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputRawFile.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputRawFile.Tpo $(DEPDIR)/CRC_DabMux-dabInputRawFile.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputRawFile.cpp' object='CRC_DabMux-dabInputRawFile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputRawFile.obj `if test -f 'dabInputRawFile.cpp'; then $(CYGPATH_W) 'dabInputRawFile.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputRawFile.cpp'; fi`
+
+CRC_DabMux-dabInputRawFifo.o: dabInputRawFifo.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputRawFifo.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputRawFifo.Tpo -c -o CRC_DabMux-dabInputRawFifo.o `test -f 'dabInputRawFifo.cpp' || echo '$(srcdir)/'`dabInputRawFifo.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputRawFifo.Tpo $(DEPDIR)/CRC_DabMux-dabInputRawFifo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputRawFifo.cpp' object='CRC_DabMux-dabInputRawFifo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputRawFifo.o `test -f 'dabInputRawFifo.cpp' || echo '$(srcdir)/'`dabInputRawFifo.cpp
+
+CRC_DabMux-dabInputRawFifo.obj: dabInputRawFifo.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputRawFifo.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputRawFifo.Tpo -c -o CRC_DabMux-dabInputRawFifo.obj `if test -f 'dabInputRawFifo.cpp'; then $(CYGPATH_W) 'dabInputRawFifo.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputRawFifo.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputRawFifo.Tpo $(DEPDIR)/CRC_DabMux-dabInputRawFifo.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputRawFifo.cpp' object='CRC_DabMux-dabInputRawFifo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputRawFifo.obj `if test -f 'dabInputRawFifo.cpp'; then $(CYGPATH_W) 'dabInputRawFifo.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputRawFifo.cpp'; fi`
+
+CRC_DabMux-dabInputSlip.o: dabInputSlip.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputSlip.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputSlip.Tpo -c -o CRC_DabMux-dabInputSlip.o `test -f 'dabInputSlip.cpp' || echo '$(srcdir)/'`dabInputSlip.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputSlip.Tpo $(DEPDIR)/CRC_DabMux-dabInputSlip.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputSlip.cpp' object='CRC_DabMux-dabInputSlip.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputSlip.o `test -f 'dabInputSlip.cpp' || echo '$(srcdir)/'`dabInputSlip.cpp
+
+CRC_DabMux-dabInputSlip.obj: dabInputSlip.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputSlip.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputSlip.Tpo -c -o CRC_DabMux-dabInputSlip.obj `if test -f 'dabInputSlip.cpp'; then $(CYGPATH_W) 'dabInputSlip.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputSlip.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputSlip.Tpo $(DEPDIR)/CRC_DabMux-dabInputSlip.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputSlip.cpp' object='CRC_DabMux-dabInputSlip.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputSlip.obj `if test -f 'dabInputSlip.cpp'; then $(CYGPATH_W) 'dabInputSlip.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputSlip.cpp'; fi`
+
+CRC_DabMux-dabInputTest.o: dabInputTest.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputTest.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputTest.Tpo -c -o CRC_DabMux-dabInputTest.o `test -f 'dabInputTest.cpp' || echo '$(srcdir)/'`dabInputTest.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputTest.Tpo $(DEPDIR)/CRC_DabMux-dabInputTest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputTest.cpp' object='CRC_DabMux-dabInputTest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputTest.o `test -f 'dabInputTest.cpp' || echo '$(srcdir)/'`dabInputTest.cpp
+
+CRC_DabMux-dabInputTest.obj: dabInputTest.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputTest.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputTest.Tpo -c -o CRC_DabMux-dabInputTest.obj `if test -f 'dabInputTest.cpp'; then $(CYGPATH_W) 'dabInputTest.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputTest.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputTest.Tpo $(DEPDIR)/CRC_DabMux-dabInputTest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputTest.cpp' object='CRC_DabMux-dabInputTest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputTest.obj `if test -f 'dabInputTest.cpp'; then $(CYGPATH_W) 'dabInputTest.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputTest.cpp'; fi`
+
+CRC_DabMux-dabInputUdp.o: dabInputUdp.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputUdp.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputUdp.Tpo -c -o CRC_DabMux-dabInputUdp.o `test -f 'dabInputUdp.cpp' || echo '$(srcdir)/'`dabInputUdp.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputUdp.Tpo $(DEPDIR)/CRC_DabMux-dabInputUdp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputUdp.cpp' object='CRC_DabMux-dabInputUdp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputUdp.o `test -f 'dabInputUdp.cpp' || echo '$(srcdir)/'`dabInputUdp.cpp
+
+CRC_DabMux-dabInputUdp.obj: dabInputUdp.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabInputUdp.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabInputUdp.Tpo -c -o CRC_DabMux-dabInputUdp.obj `if test -f 'dabInputUdp.cpp'; then $(CYGPATH_W) 'dabInputUdp.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputUdp.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabInputUdp.Tpo $(DEPDIR)/CRC_DabMux-dabInputUdp.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabInputUdp.cpp' object='CRC_DabMux-dabInputUdp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabInputUdp.obj `if test -f 'dabInputUdp.cpp'; then $(CYGPATH_W) 'dabInputUdp.cpp'; else $(CYGPATH_W) '$(srcdir)/dabInputUdp.cpp'; fi`
+
+CRC_DabMux-dabOutput.o: dabOutput.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabOutput.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabOutput.Tpo -c -o CRC_DabMux-dabOutput.o `test -f 'dabOutput.cpp' || echo '$(srcdir)/'`dabOutput.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabOutput.Tpo $(DEPDIR)/CRC_DabMux-dabOutput.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabOutput.cpp' object='CRC_DabMux-dabOutput.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabOutput.o `test -f 'dabOutput.cpp' || echo '$(srcdir)/'`dabOutput.cpp
+
+CRC_DabMux-dabOutput.obj: dabOutput.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabOutput.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabOutput.Tpo -c -o CRC_DabMux-dabOutput.obj `if test -f 'dabOutput.cpp'; then $(CYGPATH_W) 'dabOutput.cpp'; else $(CYGPATH_W) '$(srcdir)/dabOutput.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabOutput.Tpo $(DEPDIR)/CRC_DabMux-dabOutput.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabOutput.cpp' object='CRC_DabMux-dabOutput.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabOutput.obj `if test -f 'dabOutput.cpp'; then $(CYGPATH_W) 'dabOutput.cpp'; else $(CYGPATH_W) '$(srcdir)/dabOutput.cpp'; fi`
+
+CRC_DabMux-Eti.o: Eti.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-Eti.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-Eti.Tpo -c -o CRC_DabMux-Eti.o `test -f 'Eti.cpp' || echo '$(srcdir)/'`Eti.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-Eti.Tpo $(DEPDIR)/CRC_DabMux-Eti.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Eti.cpp' object='CRC_DabMux-Eti.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-Eti.o `test -f 'Eti.cpp' || echo '$(srcdir)/'`Eti.cpp
+
+CRC_DabMux-Eti.obj: Eti.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-Eti.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-Eti.Tpo -c -o CRC_DabMux-Eti.obj `if test -f 'Eti.cpp'; then $(CYGPATH_W) 'Eti.cpp'; else $(CYGPATH_W) '$(srcdir)/Eti.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-Eti.Tpo $(DEPDIR)/CRC_DabMux-Eti.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Eti.cpp' object='CRC_DabMux-Eti.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-Eti.obj `if test -f 'Eti.cpp'; then $(CYGPATH_W) 'Eti.cpp'; else $(CYGPATH_W) '$(srcdir)/Eti.cpp'; fi`
+
+CRC_DabMux-TcpLog.o: TcpLog.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-TcpLog.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-TcpLog.Tpo -c -o CRC_DabMux-TcpLog.o `test -f 'TcpLog.cpp' || echo '$(srcdir)/'`TcpLog.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-TcpLog.Tpo $(DEPDIR)/CRC_DabMux-TcpLog.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TcpLog.cpp' object='CRC_DabMux-TcpLog.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-TcpLog.o `test -f 'TcpLog.cpp' || echo '$(srcdir)/'`TcpLog.cpp
+
+CRC_DabMux-TcpLog.obj: TcpLog.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-TcpLog.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-TcpLog.Tpo -c -o CRC_DabMux-TcpLog.obj `if test -f 'TcpLog.cpp'; then $(CYGPATH_W) 'TcpLog.cpp'; else $(CYGPATH_W) '$(srcdir)/TcpLog.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-TcpLog.Tpo $(DEPDIR)/CRC_DabMux-TcpLog.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TcpLog.cpp' object='CRC_DabMux-TcpLog.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-TcpLog.obj `if test -f 'TcpLog.cpp'; then $(CYGPATH_W) 'TcpLog.cpp'; else $(CYGPATH_W) '$(srcdir)/TcpLog.cpp'; fi`
+
+CRC_DabMux-UdpSocket.o: UdpSocket.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-UdpSocket.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-UdpSocket.Tpo -c -o CRC_DabMux-UdpSocket.o `test -f 'UdpSocket.cpp' || echo '$(srcdir)/'`UdpSocket.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-UdpSocket.Tpo $(DEPDIR)/CRC_DabMux-UdpSocket.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='UdpSocket.cpp' object='CRC_DabMux-UdpSocket.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-UdpSocket.o `test -f 'UdpSocket.cpp' || echo '$(srcdir)/'`UdpSocket.cpp
+
+CRC_DabMux-UdpSocket.obj: UdpSocket.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-UdpSocket.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-UdpSocket.Tpo -c -o CRC_DabMux-UdpSocket.obj `if test -f 'UdpSocket.cpp'; then $(CYGPATH_W) 'UdpSocket.cpp'; else $(CYGPATH_W) '$(srcdir)/UdpSocket.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-UdpSocket.Tpo $(DEPDIR)/CRC_DabMux-UdpSocket.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='UdpSocket.cpp' object='CRC_DabMux-UdpSocket.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-UdpSocket.obj `if test -f 'UdpSocket.cpp'; then $(CYGPATH_W) 'UdpSocket.cpp'; else $(CYGPATH_W) '$(srcdir)/UdpSocket.cpp'; fi`
+
+CRC_DabMux-InetAddress.o: InetAddress.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-InetAddress.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-InetAddress.Tpo -c -o CRC_DabMux-InetAddress.o `test -f 'InetAddress.cpp' || echo '$(srcdir)/'`InetAddress.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-InetAddress.Tpo $(DEPDIR)/CRC_DabMux-InetAddress.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='InetAddress.cpp' object='CRC_DabMux-InetAddress.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-InetAddress.o `test -f 'InetAddress.cpp' || echo '$(srcdir)/'`InetAddress.cpp
+
+CRC_DabMux-InetAddress.obj: InetAddress.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-InetAddress.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-InetAddress.Tpo -c -o CRC_DabMux-InetAddress.obj `if test -f 'InetAddress.cpp'; then $(CYGPATH_W) 'InetAddress.cpp'; else $(CYGPATH_W) '$(srcdir)/InetAddress.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-InetAddress.Tpo $(DEPDIR)/CRC_DabMux-InetAddress.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='InetAddress.cpp' object='CRC_DabMux-InetAddress.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-InetAddress.obj `if test -f 'InetAddress.cpp'; then $(CYGPATH_W) 'InetAddress.cpp'; else $(CYGPATH_W) '$(srcdir)/InetAddress.cpp'; fi`
+
+CRC_DabMux-dabUtils.o: dabUtils.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabUtils.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabUtils.Tpo -c -o CRC_DabMux-dabUtils.o `test -f 'dabUtils.cpp' || echo '$(srcdir)/'`dabUtils.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabUtils.Tpo $(DEPDIR)/CRC_DabMux-dabUtils.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabUtils.cpp' object='CRC_DabMux-dabUtils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabUtils.o `test -f 'dabUtils.cpp' || echo '$(srcdir)/'`dabUtils.cpp
+
+CRC_DabMux-dabUtils.obj: dabUtils.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-dabUtils.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-dabUtils.Tpo -c -o CRC_DabMux-dabUtils.obj `if test -f 'dabUtils.cpp'; then $(CYGPATH_W) 'dabUtils.cpp'; else $(CYGPATH_W) '$(srcdir)/dabUtils.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-dabUtils.Tpo $(DEPDIR)/CRC_DabMux-dabUtils.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dabUtils.cpp' object='CRC_DabMux-dabUtils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-dabUtils.obj `if test -f 'dabUtils.cpp'; then $(CYGPATH_W) 'dabUtils.cpp'; else $(CYGPATH_W) '$(srcdir)/dabUtils.cpp'; fi`
+
+CRC_DabMux-Dmb.o: Dmb.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-Dmb.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-Dmb.Tpo -c -o CRC_DabMux-Dmb.o `test -f 'Dmb.cpp' || echo '$(srcdir)/'`Dmb.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-Dmb.Tpo $(DEPDIR)/CRC_DabMux-Dmb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Dmb.cpp' object='CRC_DabMux-Dmb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-Dmb.o `test -f 'Dmb.cpp' || echo '$(srcdir)/'`Dmb.cpp
+
+CRC_DabMux-Dmb.obj: Dmb.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-Dmb.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-Dmb.Tpo -c -o CRC_DabMux-Dmb.obj `if test -f 'Dmb.cpp'; then $(CYGPATH_W) 'Dmb.cpp'; else $(CYGPATH_W) '$(srcdir)/Dmb.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-Dmb.Tpo $(DEPDIR)/CRC_DabMux-Dmb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Dmb.cpp' object='CRC_DabMux-Dmb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-Dmb.obj `if test -f 'Dmb.cpp'; then $(CYGPATH_W) 'Dmb.cpp'; else $(CYGPATH_W) '$(srcdir)/Dmb.cpp'; fi`
+
+CRC_DabMux-Interleaver.o: Interleaver.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-Interleaver.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-Interleaver.Tpo -c -o CRC_DabMux-Interleaver.o `test -f 'Interleaver.cpp' || echo '$(srcdir)/'`Interleaver.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-Interleaver.Tpo $(DEPDIR)/CRC_DabMux-Interleaver.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Interleaver.cpp' object='CRC_DabMux-Interleaver.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-Interleaver.o `test -f 'Interleaver.cpp' || echo '$(srcdir)/'`Interleaver.cpp
+
+CRC_DabMux-Interleaver.obj: Interleaver.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-Interleaver.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-Interleaver.Tpo -c -o CRC_DabMux-Interleaver.obj `if test -f 'Interleaver.cpp'; then $(CYGPATH_W) 'Interleaver.cpp'; else $(CYGPATH_W) '$(srcdir)/Interleaver.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-Interleaver.Tpo $(DEPDIR)/CRC_DabMux-Interleaver.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Interleaver.cpp' object='CRC_DabMux-Interleaver.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-Interleaver.obj `if test -f 'Interleaver.cpp'; then $(CYGPATH_W) 'Interleaver.cpp'; else $(CYGPATH_W) '$(srcdir)/Interleaver.cpp'; fi`
+
+CRC_DabMux-ReedSolomon.o: ReedSolomon.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-ReedSolomon.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-ReedSolomon.Tpo -c -o CRC_DabMux-ReedSolomon.o `test -f 'ReedSolomon.cpp' || echo '$(srcdir)/'`ReedSolomon.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-ReedSolomon.Tpo $(DEPDIR)/CRC_DabMux-ReedSolomon.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ReedSolomon.cpp' object='CRC_DabMux-ReedSolomon.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-ReedSolomon.o `test -f 'ReedSolomon.cpp' || echo '$(srcdir)/'`ReedSolomon.cpp
+
+CRC_DabMux-ReedSolomon.obj: ReedSolomon.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-ReedSolomon.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-ReedSolomon.Tpo -c -o CRC_DabMux-ReedSolomon.obj `if test -f 'ReedSolomon.cpp'; then $(CYGPATH_W) 'ReedSolomon.cpp'; else $(CYGPATH_W) '$(srcdir)/ReedSolomon.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-ReedSolomon.Tpo $(DEPDIR)/CRC_DabMux-ReedSolomon.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='ReedSolomon.cpp' object='CRC_DabMux-ReedSolomon.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-ReedSolomon.obj `if test -f 'ReedSolomon.cpp'; then $(CYGPATH_W) 'ReedSolomon.cpp'; else $(CYGPATH_W) '$(srcdir)/ReedSolomon.cpp'; fi`
+
+CRC_DabMux-TcpServer.o: TcpServer.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-TcpServer.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-TcpServer.Tpo -c -o CRC_DabMux-TcpServer.o `test -f 'TcpServer.cpp' || echo '$(srcdir)/'`TcpServer.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-TcpServer.Tpo $(DEPDIR)/CRC_DabMux-TcpServer.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TcpServer.cpp' object='CRC_DabMux-TcpServer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-TcpServer.o `test -f 'TcpServer.cpp' || echo '$(srcdir)/'`TcpServer.cpp
+
+CRC_DabMux-TcpServer.obj: TcpServer.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-TcpServer.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-TcpServer.Tpo -c -o CRC_DabMux-TcpServer.obj `if test -f 'TcpServer.cpp'; then $(CYGPATH_W) 'TcpServer.cpp'; else $(CYGPATH_W) '$(srcdir)/TcpServer.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-TcpServer.Tpo $(DEPDIR)/CRC_DabMux-TcpServer.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TcpServer.cpp' object='CRC_DabMux-TcpServer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-TcpServer.obj `if test -f 'TcpServer.cpp'; then $(CYGPATH_W) 'TcpServer.cpp'; else $(CYGPATH_W) '$(srcdir)/TcpServer.cpp'; fi`
+
+CRC_DabMux-TcpSocket.o: TcpSocket.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-TcpSocket.o -MD -MP -MF $(DEPDIR)/CRC_DabMux-TcpSocket.Tpo -c -o CRC_DabMux-TcpSocket.o `test -f 'TcpSocket.cpp' || echo '$(srcdir)/'`TcpSocket.cpp
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-TcpSocket.Tpo $(DEPDIR)/CRC_DabMux-TcpSocket.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TcpSocket.cpp' object='CRC_DabMux-TcpSocket.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-TcpSocket.o `test -f 'TcpSocket.cpp' || echo '$(srcdir)/'`TcpSocket.cpp
+
+CRC_DabMux-TcpSocket.obj: TcpSocket.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CRC_DabMux-TcpSocket.obj -MD -MP -MF $(DEPDIR)/CRC_DabMux-TcpSocket.Tpo -c -o CRC_DabMux-TcpSocket.obj `if test -f 'TcpSocket.cpp'; then $(CYGPATH_W) 'TcpSocket.cpp'; else $(CYGPATH_W) '$(srcdir)/TcpSocket.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/CRC_DabMux-TcpSocket.Tpo $(DEPDIR)/CRC_DabMux-TcpSocket.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='TcpSocket.cpp' object='CRC_DabMux-TcpSocket.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CRC_DabMux_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CRC_DabMux-TcpSocket.obj `if test -f 'TcpSocket.cpp'; then $(CYGPATH_W) 'TcpSocket.cpp'; else $(CYGPATH_W) '$(srcdir)/TcpSocket.cpp'; fi`
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic ctags distclean distclean-compile \
+ distclean-generic distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-binPROGRAMS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/PcDebug.h b/src/PcDebug.h
new file mode 100644
index 0000000..4e966d3
--- /dev/null
+++ b/src/PcDebug.h
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
+ Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PC_DEBUG_
+#define PC_DEBUG_
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#define LOG stderr
+
+#if !defined(_WIN32) || defined(__MINGW32__)
+# ifndef PDEBUG
+# ifdef DEBUG
+# define PDEBUG(fmt, args...) fprintf (LOG, fmt , ## args)
+# else
+# define PDEBUG(fmt, args...)
+# endif
+# endif
+# ifdef DEBUG
+# define PDEBUG_VERBOSE(level, verbosity, fmt, args...) if (level <= verbosity) { fprintf(LOG, fmt, ## args); fflush(LOG); }
+# define PDEBUG0_VERBOSE(level, verbosity, txt) if (level <= verbosity) { fprintf(LOG, txt); fflush(LOG); }
+# define PDEBUG1_VERBOSE(level, verbosity, txt, arg0) if (level <= verbosity) { fprintf(LOG, txt, arg0); fflush(LOG); }
+# define PDEBUG2_VERBOSE(level, verbosity, txt, arg0, arg1) if (level <= verbosity) { fprintf(LOG, txt, arg0, arg1); fflush(LOG); }
+# define PDEBUG3_VERBOSE(level, verbosity, txt, arg0, arg1, arg2) if (level <= verbosity) { fprintf(LOG, txt, arg0, arg1, arg2); fflush(LOG); }
+# define PDEBUG4_VERBOSE(level, verbosity, txt, arg0, arg1, arg2, arg3) if (level <= verbosity) { fprintf(LOG, txt, arg0, arg1, arg2, arg3); fflush(LOG); }
+# else
+# define PDEBUG_VERBOSE(level, verbosity, fmt, args...)
+# define PDEBUG0_VERBOSE(level, verbosity, txt)
+# define PDEBUG1_VERBOSE(level, verbosity, txt, arg0)
+# define PDEBUG2_VERBOSE(level, verbosity, txt, arg0, arg1)
+# define PDEBUG3_VERBOSE(level, verbosity, txt, arg0, arg1, arg2)
+# define PDEBUG4_VERBOSE(level, verbosity, txt, arg0, arg1, arg2, arg3)
+# endif // DEBUG
+#else // _WIN32
+# ifdef _DEBUG
+# define PDEBUG
+# define PDEBUG_VERBOSE
+# define PDEBUG0_VERBOSE(level, verbosity, txt) if (level <= verbosity) { fprintf(LOG, txt); fflush(LOG); }
+# define PDEBUG1_VERBOSE(level, verbosity, txt, arg0) if (level <= verbosity) { fprintf(LOG, txt, arg0); fflush(LOG); }
+# define PDEBUG2_VERBOSE(level, verbosity, txt, arg0, arg1) if (level <= verbosity) { fprintf(LOG, txt, arg0, arg1); fflush(LOG); }
+# define PDEBUG3_VERBOSE(level, verbosity, txt, arg0, arg1, arg2) if (level <= verbosity) { fprintf(LOG, txt, arg0, arg1, arg2); fflush(LOG); }
+# define PDEBUG4_VERBOSE(level, verbosity, txt, arg0, arg1, arg2, arg3) if (level <= verbosity) { fprintf(LOG, txt, arg0, arg1, arg2, arg3); fflush(LOG); }
+# else
+# define PDEBUG
+# define PDEBUG_VERBOSE
+# define PDEBUG0_VERBOSE(level, verbosity, txt)
+# define PDEBUG1_VERBOSE(level, verbosity, txt, arg0)
+# define PDEBUG2_VERBOSE(level, verbosity, txt, arg0, arg1)
+# define PDEBUG3_VERBOSE(level, verbosity, txt, arg0, arg1, arg2)
+# define PDEBUG4_VERBOSE(level, verbosity, txt, arg0, arg1, arg2, arg3)
+# endif
+#endif
+
+#endif // PC_DEBUG_
diff --git a/src/ReedSolomon.cpp b/src/ReedSolomon.cpp
new file mode 100644
index 0000000..31d5021
--- /dev/null
+++ b/src/ReedSolomon.cpp
@@ -0,0 +1,105 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right
+ of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ReedSolomon.h"
+#include <stdio.h> // For galois.h ...
+#include <string.h> // For memcpy
+
+extern "C" {
+#include <fec.h>
+}
+#include <assert.h>
+#include <stdlib.h>
+
+#define SYMSIZE 8
+
+
+ReedSolomon::ReedSolomon(int N, int K, bool reverse, int gfpoly, int firstRoot, int primElem)
+{
+ setReverse(reverse);
+
+ myN = N;
+ myK = K;
+
+ int symsize = SYMSIZE;
+ int nroots = N - K;
+ int pad = ((1 << symsize) - 1) - N;
+
+ rsData = init_rs_char(symsize, gfpoly, firstRoot, primElem, nroots, pad);
+
+ if (rsData == NULL) {
+ fprintf(stderr, "ERROR: Invalid Reed Solomon parameters!\n");
+ abort();
+ }
+}
+
+
+ReedSolomon::~ReedSolomon()
+{
+ free_rs_char(rsData);
+}
+
+
+void ReedSolomon::setReverse(bool state)
+{
+ reverse = state;
+}
+
+
+int ReedSolomon::encode(void* data, void* fec, unsigned long size)
+{
+ unsigned char* input = reinterpret_cast<unsigned char*>(data);
+ unsigned char* output = reinterpret_cast<unsigned char*>(fec);
+ int ret = 0;
+
+ if (reverse) {
+ unsigned char* buffer = new unsigned char[myN];
+ memcpy(buffer, input, myK);
+ memcpy(&buffer[myK], output, myN - myK);
+
+ ret = decode_rs_char(rsData, buffer, NULL, 0);
+ if ((ret != 0) && (ret != -1)) {
+ memcpy(input, buffer, myK);
+ memcpy(output, &buffer[myK], myN - myK);
+ }
+
+ delete[] buffer;
+ } else {
+ encode_rs_char(rsData, input, output);
+ }
+
+ return ret;
+}
+
+
+int ReedSolomon::encode(void* data, unsigned long size)
+{
+ unsigned char* input = reinterpret_cast<unsigned char*>(data);
+ int ret = 0;
+
+ if (reverse) {
+ ret = decode_rs_char(rsData, input, NULL, 0);
+ } else {
+ encode_rs_char(rsData, input, &input[188]);
+ }
+
+ return ret;
+}
diff --git a/src/ReedSolomon.h b/src/ReedSolomon.h
new file mode 100644
index 0000000..2a94542
--- /dev/null
+++ b/src/ReedSolomon.h
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right
+ of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _REEDSOLOMON
+#define _REEDSOLOMON
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+
+class ReedSolomon
+{
+public:
+ ReedSolomon(int N, int K, bool reverse = false,
+ int gfpoly = 0x11d, int firstRoot = 0, int primElem = 1);
+ ReedSolomon(const ReedSolomon& clone);
+ virtual ~ReedSolomon();
+
+ void setReverse(bool state);
+ int encode(void* data, void* fec, unsigned long size);
+ int encode(void* data, unsigned long size);
+
+protected:
+ int myN;
+ int myK;
+
+private:
+ void* rsData;
+ bool reverse;
+};
+
+
+#endif // _REEDSOLOMON
diff --git a/src/TcpLog.cpp b/src/TcpLog.cpp
new file mode 100644
index 0000000..7161c92
--- /dev/null
+++ b/src/TcpLog.cpp
@@ -0,0 +1,330 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in
+ Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "TcpLog.h"
+#include "InetAddress.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef _WIN32
+# include <io.h>
+#
+# define vsnprintf _vsnprintf
+# define MSG_NOSIGNAL 0
+# define socklen_t int
+#else
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <unistd.h>
+#endif
+
+#include <sstream>
+
+
+const int TcpLog::EMERG = 0; // system is unusable
+const int TcpLog::ALERT = 1; // action must be taken immediately
+const int TcpLog::CRIT = 2; // critical conditions
+const int TcpLog::ERR = 3; // error conditions
+const int TcpLog::WARNING = 4; // warning conditions
+const int TcpLog::NOTICE = 5; // normal but significant condition
+const int TcpLog::INFO = 6; // informational
+const int TcpLog::DBG = 7; // debug-level messages
+
+
+TcpLog::TcpLog() : listenPort(0), client(-1), name(NULL), serverThread(0), running(false)
+{
+ buffer = (char*)malloc(512);
+ bufferSize = 512;
+ headers = (char**)malloc(sizeof(char**));
+ headers[0] = NULL;
+}
+
+
+TcpLog::~TcpLog()
+{
+ if (running) {
+ running = false;
+ }
+ if (client != -1) {
+ ::close(client);
+ }
+ if (headers != NULL) {
+ for (int count = 0; headers[count] != NULL; ++count) {
+ free(headers[count]);
+ }
+ free(headers);
+ }
+}
+
+
+//TcpLog::TcpLog(int port);
+
+
+void TcpLog::open(const char *ident, const int option, const int port)
+{
+ listenPort = port;
+
+ if (name != NULL) {
+ free(name);
+ }
+ name = strdup(ident);
+
+ if (running) {
+ running = false;
+#ifdef WIN32
+ DWORD status;
+ for (int i = 0; i < 5; ++i) {
+ if (GetExitCodeThread(serverThread, &status)) {
+ break;
+ }
+ Sleep(100);
+ }
+ TerminateThread(serverThread, 1);
+#else
+ pthread_join(serverThread, NULL);
+#endif
+ }
+ running = true;
+#ifdef _WIN32
+ serverThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)listen, this, 0, NULL);
+ if (serverThread == NULL) {
+ fprintf(stderr, "Can't create TCP listen thread\n");
+ }
+#else
+ pthread_create(&serverThread, NULL, (void*(*)(void*))listen, this);
+#endif
+}
+
+
+void TcpLog::printHeader(const int priority, const char *format, ...)
+{
+ static char last = '\n';
+ std::string beginning;
+ std::string message;
+ int ret;
+
+
+ beginning = "<";
+ beginning += '0' + (priority % 10);
+ beginning += "> ";
+
+ va_list argp;
+ va_start(argp, format);
+ for (ret = vsnprintf(buffer, bufferSize, format, argp);
+ ret >= bufferSize || ret == -1;
+ ret = vsprintf(buffer, format, argp)) {
+ if (ret == -1) {
+ buffer = (char*)realloc(buffer, bufferSize * 2);
+ bufferSize *= 2;
+ } else {
+ buffer = (char*)realloc(buffer, ret + 1);
+ bufferSize = ret + 1;
+ }
+ }
+ va_end(argp);
+
+ if (last == '\n') {
+ message += beginning;
+ }
+ message += buffer;
+
+ last = buffer[ret - 1];
+
+ for (unsigned long pos = message.find('\n');
+ pos != std::string::npos && ++pos != message.size();
+ pos = message.find('\n', pos)) {
+ message.insert(pos, beginning);
+ }
+
+ fprintf(stderr, message.c_str());
+ if (client != -1) {
+ if (write(client, message.c_str(), message.size())
+ != (int)message.size()) {
+ fprintf(stderr, "<6> Client closed\n");
+ ::close(client);
+ client = -1;
+ }
+ }
+
+ int count = 0;
+ while (headers[count++] != NULL) {
+ }
+ headers = (char**)realloc(headers, sizeof(char**) * (count + 1));
+ headers[count - 1] = strdup(message.c_str());
+ headers[count] = NULL;
+}
+
+
+void TcpLog::print(const int priority, const char *format, ...)
+{
+ static char last = '\n';
+ std::string beginning;
+ std::string message;
+ int ret;
+
+
+ beginning = "<";
+ beginning += '0' + (priority % 10);
+ beginning += "> ";
+
+ va_list argp;
+ va_start(argp, format);
+ for (ret = vsnprintf(buffer, bufferSize, format, argp);
+ ret >= bufferSize || ret == -1;
+ ret = vsprintf(buffer, format, argp)) {
+ if (ret == -1) {
+ buffer = (char*)realloc(buffer, bufferSize * 2);
+ bufferSize *= 2;
+ } else {
+ buffer = (char*)realloc(buffer, ret + 1);
+ bufferSize = ret + 1;
+ }
+ }
+ va_end(argp);
+
+ if (last == '\n') {
+ message += beginning;
+ }
+ message += buffer;
+
+ last = buffer[ret - 1];
+
+ for (unsigned long pos = message.find('\n');
+ pos != std::string::npos && ++pos != message.size();
+ pos = message.find('\n', pos)) {
+ message.insert(pos, beginning);
+ }
+
+ fprintf(stderr, message.c_str());
+ if (client != -1) {
+ if (send(client, message.c_str(), message.size(), MSG_NOSIGNAL)
+ != (int)message.size()) {
+ fprintf(stderr, "<6> Client closed\n");
+ ::close(client);
+ client = -1;
+ }
+ }
+}
+
+
+void TcpLog::close(void)
+{
+}
+
+
+void* TcpLog::listen(TcpLog* obj)
+{
+ int server;
+ struct sockaddr_in server_addr;
+ struct sockaddr_in client_addr;
+ socklen_t addrlen = sizeof(client_addr);
+
+#ifdef _WIN32
+ WSADATA wsaData;
+ WORD wVersionRequested = wVersionRequested = MAKEWORD( 2, 2 );
+
+ int res = WSAStartup( wVersionRequested, &wsaData );
+ if (res) {
+ fprintf(stderr, "Can't initialize winsock\n");
+ ExitThread(1);
+ }
+#endif
+ server = socket(PF_INET, SOCK_STREAM, 0);
+ if (server == INVALID_SOCKET) {
+#ifdef _WIN32
+ fprintf(stderr, "Can't create socket\n");
+ ExitThread(1);
+#else
+ perror("Can't create socket");
+ pthread_exit(NULL);
+#endif
+ }
+
+ int reuse = 1;
+ if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse))
+ == -1) {
+ perror("Can't set socket reusable");
+ }
+
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_port = htons(obj->listenPort);
+ server_addr.sin_addr.s_addr = INADDR_ANY;
+
+ if (bind(server, (struct sockaddr*)&server_addr, sizeof(server_addr))
+ == -1) {
+ perror("Can't bind socket");
+ fprintf(stderr, " port: %i\n", obj->listenPort);
+#ifdef _WIN32
+ ExitThread(1);
+#else
+ pthread_exit(NULL);
+#endif
+ }
+
+ if (::listen(server, 1) == -1) {
+ perror("Can't listen on socket");
+#ifdef _WIN32
+ ExitThread(1);
+#else
+ pthread_exit(NULL);
+#endif
+ }
+
+ while (obj->running) {
+ int client = accept(server, (struct sockaddr*)&client_addr, &addrlen);
+ if (client == INVALID_SOCKET) {
+#ifdef _WIN32
+ if (WSAGetLastError() != WSAEINTR) {
+ setInetError("Can't accept client");
+ fprintf(stderr, "%s: %s\n", inetErrDesc, inetErrMsg);
+ ExitThread(1);
+ }
+#else
+ perror("Can't accept client");
+ pthread_exit(NULL);
+#endif
+ }
+ obj->print(INFO, "%s:%d connected\n",
+ inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
+ if (obj->client != -1) {
+ ::close(obj->client);
+ }
+ obj->client = client;
+ for (int i = 0; obj->headers[i] != NULL; ++i) {
+ send(client, obj->headers[i], strlen(obj->headers[i]), MSG_NOSIGNAL);
+ }
+ }
+ if (obj->client != -1) {
+ ::close(obj->client);
+ obj->client = -1;
+ }
+ ::close(server);
+
+#ifdef _WIN32
+ ExitThread(1);
+#else
+ pthread_exit(NULL);
+#endif
+ return NULL;
+}
diff --git a/src/TcpLog.h b/src/TcpLog.h
new file mode 100644
index 0000000..c9abd70
--- /dev/null
+++ b/src/TcpLog.h
@@ -0,0 +1,69 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in
+ Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TCP_LOG
+#define _TCP_LOG
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifndef _WIN32
+# include <pthread.h>
+#else
+# include <winsock2.h>
+# define pthread_t HANDLE
+#endif
+
+class TcpLog {
+public:
+ TcpLog();
+ ~TcpLog();
+
+ void open(const char *ident, const int option, const int port);
+ void printHeader(const int priority, const char *format, ...);
+ void print(const int priority, const char *format, ...);
+ void close(void);
+
+ const static int EMERG; // system is unusable
+ const static int ALERT; // action must be taken immediately
+ const static int CRIT; // critical conditions
+ const static int ERR; // error conditions
+ const static int WARNING; // warning conditions
+ const static int NOTICE; // normal but significant condition
+ const static int INFO; // informational
+ const static int DBG; // debug-level messages
+
+private:
+ static void* listen(TcpLog* obj);
+
+ int listenPort;
+ int client;
+ char* name;
+ pthread_t serverThread;
+ bool running;
+ char* buffer;
+ int bufferSize;
+ char** headers;
+};
+
+
+#endif // _TCP_LOG
diff --git a/src/TcpServer.cpp b/src/TcpServer.cpp
new file mode 100644
index 0000000..00a50e9
--- /dev/null
+++ b/src/TcpServer.cpp
@@ -0,0 +1,243 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in
+ Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "TcpServer.h"
+#include <iostream>
+#include <stdio.h>
+#include <errno.h>
+
+#ifdef _WIN32
+#else
+# include <sys/socket.h>
+#endif
+
+#ifdef TRACE_ON
+# ifndef TRACE_CLASS
+# define TRACE_CLASS(class, func) cout <<"-" <<(class) <<"\t(" <<this <<")::" <<(func) <<endl
+# define TRACE_STATIC(class, func) cout <<"-" <<(class) <<"\t(static)::" <<(func) <<endl
+# endif
+#else
+# ifndef TRACE_CLASS
+# define TRACE_CLASS(class, func)
+# define TRACE_STATIC(class, func)
+# endif
+#endif
+
+
+/// Must be call once before doing any operation on sockets
+int TcpServer::init()
+{
+#ifdef _WIN32
+ WSADATA wsaData;
+ WORD wVersionRequested = wVersionRequested = MAKEWORD( 2, 2 );
+
+ int res = WSAStartup( wVersionRequested, &wsaData );
+ if (res) {
+ setInetError("Can't initialize winsock");
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+
+/// Must be call once before leaving application
+int TcpServer::clean()
+{
+#ifdef _WIN32
+ int res = WSACleanup();
+ if (res) {
+ setInetError("Can't initialize winsock");
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+
+/**
+ * Two step constructor. Create must be called prior to use this
+ * socket.
+ */
+TcpServer::TcpServer() :
+ listenSocket(INVALID_SOCKET)
+{
+ TRACE_CLASS("TcpServer", "TcpServer()");
+}
+
+
+/**
+ * One step constructor.
+ * @param port The port number on which the socket will be bind
+ * @param name The IP address on which the socket will be bind.
+ * It is used to bind the socket on a specific interface if
+ * the computer have many NICs.
+ */
+TcpServer::TcpServer(int port, const char *name) :
+ listenSocket(INVALID_SOCKET)
+{
+ TRACE_CLASS("TcpServer", "TcpServer(int, char*)");
+ create(port, name);
+}
+
+
+/**
+ * Two step initializer. This function must be called after the constructor
+ * without argument as been called.
+ * @param port The port number on which the socket will be bind
+ * @param name The IP address on which the socket will be bind.
+ * It is used to bind the socket on a specific interface if
+ * the computer have many NICs.
+ * @return 0 if ok
+ * -1 if error
+ */
+int TcpServer::create(int port, const char *name)
+{
+ TRACE_CLASS("TcpServer", "create(int, char*)");
+ if (listenSocket != INVALID_SOCKET)
+ closesocket(listenSocket);
+ address.setAddress(name);
+ address.setPort(port);
+ if ((listenSocket = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
+ setInetError("Can't create socket");
+ return -1;
+ }
+ reuseopt_t reuse = 1;
+ if (setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))
+ == SOCKET_ERROR) {
+ setInetError("Can't reuse address");
+ return -1;
+ }
+ if (bind(listenSocket, address.getAddress(), sizeof(sockaddr_in)) == SOCKET_ERROR) {
+ setInetError("Can't bind socket");
+ closesocket(listenSocket);
+ listenSocket = INVALID_SOCKET;
+ return -1;
+ }
+ return 0;
+}
+
+
+/**
+ * Close the underlying socket.
+ * @return 0 if ok
+ * -1 if error
+ */
+int TcpServer::close()
+{
+ TRACE_CLASS("TcpServer", "close()");
+ if (listenSocket != INVALID_SOCKET) {
+ int res = closesocket(listenSocket);
+ if (res != 0) {
+ setInetError("Can't close socket");
+ return -1;
+ }
+ listenSocket = INVALID_SOCKET;
+ }
+ return 0;
+}
+
+
+/// Destructor
+TcpServer::~TcpServer()
+{
+ TRACE_CLASS("TcpServer", "~TcpServer()");
+ close();
+}
+
+
+int TcpServer::listen()
+{
+ TRACE_CLASS("TcpServer", "listen()");
+ if (::listen(listenSocket, 1) == SOCKET_ERROR) {
+ setInetError("Can't listen on socket");
+ return -1;
+ }
+ return 0;
+}
+
+
+TcpSocket* TcpServer::accept()
+{
+ SOCKET socket;
+ TcpSocket* client = NULL;
+ InetAddress addr;
+ socklen_t addrLen = sizeof(sockaddr_in);
+
+ socket = ::accept(listenSocket, addr.getAddress(), &addrLen);
+ if (socket == SOCKET_ERROR) {
+ setInetError("Can't accept connection on socket");
+ } else {
+ client = new TcpSocket();
+ client->setSocket(socket, addr);
+ }
+ return client;
+}
+
+/*
+WSAEINTR
+WSAEBADF
+WSAEACCES
+WSAEFAULT
+WSAEINVAL
+WSAEMFILE
+WSAEWOULDBLOCK
+WSAEINPROGRESS
+WSAEALREADY
+WSAENOTSOCK
+WSAEDESTADDRREQ
+WSAEMSGSIZE
+WSAEPROTOTYPE
+WSAENOPROTOOPT
+WSAEPROTONOSUPPORT
+WSAESOCKTNOSUPPORT
+WSAEOPNOTSUPP
+WSAEPFNOSUPPORT
+WSAEAFNOSUPPORT
+WSAEADDRINUSE
+WSAEADDRNOTAVAIL
+WSAENETDOWN
+WSAENETUNREACH
+WSAENETRESET
+WSAECONNABORTED
+WSAECONNRESET
+WSAENOBUFS
+WSAEISCONN
+WSAENOTCONN
+WSAESHUTDOWN
+WSAETOOMANYREFS
+WSAETIMEDOUT
+WSAECONNREFUSED
+WSAELOOP
+WSAENAMETOOLONG
+WSAEHOSTDOWN
+WSAEHOSTUNREACH
+WSAENOTEMPTY
+WSAEPROCLIM
+WSAEUSERS
+WSAEDQUOT
+WSAESTALE
+WSAEREMOTE
+WSAEDISCON
+WSASYSNOTREADY
+WSAVERNOTSUPPORTED
+WSANOTINITIALISED
+*/
diff --git a/src/TcpServer.h b/src/TcpServer.h
new file mode 100644
index 0000000..c4d9a4d
--- /dev/null
+++ b/src/TcpServer.h
@@ -0,0 +1,84 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in
+ Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TCPSERVER
+#define _TCPSERVER
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "InetAddress.h"
+#ifdef _WIN32
+# include <winsock.h>
+# define socklen_t int
+# define reuseopt_t char
+#else
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <unistd.h>
+# include <netdb.h>
+# include <arpa/inet.h>
+# include <pthread.h>
+# define SOCKET int
+# define INVALID_SOCKET -1
+# define SOCKET_ERROR -1
+# define reuseopt_t int
+#endif
+//#define INVALID_PORT -1
+
+#include <iostream>
+#include "TcpSocket.h"
+//#include "SocketSelector.h"
+
+/**
+ * This class represents a socket for sending and receiving UDP packets.
+ *
+ * A UDP socket is the sending or receiving point for a packet delivery service.
+ * Each packet sent or received on a datagram socket is individually
+ * addressed and routed. Multiple packets sent from one machine to another may
+ * be routed differently, and may arrive in any order.
+ * @author Pascal Charest pascal.charest@crc.ca
+ */
+class TcpServer {
+ friend class SocketSelector;
+public:
+ TcpServer();
+ TcpServer(int port, const char *name = NULL);
+ ~TcpServer();
+
+ static int init();
+ static int clean();
+
+ int create(int port, const char *name = NULL);
+ int close();
+ int listen();
+ TcpSocket* accept();
+
+
+ protected:
+ /// The address on which the socket is binded.
+ InetAddress address;
+ /// The low-level socket used by system functions.
+ SOCKET listenSocket;
+};
+
+#endif // _TCPSERVER
diff --git a/src/TcpSocket.cpp b/src/TcpSocket.cpp
new file mode 100644
index 0000000..723d06b
--- /dev/null
+++ b/src/TcpSocket.cpp
@@ -0,0 +1,366 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in
+ Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "TcpSocket.h"
+#include <iostream>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+
+#ifdef _WIN32
+#else
+# include <unistd.h>
+#endif
+
+#ifdef TRACE_ON
+# ifndef TRACE_CLASS
+# define TRACE_CLASS(class, func) cout <<"-" <<(class) <<"\t(" <<this <<")::" <<(func) <<endl
+# define TRACE_STATIC(class, func) cout <<"-" <<(class) <<"\t(static)::" <<(func) <<endl
+# endif
+#else
+# ifndef TRACE_CLASS
+# define TRACE_CLASS(class, func)
+# define TRACE_STATIC(class, func)
+# endif
+#endif
+
+
+/// Must be call once before doing any operation on sockets
+int TcpSocket::init()
+{
+#ifdef _WIN32
+ WSADATA wsaData;
+ WORD wVersionRequested = wVersionRequested = MAKEWORD( 2, 2 );
+
+ int res = WSAStartup( wVersionRequested, &wsaData );
+ if (res) {
+ setInetError("Can't initialize winsock");
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+
+/// Must be call once before leaving application
+int TcpSocket::clean()
+{
+#ifdef _WIN32
+ int res = WSACleanup();
+ if (res) {
+ setInetError("Can't initialize winsock");
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+
+/**
+ * Two step constructor. Create must be called prior to use this
+ * socket.
+ */
+TcpSocket::TcpSocket() :
+ listenSocket(INVALID_SOCKET)
+{
+ TRACE_CLASS("TcpSocket", "TcpSocket()");
+}
+
+
+/**
+ * One step constructor.
+ * @param port The port number on which the socket will be bind
+ * @param name The IP address on which the socket will be bind.
+ * It is used to bind the socket on a specific interface if
+ * the computer have many NICs.
+ */
+TcpSocket::TcpSocket(int port, char *name) :
+ listenSocket(INVALID_SOCKET)
+{
+ TRACE_CLASS("TcpSocket", "TcpSocket(int, char*)");
+ create(port, name);
+}
+
+
+/**
+ * Close the underlying socket.
+ * @return 0 if ok
+ * -1 if error
+ */
+int TcpSocket::close()
+{
+ TRACE_CLASS("TcpSocket", "close()");
+ if (listenSocket != INVALID_SOCKET) {
+ int res = closesocket(listenSocket);
+ if (res != 0) {
+ setInetError("Can't close socket");
+ return -1;
+ }
+ listenSocket = INVALID_SOCKET;
+ }
+ return 0;
+}
+
+
+/**
+ * Two step initializer. This function must be called after the constructor
+ * without argument as been called.
+ * @param port The port number on which the socket will be bind
+ * @param name The IP address on which the socket will be bind.
+ * It is used to bind the socket on a specific interface if
+ * the computer have many NICs.
+ * @return 0 if ok
+ * -1 if error
+ */
+int TcpSocket::create(int port, char *name)
+{
+ TRACE_CLASS("TcpSocket", "create(int, char*)");
+ if (listenSocket != INVALID_SOCKET)
+ closesocket(listenSocket);
+ address.setAddress(name);
+ address.setPort(port);
+ if ((listenSocket = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
+ setInetError("Can't create socket");
+ return -1;
+ }
+ reuseopt_t reuse = 1;
+ if (setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))
+ == SOCKET_ERROR) {
+ setInetError("Can't reuse address");
+ return -1;
+ }
+ if (bind(listenSocket, address.getAddress(), sizeof(sockaddr_in)) == SOCKET_ERROR) {
+ setInetError("Can't bind socket");
+ closesocket(listenSocket);
+ listenSocket = INVALID_SOCKET;
+ return -1;
+ }
+ return 0;
+}
+
+
+/// Destructor
+TcpSocket::~TcpSocket() {
+ TRACE_CLASS("TcpSocket", "~TcpSocket()");
+ close();
+}
+
+
+/**
+ * Receive an telnet packet, i.e a TCP stream ending with carriage return.
+ * @param data The buffer that will receive data.
+ * @param size The buffer size.
+ * @return > 0 if ok, -1 (SOCKET_ERROR) if error
+ */
+int TcpSocket::telnetRead(void* data, int size)
+{
+ TRACE_CLASS("TcpSocket", "read(void*, size)");
+ int ret;
+
+ printf("selectCall\n");
+
+ printf("readread 1\n");
+ char *line=GetLine(listenSocket);
+ ret=strlen(line);
+ printf("readread 2\n");
+ if (ret <= size)
+ {
+ strcpy((char*)data, line);
+ }
+ else
+ {
+// size_t n = size;
+ strcpy((char*)data, line);
+ ret = size;
+ }
+ printf("TELNET READ returned %d\n", ret);
+ return ret;
+}
+
+/**
+ * Receive a TCP stream.
+ * @param data The buffer that will receive data.
+ * @param size The buffer size.
+ * @return > 0 if ok, -1 (SOCKET_ERROR) if error
+ */
+int TcpSocket::read(void* data, int size)
+{
+ TRACE_CLASS("TcpSocket", "read(void*, size)");
+
+ int ret = recv(listenSocket, (char*)data, size, 0);
+ if (ret == SOCKET_ERROR) {
+ setInetError("Can't receive TCP packet");
+ return -1;
+ }
+ return ret;
+}
+
+
+#define MAX 512
+char* TcpSocket::GetLine(int fd)
+{
+ static char line[MAX];
+ static char netread[MAX] = "";
+ int n, len;
+ char *p;
+
+ len = strlen(netread);
+
+ /* look for \r\n in netread buffer */
+ p = strstr(netread, "\r\n");
+ if (p == NULL) {
+ /* fill buff - no \r\n found */
+ //n = ::read(fd, (void*)(netread+len), (size_t)(MAX-len));
+ n = recv(fd, (netread+len), MAX-len, 0);
+ if (n == SOCKET_ERROR) {
+ setInetError("Can't receive TCP packet");
+ return NULL;
+ }
+ len += n;
+ netread[len] = '\0';
+ if (n>0)
+ return GetLine(fd);
+ }
+ if (p!=NULL)
+ {
+ *p = '\0';
+ strcpy(line, netread);
+ /* copy rest of buf down */
+ memmove(netread, p+2, strlen(p+2)+1);
+ }
+ return line;
+}
+
+
+/**
+ * Send an TCP packet.
+ * @param data The buffer taht will be sent.
+ * @param size Number of bytes to send.
+ * return 0 if ok, -1 if error
+ */
+int TcpSocket::write(const void* data, int size)
+{
+#ifdef DUMP
+ TRACE_CLASS("TcpSocket", "write(const void*, int)");
+#endif
+
+ // ignore BROKENPIPE signal (we handle it instead)
+// void* old_sigpipe = signal ( SIGPIPE, SIG_IGN );
+ // try to send data
+ int ret = send(listenSocket, (char*)data, size, 0 /*MSG_NOSIGNAL*/ );
+ // restore the BROKENPIPE handling
+// signal ( SIGPIPE, (__sighandler_t)old_sigpipe );
+ if (ret == SOCKET_ERROR) {
+ setInetError("Can't send TCP packet");
+ return -1;
+ }
+ return ret;
+}
+
+
+int TcpSocket::setDestination(InetAddress &addr)
+{
+ address = addr;
+ int ret = connect(listenSocket, addr.getAddress(), sizeof(*addr.getAddress()));
+ // A etre verifier: code de retour differend entre Linux et Windows
+ return ret;
+}
+
+
+void TcpSocket::setSocket(SOCKET socket, InetAddress &addr)
+{
+ if (listenSocket != INVALID_SOCKET)
+ closesocket(listenSocket);
+ listenSocket = socket;
+ address = addr;
+}
+
+
+InetAddress TcpSocket::getAddress()
+{
+ return address;
+}
+
+
+int TcpSocket::PeekCount()
+{
+ int count;
+ char tempBuffer[3];
+ int size=3;
+
+ count = recv(listenSocket, tempBuffer, size, MSG_PEEK);
+ if (count == -1)
+ {
+ printf("ERROR WHEN PEEKING SOCKET\n");
+ }
+ return count;
+}
+
+/*
+WSAEINTR
+WSAEBADF
+WSAEACCES
+WSAEFAULT
+WSAEINVAL
+WSAEMFILE
+WSAEWOULDBLOCK
+WSAEINPROGRESS
+WSAEALREADY
+WSAENOTSOCK
+WSAEDESTADDRREQ
+WSAEMSGSIZE
+WSAEPROTOTYPE
+WSAENOPROTOOPT
+WSAEPROTONOSUPPORT
+WSAESOCKTNOSUPPORT
+WSAEOPNOTSUPP
+WSAEPFNOSUPPORT
+WSAEAFNOSUPPORT
+WSAEADDRINUSE
+WSAEADDRNOTAVAIL
+WSAENETDOWN
+WSAENETUNREACH
+WSAENETRESET
+WSAECONNABORTED
+WSAECONNRESET
+WSAENOBUFS
+WSAEISCONN
+WSAENOTCONN
+WSAESHUTDOWN
+WSAETOOMANYREFS
+WSAETIMEDOUT
+WSAECONNREFUSED
+WSAELOOP
+WSAENAMETOOLONG
+WSAEHOSTDOWN
+WSAEHOSTUNREACH
+WSAENOTEMPTY
+WSAEPROCLIM
+WSAEUSERS
+WSAEDQUOT
+WSAESTALE
+WSAEREMOTE
+WSAEDISCON
+WSASYSNOTREADY
+WSAVERNOTSUPPORTED
+WSANOTINITIALISED
+*/
diff --git a/src/TcpSocket.h b/src/TcpSocket.h
new file mode 100644
index 0000000..7c92af0
--- /dev/null
+++ b/src/TcpSocket.h
@@ -0,0 +1,97 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in
+ Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TCPSOCKET
+#define _TCPSOCKET
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "InetAddress.h"
+#ifdef _WIN32
+# include <winsock.h>
+# define socklen_t int
+# define reuseopt_t char
+#else
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <unistd.h>
+# include <netdb.h>
+# include <arpa/inet.h>
+# include <pthread.h>
+# define SOCKET int
+# define INVALID_SOCKET -1
+# define SOCKET_ERROR -1
+# define reuseopt_t int
+#endif
+//#define INVALID_PORT -1
+
+//# include "SocketSelector.h"
+
+#include <iostream>
+
+/**
+ * This class represents a socket for sending and receiving UDP packets.
+ *
+ * A UDP socket is the sending or receiving point for a packet delivery service.
+ * Each packet sent or received on a datagram socket is individually
+ * addressed and routed. Multiple packets sent from one machine to another may
+ * be routed differently, and may arrive in any order.
+ * @author Pascal Charest pascal.charest@crc.ca
+ */
+class TcpSocket {
+ friend class SocketSelector;
+ public:
+ TcpSocket();
+ TcpSocket(int port, char *name = NULL);
+ ~TcpSocket();
+
+ static int init();
+ static int clean();
+
+ int create(int port = 0, char *name = NULL);
+ int close();
+
+ int write(const void* data, int size);
+ int read(void* data, int size);
+ int telnetRead(void* data, int size);
+ /**
+ * Connects the socket on a specific address. Only data from this address
+ * will be received.
+ * @param addr The address to connect the socket
+ * @warning Not implemented yet.
+ */
+ int setDestination(InetAddress &addr);
+ InetAddress getAddress();
+ void setSocket(SOCKET socket, InetAddress &addr);
+ char* GetLine(int fd);
+
+ int PeekCount();
+
+ protected:
+ /// The address on which the socket is binded.
+ InetAddress address;
+ /// The low-level socket used by system functions.
+ SOCKET listenSocket;
+};
+
+#endif // _TCPSOCKET
diff --git a/src/UdpSocket.cpp b/src/UdpSocket.cpp
new file mode 100644
index 0000000..f3b2ca0
--- /dev/null
+++ b/src/UdpSocket.cpp
@@ -0,0 +1,455 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
+ Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "UdpSocket.h"
+
+#include <iostream>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+
+#ifdef TRACE_ON
+# ifndef TRACE_CLASS
+# define TRACE_CLASS(class, func) cout <<"-" <<(class) <<"\t(" <<this <<")::" <<(func) <<endl
+# define TRACE_STATIC(class, func) cout <<"-" <<(class) <<"\t(static)::" <<(func) <<endl
+# endif
+#else
+# ifndef TRACE_CLASS
+# define TRACE_CLASS(class, func)
+# define TRACE_STATIC(class, func)
+# endif
+#endif
+
+
+/// Must be call once before doing any operation on sockets
+int UdpSocket::init()
+{
+#ifdef _WIN32
+ WSADATA wsaData;
+ WORD wVersionRequested = wVersionRequested = MAKEWORD( 2, 2 );
+
+ int res = WSAStartup( wVersionRequested, &wsaData );
+ if (res) {
+ setInetError("Can't initialize winsock");
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+
+/// Must be call once before leaving application
+int UdpSocket::clean()
+{
+#ifdef _WIN32
+ int res = WSACleanup();
+ if (res) {
+ setInetError("Can't initialize winsock");
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+
+/**
+ * Two step constructor. Create must be called prior to use this
+ * socket.
+ */
+UdpSocket::UdpSocket() :
+ listenSocket(INVALID_SOCKET)
+{
+ TRACE_CLASS("UdpSocket", "UdpSocket()");
+}
+
+
+/**
+ * One step constructor.
+ * @param port The port number on which the socket will be bind
+ * @param name The IP address on which the socket will be bind.
+ * It is used to bind the socket on a specific interface if
+ * the computer have many NICs.
+ */
+UdpSocket::UdpSocket(int port, char *name) :
+ listenSocket(INVALID_SOCKET)
+{
+ TRACE_CLASS("UdpSocket", "UdpSocket(int, char*)");
+ create(port, name);
+}
+
+
+/**
+ * This functin set blocking mode. The socket can be blocking or not,
+ * depending of the parametre. By default, the socket is blocking.
+ * @param block If true, set the socket blocking, otherwise set non-blocking
+ * @return 0 if ok
+ * -1 if error
+ */
+int UdpSocket::setBlocking(bool block)
+{
+#ifdef _WIN32
+ unsigned long res = block ? 0 : 1;
+ if (ioctlsocket(listenSocket, FIONBIO, &res) != 0) {
+ setInetError("Can't change blocking state of socket");
+ return -1;
+ }
+ return 0;
+#else
+ int res;
+ if (block)
+ res = fcntl(listenSocket, F_SETFL, 0);
+ else
+ res = fcntl(listenSocket, F_SETFL, O_NONBLOCK);
+ if (res == SOCKET_ERROR) {
+ setInetError("Can't change blocking state of socket");
+ return -1;
+ }
+ return 0;
+#endif
+}
+
+
+/**
+ * Two step initializer. This function must be called after the constructor
+ * without argument as been called.
+ * @param port The port number on which the socket will be bind
+ * @param name The IP address on which the socket will be bind.
+ * It is used to bind the socket on a specific interface if
+ * the computer have many NICs.
+ * @return 0 if ok
+ * -1 if error
+ */
+int UdpSocket::create(int port, char *name)
+{
+ TRACE_CLASS("UdpSocket", "create(int, char*)");
+ if (listenSocket != INVALID_SOCKET)
+ closesocket(listenSocket);
+ address.setAddress(name);
+ address.setPort(port);
+ if ((listenSocket = socket(PF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
+ setInetError("Can't create socket");
+ return -1;
+ }
+ reuseopt_t reuse = 1;
+ if (setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))
+ == SOCKET_ERROR) {
+ setInetError("Can't reuse address");
+ return -1;
+ }
+ if (bind(listenSocket, address.getAddress(), sizeof(sockaddr_in)) == SOCKET_ERROR) {
+ setInetError("Can't bind socket");
+ closesocket(listenSocket);
+ listenSocket = INVALID_SOCKET;
+ return -1;
+ }
+ return 0;
+}
+
+
+/// Destructor
+UdpSocket::~UdpSocket() {
+ TRACE_CLASS("UdpSocket", "~UdpSocket()");
+ if (listenSocket != INVALID_SOCKET)
+ closesocket(listenSocket);
+}
+
+
+/**
+ * Receive an UDP packet.
+ * @param packet The packet that will receive data. The address will be set
+ * to the source address.
+ * @return 0 if ok, -1 if error
+ */
+int UdpSocket::receive(UdpPacket &packet)
+{
+ TRACE_CLASS("UdpSocket", "receive(UdpPacket)");
+ socklen_t addrSize;
+ addrSize = sizeof(*packet.getAddress().getAddress());
+ int ret = recvfrom(listenSocket, packet.getData(), packet.getSize() - packet.getOffset(), 0,
+ packet.getAddress().getAddress(), &addrSize);
+ if (ret == SOCKET_ERROR) {
+ packet.setLength(0);
+#ifndef _WIN32
+ if (errno == EAGAIN)
+ return 0;
+#endif
+ setInetError("Can't receive UDP packet");
+ return -1;
+ }
+ packet.setLength(ret);
+ if (ret == (long)packet.getSize()) {
+ packet.setSize(packet.getSize() << 1);
+ }
+ return 0;
+}
+
+
+/**
+ * Send an UDP packet.
+ * @param packet The UDP packet to be sent. It includes the data and the
+ * destination address
+ * return 0 if ok, -1 if error
+ */
+int UdpSocket::send(UdpPacket &packet)
+{
+#ifdef DUMP
+ TRACE_CLASS("UdpSocket", "send(UdpPacket)");
+#endif
+ int ret = sendto(listenSocket, packet.getData(), packet.getLength(), 0,
+ packet.getAddress().getAddress(), sizeof(*packet.getAddress().getAddress()));
+ if (ret == SOCKET_ERROR
+#ifndef _WIN32
+ && errno != ECONNREFUSED
+#endif
+ ) {
+ setInetError("Can't send UDP packet");
+ return -1;
+ }
+ return 0;
+}
+
+
+/**
+ * Must be called to receive data on a multicast address.
+ * @param groupname The multica
+st address to join.
+ * @return 0 if ok, -1 if error
+ */
+int UdpSocket::joinGroup(char* groupname)
+{
+ TRACE_CLASS("UdpSocket", "joinGroup(char*)");
+#ifdef _WIN32
+ ip_mreq group;
+#else
+ ip_mreqn group;
+#endif
+ if ((group.imr_multiaddr.s_addr = inet_addr(groupname)) == INADDR_NONE) {
+ setInetError(groupname);
+ return -1;
+ }
+ if (!IN_MULTICAST(ntohl(group.imr_multiaddr.s_addr))) {
+ setInetError("Not a multicast address");
+ return -1;
+ }
+#ifdef _WIN32
+ group.imr_interface.s_addr = 0;
+ if (setsockopt(listenSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&group, sizeof(group))
+ == SOCKET_ERROR) {
+ setInetError("Can't join multicast group");
+ return -1;
+ }
+#else
+ group.imr_address.s_addr = htons(INADDR_ANY);;
+ group.imr_ifindex = 0;
+ if (setsockopt(listenSocket, SOL_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group))
+ == SOCKET_ERROR) {
+ setInetError("Can't join multicast group");
+ }
+#endif
+ return 0;
+}
+
+
+/**
+ * Constructs an UDP packet.
+ * @param initSize The initial size of the data buffer
+ */
+UdpPacket::UdpPacket(unsigned int initSize) :
+ dataBuf(new char[initSize]),
+ length(0),
+ size(initSize),
+ offset(0)
+{
+ TRACE_CLASS("UdpPacket", "UdpPacket(unsigned int)");
+ if (dataBuf == NULL)
+ size = 0;
+}
+
+
+/// Destructor
+UdpPacket::~UdpPacket()
+{
+ TRACE_CLASS("UdpPacket", "~UdpPacket()");
+ if (dataBuf != NULL) {
+ delete []dataBuf;
+ dataBuf = NULL;
+ }
+}
+
+
+/**
+ * Changes size of the data buffer size. \a Length + \a offset data will be copied
+ * in the new buffer.
+ * @warning The pointer to data will be changed
+ * @param newSize The new data buffer size
+ */
+void UdpPacket::setSize(unsigned newSize)
+{
+ TRACE_CLASS("UdpPacket", "setSize(unsigned)");
+ char *tmp = new char[newSize];
+ if (length > newSize)
+ length = newSize;
+ if (tmp) {
+ memcpy(tmp, dataBuf, length);
+ delete []dataBuf;
+ dataBuf = tmp;
+ size = newSize;
+ }
+}
+
+
+/**
+ * Give the pointer to data. It is ajusted with the \a offset.
+ * @warning This pointer change. when the \a size of the buffer and the \a offset change.
+ * @return The pointer
+ */
+char *UdpPacket::getData()
+{
+ return dataBuf + offset;
+}
+
+
+/**
+ * Add some data at the end of data buffer and adjust size.
+ * @param data Pointer to the data to add
+ * @param size Size in bytes of new data
+ */
+void UdpPacket::addData(void *data, unsigned size)
+{
+ if (length + size > this->size) {
+ setSize(this->size << 1);
+ }
+ memcpy(dataBuf + length, data, size);
+ length += size;
+}
+
+
+/**
+ * Returns the length of useful data. Data before the \a offset are ignored.
+ * @return The data length
+ */
+unsigned long UdpPacket::getLength()
+{
+ return length - offset;
+}
+
+
+/**
+ * Returns the size of the data buffer.
+ * @return The data buffer size
+ */
+unsigned long UdpPacket::getSize()
+{
+ return size;
+}
+
+
+/**
+ * Returns the offset value.
+ * @return The offset value
+ */
+unsigned long UdpPacket::getOffset()
+{
+ return offset;
+}
+
+
+/**
+ * Sets the data length value. Data before the \a offset are ignored.
+ * @param len The new length of data
+ */
+void UdpPacket::setLength(unsigned long len)
+{
+ length = len + offset;
+}
+
+
+/**
+ * Sets the data offset. Data length is ajusted to ignore data before the \a offset.
+ * @param val The new data offset.
+ */
+void UdpPacket::setOffset(unsigned long val)
+{
+ offset = val;
+ if (offset > length)
+ length = offset;
+}
+
+
+/**
+ * Returns the UDP address of the data.
+ * @return The UDP address
+ */
+InetAddress &UdpPacket::getAddress()
+{
+ return address;
+}
+
+/*
+WSAEINTR
+WSAEBADF
+WSAEACCES
+WSAEFAULT
+WSAEINVAL
+WSAEMFILE
+WSAEWOULDBLOCK
+WSAEINPROGRESS
+WSAEALREADY
+WSAENOTSOCK
+WSAEDESTADDRREQ
+WSAEMSGSIZE
+WSAEPROTOTYPE
+WSAENOPROTOOPT
+WSAEPROTONOSUPPORT
+WSAESOCKTNOSUPPORT
+WSAEOPNOTSUPP
+WSAEPFNOSUPPORT
+WSAEAFNOSUPPORT
+WSAEADDRINUSE
+WSAEADDRNOTAVAIL
+WSAENETDOWN
+WSAENETUNREACH
+WSAENETRESET
+WSAECONNABORTED
+WSAECONNRESET
+WSAENOBUFS
+WSAEISCONN
+WSAENOTCONN
+WSAESHUTDOWN
+WSAETOOMANYREFS
+WSAETIMEDOUT
+WSAECONNREFUSED
+WSAELOOP
+WSAENAMETOOLONG
+WSAEHOSTDOWN
+WSAEHOSTUNREACH
+WSAENOTEMPTY
+WSAEPROCLIM
+WSAEUSERS
+WSAEDQUOT
+WSAESTALE
+WSAEREMOTE
+WSAEDISCON
+WSASYSNOTREADY
+WSAVERNOTSUPPORTED
+WSANOTINITIALISED
+*/
diff --git a/src/UdpSocket.h b/src/UdpSocket.h
new file mode 100644
index 0000000..a500606
--- /dev/null
+++ b/src/UdpSocket.h
@@ -0,0 +1,126 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
+ Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _UDPSOCKET
+#define _UDPSOCKET
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "InetAddress.h"
+#ifdef _WIN32
+# include <winsock.h>
+# define socklen_t int
+# define reuseopt_t char
+#else
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <unistd.h>
+# include <netdb.h>
+# include <arpa/inet.h>
+# include <pthread.h>
+# define SOCKET int
+# define INVALID_SOCKET -1
+# define SOCKET_ERROR -1
+# define reuseopt_t int
+#endif
+//#define INVALID_PORT -1
+
+#include <stdlib.h>
+#include <iostream>
+class UdpPacket;
+
+
+/**
+ * This class represents a socket for sending and receiving UDP packets.
+ *
+ * A UDP socket is the sending or receiving point for a packet delivery service.
+ * Each packet sent or received on a datagram socket is individually
+ * addressed and routed. Multiple packets sent from one machine to another may
+ * be routed differently, and may arrive in any order.
+ * @author Pascal Charest pascal.charest@crc.ca
+ */
+class UdpSocket {
+ public:
+ UdpSocket();
+ UdpSocket(int port, char *name = NULL);
+ ~UdpSocket();
+
+ static int init();
+ static int clean();
+
+ int create(int port = 0, char *name = NULL);
+
+ int send(UdpPacket &packet);
+ int receive(UdpPacket &packet);
+ int joinGroup(char* groupname);
+ /**
+ * Connects the socket on a specific address. Only data from this address
+ * will be received.
+ * @param addr The address to connect the socket
+ * @warning Not implemented yet.
+ */
+ void connect(InetAddress &addr);
+ int setBlocking(bool block);
+
+ protected:
+ /// The address on which the socket is binded.
+ InetAddress address;
+ /// The low-level socket used by system functions.
+ SOCKET listenSocket;
+};
+
+/**
+ * This class represents a UDP packet.
+ *
+ * UDP packets are used to implement a connectionless packet delivery service.
+ * Each message is routed from one machine to another based solely on
+ * information contained within that packet. Multiple packets sent from one
+ * machine to another might be routed differently, and might arrive in any order.
+ * @author Pascal Charest pascal.charest@crc.ca
+ */
+class UdpPacket {
+ public:
+ UdpPacket(unsigned int initSize = 1024);
+ // Not implemented
+ UdpPacket(const UdpPacket& packet);
+ ~UdpPacket();
+
+ char *getData();
+ void addData(void *data, unsigned size);
+ unsigned long getLength();
+ unsigned long getSize();
+ unsigned long getOffset();
+ void setLength(unsigned long len);
+ void setOffset(unsigned long val);
+ void setSize(unsigned newSize);
+ InetAddress &getAddress();
+ // Not implemented
+ const UdpPacket &operator=(const UdpPacket&);
+
+ private:
+ char *dataBuf;
+ unsigned long length, size, offset;
+ InetAddress address;
+};
+
+#endif // _UDPSOCKET
diff --git a/src/bridge.c b/src/bridge.c
new file mode 100644
index 0000000..5a9de23
--- /dev/null
+++ b/src/bridge.c
@@ -0,0 +1,515 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
+ Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#ifdef _WIN32
+# include <winsock2.h>
+#else
+# include <netinet/in.h>
+#endif // _WIN32
+#include <string.h>
+#include "bridge.h"
+#include "crc.h"
+
+#include <assert.h>
+#include "PcDebug.h"
+
+#ifdef _WIN32
+# ifdef _DEBUG
+ int bridgeVerbosity = 0;
+# endif
+#else
+# ifdef DEBUG
+ int bridgeVerbosity = 0;
+# endif
+#endif
+
+void printStats(struct bridgeInfo* info, FILE* out)
+{
+ struct bridgeStats stats = getStats(info);
+ fprintf(out, "frames : %lu\n", stats.frames);
+ fprintf(out, " valids : %lu\n", stats.valids);
+ fprintf(out, " invalids : %lu\n", stats.invalids);
+ fprintf(out, " bytes : %lu\n", stats.bytes);
+ fprintf(out, " packets : %lu\n", stats.packets);
+ fprintf(out, " errors : %lu\n", stats.errors);
+ fprintf(out, " missings : %lu\n", stats.missings);
+ fprintf(out, " dropped : %lu\n", stats.dropped);
+ fprintf(out, " crc : %lu\n", stats.crc);
+ fprintf(out, " overruns : %lu\n", stats.overruns);
+}
+
+
+void resetStats(struct bridgeInfo* info)
+{
+ memset(&info->stats, 0, sizeof(info->stats));
+}
+
+
+struct bridgeStats getStats(struct bridgeInfo* info)
+{
+ return info->stats;
+}
+
+
+void bridgeInitInfo(struct bridgeInfo* info)
+{
+ memset(info, 0, sizeof(*info));
+ info->transmitted = -8;
+};
+
+
+int writePacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut,
+ struct bridgeInfo* info)
+{
+ static struct bridgeHdr header = { 0 };
+
+ PDEBUG4_VERBOSE(1, bridgeVerbosity, "writePacket\n sizeIn: %i, sizeOut: %i, "
+ "offset: %i, transmitted: %i\n",
+ sizeIn, sizeOut, info->offset, info->transmitted);
+
+ assert(info->transmitted < sizeIn);
+
+ if ((info->offset == 0) && (sizeIn > 0)) {
+ ((unsigned short*)dataOut)[0] = 0xb486;
+ info->offset = 2;
+ }
+ if (sizeIn == 0) {
+ memset((unsigned char*)dataOut + info->offset, 0, sizeOut - info->offset);
+ info->offset = 0;
+ info->transmitted = -8;
+ PDEBUG1_VERBOSE(1, bridgeVerbosity, " return %i (sizeIn == 0)\n",
+ sizeOut);
+ return 0;
+ }
+
+ while (info->offset < sizeOut) {
+ switch (info->transmitted) {
+ case (-8):
+ ((unsigned char*)dataOut)[info->offset++] = 0xcb;
+ ++info->transmitted;
+ break;
+ case (-7):
+ ((unsigned char*)dataOut)[info->offset++] = 0x28;
+ ++info->transmitted;
+ break;
+ case (-6):
+ header.size = htons((unsigned short)sizeIn);
+ header.crc = htons((unsigned short)(crc16(0xffff, &header, 4) ^ 0xffff));
+ ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[0];
+ ++info->transmitted;
+ break;
+ case (-5):
+ ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[1];
+ ++info->transmitted;
+ break;
+ case (-4):
+ ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[2];
+ ++info->transmitted;
+ break;
+ case (-3):
+ ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[3];
+ ++info->transmitted;
+ break;
+ case (-2):
+ ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[4];
+ ++info->transmitted;
+ break;
+ case (-1):
+ ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[5];
+ ++info->transmitted;
+ header.seqNb = htons((unsigned short)(ntohs(header.seqNb) + 1));
+ break;
+ default:
+ ((unsigned char*)dataOut)[info->offset++] =
+ ((unsigned char*)dataIn)[info->transmitted++];
+ if (info->transmitted == sizeIn) {
+ PDEBUG2_VERBOSE(1, bridgeVerbosity,
+ " Packet done, %i bytes at offset %i\n",
+ info->transmitted, info->offset);
+ PDEBUG1_VERBOSE(1, bridgeVerbosity,
+ " return %i (sizeIn == transmitted)\n", info->offset);
+ info->transmitted = -8;
+ return info->offset;
+ }
+ }
+ }
+
+ PDEBUG1_VERBOSE(1, bridgeVerbosity, " return %i (offset >= sizeOut)\n",
+ info->offset);
+ info->offset = 0;
+ return 0;
+}
+
+
+int getPacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut,
+ struct bridgeInfo* info, char async)
+{
+ unsigned char* in = (unsigned char*)dataIn;
+ unsigned char* out = (unsigned char*)dataOut;
+ unsigned char ch;
+ unsigned short crc;
+ unsigned short diff;
+
+ PDEBUG3_VERBOSE(1, bridgeVerbosity,
+ "getPacket\n pos\t%i\n state\t%i\n received\t%i\n",
+ info->pos, info->state, info->received);
+
+ if (info->pos == 0) {
+ ++info->stats.frames;
+ if (((unsigned short*)dataIn)[0] != 0xb486) {
+ if (((unsigned short*)dataIn)[0] != 0) {
+ ++info->stats.invalids;
+ printf("WARNING: processing frame with invalid magic "
+ "number!\n");
+ } else {
+ PDEBUG0_VERBOSE(1, bridgeVerbosity,
+ "getPacket: not a valid frame\n");
+ return 0;
+ }
+ } else {
+ PDEBUG0_VERBOSE(2, bridgeVerbosity, "Valid frame\n");
+ info->pos += 2;
+ ++info->stats.valids;
+ }
+ info->stats.bytes += sizeIn;
+ }
+ while (info->pos < sizeIn) {
+ ch = in[info->pos++];
+ switch (info->state) {
+ case 0: // sync search
+ info->sync <<= 8;
+ info->sync |= ch;
+ if (info->sync == 0xcb28) {
+ PDEBUG0_VERBOSE(2, bridgeVerbosity, "Sync found\n");
+ ++info->stats.packets;
+ info->received = 0;
+ info->state = 1;
+ }
+ if (info->sync == 0) { // Padding
+ info->pos = 0;
+ return 0;
+ }
+ break;
+ case 1: // header search
+ ((char*)&info->header)[info->received++] = ch;
+ if (info->received == sizeof(struct bridgeHdr)) {
+ PDEBUG0_VERBOSE(2, bridgeVerbosity, "Header found\n");
+ out = (unsigned char*)dataOut;
+ info->received = 0;
+ info->state = 2;
+ crc = crc16(0xffff, &info->header, 4);
+ crc ^= 0xffff;
+ info->header.size = ntohs(info->header.size);
+ info->header.seqNb = ntohs(info->header.seqNb);
+ info->header.crc = ntohs(info->header.crc);
+ PDEBUG4_VERBOSE(2, bridgeVerbosity,
+ " size\t%i\n seq\t%i\n crc\t0x%.4x (0x%.4x)\n",
+ info->header.size, info->header.seqNb,
+ info->header.crc, crc);
+ if (crc != info->header.crc) {
+ PDEBUG0_VERBOSE(2, bridgeVerbosity, "CRC error\n");
+ ++info->stats.errors;
+ ++info->stats.crc;
+ info->state = 0;
+ if (info->pos < sizeof(struct bridgeHdr) + 2 + 2) {
+ info->pos = 2;
+ }
+ } else {
+ if (!info->initSeq) {
+ info->lastSeq = info->header.seqNb;
+ info->initSeq = 1;
+ } else {
+ if (info->header.seqNb > info->lastSeq) {
+ diff = (info->header.seqNb - info->lastSeq) - 1;
+ } else {
+ diff = ((short)info->lastSeq -
+ (short)info->header.seqNb) - 1;
+ }
+ info->stats.errors += diff;
+ info->stats.missings += diff;
+ info->lastSeq = info->header.seqNb;
+ }
+ }
+ }
+ break;
+ case 2: // data
+ out[info->received++] = ch;
+ if (info->received == info->header.size) {
+ PDEBUG0_VERBOSE(2, bridgeVerbosity, "data found\n");
+ info->state = 0;
+ return info->received;
+ }
+ if (info->received == sizeOut) {
+ PDEBUG1_VERBOSE(1, bridgeVerbosity, "To much data: %i\n",
+ info->received);
+ ++info->stats.errors;
+ ++info->stats.overruns;
+ info->sync = 0;
+ info->state = 0;
+ return -1;
+ }
+ break;
+ case 3: // Padding or sync
+ if (ch == 0) { // Padding
+ info->pos = 0;
+ return 0;
+ }
+ if (ch != 0xcb) { // error
+ info->sync = ch;
+ info->state = 0;
+ } else {
+ info->state = 4;
+ }
+ break;
+ case 4: // Low byte sync
+ if (ch != 28) { // error
+ info->sync <<= 8;
+ info->sync |= ch;
+ info->state = 0;
+ } else {
+ info->state = 2;
+ }
+ break;
+ }
+ }
+ info->pos = 0;
+ return 0;
+}
+
+
+void dump(void* data, int size, FILE* stream)
+{
+ int i;
+ fprintf(stream, "%i bytes\n", size);
+ for (i = 0; i < size; ++i) {
+ fprintf(stream, " 0x%.2x", ((unsigned char*)data)[i]);
+ if (i % 8 == 7)
+ fprintf(stream, "\n");
+ }
+ fprintf(stream, "\n");
+}
+
+
+#ifdef BRIDGE_TEST
+#include <stdlib.h>
+
+
+int test(const unsigned char* data)
+{
+ unsigned char bridgeSize = data[0];
+ unsigned char nbInput = data[1];
+ unsigned char nbBridge = 1;
+ struct bridgeInfo info;
+
+ int i, j;
+ int index = 0;
+ int max = 0;
+ int nbBytes;
+
+ unsigned char** inputData;
+ unsigned char** bridgeData;
+ unsigned char* outputData;
+
+ inputData = malloc(nbInput * 4);
+ bridgeData = malloc(nbBridge * 4);
+ for (i = 0; i < nbInput; ++i) {
+ if (data[i + 2] > 0)
+ inputData[i] = malloc(data[i + 2]);
+ if (data[i + 2] > max) {
+ max = data[i + 2];
+ }
+ for (j = 0; j < data[i + 2]; ++j) {
+ inputData[i][j] = index++;
+ }
+ }
+ bridgeData[0] = malloc(bridgeSize);
+ memset(bridgeData[0], 0, bridgeSize);
+ outputData = malloc(max);
+ bridgeInitInfo(&info);
+
+ // Write packets
+ index = 0;
+ while (1) {
+ if (data[index + 2] == 0) {
+ if (++index == nbInput)
+ break;
+ }
+ while ((nbBytes = writePacket(inputData[index], data[index + 2],
+ bridgeData[nbBridge - 1], bridgeSize, &info))
+ != 0) {
+ if (++index == nbInput) {
+ break;
+ }
+ }
+ if (index == nbInput)
+ break;
+ // TODO check null
+ bridgeData = realloc(bridgeData, (++nbBridge) * 4);
+ bridgeData[nbBridge - 1] = malloc(bridgeSize);
+ memset(bridgeData[nbBridge - 1], 0, bridgeSize);
+ }
+// if (nbBytes != bridgeSize) {
+ writePacket(NULL, 0, bridgeData[nbBridge - 1], bridgeSize, &info);
+// }
+
+ // read packets
+ index = 0;
+ for (i = 0; i < nbBridge; ++i) {
+ while ((nbBytes = getPacket(bridgeData[i], bridgeSize, outputData, max,
+ &info, 0)) != 0) {
+ while (data[index + 2] == 0) {
+ ++index;
+ }
+ if (nbBytes != data[index + 2]) {
+ printf("FAILED\n");
+ printf("Invalid size at bridge %i, data %i: %i != %i\n",
+ i, index, nbBytes, data[index + 2]);
+ for (i = 0; i < nbInput; ++i) {
+ printf("Input %i: ", i);
+ dump(inputData[i], data[i + 2], stdout);
+ }
+ for (i = 0; i < nbBridge; ++i) {
+ printf("Bridge %i: ", i);
+ dump(bridgeData[i], bridgeSize, stdout);
+ }
+ printf("Output %i: ", index);
+ dump(outputData, nbBytes, stdout);
+ return -1;
+ }
+ if (memcmp(outputData, inputData[index], data[index + 2]) != 0) {
+ printf("FAILED\n");
+ printf("output != input\n");
+ for (i = 0; i < nbInput; ++i) {
+ printf("Input %i: ", i);
+ dump(inputData[i], data[i + 2], stdout);
+ }
+ for (i = 0; i < nbBridge; ++i) {
+ printf("Bridge %i: ", i);
+ dump(bridgeData[i], bridgeSize, stdout);
+ }
+ printf("Output %i: ", index);
+ dump(outputData, nbBytes, stdout);
+ }
+ ++index;
+ }
+ }
+
+ printf("SUCCESS\n");
+
+ for (i = 0; i < nbInput; ++i) {
+ if (data[i + 2] > 0)
+ free(inputData[i]);
+ }
+ free(inputData);
+ free(outputData);
+ for (i = 0; i < nbBridge; ++i) {
+ free(bridgeData[i]);
+ }
+ free(bridgeData);
+
+ return -1;
+}
+
+
+int main(int argc, char* argv[])
+{
+ int i;
+ // test: bridgesize, nbinput [, input1, input2, ... ]
+ const unsigned char complete[] = { 32, 1, 16 };
+ const unsigned char split[] = { 32, 1, 48 };
+ const unsigned char twice[] = {32, 2, 8, 4 };
+ const unsigned char secondSplit[] = { 32, 2, 16, 16 };
+ const unsigned char headerSplit[][4] = {
+ { 32, 2, 23, 16 },
+ { 32, 2, 22, 16 },
+ { 32, 2, 21, 16 },
+ { 32, 2, 20, 16 },
+ { 32, 2, 19, 16 },
+ { 32, 2, 18, 16 },
+ { 32, 2, 17, 16 }
+ };
+ const unsigned char two[] = { 32, 3, 16, 0, 16 };
+ const unsigned char doubleSplit[] = { 32, 2, 32, 32 };
+ const unsigned char full[] = { 32, 2, 24, 12 };
+ const unsigned char empty[] = { 32, 3, 0, 0, 5 };
+
+#ifdef _WIN32
+ #ifdef _DEBUG
+ bridgeVerbosity = argc - 1;
+ #endif // DEBUG
+#else
+ #ifdef DEBUG
+ bridgeVerbosity = argc - 1;
+ #endif // DEBUG
+#endif // _WIN32
+
+ printf("Complete: ");
+ test(complete);
+ // printStats(stdout);
+ fflush(stdout);
+
+ printf("split: ");
+ test(split);
+ // printStats(stdout);
+ fflush(stdout);
+
+ printf("twice: ");
+ test(twice);
+ // printStats(stdout);
+ fflush(stdout);
+
+ printf("second split: ");
+ test(secondSplit);
+ // printStats(stdout);
+ fflush(stdout);
+
+ for (i = 0; i < sizeof(headerSplit) / sizeof(headerSplit[0]); ++i) {
+ printf("headerSplit%i: ", i);
+ test(headerSplit[i]);
+ // printStats(stdout);
+ fflush(stdout);
+ }
+
+ printf("two: ");
+ test(two);
+ // printStats(stdout);
+ fflush(stdout);
+
+ printf("doubleSplit: ");
+ test(doubleSplit);
+ // printStats(stdout);
+ fflush(stdout);
+
+ printf("full: ");
+ test(full);
+ // printStats(stdout);
+ fflush(stdout);
+
+ printf("empty: ");
+ test(empty);
+ // printStats(stdout);
+ fflush(stdout);
+
+ return 0;
+}
+
+#endif // BRIDGE_TEST
diff --git a/src/bridge.h b/src/bridge.h
new file mode 100644
index 0000000..f7d3f41
--- /dev/null
+++ b/src/bridge.h
@@ -0,0 +1,112 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
+ Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BRIDGE
+#define _BRIDGE
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN32
+# ifdef _DEBUG
+ extern int bridgeVerbosity;
+# endif // _DEBUG
+#else
+# ifndef DEBUG
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+# else
+ extern int bridgeVerbosity;
+# endif // DEBUG
+#endif // _WIN32
+
+struct bridgeStats {
+ unsigned long frames; // Number of frames analyzed
+ unsigned long valids; // Nb of frames with a good magic number
+ unsigned long invalids; // Nb of frames with a good magic number
+ unsigned long bytes; // Nb of data bytes
+ unsigned long packets; // Nb of packets found
+ unsigned long errors;
+ unsigned long missings;
+ unsigned long dropped;
+ unsigned long crc; // Nb of crc errors
+ unsigned long overruns; // Nb of packet too big
+};
+
+
+struct bridgeHdr {
+ unsigned short size;
+ unsigned short seqNb;
+ unsigned short crc;
+};
+
+
+struct bridgeInfo {
+ // Tx
+ int transmitted; // Nb bytes written
+ int offset; // Offset of the next byte to write
+ // Rx
+ int received;
+ int pos;
+ int state;
+ unsigned short lastSeq;
+ unsigned short sync;
+ char initSeq;
+ // General
+ struct bridgeHdr header;
+ struct bridgeStats stats;
+};
+
+
+
+void dump(void* data, int size, FILE* stream);
+
+/*
+ * Example of usae:
+ * if (data.length == 0)
+ * read(data)
+ * while (writePacket() != 0)
+ * read(read)
+ * ...
+ */
+int writePacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut, struct bridgeInfo* info);
+
+int getPacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut, struct bridgeInfo* info, char async);
+
+void bridgeInitInfo(struct bridgeInfo* info);
+struct bridgeStats getStats(struct bridgeInfo* info);
+void resetStats(struct bridgeInfo* info);
+void printStats(struct bridgeInfo* info, FILE* out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _BRIDGE
diff --git a/src/crc.c b/src/crc.c
new file mode 100644
index 0000000..8dc9966
--- /dev/null
+++ b/src/crc.c
@@ -0,0 +1,266 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
+ Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "crc.h"
+#ifndef _WIN32
+# include <unistd.h>
+# include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <fcntl.h>
+
+//#define CCITT 0x1021
+
+uint8_t crc8tab[256] = {
+ 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
+ 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
+ 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
+ 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
+ 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
+ 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
+ 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
+ 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
+ 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
+ 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
+ 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
+ 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
+ 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
+ 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
+ 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
+ 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
+ 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
+ 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
+ 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
+ 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
+ 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
+ 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
+ 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
+ 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
+ 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
+ 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
+ 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
+ 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
+ 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
+ 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
+ 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
+ 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3
+};
+
+
+uint16_t crc16tab[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+
+uint32_t crc32tab[256] = {
+ 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
+ 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
+ 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
+ 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
+ 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+ 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
+ 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
+ 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+ 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
+ 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
+ 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+ 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
+ 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
+ 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
+ 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
+ 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+ 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+ 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
+ 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
+ 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
+ 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
+ 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
+ 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
+ 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
+ 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
+ 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+ 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+ 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
+ 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
+ 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
+ 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
+ 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+ 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
+ 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
+ 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+ 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
+ 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
+ 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+ 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
+ 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
+ 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
+ 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
+ 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+ 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+ 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
+ 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
+ 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
+ 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
+ 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
+ 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
+ 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
+ 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
+ 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+ 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
+ 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
+ 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
+ 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
+ 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+};
+
+// This function can be used to create a new table with a different polynom
+void init_crc8tab(uint8_t l_code, uint8_t l_init)
+{
+ unsigned i, j, msb;
+ uint8_t nb;
+ uint8_t crc;
+
+ for (i = 0; i < 256; ++i) {
+ crc = l_init;
+ nb = i ^ 0xff;
+ for (j = 0; j < 8; ++j) {
+ msb = (nb & (0x80 >> j)) && 1;
+ msb ^= (crc >> 7);
+ crc <<= 1;
+ if (msb)
+ crc ^= l_code;
+ }
+ crc8tab[i] = crc;
+ }
+}
+
+
+void init_crc16tab(uint16_t l_code, uint16_t l_init)
+{
+ unsigned i, j, msb;
+ uint8_t nb;
+ uint16_t crc;
+
+ for (i = 0; i < 256; ++i) {
+ crc = l_init;
+ nb = i ^ 0xff;
+ for (j = 0; j < 8; ++j) {
+ msb = (nb & (0x80 >> j)) && 1;
+ msb ^= (crc >> 15);
+ crc <<= 1;
+ if (msb)
+ crc ^= l_code;
+ }
+ crc ^= 0xff00;
+ crc16tab[i] = crc;
+ }
+}
+
+
+void init_crc32tab(uint32_t l_code, uint32_t l_init)
+{
+ unsigned i, j, msb;
+ uint8_t nb;
+ uint32_t crc;
+
+ for (i = 0; i < 256; ++i) {
+ crc = l_init;
+ nb = i ^ 0xff;
+ for (j = 0; j < 8; ++j) {
+ msb = (nb & (0x80 >> j)) && 1;
+ msb ^= (crc >> 31);
+ crc <<= 1;
+ if (msb)
+ crc ^= l_code;
+ }
+ crc ^= 0xffffff00;
+ crc32tab[i] = crc;
+ }
+}
+
+
+uint8_t crc8(uint8_t l_crc, const void *lp_data, unsigned l_nb)
+{
+ uint8_t* data = (uint8_t*)lp_data;
+ while (l_nb--) {
+ l_crc = crc8tab[l_crc ^ *(data++)];
+ }
+ return (l_crc);
+}
+
+
+uint16_t crc16(uint16_t l_crc, const void *lp_data, unsigned l_nb)
+{
+ uint8_t* data = (uint8_t*)lp_data;
+ while (l_nb--) {
+ l_crc =
+ (l_crc << 8) ^ crc16tab[(l_crc >> 8) ^ *(data++)];
+ }
+ return (l_crc);
+}
+
+
+uint32_t crc32(uint32_t l_crc, const void *lp_data, unsigned l_nb)
+{
+ uint8_t* data = (uint8_t*)lp_data;
+ while (l_nb--) {
+ l_crc =
+ (l_crc << 8) ^ crc32tab[((l_crc >> 24) ^ *(data++)) & 0xff];
+ }
+ return (l_crc);
+}
diff --git a/src/crc.h b/src/crc.h
new file mode 100644
index 0000000..f0da0f5
--- /dev/null
+++ b/src/crc.h
@@ -0,0 +1,59 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
+ Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CRC
+#define _CRC
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifndef _WIN32
+ #include <stdint.h>
+#else
+ #include <winsock2.h> // For types...
+ typedef BYTE uint8_t;
+ typedef WORD uint16_t;
+ typedef DWORD32 uint32_t;
+#endif
+
+
+#ifdef __cplusplus
+extern "C" { // }
+#endif
+
+void init_crc8tab(uint8_t l_code, uint8_t l_init);
+uint8_t crc8(uint8_t l_crc, const void *lp_data, unsigned l_nb);
+extern uint8_t crc8tab[];
+
+void init_crc16tab(uint16_t l_code, uint16_t l_init);
+uint16_t crc16(uint16_t l_crc, const void *lp_data, unsigned l_nb);
+extern uint16_t crc16tab[];
+
+void init_crc32tab(uint32_t l_code, uint32_t l_init);
+uint32_t crc32(uint32_t l_crc, const void *lp_data, unsigned l_nb);
+extern uint32_t crc32tab[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CRC
diff --git a/src/dabInput.cpp b/src/dabInput.cpp
new file mode 100644
index 0000000..e937008
--- /dev/null
+++ b/src/dabInput.cpp
@@ -0,0 +1,51 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in
+ Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInput.h"
+
+#include <string.h>
+
+TcpLog etiLog;
+
+
+bool dabInputOperations::operator==(const dabInputOperations& ops)
+{
+ return memcmp(this, &ops, sizeof(*this)) == 0;
+}
+
+
+int dabInputSetbuf(void* args, int size)
+{
+ return 0;
+}
+
+
+int dabInputSetbitrate(dabInputOperations* ops, void* args, int bitrate)
+{
+ if (bitrate <= 0) {
+ etiLog.print(TcpLog::ERR, "Invalid bitrate (%i)\n", bitrate);
+ return -1;
+ }
+ if (ops->setbuf(args, bitrate * 3) == 0) {
+ return bitrate;
+ }
+ return -1;
+}
diff --git a/src/dabInput.h b/src/dabInput.h
new file mode 100644
index 0000000..245a162
--- /dev/null
+++ b/src/dabInput.h
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in
+ Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_H
+#define DAB_INPUT_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "TcpLog.h"
+extern TcpLog etiLog;
+
+
+struct dabInputOperations {
+ int (*init)(void** args);
+ int (*open)(void* args, const char* name);
+ int (*setbuf)(void* args, int size);
+ int (*read)(void* args, void* buffer, int size);
+ int (*lock)(void* args);
+ int (*unlock)(void* args);
+ int (*readFrame)(dabInputOperations* ops, void* args, void* buffer, int size);
+ int (*setBitrate)(dabInputOperations* ops, void* args, int bitrate);
+ int (*close)(void* args);
+ int (*clean)(void** args);
+ int (*rewind)(void* args);
+ bool operator==(const dabInputOperations&);
+};
+
+
+int dabInputSetbuf(void* args, int size);
+int dabInputSetbitrate(dabInputOperations* ops, void* args, int bitrate);
+
+
+#endif // DAB_INPUT_H
diff --git a/src/dabInputBridgeUdp.cpp b/src/dabInputBridgeUdp.cpp
new file mode 100644
index 0000000..a2ccf85
--- /dev/null
+++ b/src/dabInputBridgeUdp.cpp
@@ -0,0 +1,124 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputBridgeUdp.h"
+#include "dabInputUdp.h"
+#include "bridge.h"
+
+
+struct dabInputBridgeUdpData {
+ dabInputUdpData* udpData;
+ bridgeInfo* info;
+};
+
+
+struct dabInputOperations dabInputBridgeUdpOperations = {
+ dabInputBridgeUdpInit,
+ dabInputBridgeUdpOpen,
+ dabInputSetbuf,
+ NULL,
+ NULL,
+ NULL,
+ dabInputBridgeUdpRead,
+ dabInputSetbitrate,
+ dabInputBridgeUdpClose,
+ dabInputBridgeUdpClean,
+ NULL
+};
+
+
+int dabInputBridgeUdpInit(void** args)
+{
+ dabInputBridgeUdpData* input = new dabInputBridgeUdpData;
+ dabInputUdpInit((void**)&input->udpData);
+ input->info = new bridgeInfo;
+ bridgeInitInfo(input->info);
+ *args = input;
+
+ return 0;
+}
+
+
+int dabInputBridgeUdpOpen(void* args, const char* inputName)
+{
+ dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)args;
+
+ return dabInputUdpOpen(input->udpData, inputName);
+}
+
+
+int dabInputBridgeUdpRead(dabInputOperations* ops, void* args, void* buffer, int size)
+{
+ int nbBytes = 0;
+ dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)args;
+ dabInputFifoStats* stats = (dabInputFifoStats*)&input->udpData->stats;
+
+ stats->frameRecords[stats->frameCount].curSize = 0;
+ stats->frameRecords[stats->frameCount].maxSize = size;
+
+ if (input->udpData->packet->getLength() == 0) {
+ input->udpData->socket->receive(*input->udpData->packet);
+ }
+ while ((nbBytes = writePacket(input->udpData->packet->getData(),
+ input->udpData->packet->getLength(), buffer, size,
+ input->info))
+ != 0) {
+ stats->frameRecords[stats->frameCount].curSize = nbBytes;
+ input->udpData->socket->receive(*input->udpData->packet);
+ }
+
+ if (input->udpData->packet->getLength() != 0) {
+ stats->frameRecords[stats->frameCount].curSize = size;
+ }
+
+ if (++stats->frameCount == NB_RECORDS) {
+ etiLog.print(TcpLog::INFO, "Data subchannel usage: (%i)",
+ stats->id);
+ for (int i = 0; i < stats->frameCount; ++i) {
+ etiLog.print(TcpLog::INFO, " %i/%i",
+ stats->frameRecords[i].curSize,
+ stats->frameRecords[i].maxSize);
+ }
+ etiLog.print(TcpLog::INFO, "\n");
+ stats->frameCount = 0;
+ }
+ return size;
+}
+
+
+int dabInputBridgeUdpClose(void* args)
+{
+ dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)args;
+
+ return dabInputUdpClose(input->udpData);
+}
+
+
+int dabInputBridgeUdpClean(void** args)
+{
+ dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)(*args);
+ dabInputUdpClean((void**)&input->udpData);
+ delete input->info;
+ delete input;
+ return 0;
+}
+
+
diff --git a/src/dabInputBridgeUdp.h b/src/dabInputBridgeUdp.h
new file mode 100644
index 0000000..c75f838
--- /dev/null
+++ b/src/dabInputBridgeUdp.h
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_BRIDGE_UDP_H
+#define DAB_INPUT_BRIDGE_UDP_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+
+
+#ifdef HAVE_FORMAT_BRIDGE
+# ifdef HAVE_INPUT_UDP
+
+
+extern struct dabInputOperations dabInputBridgeUdpOperations;
+
+int dabInputBridgeUdpInit(void** args);
+int dabInputBridgeUdpOpen(void* args, const char* inputName);
+int dabInputBridgeUdpRead(dabInputOperations* ops, void* args, void* buffer, int size);
+int dabInputBridgeUdpClose(void* args);
+int dabInputBridgeUdpClean(void** args);
+
+
+# endif
+#endif
+
+
+#endif // DAB_INPUT_BRIDGE_UDP_H
diff --git a/src/dabInputDabplusFifo.cpp b/src/dabInputDabplusFifo.cpp
new file mode 100644
index 0000000..fdff5ad
--- /dev/null
+++ b/src/dabInputDabplusFifo.cpp
@@ -0,0 +1,186 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputDabplusFifo.h"
+#include "dabInputDabplusFile.h"
+#include "dabInputFifo.h"
+#include "dabInput.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifndef _WIN32
+# define O_BINARY 0
+#endif
+
+
+#ifdef HAVE_FORMAT_DABPLUS
+# ifdef HAVE_INPUT_FILE
+
+
+struct dabInputDabplusFifoData {
+ void* fifoData;
+ uint8_t* buffer;
+ size_t bufferSize;
+ size_t bufferIndex;
+ size_t bufferOffset;
+};
+
+
+struct dabInputOperations dabInputDabplusFifoOperations = {
+ dabInputDabplusFifoInit,
+ dabInputDabplusFifoOpen,
+ dabInputDabplusFifoSetbuf,
+ dabInputDabplusFifoRead,
+ dabInputDabplusFifoLock,
+ dabInputDabplusFifoUnlock,
+ dabInputDabplusFileReadFrame,
+ dabInputSetbitrate,
+ dabInputDabplusFifoClose,
+ dabInputDabplusFifoClean,
+ dabInputDabplusFifoRewind
+};
+
+
+int dabInputDabplusFifoInit(void** args)
+{
+ dabInputDabplusFifoData* data = new dabInputDabplusFifoData;
+
+ dabInputFifoInit(&data->fifoData);
+ data->buffer = NULL;
+ data->bufferSize = 0;
+ data->bufferIndex = 0;
+ data->bufferOffset = 0;
+
+ *args = data;
+}
+
+
+int dabInputDabplusFifoOpen(void* args, const char* filename)
+{
+ dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args;
+
+ return dabInputFifoOpen(data->fifoData, filename);
+}
+
+
+int dabInputDabplusFifoSetbuf(void* args, int size)
+{
+ dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args;
+
+ return dabInputFifoSetbuf(data->fifoData, size);
+}
+
+
+int dabInputDabplusFifoRead(void* args, void* buffer, int size)
+{
+ dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args;
+
+ if (data->bufferSize != size * 5) {
+ if (data->buffer != NULL) {
+ delete[] data->buffer;
+ }
+ data->buffer = new uint8_t[size * 5];
+ data->bufferSize = size * 5;
+ data->bufferIndex = 0;
+ }
+
+ if (data->bufferOffset < data->bufferSize) {
+ int ret = dabInputFifoRead(data->fifoData,
+ &data->buffer[data->bufferOffset],
+ data->bufferSize - data->bufferOffset);
+ if (ret < 0) {
+ return ret;
+ }
+ data->bufferOffset += ret;
+ if (data->bufferOffset != data->bufferSize) {
+ etiLog.print(TcpLog::CRIT, "ERROR: Incomplete DAB+ frame!\n");
+ return 0;
+ }
+ }
+
+ memcpy(buffer, &data->buffer[data->bufferIndex], size);
+ data->bufferIndex += size;
+ if (data->bufferIndex >= data->bufferSize) {
+ data->bufferIndex = 0;
+ data->bufferOffset = 0;
+ }
+ return size;
+}
+
+
+int dabInputDabplusFifoLock(void* args)
+{
+ dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args;
+
+ return dabInputFifoLock(data->fifoData);
+}
+
+
+int dabInputDabplusFifoUnlock(void* args)
+{
+ dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args;
+
+ return dabInputFifoUnlock(data->fifoData);
+}
+
+
+int dabInputDabplusFifoReadFrame(dabInputOperations* ops, void* args,
+ void* buffer, int size)
+{
+ dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args;
+
+ return ops->read(args, buffer, size);
+}
+
+
+int dabInputDabplusFifoClose(void* args)
+{
+ dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args;
+
+ return dabInputFifoClose(data->fifoData);
+}
+
+
+int dabInputDabplusFifoClean(void** args)
+{
+ dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args;
+
+ dabInputFifoClean(&data->fifoData);
+ delete data;
+
+ return 0;
+}
+
+
+int dabInputDabplusFifoRewind(void* args)
+{
+ dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args;
+
+ return dabInputFifoRewind(data->fifoData);
+}
+
+
+# endif
+#endif
diff --git a/src/dabInputDabplusFifo.h b/src/dabInputDabplusFifo.h
new file mode 100644
index 0000000..a02513a
--- /dev/null
+++ b/src/dabInputDabplusFifo.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_DABPLUS_FIFO_H
+#define DAB_INPUT_DABPLUS_FIFO_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#ifdef HAVE_FORMAT_DABPLUS
+# ifdef HAVE_INPUT_FIFO
+
+
+extern struct dabInputOperations dabInputDabplusFifoOperations;
+
+
+int dabInputDabplusFifoInit(void** args);
+int dabInputDabplusFifoOpen(void* args, const char* filename);
+int dabInputDabplusFifoSetbuf(void* args, int size);
+int dabInputDabplusFifoRead(void* args, void* buffer, int size);
+int dabInputDabplusFifoLock(void* args);
+int dabInputDabplusFifoUnlock(void* args);
+int dabInputDabplusFifoReadFrame(dabInputOperations* ops, void* args,
+ void* buffer, int size);
+int dabInputDabplusFifoClose(void* args);
+int dabInputDabplusFifoClean(void** args);
+int dabInputDabplusFifoRewind(void* args);
+
+
+# endif
+#endif
+
+
+#endif // DAB_INPUT_DABPLUS_FIFO_H
diff --git a/src/dabInputDabplusFile.cpp b/src/dabInputDabplusFile.cpp
new file mode 100644
index 0000000..8d46ea1
--- /dev/null
+++ b/src/dabInputDabplusFile.cpp
@@ -0,0 +1,176 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputDabplusFile.h"
+#include "dabInput.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+
+#ifndef _WIN32
+# define O_BINARY 0
+#endif
+
+
+#ifdef HAVE_FORMAT_DABPLUS
+# ifdef HAVE_INPUT_FILE
+
+
+struct dabInputOperations dabInputDabplusFileOperations = {
+ dabInputDabplusFileInit,
+ dabInputDabplusFileOpen,
+ dabInputSetbuf,
+ dabInputDabplusFileRead,
+ NULL,
+ NULL,
+ dabInputDabplusFileReadFrame,
+ dabInputSetbitrate,
+ dabInputDabplusFileClose,
+ dabInputDabplusFileClean,
+ dabInputDabplusFileRewind
+};
+
+
+int dabInputDabplusFileInit(void** args)
+{
+ dabInputDabplusFileData* data = new dabInputDabplusFileData;
+ data->file = -1;
+ data->buffer = NULL;
+ data->bufferSize = 0;
+ data->bufferIndex = 0;
+
+ *args = data;
+ return 0;
+}
+
+
+int dabInputDabplusFileOpen(void* args, const char* filename)
+{
+ dabInputDabplusFileData* data = (dabInputDabplusFileData*)args;
+ data->file = open(filename, O_RDONLY | O_BINARY);
+ if (data->file == -1) {
+ perror(filename);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int dabInputDabplusFileRead(void* args, void* buffer, int size)
+{
+ dabInputDabplusFileData* data = (dabInputDabplusFileData*)args;
+ if (data->bufferSize != size * 5) {
+ if (data->buffer == NULL) {
+ delete[] data->buffer;
+ }
+ data->buffer = new uint8_t[size * 5];
+ data->bufferSize = size * 5;
+ data->bufferIndex = 0;
+ }
+
+ if (data->bufferIndex + size > data->bufferSize) {
+ int ret = read(data->file, data->buffer, data->bufferSize);
+ if (ret != data->bufferSize) {
+ if (ret != 0) {
+ etiLog.print(TcpLog::CRIT, "ERROR: Incomplete DAB+ frame!\n");
+ }
+ return 0;
+ }
+ data->bufferIndex = 0;
+ }
+
+ memcpy(buffer, &data->buffer[data->bufferIndex], size);
+ data->bufferIndex += size;
+
+ return size;
+}
+
+
+int dabInputDabplusFileReadFrame(dabInputOperations* ops, void* args,
+ void* buffer, int size)
+{
+ //dabInputDabplusFileData* data = (dabInputDabplusFileData*)args;
+ int result;
+ uint8_t* dataOut = reinterpret_cast<uint8_t*>(buffer);
+
+ result = ops->read(args, dataOut, size);
+ if (result == -1) {
+ etiLog.print(TcpLog::CRIT, "ERROR: Can't read file\n");
+ perror("");
+ return -1;
+ }
+ if (result < size) {
+ int sizeOut = result;
+ etiLog.print(TcpLog::NOTICE, "reach end of file -> rewinding\n");
+ if (ops->rewind(args) == -1) {
+ etiLog.print(TcpLog::CRIT, "ERROR: Can't rewind file\n");
+ return -1;
+ }
+
+ result = ops->read(args, dataOut + sizeOut, size - sizeOut);
+ if (result == -1) {
+ etiLog.print(TcpLog::CRIT, "ERROR: Can't read file\n");
+ perror("");
+ return -1;
+ }
+
+ if (result < size) {
+ etiLog.print(TcpLog::CRIT, "ERROR: Not enought data in file\n");
+ return -1;
+ }
+ }
+
+ return size;
+}
+
+
+int dabInputDabplusFileClose(void* args)
+{
+ dabInputDabplusFileData* data = (dabInputDabplusFileData*)args;
+ if (data->file != -1) {
+ close(data->file);
+ }
+ return 0;
+}
+
+
+int dabInputDabplusFileClean(void** args)
+{
+ dabInputDabplusFileData* data = (dabInputDabplusFileData*)*args;
+ if (data->buffer != NULL) {
+ delete[] data->buffer;
+ }
+ delete data;
+ return 0;
+}
+
+
+int dabInputDabplusFileRewind(void* args)
+{
+ dabInputDabplusFileData* data = (dabInputDabplusFileData*)args;
+ return lseek(data->file, 0, SEEK_SET);
+}
+
+
+# endif
+#endif
diff --git a/src/dabInputDabplusFile.h b/src/dabInputDabplusFile.h
new file mode 100644
index 0000000..26a67a5
--- /dev/null
+++ b/src/dabInputDabplusFile.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_DABPLUS_FILE_H
+#define DAB_INPUT_DABPLUS_FILE_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdint.h>
+#include <unistd.h>
+
+
+#ifdef HAVE_FORMAT_DABPLUS
+# ifdef HAVE_INPUT_FILE
+
+
+extern struct dabInputOperations dabInputDabplusFileOperations;
+
+
+struct dabInputDabplusFileData {
+ int file;
+ uint8_t* buffer;
+ size_t bufferSize;
+ size_t bufferIndex;
+};
+
+
+int dabInputDabplusFileInit(void** args);
+int dabInputDabplusFileOpen(void* args, const char* filename);
+int dabInputDabplusFileRead(void* args, void* buffer, int size);
+int dabInputDabplusFileReadFrame(dabInputOperations* ops, void* args,
+ void* buffer, int size);
+int dabInputDabplusFileClose(void* args);
+int dabInputDabplusFileClean(void** args);
+int dabInputDabplusFileRewind(void* args);
+
+
+# endif
+#endif
+
+
+#endif // DAB_INPUT_DABPLUS_FILE_H
diff --git a/src/dabInputDmbFile.cpp b/src/dabInputDmbFile.cpp
new file mode 100644
index 0000000..a057764
--- /dev/null
+++ b/src/dabInputDmbFile.cpp
@@ -0,0 +1,161 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputDmbFile.h"
+#include "dabInputFifo.h"
+#include "Dmb.h"
+#include "UdpSocket.h"
+
+#include <string.h>
+#include <stdio.h>
+
+
+struct dabInputDmbFileData {
+ FILE* file;
+ Dmb* dmb;
+ dabInputFifoStats stats;
+ unsigned char buffer[188];
+ unsigned bufferLength;
+};
+
+
+struct dabInputOperations dabInputDmbFileOperations = {
+ dabInputDmbFileInit,
+ dabInputDmbFileOpen,
+ dabInputSetbuf,
+ NULL,
+ NULL,
+ NULL,
+ dabInputDmbFileRead,
+ dabInputSetbitrate,
+ dabInputDmbFileClose,
+ dabInputDmbFileClean,
+ NULL
+};
+
+
+int dabInputDmbFileInit(void** args)
+{
+ dabInputDmbFileData* input = new dabInputDmbFileData;
+ memset(&input->stats, 0, sizeof(input->stats));
+ input->stats.id = dabInputFifoData::nb++;
+ input->file = NULL;
+ input->bufferLength = 0;
+ input->dmb = new Dmb();
+ *args = input;
+
+ UdpSocket::init();
+ return 0;
+}
+
+
+int dabInputDmbFileOpen(void* args, const char* inputName)
+{
+ int returnCode = 0;
+ dabInputDmbFileData* input = (dabInputDmbFileData*)args;
+
+ input->file = fopen(inputName, "r");
+ if (input->file == NULL) {
+ perror(inputName);
+ returnCode = -1;
+ }
+
+ return returnCode;;
+}
+
+
+int dabInputDmbFileRead(dabInputOperations* ops, void* args, void* buffer, int size)
+{
+ int nbBytes = 0;
+ dabInputDmbFileData* input = (dabInputDmbFileData*)args;
+ dabInputFifoStats* stats = (dabInputFifoStats*)&input->stats;
+
+ input->stats.frameRecords[input->stats.frameCount].curSize = 0;
+ input->stats.frameRecords[input->stats.frameCount].maxSize = size;
+
+ if (input->bufferLength == 0) {
+ input->bufferLength = fread(input->buffer, 188, 1, input->file);
+ }
+/* while ((nbBytes = writePacket(input->packet->getData(),
+ input->packet->getLength(), buffer, size, input->info))
+ != 0) {
+ input->stats.frameRecords[input->stats.frameCount].curSize = nbBytes;
+ input->socket->receive(*input->packet);
+ }*/
+ while ((nbBytes = input->dmb->encode(input->buffer,
+ input->bufferLength * 188, buffer, size))
+ != 0) {
+ input->stats.frameRecords[input->stats.frameCount].curSize = nbBytes;
+ input->bufferLength = fread(input->buffer, 188, 1, input->file);
+ if (input->bufferLength == 0) {
+ etiLog.print(TcpLog::NOTICE, "reach end of file -> rewinding\n");
+ if (fseek(input->file, 0, SEEK_SET) == 0) {
+ input->bufferLength = fread(input->buffer, 188, 1, input->file);
+ }
+ }
+ //++mpgFrameNb;
+ }
+ //++dmbFrameNb;
+
+ if (input->bufferLength != 0) {
+ input->stats.frameRecords[input->stats.frameCount].curSize = size;
+ }
+
+ if (++stats->frameCount == NB_RECORDS) {
+ etiLog.print(TcpLog::INFO, "Data subchannel usage: (%i)",
+ stats->id);
+ for (int i = 0; i < stats->frameCount; ++i) {
+ etiLog.print(TcpLog::INFO, " %i/%i",
+ stats->frameRecords[i].curSize,
+ stats->frameRecords[i].maxSize);
+ }
+ etiLog.print(TcpLog::INFO, "\n");
+ stats->frameCount = 0;
+ }
+ return size;
+}
+
+
+int dabInputDmbFileClose(void* args)
+{
+ dabInputDmbFileData* input = (dabInputDmbFileData*)args;
+
+ if (input->file != NULL) {
+ if (fclose(input->file)) {
+ perror("");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+int dabInputDmbFileClean(void** args)
+{
+ dabInputDmbFileData* input = (dabInputDmbFileData*)(*args);
+ dabInputDmbFileClose(args);
+ delete input->dmb;
+ delete input;
+ return 0;
+}
+
+
diff --git a/src/dabInputDmbFile.h b/src/dabInputDmbFile.h
new file mode 100644
index 0000000..f77ab77
--- /dev/null
+++ b/src/dabInputDmbFile.h
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_DMB_FILE_H
+#define DAB_INPUT_DMB_FILE_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+
+
+#ifdef HAVE_FORMAT_DMB
+# ifdef HAVE_INPUT_FILE
+
+
+extern struct dabInputOperations dabInputDmbFileOperations;
+
+int dabInputDmbFileInit(void** args);
+int dabInputDmbFileOpen(void* args, const char* inputName);
+int dabInputDmbFileRead(dabInputOperations* ops, void* args, void* buffer, int size);
+int dabInputDmbFileClose(void* args);
+int dabInputDmbFileClean(void** args);
+
+
+# endif
+#endif
+
+
+#endif // DAB_INPUT_DMB_FILE_H
diff --git a/src/dabInputDmbUdp.cpp b/src/dabInputDmbUdp.cpp
new file mode 100644
index 0000000..935e925
--- /dev/null
+++ b/src/dabInputDmbUdp.cpp
@@ -0,0 +1,191 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputDmbUdp.h"
+#include "dabInputFifo.h"
+#include "Dmb.h"
+#include "UdpSocket.h"
+
+#include <string.h>
+#include <limits.h>
+
+
+#ifdef HAVE_FORMAT_DMB
+# ifdef HAVE_INPUT_UDP
+
+
+struct dabInputDmbUdpData {
+ UdpSocket* socket;
+ UdpPacket* packet;
+ Dmb* dmb;
+ dabInputFifoStats stats;
+};
+
+
+struct dabInputOperations dabInputDmbUdpOperations = {
+ dabInputDmbUdpInit,
+ dabInputDmbUdpOpen,
+ dabInputSetbuf,
+ NULL,
+ NULL,
+ NULL,
+ dabInputDmbUdpRead,
+ dabInputSetbitrate,
+ dabInputDmbUdpClose,
+ dabInputDmbUdpClean,
+ NULL
+};
+
+
+int dabInputDmbUdpInit(void** args)
+{
+ dabInputDmbUdpData* input = new dabInputDmbUdpData;
+ memset(&input->stats, 0, sizeof(input->stats));
+ input->stats.id = dabInputFifoData::nb++;
+ input->socket = new UdpSocket();
+ input->packet = new UdpPacket(2048);
+ input->dmb = new Dmb();
+ *args = input;
+
+ UdpSocket::init();
+ return 0;
+}
+
+
+int dabInputDmbUdpOpen(void* args, const char* inputName)
+{
+ int returnCode = 0;
+ char* address;
+ char* ptr;
+ long port;
+ address = strdup(inputName);
+ ptr = strchr(address, ':');
+ if (ptr == NULL) {
+ etiLog.print(TcpLog::ERR,
+ "\"%s\" is an invalid format for udp address: "
+ "should be [address]:port - > aborting\n", address);
+ returnCode = -1;
+ }
+ *(ptr++) = 0;
+ port = strtol(ptr, (char **)NULL, 10);
+ if ((port == LONG_MIN) || (port == LONG_MAX)) {
+ etiLog.print(TcpLog::ERR,
+ "can't convert port number in udp address %s\n",
+ address);
+ returnCode = -1;
+ }
+ if (port == 0) {
+ etiLog.print(TcpLog::ERR, "can't use port number 0 in udp address\n");
+ returnCode = -1;
+ }
+ dabInputDmbUdpData* input = (dabInputDmbUdpData*)args;
+ if (input->socket->create(port) == -1) {
+ etiLog.print(TcpLog::ERR, "can't set port %i on Dmb input (%s: %s)\n",
+ port, inetErrDesc, inetErrMsg);
+ returnCode = -1;
+ }
+
+ if (*address != 0) {
+ if (input->socket->joinGroup(address) == -1) {
+ etiLog.print(TcpLog::ERR,
+ "can't join multicast group %s (%s: %s)\n",
+ address, inetErrDesc, inetErrMsg);
+ returnCode = -1;
+ }
+ }
+
+ if (input->socket->setBlocking(false) == -1) {
+ etiLog.print(TcpLog::ERR, "can't set Dmb input socket in blocking mode "
+ "(%s: %s)\n", inetErrDesc, inetErrMsg);
+ returnCode = -1;
+ }
+
+ free(address);
+ etiLog.print(TcpLog::DBG, "check return code of create\n");
+ return returnCode;;
+}
+
+
+int dabInputDmbUdpRead(dabInputOperations* ops, void* args, void* buffer, int size)
+{
+ int nbBytes = 0;
+ dabInputDmbUdpData* input = (dabInputDmbUdpData*)args;
+ dabInputFifoStats* stats = (dabInputFifoStats*)&input->stats;
+
+ input->stats.frameRecords[input->stats.frameCount].curSize = 0;
+ input->stats.frameRecords[input->stats.frameCount].maxSize = size;
+
+ if (input->packet->getLength() == 0) {
+ input->socket->receive(*input->packet);
+ }
+/* while ((nbBytes = writePacket(input->packet->getData(),
+ input->packet->getLength(), buffer, size, input->info))
+ != 0) {
+ input->stats.frameRecords[input->stats.frameCount].curSize = nbBytes;
+ input->socket->receive(*input->packet);
+ }*/
+ while ((nbBytes = input->dmb->encode(input->packet->getData(),
+ input->packet->getLength(), buffer, size))
+ != 0) {
+ input->stats.frameRecords[input->stats.frameCount].curSize = nbBytes;
+ input->socket->receive(*input->packet);
+ //++mpgFrameNb;
+ }
+ //++dmbFrameNb;
+
+ if (input->packet->getLength() != 0) {
+ input->stats.frameRecords[input->stats.frameCount].curSize = size;
+ }
+
+ if (++stats->frameCount == NB_RECORDS) {
+ etiLog.print(TcpLog::INFO, "Data subchannel usage: (%i)",
+ stats->id);
+ for (int i = 0; i < stats->frameCount; ++i) {
+ etiLog.print(TcpLog::INFO, " %i/%i",
+ stats->frameRecords[i].curSize,
+ stats->frameRecords[i].maxSize);
+ }
+ etiLog.print(TcpLog::INFO, "\n");
+ stats->frameCount = 0;
+ }
+ return size;
+}
+
+
+int dabInputDmbUdpClose(void* args)
+{
+ return 0;
+}
+
+
+int dabInputDmbUdpClean(void** args)
+{
+ dabInputDmbUdpData* input = (dabInputDmbUdpData*)(*args);
+ delete input->socket;
+ delete input->packet;
+ delete input->dmb;
+ delete input;
+ return 0;
+}
+
+
+# endif
+#endif
diff --git a/src/dabInputDmbUdp.h b/src/dabInputDmbUdp.h
new file mode 100644
index 0000000..1dfcf35
--- /dev/null
+++ b/src/dabInputDmbUdp.h
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_DMB_UDP_H
+#define DAB_INPUT_DMB_UDP_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+
+
+#ifdef HAVE_FORMAT_DMB
+# ifdef HAVE_INPUT_UDP
+
+
+extern struct dabInputOperations dabInputDmbUdpOperations;
+
+int dabInputDmbUdpInit(void** args);
+int dabInputDmbUdpOpen(void* args, const char* inputName);
+int dabInputDmbUdpRead(dabInputOperations* ops, void* args, void* buffer, int size);
+int dabInputDmbUdpClose(void* args);
+int dabInputDmbUdpClean(void** args);
+
+
+# endif
+#endif
+
+
+#endif // DAB_INPUT_DMB_UDP_H
diff --git a/src/dabInputEnhancedFifo.cpp b/src/dabInputEnhancedFifo.cpp
new file mode 100644
index 0000000..b187aec
--- /dev/null
+++ b/src/dabInputEnhancedFifo.cpp
@@ -0,0 +1,64 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputEnhancedFifo.h"
+#include "dabInputPacketFile.h"
+#include "dabInputFifo.h"
+
+
+#ifdef HAVE_FORMAT_PACKET
+# ifdef HAVE_FORMAT_EPM
+# ifdef HAVE_INPUT_FIFO
+
+
+struct dabInputOperations dabInputEnhancedFifoOperations = {
+ dabInputEnhancedFifoInit,
+ dabInputFifoOpen,
+ dabInputFifoSetbuf,
+ dabInputFifoRead,
+ dabInputFifoLock,
+ dabInputFifoUnlock,
+ dabInputPacketFileRead,
+ dabInputSetbitrate,
+ dabInputFifoClose,
+ dabInputFifoClean,
+ dabInputFifoRewind
+};
+
+
+int dabInputEnhancedFifoInit(void** args)
+{
+ dabInputFifoInit(args);
+ dabInputFifoData* data = (dabInputFifoData*)*args;
+
+ data->packetData = new unsigned char[96];
+ data->enhancedPacketData = new unsigned char*[12];
+ for (int i = 0; i < 12; ++i) {
+ data->enhancedPacketData[i] = new unsigned char[204];
+ }
+
+ return 0;
+}
+
+
+# endif
+# endif
+#endif
diff --git a/src/dabInputEnhancedFifo.h b/src/dabInputEnhancedFifo.h
new file mode 100644
index 0000000..2479c88
--- /dev/null
+++ b/src/dabInputEnhancedFifo.h
@@ -0,0 +1,46 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_ENHANCED_FIFO_H
+#define DAB_INPUT_ENHANCED_FIFO_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+
+
+#ifdef HAVE_FORMAT_PACKET
+# ifdef HAVE_FORMAT_EPM
+# ifdef HAVE_INPUT_FIFO
+
+
+extern struct dabInputOperations dabInputEnhancedFifoOperations;
+int dabInputEnhancedFifoInit(void** args);
+
+
+# endif
+# endif
+#endif
+
+
+#endif // DAB_INPUT_ENHANCED_FIFO_H
diff --git a/src/dabInputEnhancedPacketFile.cpp b/src/dabInputEnhancedPacketFile.cpp
new file mode 100644
index 0000000..b3b48bf
--- /dev/null
+++ b/src/dabInputEnhancedPacketFile.cpp
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputEnhancedPacketFile.h"
+#include "dabInputPacketFile.h"
+#include "dabInputFile.h"
+
+
+struct dabInputOperations dabInputEnhancedPacketFileOperations = {
+ dabInputEnhancedFileInit,
+ dabInputFileOpen,
+ dabInputSetbuf,
+ dabInputFileRead,
+ NULL,
+ NULL,
+ dabInputPacketFileRead,
+ dabInputSetbitrate,
+ dabInputFileClose,
+ dabInputFileClean,
+ dabInputFileRewind
+};
+
+
+int dabInputEnhancedFileInit(void** args)
+{
+ dabInputFileInit(args);
+ dabInputFileData* data = (dabInputFileData*)*args;
+
+ data->enhancedPacketData = new unsigned char*[12];
+ for (int i = 0; i < 12; ++i) {
+ data->enhancedPacketData[i] = new unsigned char[204];
+ }
+
+ return 0;
+}
diff --git a/src/dabInputEnhancedPacketFile.h b/src/dabInputEnhancedPacketFile.h
new file mode 100644
index 0000000..0f419e0
--- /dev/null
+++ b/src/dabInputEnhancedPacketFile.h
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_ENHANCED_PACKET_FILE_H
+#define DAB_INPUT_ENHANCED_PACKET_FILE_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+
+
+#ifdef HAVE_FORMAT_PACKET
+# ifdef HAVE_FORMAT_EPM
+# ifdef HAVE_INPUT_FILE
+
+
+extern struct dabInputOperations dabInputEnhancedPacketFileOperations;
+
+int dabInputEnhancedFileInit(void** args);
+
+
+# endif
+# endif
+#endif
+
+
+#endif // DAB_INPUT_ENHANCED_PACKET_FILE_H
diff --git a/src/dabInputFifo.cpp b/src/dabInputFifo.cpp
new file mode 100644
index 0000000..a2c2ef7
--- /dev/null
+++ b/src/dabInputFifo.cpp
@@ -0,0 +1,513 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputFifo.h"
+#include "dabInputPacketFile.h"
+#include "dabInput.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+
+
+#ifdef HAVE_FORMAT_PACKET
+# ifdef HAVE_INPUT_FIFO
+
+
+int dabInputFifoData::nb = 0;
+
+
+struct dabInputOperations dabInputFifoOperations = {
+ dabInputFifoInit,
+ dabInputFifoOpen,
+ dabInputFifoSetbuf,
+ dabInputFifoRead,
+ dabInputFifoLock,
+ dabInputFifoUnlock,
+ dabInputPacketFileRead,
+ dabInputSetbitrate,
+ dabInputFifoClose,
+ dabInputFifoClean,
+ dabInputFifoRewind
+};
+
+
+int dabInputFifoInit(void** args)
+{
+ dabInputFifoData* data = new dabInputFifoData;
+ memset(data, 0, sizeof(*data));
+ data->stats.id = dabInputFifoData::nb++;
+ data->maxSize = 0;
+ data->curSize = 0;
+ data->head = 0;
+ data->tail = 0;
+ data->buffer = NULL;
+ data->packetData = NULL;
+ data->enhancedPacketData = NULL;
+ data->packetLength = 0;
+ data->enhancedPacketLength = 0;
+ data->enhancedPacketWaiting = 0;
+ data->full = false;
+ data->running = true;
+ data->thread = (pthread_t)NULL;
+#ifdef _WIN32
+ char semName[32];
+ sprintf(semName, "semInfo%i", data->stats.id);
+ data->semInfo = CreateSemaphore(NULL, 1, 1, semName);
+ if (data->semInfo == NULL) {
+ fprintf(stderr, "Can't init FIFO data semaphore %s\n", semName);
+ return -1;
+ }
+ sprintf(semName, "semBuffer%i", data->stats.id);
+ data->semBuffer = CreateSemaphore(NULL, 1, 1, semName);
+ if (data->semBuffer == NULL) {
+ fprintf(stderr, "Can't init FIFO buffer semaphore %s\n", semName);
+ return -1;
+ }
+ sprintf(semName, "semFull%i", data->stats.id);
+ data->semFull = CreateSemaphore(NULL, 1, 1, semName);
+ if (data->semFull == NULL) {
+ fprintf(stderr, "Can't init FIFO semaphore %s\n", semName);
+ return -1;
+ }
+#else
+ if (sem_init(&data->semInfo, 0, 1) == -1) {
+ perror("Can't init FIFO data semaphore");
+ return -1;
+ }
+ if (sem_init(&data->semBuffer, 0, 0) == -1) {
+ perror("Can't init fIFO buffer semaphore");
+ return -1;
+ }
+ if (sem_init(&data->semFull, 0, 0) == -1) {
+ perror("Can't init FIFO semaphore");
+ return -1;
+ }
+#endif
+
+ if (data->maxSize > 0) {
+#ifdef _WIN32
+ ReleaseSemaphore(data->semBuffer, 1, NULL);
+#else
+ sem_post(&data->semBuffer);
+#endif
+ }
+ *args = data;
+ return 0;
+}
+
+
+int dabInputFifoOpen(void* args, const char* filename)
+{
+ dabInputFifoData* data = (dabInputFifoData*)args;
+ data->file = open(filename, O_RDONLY | O_BINARY | O_NONBLOCK);
+ if (data->file == -1) {
+ perror(filename);
+ return -1;
+ }
+#ifdef _WIN32
+#else
+ int flags = fcntl(data->file, F_GETFL);
+ if (flags == -1) {
+ perror(filename);
+ return -1;
+ }
+ if (fcntl(data->file, F_SETFL, flags & ~O_NONBLOCK) == -1) {
+ perror(filename);
+ return -1;
+ }
+#endif
+
+#ifdef _WIN32
+ data->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)dabInputFifoThread, data, 0, NULL);
+ if (data->thread == NULL) {
+ fprintf(stderr, "Can't create FIFO child\n");
+ return -1;
+ }
+#else
+ if (pthread_create(&data->thread, NULL, dabInputFifoThread, data)) {
+ perror("Can't create FIFO child");
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
+
+int dabInputFifoSetbuf(void* args, int size)
+{
+ dabInputFifoData* data = (dabInputFifoData*)args;
+
+ if (data->maxSize > 0) {
+#ifdef _WIN32
+ WaitForSingleObject(data->semBuffer, INFINITE);
+#else
+ sem_wait(&data->semBuffer);
+#endif
+ }
+ if (data->buffer != NULL) {
+ delete data->buffer;
+ }
+ if (size == 0) {
+ size = 1024;
+ }
+ data->buffer = new unsigned char[size * 16];
+ data->maxSize = size * 16;
+#ifdef _WIN32
+ ReleaseSemaphore(data->semBuffer, 1, NULL);
+#else
+ sem_post(&data->semBuffer);
+#endif
+
+ return 0;
+}
+
+
+int dabInputFifoRead(void* args, void* buffer, int size)
+{
+ //fprintf(stderr, "INFO: read %i bytes\n", size);
+ dabInputFifoData* data = (dabInputFifoData*)args;
+ dabInputFifoStats* stats = &data->stats;
+ int head;
+ int tail;
+ int curSize;
+ int maxSize;
+#ifdef _WIN32
+ WaitForSingleObject(data->semInfo, INFINITE);
+#else
+ sem_wait(&data->semInfo);
+#endif
+ head = data->head;
+ tail = data->tail;
+ curSize = data->curSize;
+ maxSize = data->maxSize;
+#ifdef _WIN32
+ ReleaseSemaphore(data->semInfo, 1, NULL);
+#else
+ sem_post(&data->semInfo);
+#endif
+ //fprintf(stderr, "head: %i, tail: %i, curSize: %i\n", head, tail, curSize);
+ if (size > curSize) {
+ if (curSize == 0) {
+ stats->empty = true;
+ } else {
+ etiLog.print(TcpLog::WARNING, "Not enough data in FIFO buffer: (%i) %i/%i\n",
+ data->stats.id, curSize, size);
+ }
+ return 0;
+ }
+ if (head > tail) {
+ memcpy(buffer, data->buffer + tail, size);
+#ifdef _WIN32
+ WaitForSingleObject(data->semInfo, INFINITE);
+#else
+ sem_wait(&data->semInfo);
+#endif
+ data->tail += size;
+ data->curSize -= size;
+#ifdef _WIN32
+ ReleaseSemaphore(data->semInfo, 1, NULL);
+#else
+ sem_post(&data->semInfo);
+#endif
+ return size;
+ } else {
+ if (maxSize - tail >= size) {
+ memcpy(buffer, data->buffer + tail, size);
+#ifdef _WIN32
+ WaitForSingleObject(data->semInfo, INFINITE);
+#else
+ sem_wait(&data->semInfo);
+#endif
+ data->tail += size;
+ data->curSize -= size;
+#ifdef _WIN32
+ ReleaseSemaphore(data->semInfo, 1, NULL);
+#else
+ sem_post(&data->semInfo);
+#endif
+ return size;
+ } else {
+ memcpy(buffer, data->buffer + tail, maxSize - tail);
+#ifdef _WIN32
+ WaitForSingleObject(data->semInfo, INFINITE);
+#else
+ sem_wait(&data->semInfo);
+#endif
+ data->tail = 0;
+ data->curSize -= maxSize - tail;
+#ifdef _WIN32
+ ReleaseSemaphore(data->semInfo, 1, NULL);
+#else
+ sem_post(&data->semInfo);
+#endif
+ return maxSize - tail + dabInputFifoRead(data, (char*)buffer + maxSize - tail, size - (maxSize - tail));
+ }
+ }
+ return -1;
+}
+
+
+int dabInputFifoLock(void* args) {
+ dabInputFifoData* data = (dabInputFifoData*)args;
+ dabInputFifoStats* stats = &data->stats;
+
+ int maxSize;
+ int curSize;
+#ifdef _WIN32
+ WaitForSingleObject(data->semInfo, INFINITE);
+#else
+ sem_wait(&data->semInfo);
+#endif
+ maxSize = data->maxSize;
+ curSize = data->curSize;
+#ifdef _WIN32
+ ReleaseSemaphore(data->semInfo, 1, NULL);
+#else
+ sem_post(&data->semInfo);
+#endif
+
+ stats->bufferRecords[stats->bufferCount].curSize = curSize;
+ stats->bufferRecords[stats->bufferCount].maxSize = maxSize;
+
+ if (++stats->bufferCount == NB_RECORDS) {
+ etiLog.print(TcpLog::INFO, "FIFO buffer state: (%i)", stats->id);
+ for (int i = 0; i < stats->bufferCount; ++i) {
+ etiLog.print(TcpLog::INFO, " %i/%i",
+ stats->bufferRecords[i].curSize,
+ stats->bufferRecords[i].maxSize);
+ }
+ etiLog.print(TcpLog::INFO, "\n");
+
+ if (stats->full) {
+ etiLog.print(TcpLog::WARNING, "FIFO buffer full: (%i)\n",
+ data->stats.id);
+ stats->full = false;
+ }
+ if (stats->empty) {
+ etiLog.print(TcpLog::WARNING, "FIFO buffer empty: (%i)\n",
+ data->stats.id);
+ stats->empty = false;
+ }
+ if (stats->error) {
+ etiLog.print(TcpLog::ERR, "FIFO input read error: (%i)\n",
+ data->stats.id);
+ stats->error = false;
+ }
+ if (stats->input) {
+ etiLog.print(TcpLog::ERR, "FIFO input not connected: (%i)\n",
+ data->stats.id);
+ stats->input = false;
+ }
+
+ stats->bufferCount = 0;
+ }
+ return 0;
+}
+
+
+int dabInputFifoUnlock(void* args) {
+ dabInputFifoData* data = (dabInputFifoData*)args;
+ if (data->full) {
+#ifdef _WIN32
+ ReleaseSemaphore(data->semFull, 1, NULL);
+#else
+ sem_post(&data->semFull);
+#endif
+ }
+ return 0;
+}
+
+
+int dabInputFifoClose(void* args)
+{
+ dabInputFifoData* data = (dabInputFifoData*)args;
+ close(data->file);
+ return 0;
+}
+
+
+int dabInputFifoClean(void** args)
+{
+ dabInputFifoData* data = (dabInputFifoData*)*args;
+ data->running = false;
+ etiLog.print(TcpLog::DBG, "Wait FIFO child...\n");
+#ifdef WIN32
+ DWORD status;
+ for (int i = 0; i < 5; ++i) {
+ if (GetExitCodeThread(data->thread, &status)) {
+ break;
+ }
+ Sleep(100);
+ }
+ TerminateThread(data->thread, 1);
+ if (CloseHandle(data->thread) == 0) {
+ etiLog.print(TcpLog::DBG, "ERROR: Failed to close FIFO child thread\n");
+ }
+#else
+ if (data->thread != (pthread_t)NULL) {
+ if (pthread_join(data->thread, NULL)) {
+ etiLog.print(TcpLog::DBG, "ERROR: FIFO child thread had not exit normally\n");
+ }
+ }
+#endif
+ etiLog.print(TcpLog::DBG, "Done\n");
+#ifdef _WIN32
+ CloseHandle(data->semInfo);
+ CloseHandle(data->semFull);
+ CloseHandle(data->semBuffer);
+#else
+ sem_destroy(&data->semInfo);
+ sem_destroy(&data->semFull);
+ sem_destroy(&data->semBuffer);
+#endif
+ if (data->packetData != NULL) {
+ delete[] data->packetData;
+ }
+ if (data->enhancedPacketData != NULL) {
+ for (int i = 0; i < 12; ++i) {
+ if (data->enhancedPacketData[i] != NULL) {
+ delete[] data->enhancedPacketData[i];
+ }
+ }
+ delete[] data->enhancedPacketData;
+ }
+ delete data->buffer;
+ delete data;
+ return 0;
+}
+
+
+int dabInputFifoRewind(void* args)
+{
+ return -1;
+}
+
+
+void* dabInputFifoThread(void* args)
+{
+ dabInputFifoData* data = (dabInputFifoData*)args;
+ int head;
+ int tail;
+ int curSize;
+ int maxSize;
+ int ret;
+ while (data->running) {
+#ifdef _WIN32
+ WaitForSingleObject(data->semBuffer, INFINITE);
+ WaitForSingleObject(data->semInfo, INFINITE);
+#else
+ sem_wait(&data->semBuffer);
+ sem_wait(&data->semInfo);
+#endif
+ head = data->head;
+ tail = data->tail;
+ curSize = data->curSize;
+ maxSize = data->maxSize;
+#ifdef _WIN32
+ ReleaseSemaphore(data->semInfo, 1, NULL);
+#else
+ sem_post(&data->semInfo);
+#endif
+ //fprintf(stderr, "thread, head: %i, tail: %i, curSize: %i\n", head, tail, curSize);
+
+ if (curSize == maxSize) {
+ data->stats.full = true;
+ data->full = true;
+#ifdef _WIN32
+ WaitForSingleObject(data->semFull, INFINITE);
+#else
+ sem_wait(&data->semFull);
+#endif
+ } else if (head >= tail) { // 2 blocks
+ ret = read(data->file, data->buffer + head, maxSize - head);
+ if (ret == 0) {
+ data->stats.input = true;
+ data->full = true;
+#ifdef _WIN32
+ WaitForSingleObject(data->semFull, INFINITE);
+#else
+ sem_wait(&data->semFull);
+#endif
+ } else if (ret == -1) {
+ data->stats.error = true;
+ } else {
+#ifdef _WIN32
+ WaitForSingleObject(data->semInfo, INFINITE);
+#else
+ sem_wait(&data->semInfo);
+#endif
+ data->head += ret;
+ data->curSize += ret;
+ if (data->head == maxSize) {
+ data->head = 0;
+ }
+#ifdef _WIN32
+ ReleaseSemaphore(data->semInfo, 1, NULL);
+#else
+ sem_post(&data->semInfo);
+#endif
+ }
+ } else { // 1 block
+ ret = read(data->file, data->buffer + head, tail - head);
+ if (ret == 0) {
+ data->stats.input = true;
+ data->full = true;
+#ifdef _WIN32
+ WaitForSingleObject(data->semFull, INFINITE);
+#else
+ sem_wait(&data->semFull);
+#endif
+ } else if (ret == -1) {
+ data->stats.error = true;
+ } else {
+#ifdef _WIN32
+ WaitForSingleObject(data->semInfo, INFINITE);
+#else
+ sem_wait(&data->semInfo);
+#endif
+ data->head += ret;
+ data->curSize += ret;
+ if (data->head == maxSize) {
+ data->head = 0;
+ }
+#ifdef _WIN32
+ ReleaseSemaphore(data->semInfo, 1, NULL);
+#else
+ sem_post(&data->semInfo);
+#endif
+ }
+ }
+#ifdef _WIN32
+ ReleaseSemaphore(data->semBuffer, 1, NULL);
+#else
+ sem_post(&data->semBuffer);
+#endif
+ }
+ return NULL;
+}
+
+
+# endif
+#endif
diff --git a/src/dabInputFifo.h b/src/dabInputFifo.h
new file mode 100644
index 0000000..1844d1e
--- /dev/null
+++ b/src/dabInputFifo.h
@@ -0,0 +1,101 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_FIFO_H
+#define DAB_INPUT_FIFO_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInputFile.h"
+#include "TcpLog.h"
+extern TcpLog etiLog;
+
+
+#ifdef _WIN32
+# include <io.h>
+
+# define sem_t HANDLE
+# define O_NONBLOCK 0
+#else
+# include <semaphore.h>
+# define O_BINARY 0
+#endif
+
+
+#ifdef HAVE_FORMAT_PACKET
+# ifdef HAVE_INPUT_FIFO
+extern struct dabInputOperations dabInputFifoOperations;
+
+
+struct dabInputFifoStatRecord {
+ int curSize;
+ int maxSize;
+};
+
+
+#define NB_RECORDS 10
+struct dabInputFifoStats {
+ int id;
+ bool full;
+ bool empty;
+ bool error;
+ bool input;
+ int bufferCount;
+ dabInputFifoStatRecord bufferRecords[NB_RECORDS];
+ int frameCount;
+ dabInputFifoStatRecord frameRecords[NB_RECORDS];
+};
+
+
+struct dabInputFifoData : dabInputFileData {
+ static int nb;
+ int maxSize;
+ int curSize;
+ int head;
+ int tail;
+ dabInputFifoStats stats;
+ unsigned char* buffer;
+ pthread_t thread;
+ sem_t semInfo;
+ sem_t semBuffer;
+ sem_t semFull;
+ bool full;
+ bool running;
+};
+
+
+int dabInputFifoInit(void** args);
+int dabInputFifoOpen(void* args, const char* filename);
+int dabInputFifoSetbuf(void* args, int size);
+int dabInputFifoRead(void* args, void* buffer, int size);
+int dabInputFifoLock(void* args);
+int dabInputFifoUnlock(void* args);
+int dabInputFifoClose(void* args);
+int dabInputFifoClean(void** args);
+int dabInputFifoRewind(void* args);
+void* dabInputFifoThread(void* args);
+
+
+# endif
+#endif
+
+#endif // DAB_INPUT_FIFO_H
diff --git a/src/dabInputFile.cpp b/src/dabInputFile.cpp
new file mode 100644
index 0000000..330519a
--- /dev/null
+++ b/src/dabInputFile.cpp
@@ -0,0 +1,104 @@
+/*
+ Copyright (C) 2009,2011 Her Majesty the Queen in Right of Canada
+ (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputFile.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifndef _WIN32
+# define O_BINARY 0
+#endif
+
+
+int dabInputFileInit(void** args)
+{
+ dabInputFileData* data = new dabInputFileData;
+ data->file = -1;
+ data->parity = false;
+ data->packetLength = 0;
+ data->packetData = new unsigned char[96];
+ data->enhancedPacketData = NULL;
+ data->enhancedPacketLength = 0;
+ data->enhancedPacketWaiting = 0;
+
+ *args = data;
+ return 0;
+}
+
+
+int dabInputFileOpen(void* args, const char* filename)
+{
+ dabInputFileData* data = (dabInputFileData*)args;
+ data->file = open(filename, O_RDONLY | O_BINARY);
+ if (data->file == -1) {
+ perror(filename);
+ return -1;
+ }
+ return 0;
+}
+
+
+int dabInputFileRead(void* args, void* buffer, int size)
+{
+ dabInputFileData* data = (dabInputFileData*)args;
+ return read(data->file, buffer, size);
+}
+
+
+int dabInputFileClose(void* args)
+{
+ dabInputFileData* data = (dabInputFileData*)args;
+ if (data->file != -1) {
+ close(data->file);
+ }
+ return 0;
+}
+
+
+int dabInputFileClean(void** args)
+{
+ dabInputFileData* data = (dabInputFileData*)*args;
+ if (data->packetData != NULL) {
+ delete[] data->packetData;
+ }
+ if (data->enhancedPacketData != NULL) {
+ for (int i = 0; i < 12; ++i) {
+ if (data->enhancedPacketData[i] != NULL) {
+ delete[] data->enhancedPacketData[i];
+ }
+ }
+ delete[] data->enhancedPacketData;
+ }
+ delete data;
+ return 0;
+}
+
+
+int dabInputFileRewind(void* args)
+{
+ dabInputFileData* data = (dabInputFileData*)args;
+ return lseek(data->file, 0, SEEK_SET);
+}
+
+
diff --git a/src/dabInputFile.h b/src/dabInputFile.h
new file mode 100644
index 0000000..af2798b
--- /dev/null
+++ b/src/dabInputFile.h
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_FILE_H
+#define DAB_INPUT_FILE_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+struct dabInputFileData {
+ int file;
+ bool parity;
+ unsigned packetLength;
+ unsigned char* packetData;
+ unsigned char** enhancedPacketData;
+ unsigned enhancedPacketLength;
+ unsigned enhancedPacketWaiting;
+};
+
+
+int dabInputFileInit(void** args);
+int dabInputFileOpen(void* args, const char* filename);
+int dabInputFileRead(void* args, void* buffer, int size);
+int dabInputFileClose(void* args);
+int dabInputFileClean(void** args);
+int dabInputFileRewind(void* args);
+
+
+#endif // DAB_INPUT_FILE_H
diff --git a/src/dabInputMpegFifo.cpp b/src/dabInputMpegFifo.cpp
new file mode 100644
index 0000000..b34ee76
--- /dev/null
+++ b/src/dabInputMpegFifo.cpp
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputMpegFifo.h"
+#include "dabInputFifo.h"
+#include "dabInputMpegFile.h"
+
+
+#ifdef HAVE_FORMAT_MPEG
+# ifdef HAVE_INPUT_FIFO
+
+
+struct dabInputOperations dabInputMpegFifoOperations = {
+ dabInputFifoInit,
+ dabInputFifoOpen,
+ dabInputFifoSetbuf,
+ dabInputFifoRead,
+ dabInputFifoLock,
+ dabInputFifoUnlock,
+ dabInputMpegFileRead,
+ dabInputSetbitrate,
+ dabInputFifoClose,
+ dabInputFifoClean,
+ dabInputFifoRewind
+};
+
+
+# endif
+#endif
diff --git a/src/dabInputMpegFifo.h b/src/dabInputMpegFifo.h
new file mode 100644
index 0000000..e7b54dd
--- /dev/null
+++ b/src/dabInputMpegFifo.h
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_MPEG_FIFO_H
+#define DAB_INPUT_MPEG_FIFO_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#ifdef HAVE_FORMAT_MPEG
+# ifdef HAVE_INPUT_FIFO
+extern struct dabInputOperations dabInputMpegFifoOperations;
+# endif
+#endif
+
+
+#endif // DAB_INPUT_MPEG_FIFO_H
diff --git a/src/dabInputMpegFile.cpp b/src/dabInputMpegFile.cpp
new file mode 100644
index 0000000..0a06b2f
--- /dev/null
+++ b/src/dabInputMpegFile.cpp
@@ -0,0 +1,201 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputMpegFile.h"
+#include "dabInputFile.h"
+#include "mpeg.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+
+#ifdef HAVE_FORMAT_MPEG
+# ifdef HAVE_INPUT_FILE
+
+
+struct dabInputOperations dabInputMpegFileOperations = {
+ dabInputFileInit,
+ dabInputFileOpen,
+ dabInputSetbuf,
+ dabInputFileRead,
+ NULL,
+ NULL,
+ dabInputMpegFileRead,
+ dabInputMpegSetbitrate,
+ dabInputFileClose,
+ dabInputFileClean,
+ dabInputFileRewind
+};
+
+
+#define MPEG_FREQUENCY -2
+#define MPEG_PADDING -3
+#define MPEG_COPYRIGHT -4
+#define MPEG_ORIGINAL -5
+#define MPEG_EMPHASIS -6
+int checkDabMpegFrame(void* data) {
+ mpegHeader* header = (mpegHeader*)data;
+ unsigned long* headerData = (unsigned long*)data;
+ if ((*headerData & 0x0f0ffcff) == 0x0004fcff) return 0;
+ if ((*headerData & 0x0f0ffcff) == 0x0004f4ff) return 0;
+ if (getMpegFrequency(header) != 48000) {
+ if (getMpegFrequency(header) != 24000) {
+ return MPEG_FREQUENCY;
+ }
+ }
+ if (header->padding != 0) {
+ return MPEG_PADDING;
+ }
+ if (header->copyright != 0) {
+ return MPEG_COPYRIGHT;
+ }
+ if (header->original != 0) {
+ return MPEG_ORIGINAL;
+ }
+ if (header->emphasis != 0) {
+ return MPEG_EMPHASIS;
+ }
+ return -1;
+}
+
+
+int dabInputMpegFileRead(dabInputOperations* ops, void* args, void* buffer, int size)
+{
+ dabInputFileData* data = (dabInputFileData*)args;
+ int result;
+ bool rewind = false;
+READ_SUBCHANNEL:
+ if (data->parity) {
+ result = readData(data->file, buffer, size, 2);
+ data->parity = false;
+ return 0;
+ } else {
+ result = readMpegHeader(data->file, buffer, size);
+ if (result > 0) {
+ result = readMpegFrame(data->file, buffer, size);
+ if (result < 0 && getMpegFrequency(buffer) == 24000) {
+ data->parity = true;
+ result = size;
+ }
+ }
+ }
+ switch (result) {
+ case MPEG_BUFFER_UNDERFLOW:
+ etiLog.print(TcpLog::WARNING, "data underflow -> frame muted\n");
+ goto MUTE_SUBCHANNEL;
+ case MPEG_BUFFER_OVERFLOW:
+ etiLog.print(TcpLog::WARNING, "bitrate too high -> frame muted\n");
+ goto MUTE_SUBCHANNEL;
+ case MPEG_FILE_EMPTY:
+ if (rewind) {
+ etiLog.print(TcpLog::ERR, "file rewinded and still empty "
+ "-> frame muted\n");
+ goto MUTE_SUBCHANNEL;
+ } else {
+ rewind = true;
+ etiLog.print(TcpLog::NOTICE, "reach end of file -> rewinding\n");
+ lseek(data->file, 0, SEEK_SET);
+ goto READ_SUBCHANNEL;
+ }
+ case MPEG_FILE_ERROR:
+ etiLog.print(TcpLog::CRIT, "can't read file (%i) -> frame muted\n", errno);
+ perror("");
+ goto MUTE_SUBCHANNEL;
+ case MPEG_SYNC_NOT_FOUND:
+ etiLog.print(TcpLog::CRIT, "mpeg sync not found, maybe is not a valid file "
+ "-> frame muted\n");
+ goto MUTE_SUBCHANNEL;
+ case MPEG_INVALID_FRAME:
+ etiLog.print(TcpLog::CRIT, "file is not a valid mpeg file "
+ "-> frame muted\n");
+ goto MUTE_SUBCHANNEL;
+ default:
+ if (result < 0) {
+ etiLog.print(TcpLog::CRIT,
+ "unknown error (code = %i) -> frame muted\n",
+ result);
+MUTE_SUBCHANNEL:
+ memset(buffer, 0, size);
+ } else {
+ if (result < size) {
+ etiLog.print(TcpLog::WARNING, "bitrate too low from file "
+ "-> frame padded\n");
+ memset((char*)buffer + result, 0, size - result);
+ }
+ result = checkDabMpegFrame(buffer);
+ switch (result) {
+ case MPEG_FREQUENCY:
+ etiLog.print(TcpLog::ERR, "file has a frame with an invalid "
+ "frequency: %i, should be 48000 or 24000\n",
+ getMpegFrequency(buffer));
+ break;
+ case MPEG_PADDING:
+ etiLog.print(TcpLog::WARNING,
+ "file has a frame with padding bit set\n");
+ break;
+ case MPEG_COPYRIGHT:
+ etiLog.print(TcpLog::WARNING,
+ "file has a frame with copyright bit set\n");
+ break;
+ case MPEG_ORIGINAL:
+ etiLog.print(TcpLog::WARNING,
+ "file has a frame with original bit set\n");
+ break;
+ case MPEG_EMPHASIS:
+ etiLog.print(TcpLog::WARNING,
+ "file has a frame with emphasis bits set\n");
+ break;
+ default:
+ if (result < 0) {
+ etiLog.print(TcpLog::CRIT, "mpeg file has an invalid DAB "
+ "mpeg frame (unknown reason: %i)\n", result);
+ }
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+
+int dabInputMpegSetbitrate(dabInputOperations* ops, void* args, int bitrate)
+{
+ //dabInputFileData* data = (dabInputFileData*)args;
+ if (bitrate == 0) {
+ char buffer[4];
+
+ if (ops->readFrame(ops, args, buffer, 4) == 0) {
+ bitrate = getMpegBitrate(buffer);
+ } else {
+ bitrate = -1;
+ }
+ ops->rewind(args);
+ }
+ if (ops->setbuf(args, bitrate * 3) != 0) {
+ bitrate = -1;
+ }
+ return bitrate;
+}
+
+
+# endif
+#endif
diff --git a/src/dabInputMpegFile.h b/src/dabInputMpegFile.h
new file mode 100644
index 0000000..741a5f7
--- /dev/null
+++ b/src/dabInputMpegFile.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_MPEG_FILE_H
+#define DAB_INPUT_MPEG_FILE_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+
+
+#ifdef HAVE_FORMAT_MPEG
+# ifdef HAVE_INPUT_FILE
+extern struct dabInputOperations dabInputMpegFileOperations;
+
+int dabInputMpegFileRead(dabInputOperations* ops, void* args, void* buffer, int size);
+int dabInputMpegSetbitrate(dabInputOperations* ops, void* args, int bitrate);
+int checkDabMpegFrame(void* data);
+# endif
+#endif
+
+
+#endif // DAB_INPUT_MPEG_FILE_H
diff --git a/src/dabInputPacketFile.cpp b/src/dabInputPacketFile.cpp
new file mode 100644
index 0000000..65b5ebe
--- /dev/null
+++ b/src/dabInputPacketFile.cpp
@@ -0,0 +1,263 @@
+/*
+ Copyright (C) 2009, 2011 Her Majesty the Queen in Right of Canada
+ (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputPacketFile.h"
+#include "dabInputFile.h"
+#include "dabInputFifo.h"
+#include "ReedSolomon.h"
+
+#ifdef HAVE_FORMAT_PACKET
+# ifdef HAVE_INPUT_FILE
+
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+
+#ifdef _WIN32
+# pragma pack(push, 1)
+#endif
+struct packetHeader {
+ unsigned char addressHigh:2;
+ unsigned char last:1;
+ unsigned char first:1;
+ unsigned char continuityIndex:2;
+ unsigned char packetLength:2;
+ unsigned char addressLow;
+ unsigned char dataLength:7;
+ unsigned char command;
+}
+#ifdef _WIN32
+# pragma pack(pop)
+#else
+__attribute((packed))
+#endif
+;
+
+
+struct dabInputOperations dabInputPacketFileOperations = {
+ dabInputFileInit,
+ dabInputFileOpen,
+ dabInputSetbuf,
+ dabInputFileRead,
+ NULL,
+ NULL,
+ dabInputPacketFileRead,
+ dabInputSetbitrate,
+ dabInputFileClose,
+ dabInputFileClean,
+ dabInputFileRewind
+};
+
+
+int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer,
+ int size)
+{
+ dabInputFileData* data = (dabInputFileData*)args;
+ unsigned char* dataBuffer = (unsigned char*)buffer;
+ int written = 0;
+ int length;
+ packetHeader* header;
+ int indexRow;
+ int indexCol;
+
+ while (written < size) {
+ if (data->enhancedPacketWaiting > 0) {
+ *dataBuffer = 192 - data->enhancedPacketWaiting;
+ *dataBuffer /= 22;
+ *dataBuffer <<= 2;
+ *(dataBuffer++) |= 0x03;
+ *(dataBuffer++) = 0xfe;
+ indexCol = 188;
+ indexCol += (192 - data->enhancedPacketWaiting) / 12;
+ indexRow = 0;
+ indexRow += (192 - data->enhancedPacketWaiting) % 12;
+ for (int j = 0; j < 22; ++j) {
+ if (data->enhancedPacketWaiting == 0) {
+ *(dataBuffer++) = 0;
+ } else {
+ *(dataBuffer++) = data->enhancedPacketData[indexRow][indexCol];
+ if (++indexRow == 12) {
+ indexRow = 0;
+ ++indexCol;
+ }
+ --data->enhancedPacketWaiting;
+ }
+ }
+ written += 24;
+ if (data->enhancedPacketWaiting == 0) {
+ data->enhancedPacketLength = 0;
+ }
+ } else if (data->packetLength != 0) {
+ header = (packetHeader*)data->packetData;
+ if (written + data->packetLength > (unsigned)size) {
+ memset(dataBuffer, 0, 22);
+ dataBuffer[22] = 0x60;
+ dataBuffer[23] = 0x4b;
+ length = 24;
+ } else if (data->enhancedPacketData != NULL) {
+ if (data->enhancedPacketLength + data->packetLength
+ > (12 * 188)) {
+ memset(dataBuffer, 0, 22);
+ dataBuffer[22] = 0x60;
+ dataBuffer[23] = 0x4b;
+ length = 24;
+ } else {
+ memcpy(dataBuffer, data->packetData, data->packetLength);
+ length = data->packetLength;
+ data->packetLength = 0;
+ }
+ } else {
+ memcpy(dataBuffer, data->packetData, data->packetLength);
+ length = data->packetLength;
+ data->packetLength = 0;
+ }
+ if (data->enhancedPacketData != NULL) {
+ indexCol = data->enhancedPacketLength / 12;
+ indexRow = data->enhancedPacketLength % 12; // TODO Check if always 0
+ for (int j = 0; j < length; ++j) {
+ data->enhancedPacketData[indexRow][indexCol] = dataBuffer[j];
+ if (++indexRow == 12) {
+ indexRow = 0;
+ ++indexCol;
+ }
+ }
+ data->enhancedPacketLength += length;
+ if (data->enhancedPacketLength >= (12 * 188)) {
+ data->enhancedPacketLength = (12 * 188);
+ ReedSolomon encoder(204, 188);
+ for (int j = 0; j < 12; ++j) {
+ encoder.encode(data->enhancedPacketData[j], 188);
+ }
+ data->enhancedPacketWaiting = 192;
+ }
+ }
+ written += length;
+ dataBuffer += length;
+ } else {
+ int nbBytes = ops->read(args, dataBuffer, 3);
+ header = (packetHeader*)dataBuffer;
+ if (nbBytes == -1) {
+ if (errno == EAGAIN) goto END_PACKET;
+ perror("Packet file");
+ return -1;
+ } else if (nbBytes == 0) {
+ if (ops->rewind(args) == -1) {
+ goto END_PACKET;
+ }
+ continue;
+ } else if (nbBytes < 3) {
+ etiLog.print(TcpLog::ERR,
+ "Error while reading file for packet header; "
+ "read %i out of 3 bytes\n", nbBytes);
+ break;
+ }
+
+ length = header->packetLength * 24 + 24;
+ if (written + length > size) {
+ memcpy(data->packetData, header, 3);
+ ops->read(args, &data->packetData[3], length - 3);
+ data->packetLength = length;
+ continue;
+ }
+ if (data->enhancedPacketData != NULL) {
+ if (data->enhancedPacketLength + length > (12 * 188)) {
+ memcpy(data->packetData, header, 3);
+ ops->read(args, &data->packetData[3], length - 3);
+ data->packetLength = length;
+ continue;
+ }
+ }
+ nbBytes = ops->read(args, dataBuffer + 3, length - 3);
+ if (nbBytes == -1) {
+ perror("Packet file");
+ return -1;
+ } else if (nbBytes == 0) {
+ etiLog.print(TcpLog::NOTICE,
+ "Packet header read, but no data!\n");
+ if (ops->rewind(args) == -1) {
+ goto END_PACKET;
+ }
+ continue;
+ } else if (nbBytes < length - 3) {
+ etiLog.print(TcpLog::ERR, "Error while reading packet file; "
+ "read %i out of %i bytes\n", nbBytes, length - 3);
+ break;
+ }
+ if (data->enhancedPacketData != NULL) {
+ indexCol = data->enhancedPacketLength / 12;
+ indexRow = data->enhancedPacketLength % 12; // TODO Check if always 0
+ for (int j = 0; j < length; ++j) {
+ data->enhancedPacketData[indexRow][indexCol] = dataBuffer[j];
+ if (++indexRow == 12) {
+ indexRow = 0;
+ ++indexCol;
+ }
+ }
+ data->enhancedPacketLength += length;
+ if (data->enhancedPacketLength >= (12 * 188)) {
+ if (data->enhancedPacketLength > (12 * 188)) {
+ etiLog.print(TcpLog::ERR,
+ "Error, too much enhanced packet data!\n");
+ }
+ ReedSolomon encoder(204, 188);
+ for (int j = 0; j < 12; ++j) {
+ encoder.encode(data->enhancedPacketData[j], 188);
+ }
+ data->enhancedPacketWaiting = 192;
+ }
+ }
+ written += length;
+ dataBuffer += length;
+ }
+ }
+END_PACKET:
+ if (ops->read == dabInputFifoRead) {
+ dabInputFifoData* fifoData = (dabInputFifoData*)args;
+ dabInputFifoStats* fifoStats = (dabInputFifoStats*)&fifoData->stats;
+ fifoStats->frameRecords[fifoStats->frameCount].curSize = written;
+ fifoStats->frameRecords[fifoStats->frameCount].maxSize = size;
+ if (++fifoStats->frameCount == NB_RECORDS) {
+ etiLog.print(TcpLog::INFO, "Packet subchannel usage: (%i)",
+ fifoStats->id);
+ for (int i = 0; i < fifoStats->frameCount; ++i) {
+ etiLog.print(TcpLog::INFO, " %i/%i",
+ fifoStats->frameRecords[i].curSize,
+ fifoStats->frameRecords[i].maxSize);
+ }
+ etiLog.print(TcpLog::INFO, "\n");
+ fifoStats->frameCount = 0;
+ }
+ }
+ while (written < size) {
+ memset(dataBuffer, 0, 22);
+ dataBuffer[22] = 0x60;
+ dataBuffer[23] = 0x4b;
+ dataBuffer += 24;
+ written += 24;
+ }
+ return written;
+}
+
+
+# endif
+#endif
diff --git a/src/dabInputPacketFile.h b/src/dabInputPacketFile.h
new file mode 100644
index 0000000..9559ac1
--- /dev/null
+++ b/src/dabInputPacketFile.h
@@ -0,0 +1,46 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_PACKET_FILE_H
+#define DAB_INPUT_PACKET_FILE_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+
+
+#ifdef HAVE_FORMAT_PACKET
+# ifdef HAVE_INPUT_FILE
+
+
+extern struct dabInputOperations dabInputPacketFileOperations;
+
+int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer,
+ int size);
+
+
+# endif
+#endif
+
+
+#endif // DAB_INPUT_PACKET_FILE_H
diff --git a/src/dabInputPrbs.cpp b/src/dabInputPrbs.cpp
new file mode 100644
index 0000000..3b7a0dc
--- /dev/null
+++ b/src/dabInputPrbs.cpp
@@ -0,0 +1,146 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputPrbs.h"
+
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+
+
+#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)
+{
+ prbs_data* data = (prbs_data*)args;
+
+ if (*name != ':') {
+ etiLog.print(TcpLog::ERR,
+ "Sorry, PRBS address format is prbs://:polynomial.\n");
+ errno = EINVAL;
+ return -1;
+ }
+
+ long polynomial = strtol(++name, (char **)NULL, 10);
+ if ((polynomial == LONG_MIN) || (polynomial == LONG_MAX)) {
+ etiLog.print(TcpLog::ERR, "can't convert polynomial number %s\n", name);
+ errno = EINVAL;
+ return -1;
+ }
+ if (polynomial == 0) {
+ etiLog.print(TcpLog::ERR, "you must specify a polynomial number\n");
+ errno = EINVAL;
+ return -1;
+ }
+
+ data->polynomial = polynomial;
+ data->accum = 0;
+ gen_prbs_table(data);
+ gen_weight_table(data);
+ dabInputPrbsRewind(args);
+
+ return 0;
+}
+
+
+int dabInputPrbsRead(void* args, void* buffer, int size)
+{
+ prbs_data* data = (prbs_data*)args;
+ unsigned char* cbuffer = reinterpret_cast<unsigned char*>(buffer);
+
+ for(int i = 0; i < size; ++i) {
+ data->accum = update_prbs(args);
+ *(cbuffer++) = (unsigned char)(data->accum & 0xff);
+ }
+
+ 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)
+{
+ return bitrate;
+}
+
+
+int dabInputPrbsClose(void* args)
+{
+ return 0;
+}
+
+
+int dabInputPrbsClean(void** args)
+{
+ delete (prbs_data*)(*args);
+ 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
new file mode 100644
index 0000000..e51b79f
--- /dev/null
+++ b/src/dabInputPrbs.h
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_PRBS_H
+#define DAB_INPUT_PRBS_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+#include "prbs.h"
+
+#include <errno.h>
+
+
+#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);
+
+
+# endif
+#endif
+
+
+#endif // DAB_INPUT_PRBS_H
diff --git a/src/dabInputRawFifo.cpp b/src/dabInputRawFifo.cpp
new file mode 100644
index 0000000..b40e14d
--- /dev/null
+++ b/src/dabInputRawFifo.cpp
@@ -0,0 +1,193 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputRawFifo.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+
+#ifndef _WIN32
+# define O_BINARY 0
+#endif
+
+
+#ifdef HAVE_FORMAT_RAW
+# ifdef HAVE_INPUT_FILE
+
+
+struct dabInputOperations dabInputRawFifoOperations = {
+ dabInputRawFifoInit,
+ dabInputRawFifoOpen,
+ dabInputRawFifoSetbuf,
+ dabInputRawFifoRead,
+ NULL,
+ NULL,
+ dabInputRawFifoReadFrame,
+ dabInputSetbitrate,
+ dabInputRawFifoClose,
+ dabInputRawFifoClean,
+ dabInputRawFifoRewind
+};
+
+
+int dabInputRawFifoInit(void** args)
+{
+ dabInputRawFifoData* data = new dabInputRawFifoData;
+ data->file = -1;
+ data->buffer = NULL;
+ data->bufferSize = 0;
+ data->bufferOffset = 0;
+
+ *args = data;
+ return 0;
+}
+
+
+int dabInputRawFifoOpen(void* args, const char* filename)
+{
+ dabInputRawFifoData* data = (dabInputRawFifoData*)args;
+ data->file = open(filename, O_RDONLY | O_BINARY | O_NONBLOCK);
+ if (data->file == -1) {
+ perror(filename);
+ return -1;
+ }
+#ifdef _WIN32
+#else
+ int flags = fcntl(data->file, F_GETFL);
+ if (flags == -1) {
+ perror(filename);
+ return -1;
+ }
+ if (fcntl(data->file, F_SETFL, flags & ~O_NONBLOCK) == -1) {
+ perror(filename);
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
+
+int dabInputRawFifoSetbuf(void* args, int size)
+{
+ dabInputRawFifoData* data = (dabInputRawFifoData*)args;
+
+ if (size <= 0) {
+ return size;
+ }
+
+ if (data->bufferSize != size) {
+ if (data->buffer != NULL) {
+ delete[] data->buffer;
+ }
+ data->buffer = new uint8_t[size];
+ data->bufferSize = size;
+ data->bufferOffset = 0;
+ }
+
+ return 0;
+}
+
+
+int dabInputRawFifoRead(void* args, void* buffer, int size)
+{
+ dabInputRawFifoData* data = (dabInputRawFifoData*)args;
+
+ return read(data->file, buffer, size);
+}
+
+
+int dabInputRawFifoReadFrame(dabInputOperations* ops, void* args,
+ void* buffer, int size)
+{
+ dabInputRawFifoData* data = (dabInputRawFifoData*)args;
+ int result;
+
+ result = ops->read(args, data->buffer + data->bufferOffset, size - data->bufferOffset);
+ if (result == -1) {
+ etiLog.print(TcpLog::CRIT, "ERROR: Can't read fifo\n");
+ perror("");
+ return -1;
+ }
+
+ if (result + data->bufferOffset < size) {
+ data->bufferOffset += result;
+
+ etiLog.print(TcpLog::NOTICE, "reach end of fifo -> rewinding\n");
+ if (ops->rewind(args) == -1) {
+ etiLog.print(TcpLog::CRIT, "ERROR: Can't rewind fifo\n");
+ return -1;
+ }
+
+ result = ops->read(args, data->buffer + data->bufferOffset, size - data->bufferOffset);
+ if (result == -1) {
+ etiLog.print(TcpLog::CRIT, "ERROR: Can't read fifo\n");
+ perror("");
+ return -1;
+ }
+
+ if (result < size) {
+ etiLog.print(TcpLog::CRIT, "ERROR: Not enought data in fifo\n");
+ return 0;
+ }
+ }
+
+ memcpy(buffer, data->buffer, size);
+ data->bufferOffset = 0;
+
+ return size;
+}
+
+
+int dabInputRawFifoClose(void* args)
+{
+ dabInputRawFifoData* data = (dabInputRawFifoData*)args;
+
+ if (data->file != -1) {
+ close(data->file);
+ data->file = -1;
+ }
+ return 0;
+}
+
+
+int dabInputRawFifoClean(void** args)
+{
+ dabInputRawFifoData* data = (dabInputRawFifoData*)*args;
+ if (data->buffer != NULL) {
+ delete[] data->buffer;
+ }
+ delete data;
+ return 0;
+}
+
+
+int dabInputRawFifoRewind(void* args)
+{
+ dabInputRawFifoData* data = (dabInputRawFifoData*)args;
+ return lseek(data->file, 0, SEEK_SET);
+}
+
+
+# endif
+#endif
diff --git a/src/dabInputRawFifo.h b/src/dabInputRawFifo.h
new file mode 100644
index 0000000..4afe55d
--- /dev/null
+++ b/src/dabInputRawFifo.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_RAW_FIFO_H
+#define DAB_INPUT_RAW_FIFO_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "dabInput.h"
+
+#include <stdint.h>
+
+
+#ifdef HAVE_FORMAT_RAW
+# ifdef HAVE_INPUT_FILE
+
+
+extern struct dabInputOperations dabInputRawFifoOperations;
+
+int dabInputRawFifoInit(void** args);
+int dabInputRawFifoOpen(void* args, const char* filename);
+int dabInputRawFifoSetbuf(void* args, int size);
+int dabInputRawFifoRead(void* args, void* buffer, int size);
+int dabInputRawFifoReadFrame(dabInputOperations* ops, void* args,
+ void* buffer, int size);
+int dabInputRawFifoClose(void* args);
+int dabInputRawFifoClean(void** args);
+int dabInputRawFifoRewind(void* args);
+
+
+struct dabInputRawFifoData {
+ int file;
+ uint8_t* buffer;
+ size_t bufferSize;
+ size_t bufferOffset;
+};
+
+
+# endif
+#endif
+
+#endif // DAB_INPUT_RAW_FIFO_H
diff --git a/src/dabInputRawFile.cpp b/src/dabInputRawFile.cpp
new file mode 100644
index 0000000..17be73c
--- /dev/null
+++ b/src/dabInputRawFile.cpp
@@ -0,0 +1,59 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputRawFile.h"
+#include "dabInputFile.h"
+
+
+#ifdef HAVE_FORMAT_RAW
+# ifdef HAVE_INPUT_FILE
+
+
+struct dabInputOperations dabInputRawFileOperations = {
+ dabInputFileInit,
+ dabInputFileOpen,
+ dabInputSetbuf,
+ dabInputFileRead,
+ NULL,
+ NULL,
+ dabInputRawFileRead,
+ dabInputSetbitrate,
+ dabInputFileClose,
+ dabInputFileClean,
+ dabInputFileRewind
+};
+
+
+int dabInputRawFileRead(dabInputOperations* ops, void* args, void* buffer,
+ int size)
+{
+ int ret = ops->read(args, buffer, size);
+ if (ret == 0) {
+ etiLog.print(TcpLog::NOTICE, "reach end of raw file -> rewinding\n");
+ ops->rewind(args);
+ ret = ops->read(args, buffer, size);
+ }
+ return ret;
+}
+
+
+# endif
+#endif
diff --git a/src/dabInputRawFile.h b/src/dabInputRawFile.h
new file mode 100644
index 0000000..e75f962
--- /dev/null
+++ b/src/dabInputRawFile.h
@@ -0,0 +1,45 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_RAW_FILE_H
+#define DAB_INPUT_RAW_FILE_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+
+
+#ifdef HAVE_FORMAT_RAW
+# ifdef HAVE_INPUT_FILE
+
+
+extern struct dabInputOperations dabInputRawFileOperations;
+
+int dabInputRawFileRead(dabInputOperations* ops, void* args, void* buffer,
+ int size);
+
+
+# endif
+#endif
+
+#endif // DAB_INPUT_RAW_FILE_H
diff --git a/src/dabInputSlip.cpp b/src/dabInputSlip.cpp
new file mode 100644
index 0000000..7663d2c
--- /dev/null
+++ b/src/dabInputSlip.cpp
@@ -0,0 +1,408 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputSlip.h"
+#include "dabInputFifo.h"
+#include "TcpServer.h"
+#include "UdpSocket.h"
+#include "bridge.h"
+
+#include <signal.h>
+#include <string.h>
+#include <limits.h>
+
+
+#ifdef _WIN32
+# include <io.h>
+
+# define sem_t HANDLE
+# define O_NONBLOCK 0
+#else
+# include <semaphore.h>
+# define O_BINARY 0
+#endif
+
+
+struct dabInputSlipData {
+ TcpServer* server;
+ UdpPacket** packets;
+ UdpPacket* buffer;
+ bridgeInfo* info;
+ dabInputFifoStats stats;
+ pthread_t thread;
+ sem_t semWrite;
+ sem_t semQueue;
+ bool reading;
+ volatile int nbPackets;
+ volatile int queueSize;
+ volatile int packetSize;
+};
+
+
+struct dabInputOperations dabInputSlipOperations = {
+ dabInputSlipInit,
+ dabInputSlipOpen,
+ dabInputSlipSetbuf,
+ dabInputSlipRead,
+ NULL,
+ NULL,
+ dabInputSlipReadFrame,
+ dabInputSetbitrate,
+ dabInputSlipClose,
+ dabInputSlipClean,
+ NULL
+};
+
+
+int dabInputSlipInit(void** args)
+{
+ dabInputSlipData* data = new dabInputSlipData;
+ memset(&data->stats, 0, sizeof(data->stats));
+ data->stats.id = dabInputFifoData::nb++;
+ data->server = new TcpServer();
+ data->packetSize = 1500;
+ data->queueSize = 10;
+ data->packets = new UdpPacket*[data->queueSize];
+ for (int i = 0; i < data->queueSize; ++i) {
+ data->packets[i] = new UdpPacket(data->packetSize);
+ }
+ data->buffer = new UdpPacket(data->packetSize);
+ data->nbPackets = 0;
+ data->info = new bridgeInfo;
+ data->thread = (pthread_t)NULL;
+ bridgeInitInfo(data->info);
+
+#ifdef _WIN32
+ char semName[32];
+ sprintf(semName, "semWrite%i", data->stats.id);
+ data->semWrite = CreateSemaphore(NULL, 1, 1, semName);
+ if (data->semWrite == NULL) {
+ fprintf(stderr, "Can't init SLIP data write semaphore %s\n", semName);
+ return -1;
+ }
+ sprintf(semName, "semQueue%i", data->stats.id);
+ data->semQueue = CreateSemaphore(NULL, 1, 1, semName);
+ if (data->semQueue == NULL) {
+ fprintf(stderr, "Can't init SLIP data index semaphore %s\n", semName);
+ return -1;
+ }
+#else
+ if (sem_init(&data->semWrite, 0, data->queueSize) == -1) {
+ perror("Can't init SLIP data write semaphore");
+ return -1;
+ }
+ if (sem_init(&data->semQueue, 0, 1) == -1) {
+ perror("Can't init SLIP data index semaphore");
+ return -1;
+ }
+#endif
+ data->reading = false;
+
+ *args = data;
+ return 0;
+}
+
+
+void* dabInputSlipThread(void* args)
+{
+ dabInputSlipData* data = (dabInputSlipData*)args;
+ TcpSocket* client;
+
+ while ((client = data->server->accept()) != NULL) {
+ int size = 0;
+ etiLog.print(TcpLog::INFO, "SLIP server got a new client.\n");
+
+#ifdef _WIN32
+ WaitForSingleObject(data->semWrite, INFINITE);
+ WaitForSingleObject(data->semQueue, INFINITE);
+#else
+ sem_wait(&data->semWrite);
+ sem_wait(&data->semQueue);
+#endif
+ UdpPacket* packet = data->packets[data->nbPackets];
+#ifdef _WIN32
+ ReleaseSemaphore(data->semQueue, 1, NULL);
+#else
+ sem_post(&data->semQueue);
+#endif
+
+ while ((size = client->read(packet->getData(), packet->getSize()))
+ > 0) {
+ packet->setLength(size);
+#ifdef _WIN32
+ WaitForSingleObject(data->semQueue, INFINITE);
+#else
+ sem_wait(&data->semQueue);
+#endif
+ data->nbPackets++;
+#ifdef _WIN32
+ ReleaseSemaphore(data->semQueue, 1, NULL);
+#else
+ sem_post(&data->semQueue);
+#endif
+
+#ifdef _WIN32
+ WaitForSingleObject(data->semWrite, INFINITE);
+ WaitForSingleObject(data->semQueue, INFINITE);
+#else
+ sem_wait(&data->semWrite);
+ sem_wait(&data->semQueue);
+#endif
+ packet = data->packets[data->nbPackets];
+#ifdef _WIN32
+ ReleaseSemaphore(data->semQueue, 1, NULL);
+#else
+ sem_post(&data->semQueue);
+#endif
+ }
+ etiLog.print(TcpLog::INFO, "SLIP server client deconnected.\n");
+ client->close();
+ }
+ etiLog.print(TcpLog::ERR, "SLIP thread can't accept new client (%s)\n",
+ inetErrDesc, inetErrMsg);
+
+ return NULL;
+}
+
+
+int dabInputSlipOpen(void* args, const char* inputName)
+{
+ const char* address;
+ long port;
+ address = strchr(inputName, ':');
+ if (address == NULL) {
+ etiLog.print(TcpLog::ERR, "\"%s\" SLIP address format is invalid: "
+ "should be [address]:port - > aborting\n", inputName);
+ return -1;
+ }
+ ++address;
+ port = strtol(address, (char **)NULL, 10);
+ if ((port == LONG_MIN) || (port == LONG_MAX)) {
+ etiLog.print(TcpLog::ERR, "can't convert port number in SLIP address %s\n",
+ address);
+ return -1;
+ }
+ if (port == 0) {
+ etiLog.print(TcpLog::ERR, "can't use port number 0 in SLIP address\n");
+ return -1;
+ }
+ dabInputSlipData* data = (dabInputSlipData*)args;
+ if (data->server->create(port) == -1) {
+ etiLog.print(TcpLog::ERR, "can't set port %i on SLIP input (%s: %s)\n",
+ port, inetErrDesc, inetErrMsg);
+ return -1;
+ }
+
+ if (data->server->listen() == -1) {
+ etiLog.print(TcpLog::ERR, "can't listen on SLIP socket(%s: %s)\n",
+ inetErrDesc, inetErrMsg);
+ return -1;
+ }
+#ifdef _WIN32
+ data->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)dabInputSlipThread, data, 0, NULL);
+ if (data->thread == NULL) {
+ fprintf(stderr, "Can't create SLIP child");
+ return -1;
+ }
+#else
+ if (pthread_create(&data->thread, NULL, dabInputSlipThread, data)) {
+ perror("Can't create SLIP child");
+ return -1;
+ }
+#endif
+
+ etiLog.print(TcpLog::DBG, "check return code of create\n");
+ return 0;
+}
+
+
+int dabInputSlipSetbuf(void* args, int size)
+{
+ dabInputSlipData* data = (dabInputSlipData*)args;
+
+ if (size <= 10) {
+ return -1;
+ }
+
+ data->packetSize = size - 10;
+ if (data->packets == NULL) {
+ data->packets = new UdpPacket*[data->queueSize];
+ }
+ for (int i = 0; i < data->queueSize; ++i) {
+ if (data->packets[i] == NULL) {
+ data->packets[i] = new UdpPacket(data->packetSize);
+ } else {
+ data->packets[i]->setSize(data->packetSize);
+ }
+ }
+ if (data->buffer == NULL) {
+ data->buffer = new UdpPacket(data->packetSize);
+ } else {
+ data->buffer->setSize(data->packetSize);
+ }
+
+ return 0;
+}
+
+
+int dabInputSlipRead(void* args, void* buffer, int size)
+{
+ dabInputSlipData* data = (dabInputSlipData*)args;
+
+ if (data->nbPackets > 0) { // data ready
+ UdpPacket* temp;
+ temp = data->buffer;
+ data->buffer = data->packets[0];
+
+#ifdef _WIN32
+ WaitForSingleObject(data->semQueue, INFINITE);
+#else
+ sem_wait(&data->semQueue);
+#endif
+ for (int i = 1; i < data->queueSize; ++i) {
+ data->packets[i - 1] = data->packets[i];
+ }
+ data->packets[data->queueSize - 1] = temp;
+ --data->nbPackets;
+#ifdef _WIN32
+ ReleaseSemaphore(data->semQueue, 1, NULL);
+ ReleaseSemaphore(data->semWrite, 1, NULL);
+#else
+ sem_post(&data->semQueue);
+ sem_post(&data->semWrite);
+#endif
+ } else {
+ data->buffer->setLength(0);
+ }
+
+ return data->buffer->getLength();
+}
+
+
+int dabInputSlipReadFrame(dabInputOperations* ops, void* args, void* buffer, int size)
+{
+ int nbBytes = 0;
+ dabInputSlipData* data = (dabInputSlipData*)args;
+ dabInputFifoStats* stats = (dabInputFifoStats*)&data->stats;
+
+#ifdef _WIN32
+ WaitForSingleObject(data->semQueue, INFINITE);
+#else
+ sem_wait(&data->semQueue);
+#endif
+ stats->bufferRecords[stats->bufferCount].curSize = data->nbPackets;
+ stats->bufferRecords[stats->bufferCount].maxSize = data->queueSize;
+#ifdef _WIN32
+ ReleaseSemaphore(data->semQueue, 1, NULL);
+#else
+ sem_post(&data->semQueue);
+#endif
+ if (++stats->bufferCount == NB_RECORDS) {
+ etiLog.print(TcpLog::INFO, "SLIP buffer state: (%i)", stats->id);
+ for (int i = 0; i < stats->bufferCount; ++i) {
+ etiLog.print(TcpLog::INFO, " %i/%i",
+ stats->bufferRecords[i].curSize,
+ stats->bufferRecords[i].maxSize);
+ }
+ etiLog.print(TcpLog::INFO, "\n");
+
+ stats->bufferCount = 0;
+ }
+
+ data->stats.frameRecords[data->stats.frameCount].curSize = 0;
+ data->stats.frameRecords[data->stats.frameCount].maxSize = size;
+
+ if (data->buffer->getLength() == 0) {
+ ops->read(args, NULL, 0);
+ }
+ while ((nbBytes = writePacket(data->buffer->getData(),
+ data->buffer->getLength(), buffer, size, data->info))
+ != 0) {
+ data->stats.frameRecords[data->stats.frameCount].curSize = nbBytes;
+ ops->read(args, NULL, 0);
+ }
+
+ if (data->buffer->getLength() != 0) {
+ data->stats.frameRecords[data->stats.frameCount].curSize = size;
+ }
+
+ if (++stats->frameCount == NB_RECORDS) {
+ etiLog.print(TcpLog::INFO, "Data subchannel usage: (%i)",
+ stats->id);
+ for (int i = 0; i < stats->frameCount; ++i) {
+ etiLog.print(TcpLog::INFO, " %i/%i",
+ stats->frameRecords[i].curSize,
+ stats->frameRecords[i].maxSize);
+ }
+ etiLog.print(TcpLog::INFO, "\n");
+ stats->frameCount = 0;
+ }
+ return size;
+}
+
+
+int dabInputSlipClose(void* args)
+{
+ dabInputSlipData* data = (dabInputSlipData*)args;
+ data->server->close();
+#ifdef WIN32
+ DWORD status;
+ for (int i = 0; i < 5; ++i) {
+ if (GetExitCodeThread(data->thread, &status)) {
+ break;
+ }
+ Sleep(100);
+ }
+ TerminateThread(data->thread, 1);
+#else
+ if (data->thread != (pthread_t)NULL) {
+ pthread_kill(data->thread, SIGPIPE);
+ }
+#endif
+ return 0;
+}
+
+
+int dabInputSlipClean(void** args)
+{
+ dabInputSlipData* data = (dabInputSlipData*)(*args);
+#ifdef _WIN32
+ CloseHandle(data->thread);
+ CloseHandle(data->semWrite);
+ CloseHandle(data->semQueue);
+#else
+ sem_destroy(&data->semWrite);
+ sem_destroy(&data->semQueue);
+#endif
+ for (int i = 0; i < data->queueSize; ++i) {
+ if (data->packets[i] != NULL) {
+ delete data->packets[i];
+ }
+ }
+ delete []data->packets;
+ delete data->buffer;
+ delete data->server;
+ delete data->info;
+ delete data;
+ return 0;
+}
+
+
diff --git a/src/dabInputSlip.h b/src/dabInputSlip.h
new file mode 100644
index 0000000..bcaf0d1
--- /dev/null
+++ b/src/dabInputSlip.h
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_SLIP_H
+#define DAB_INPUT_SLIP_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+
+
+#ifdef HAVE_FORMAT_BRIDGE
+# ifdef HAVE_INPUT_SLIP
+
+
+extern struct dabInputOperations dabInputSlipOperations;
+
+int dabInputSlipInit(void** args);
+void* dabInputSlipThread(void* args);
+int dabInputSlipOpen(void* args, const char* inputName);
+int dabInputSlipSetbuf(void* args, int size);
+int dabInputSlipRead(void* args, void* buffer, int size);
+int dabInputSlipReadFrame(dabInputOperations* ops, void* args, void* buffer, int size);
+int dabInputSlipClose(void* args);
+int dabInputSlipClean(void** args);
+
+
+# endif
+#endif
+
+
+#endif // DAB_INPUT_SLIP_H
diff --git a/src/dabInputTest.cpp b/src/dabInputTest.cpp
new file mode 100644
index 0000000..78adaa8
--- /dev/null
+++ b/src/dabInputTest.cpp
@@ -0,0 +1,105 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputTest.h"
+
+#include <string.h>
+#ifdef _WIN32
+#else
+# include <arpa/inet.h>
+#endif
+
+
+#ifdef HAVE_FORMAT_RAW
+# ifdef HAVE_INPUT_TEST
+
+
+struct dabInputTestData {
+ unsigned long counter;
+};
+
+
+struct dabInputOperations dabInputTestOperations = {
+ dabInputTestInit,
+ dabInputTestOpen,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ dabInputTestRead,
+ dabInputTestSetbitrate,
+ dabInputTestClose,
+ dabInputTestClean,
+ NULL
+};
+
+
+int dabInputTestInit(void** args)
+{
+ dabInputTestData* input = new dabInputTestData;
+ memset(input, 0, sizeof(*input));
+ input->counter = 0;
+ *args = input;
+ return 0;
+}
+
+
+int dabInputTestOpen(void* args, const char* inputName)
+{
+ return 0;
+}
+
+
+int dabInputTestRead(dabInputOperations* ops, void* args, void* buffer, int size)
+{
+ dabInputTestData* input = (dabInputTestData*)args;
+ char* data = (char*)buffer;
+
+ *((long*)buffer) = htonl(input->counter++);
+ for (int i = sizeof(input->counter); i < size; ++i) {
+ data[i] = i;
+ }
+ return size;
+}
+
+
+int dabInputTestSetbitrate(dabInputOperations* ops, void* args, int bitrate)
+{
+ return bitrate;
+}
+
+
+int dabInputTestClose(void* args)
+{
+ return 0;
+}
+
+
+int dabInputTestClean(void** args)
+{
+ dabInputTestData* input = (dabInputTestData*)(*args);
+ delete input;
+ return 0;
+}
+
+
+# endif
+#endif
diff --git a/src/dabInputTest.h b/src/dabInputTest.h
new file mode 100644
index 0000000..5e21e80
--- /dev/null
+++ b/src/dabInputTest.h
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_TEST_H
+#define DAB_INPUT_TEST_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+
+
+#ifdef HAVE_FORMAT_RAW
+# ifdef HAVE_INPUT_TEST
+
+
+extern struct dabInputOperations dabInputTestOperations;
+
+int dabInputTestInit(void** args);
+int dabInputTestOpen(void* args, const char* inputName);
+int dabInputTestRead(dabInputOperations* ops, void* args, void* buffer, int size);
+int dabInputTestSetbitrate(dabInputOperations* ops, void* args, int bitrate);
+int dabInputTestClose(void* args);
+int dabInputTestClean(void** args);
+
+
+# endif
+#endif
+
+
+#endif // DAB_INPUT_TEST_H
diff --git a/src/dabInputUdp.cpp b/src/dabInputUdp.cpp
new file mode 100644
index 0000000..b128584
--- /dev/null
+++ b/src/dabInputUdp.cpp
@@ -0,0 +1,189 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabInputUdp.h"
+
+#include <string.h>
+#include <limits.h>
+
+
+#ifdef __MINGW32__
+# define bzero(s, n) memset(s, 0, n)
+#endif
+
+#ifdef HAVE_FORMAT_RAW
+# ifdef HAVE_INPUT_UDP
+
+
+struct dabInputOperations dabInputUdpOperations = {
+ dabInputUdpInit,
+ dabInputUdpOpen,
+ dabInputSetbuf,
+ NULL,
+ NULL,
+ NULL,
+ dabInputUdpRead,
+ dabInputSetbitrate,
+ dabInputUdpClose,
+ dabInputUdpClean,
+ NULL
+};
+
+
+int dabInputUdpInit(void** args)
+{
+ dabInputUdpData* input = new dabInputUdpData;
+ memset(&input->stats, 0, sizeof(input->stats));
+ input->stats.id = dabInputFifoData::nb++;
+ input->socket = new UdpSocket();
+ input->packet = new UdpPacket(2048);
+ *args = input;
+
+ UdpSocket::init();
+ return 0;
+}
+
+
+int dabInputUdpOpen(void* args, const char* inputName)
+{
+ int returnCode = 0;
+ char* address;
+ char* ptr;
+ long port;
+ address = strdup(inputName);
+ ptr = strchr(address, ':');
+ if (ptr == NULL) {
+ etiLog.print(TcpLog::ERR,
+ "\"%s\" is an invalid format for udp address: "
+ "should be [address]:port - > aborting\n", address);
+ returnCode = -1;
+ }
+ *(ptr++) = 0;
+ port = strtol(ptr, (char **)NULL, 10);
+ if ((port == LONG_MIN) || (port == LONG_MAX)) {
+ etiLog.print(TcpLog::ERR,
+ "can't convert port number in udp address %s\n",
+ address);
+ returnCode = -1;
+ }
+ if (port == 0) {
+ etiLog.print(TcpLog::ERR, "can't use port number 0 in udp address\n");
+ returnCode = -1;
+ }
+ dabInputUdpData* input = (dabInputUdpData*)args;
+ if (input->socket->create(port) == -1) {
+ etiLog.print(TcpLog::ERR, "can't set port %i on Udp input (%s: %s)\n",
+ port, inetErrDesc, inetErrMsg);
+ returnCode = -1;
+ }
+
+ if (*address != 0) {
+ if (input->socket->joinGroup(address) == -1) {
+ etiLog.print(TcpLog::ERR,
+ "can't join multicast group %s (%s: %s)\n",
+ address, inetErrDesc, inetErrMsg);
+ returnCode = -1;
+ }
+ }
+
+ if (input->socket->setBlocking(false) == -1) {
+ etiLog.print(TcpLog::ERR, "can't set Udp input socket in blocking mode "
+ "(%s: %s)\n", inetErrDesc, inetErrMsg);
+ returnCode = -1;
+ }
+
+ free(address);
+ etiLog.print(TcpLog::DBG, "check return code of create\n");
+ return returnCode;;
+}
+
+
+int dabInputUdpRead(dabInputOperations* ops, void* args, void* buffer, int size)
+{
+ int nbBytes = 0;
+ uint8_t* data = reinterpret_cast<uint8_t*>(buffer);
+
+ dabInputUdpData* input = (dabInputUdpData*)args;
+ dabInputFifoStats* stats = (dabInputFifoStats*)&input->stats;
+
+ input->stats.frameRecords[input->stats.frameCount].curSize = 0;
+ input->stats.frameRecords[input->stats.frameCount].maxSize = size;
+
+ if (input->packet->getLength() == 0) {
+ input->socket->receive(*input->packet);
+ }
+
+ while (nbBytes < size) {
+ unsigned freeSize = size - nbBytes;
+ if (input->packet->getLength() > freeSize) {
+ // Not enought place in output
+ memcpy(&data[nbBytes], input->packet->getData(), freeSize);
+ nbBytes = size;
+ input->packet->setOffset(input->packet->getOffset() + freeSize);
+ } else {
+ unsigned length = input->packet->getLength();
+ memcpy(&data[nbBytes], input->packet->getData(), length);
+ nbBytes += length;
+ input->packet->setOffset(0);
+ input->socket->receive(*input->packet);
+ if (input->packet->getLength() == 0) {
+ break;
+ }
+ }
+ }
+ input->stats.frameRecords[input->stats.frameCount].curSize = nbBytes;
+ bzero(&data[nbBytes], size - nbBytes);
+
+ input->stats.frameRecords[input->stats.frameCount].curSize = nbBytes;
+ if (++stats->frameCount == NB_RECORDS) {
+ etiLog.print(TcpLog::INFO, "Data subchannel usage: (%i)",
+ stats->id);
+ for (int i = 0; i < stats->frameCount; ++i) {
+ etiLog.print(TcpLog::INFO, " %i/%i",
+ stats->frameRecords[i].curSize,
+ stats->frameRecords[i].maxSize);
+ }
+ etiLog.print(TcpLog::INFO, "\n");
+ stats->frameCount = 0;
+ }
+
+ return size;
+}
+
+
+int dabInputUdpClose(void* args)
+{
+ return 0;
+}
+
+
+int dabInputUdpClean(void** args)
+{
+ dabInputUdpData* input = (dabInputUdpData*)(*args);
+ delete input->socket;
+ delete input->packet;
+ delete input;
+ return 0;
+}
+
+
+# endif
+#endif
diff --git a/src/dabInputUdp.h b/src/dabInputUdp.h
new file mode 100644
index 0000000..c0de1dd
--- /dev/null
+++ b/src/dabInputUdp.h
@@ -0,0 +1,59 @@
+/*
+ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
+ Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DAB_INPUT_UDP_H
+#define DAB_INPUT_UDP_H
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "dabInput.h"
+#include "dabInputFifo.h"
+#include "UdpSocket.h"
+
+
+#ifdef HAVE_FORMAT_RAW
+# ifdef HAVE_INPUT_UDP
+
+
+extern struct dabInputOperations dabInputUdpOperations;
+
+
+struct dabInputUdpData {
+ UdpSocket* socket;
+ UdpPacket* packet;
+ dabInputFifoStats stats;
+};
+
+
+int dabInputUdpInit(void** args);
+int dabInputUdpOpen(void* args, const char* inputName);
+int dabInputUdpRead(dabInputOperations* ops, void* args, void* buffer, int size);
+int dabInputUdpClose(void* args);
+int dabInputUdpClean(void** args);
+
+
+# endif
+#endif
+
+
+#endif // DAB_INPUT_UDP_H
diff --git a/src/dabOutput.cpp b/src/dabOutput.cpp
new file mode 100644
index 0000000..5351501
--- /dev/null
+++ b/src/dabOutput.cpp
@@ -0,0 +1,1112 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in
+ Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabOutput.h"
+#include "UdpSocket.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <limits.h>
+
+#ifdef _WIN32
+# include <io.h>
+# ifdef __MINGW32__
+# define FS_DECLARE_CFG_ARRAYS
+# include <winioctl.h>
+# endif
+# include <sdci.h>
+#else
+# include <farsync.h>
+# include <unistd.h>
+# include <sys/time.h>
+# ifndef O_BINARY
+# define O_BINARY 0
+# endif // O_BINARY
+#endif
+
+
+int dabOutputDefaultInit(void** args) {
+ return -1;
+}
+
+
+int dabOutputDefaultOpen(void* args, const char* filename)
+{
+ return -1;
+}
+
+
+int dabOutputDefaultWrite(void* args, void* buffer, int size)
+{
+ return -1;
+}
+
+
+int dabOutputDefaultClose(void* args)
+{
+ return -1;
+}
+
+
+int dabOutputDefaultClean(void** args)
+{
+ return -1;
+}
+
+
+struct dabOutputOperations dabOutputDefaultOperations = {
+ dabOutputDefaultInit,
+ dabOutputDefaultOpen,
+ dabOutputDefaultWrite,
+ dabOutputDefaultClose,
+ dabOutputDefaultClean
+};
+
+
+enum EtiFileType {
+ ETI_FILE_TYPE_NONE = 0,
+ ETI_FILE_TYPE_RAW,
+ ETI_FILE_TYPE_STREAMED,
+ ETI_FILE_TYPE_FRAMED
+};
+
+
+struct dabOutputFifoData {
+ int file;
+ EtiFileType type;
+ unsigned long nbFrames;
+};
+
+
+int dabOutputFifoInit(void** args)
+{
+ dabOutputFifoData* data = new dabOutputFifoData;
+
+ *args = data;
+ data->file = -1;
+ data->type = ETI_FILE_TYPE_STREAMED;
+ data->nbFrames = 0;
+ return 0;
+}
+
+
+int dabOutputFifoOpen(void* args, const char* filename)
+{
+ dabOutputFifoData* data = (dabOutputFifoData*)args;
+
+ char* token = strchr((char*)filename, '?');
+ if (token != NULL) {
+ *(token++) = 0;
+ char* nextPair;
+ char* key;
+ char* value;
+ do {
+ nextPair = strchr(token, '&');
+ if (nextPair != NULL) {
+ *nextPair = 0;
+ }
+ key = token;
+ value = strchr(token, '=');
+ if (value != NULL) {
+ *(value++) = 0;
+ if (strcmp(key, "type") == 0) {
+ if (strcmp(value, "raw") == 0) {
+ data->type = ETI_FILE_TYPE_RAW;
+ break;
+ } else if (strcmp(value, "framed") == 0) {
+ data->type = ETI_FILE_TYPE_FRAMED;
+ break;
+ } else if (strcmp(value, "streamed") == 0) {
+ data->type = ETI_FILE_TYPE_STREAMED;
+ break;
+ } else {
+ etiLog.printHeader(TcpLog::ERR,
+ "File type '%s' is not supported.\n", value);
+ return -1;
+ }
+ }
+ }
+ } while (nextPair != NULL);
+ }
+
+ data->file = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+ if (data->file == -1) {
+ perror(filename);
+ return -1;
+ }
+ return 0;
+}
+
+
+int dabOutputFifoWrite(void* args, void* buffer, int size)
+{
+ dabOutputFifoData* data = (dabOutputFifoData*)args;
+ uint8_t padding[6144];
+
+ switch (data->type) {
+ case ETI_FILE_TYPE_FRAMED:
+ if (data->nbFrames == 0) {
+ uint32_t nbFrames = (uint32_t)-1;
+ // Writting nb frame
+ if (write(data->file, &nbFrames, 4) == -1) goto FIFO_WRITE_ERROR;
+ }
+ case ETI_FILE_TYPE_STREAMED:
+ // Writting frame length
+ if (write(data->file, &size, 2) == -1) goto FIFO_WRITE_ERROR;
+ // Appending data
+ if (write(data->file, buffer, size) == -1) goto FIFO_WRITE_ERROR;
+ break;
+ case ETI_FILE_TYPE_RAW:
+ // Appending data
+ if (write(data->file, buffer, size) == -1) goto FIFO_WRITE_ERROR;
+ // Appending padding
+ memset(padding, 0x55, 6144 - size);
+ if (write(data->file, padding, 6144 - size) == -1) goto FIFO_WRITE_ERROR;
+ break;
+ default:
+ etiLog.printHeader(TcpLog::ERR, "File type is not supported.\n");
+ return -1;
+ }
+
+
+ return size;
+
+FIFO_WRITE_ERROR:
+ perror("Error while writting to file");
+ return -1;
+}
+
+
+int dabOutputFifoClose(void* args)
+{
+ dabOutputFifoData* data = (dabOutputFifoData*)args;
+
+ if (close(data->file) == 0) {
+ data->file = -1;
+ return 0;
+ }
+ perror("Can't close file");
+ return -1;
+}
+
+
+int dabOutputFifoClean(void** args)
+{
+ delete (dabOutputFifoData*)(*args);
+ return 0;
+}
+
+
+struct dabOutputOperations dabOutputFifoOperations = {
+ dabOutputFifoInit,
+ dabOutputFifoOpen,
+ dabOutputFifoWrite,
+ dabOutputFifoClose,
+ dabOutputFifoClean
+};
+
+
+struct dabOutputFileData {
+ int file;
+ EtiFileType type;
+ unsigned long nbFrames;
+};
+
+
+int dabOutputFileInit(void** args)
+{
+ dabOutputFileData* data = new dabOutputFileData;
+
+ *args = data;
+ data->file = -1;
+ data->type = ETI_FILE_TYPE_FRAMED;
+ data->nbFrames = 0;
+ return 0;
+}
+
+
+int dabOutputFileWrite(void* args, void* buffer, int size)
+{
+ dabOutputFileData* data = (dabOutputFileData*)args;
+
+ uint8_t padding[6144];
+ ++data->nbFrames;
+
+ switch (data->type) {
+ case ETI_FILE_TYPE_FRAMED:
+ // Writting nb of frames at beginning of file
+ if (lseek(data->file, 0, SEEK_SET) == -1) goto FILE_WRITE_ERROR;
+ if (write(data->file, &data->nbFrames, 4) == -1) goto FILE_WRITE_ERROR;
+
+ // Writting nb frame length at end of file
+ if (lseek(data->file, 0, SEEK_END) == -1) goto FILE_WRITE_ERROR;
+ if (write(data->file, &size, 2) == -1) goto FILE_WRITE_ERROR;
+
+ // Appending data
+ if (write(data->file, buffer, size) == -1) goto FILE_WRITE_ERROR;
+ break;
+ case ETI_FILE_TYPE_STREAMED:
+ // Writting nb frame length at end of file
+ if (write(data->file, &size, 2) == -1) goto FILE_WRITE_ERROR;
+
+ // Appending data
+ if (write(data->file, buffer, size) == -1) goto FILE_WRITE_ERROR;
+ break;
+ case ETI_FILE_TYPE_RAW:
+ // Appending data
+ if (write(data->file, buffer, size) == -1) goto FILE_WRITE_ERROR;
+
+ // Appending padding
+ memset(padding, 0x55, 6144 - size);
+ if (write(data->file, padding, 6144 - size) == -1) goto FILE_WRITE_ERROR;
+ break;
+ default:
+ etiLog.printHeader(TcpLog::ERR, "File type is not supported.\n");
+ return -1;
+ }
+
+ return size;
+
+FILE_WRITE_ERROR:
+ perror("Error while writting to file");
+ return -1;
+}
+
+
+int dabOutputFileClean(void** args)
+{
+ delete (dabOutputFileData*)(*args);
+ return 0;
+}
+
+
+struct dabOutputOperations dabOutputFileOperations = {
+ dabOutputFileInit,
+ dabOutputFifoOpen,
+ dabOutputFileWrite,
+ dabOutputFifoClose,
+ dabOutputFileClean
+};
+
+
+struct dabOutputRawData {
+#ifdef _WIN32
+ HANDLE socket;
+#else
+ int socket;
+ bool isCyclades;
+#endif
+ unsigned char* buffer;
+};
+
+
+const unsigned char revTable[] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+
+int dabOutputRawInit(void** args)
+{
+ dabOutputRawData* data = new dabOutputRawData;
+
+ *args = data;
+#ifdef _WIN32
+ data->socket = INVALID_HANDLE_VALUE;
+#else
+ data->socket = -1;
+ data->isCyclades = false;
+#endif
+ data->buffer = new unsigned char[6144];
+ return 0;
+}
+
+
+#ifdef _WIN32
+# include <fscfg.h>
+# include <sdci.h>
+#else
+# include <netinet/in.h>
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <sys/ioctl.h>
+# include <linux/if_packet.h>
+# include <linux/netdevice.h>
+# include <net/if_arp.h>
+#endif
+int dabOutputRawOpen(void* args, const char* filename)
+{
+ dabOutputRawData* data = (dabOutputRawData*)args;
+
+ if (filename == NULL) {
+ etiLog.printHeader(TcpLog::ERR, "Socket name must be provided!\n");
+ return -1;
+ }
+
+#ifdef _WIN32
+ // Opening device
+ data->socket = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (data->socket == INVALID_HANDLE_VALUE) {
+ etiLog.printHeader(TcpLog::ERR, "Can't open raw device '%s': %i\n",
+ filename, GetLastError());
+ return -1;
+ }
+
+ // Configuring device
+ DWORD result;
+ FS_TE1_CONFIG config;
+ if (!DeviceIoControl(data->socket, IoctlCodeFarSyncGetTE1Config, NULL, 0,
+ &config, sizeof(config), &result, NULL)) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Can't get raw device '%s' config: %i\n",
+ filename, GetLastError());
+ return -1;
+ }
+ config.dataRate = 2048000;
+ config.clocking = CLOCKING_MASTER;
+ config.framing = FRAMING_E1;
+ config.structure = STRUCTURE_UNFRAMED;
+ config.iface = INTERFACE_BNC;
+ config.coding = CODING_HDB3;
+ config.lineBuildOut = LBO_0dB;
+ config.equalizer = EQUALIZER_SHORT;
+ config.transparentMode = TRUE;
+ config.loopMode = LOOP_NONE;
+ config.range = RANGE_0_40_M;
+ config.txBufferMode = BUFFER_2_FRAME;
+ config.rxBufferMode = BUFFER_2_FRAME;
+ config.startingTimeSlot = 0;
+ config.losThreshold = 2;
+ config.enableIdleCode = TRUE;
+ config.idleCode = 0xff;
+ if (!DeviceIoControl(data->socket, IoctlCodeFarSyncSetTE1Config,
+ &config, sizeof(config), NULL, 0, &result, NULL)) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Can't set raw device '%s' config: %i\n",
+ filename, GetLastError());
+ return -1;
+ }
+
+ // Starting device
+ if (!DeviceIoControl(data->socket, IoctlCodeFarSyncQuickStart, NULL, 0,
+ NULL, 0, &result, NULL)) {
+ etiLog.printHeader(TcpLog::ERR, "Can't start raw device '%s': %i\n",
+ filename, GetLastError());
+ return -1;
+ }
+#else
+ data->socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+ if (data->socket == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Are you logged as root?\n");
+ perror(filename);
+ return -1;
+ }
+
+ struct ifreq ifr;
+ struct sockaddr_ll saddr;
+ memset(&ifr, 0, sizeof(struct ifreq));
+ (void)strncpy(ifr.ifr_name, filename, sizeof(ifr.ifr_name));
+
+ // Get current Farsync configuration
+ struct fstioc_info info;
+ memset(&info, 0, sizeof(info));
+ ifr.ifr_data = (char*)&info;
+ if (ioctl(data->socket, FSTGETCONF, &ifr) == -1) {
+ etiLog.printHeader(TcpLog::DBG, "Cyclades card identified.\n");
+ data->isCyclades = true;
+
+ // Set the interface MTU if needed
+ if (ioctl(data->socket, SIOCGIFMTU, &ifr) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Can't get raw device MTU!\n");
+ perror(filename);
+ return -1;
+ } else {
+ if (ifr.ifr_mtu != 6143) {
+ ifr.ifr_mtu = 6143;
+ if (ioctl(data->socket, SIOCSIFMTU, &ifr) == -1) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Can't Cyclades device MTU!\n");
+ perror(filename);
+ return -1;
+ }
+ }
+ }
+ } else {
+ etiLog.printHeader(TcpLog::DBG, "Farsync card identified.\n");
+ data->isCyclades = false;
+
+ info.lineInterface = E1;
+ info.proto = FST_RAW;
+ info.internalClock = EXTCLK;
+ info.lineSpeed = 2048000;
+ //info.debug = DBG_INIT | DBG_OPEN | DBG_PCI | DBG_IOCTL | DBG_TX;
+ info.transparentMode = 1;
+ info.ignoreCarrier = 1;
+ info.numTxBuffers = 8;
+ info.numRxBuffers = 8;
+ info.txBufferSize = 6144;
+ info.rxBufferSize = 6144;
+ // E1 specific config
+ info.clockSource = CLOCKING_SLAVE;
+ info.structure = STRUCTURE_UNFRAMED;
+ info.interface = INTERFACE_BNC; //RJ48C;
+ info.coding = CODING_HDB3;
+ info.txBufferMode = BUFFER_2_FRAME;
+ info.idleCode = 0xff;
+ info.valid = FSTVAL_ALL;
+
+ // Setting configuration
+ etiLog.printHeader(TcpLog::DBG, "Set configuration.\n");
+ ifr.ifr_data = (char*)&info;
+ if (ioctl(data->socket, FSTSETCONF, &ifr) == -1) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Can't set Farsync configurationi!\n");
+ perror(filename);
+ return -1;
+ }
+
+ // Disabling notify
+ etiLog.printHeader(TcpLog::DBG, "Disable notify.\n");
+ int notify = 0;
+ ifr.ifr_data = (char*)&notify;
+ if (ioctl(data->socket, FSTSNOTIFY, &ifr) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Can't disable Farsync notify!\n");
+ perror(filename);
+ return -1;
+ }
+
+ // Apply the new configuration
+ // Set the interface down if needed
+ etiLog.printHeader(TcpLog::DBG, "Get flags.\n");
+ if (ioctl(data->socket, SIOCGIFFLAGS, &ifr) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Can't get Farsync flags!\n");
+ perror(filename);
+ return -1;
+ } else {
+ if (ifr.ifr_flags & IFF_UP) {
+ etiLog.printHeader(TcpLog::DBG, "Set flags.\n");
+ ifr.ifr_flags &= ~IFF_UP;
+ if (ioctl(data->socket, SIOCSIFFLAGS, &ifr) == -1) {
+ etiLog.printHeader(TcpLog::ERR,
+ "Can't turn down Farsync device!\n");
+ perror(filename);
+ return -1;
+ }
+ }
+ }
+
+ // Set the interface MTU if needed
+ etiLog.printHeader(TcpLog::DBG, "Get MTU.\n");
+ if (ioctl(data->socket, SIOCGIFMTU, &ifr) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Can't get Farsync MTU!\n");
+ perror(filename);
+ return -1;
+ } else {
+ if (ifr.ifr_mtu != 6144) {
+ etiLog.printHeader(TcpLog::DBG, "Set MTU.\n");
+ ifr.ifr_mtu = 6144;
+ if (ioctl(data->socket, SIOCSIFMTU, &ifr) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Can't set Farsync MTU!\n");
+ perror(filename);
+ return -1;
+ }
+ }
+ }
+ }
+
+ // Set the interface up if needed
+ etiLog.printHeader(TcpLog::DBG, "Get flags.\n");
+ if (ioctl(data->socket, SIOCGIFFLAGS, &ifr) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Can't get raw device flags!\n");
+ perror(filename);
+ return -1;
+ } else {
+ if (!(ifr.ifr_flags & IFF_UP)) {
+ ifr.ifr_flags |= IFF_UP;
+ etiLog.printHeader(TcpLog::DBG, "Set flags.\n");
+ if (ioctl(data->socket, SIOCSIFFLAGS, &ifr) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Can't turn up raw device!\n");
+ perror(filename);
+ return -1;
+ }
+ }
+ }
+
+ close(data->socket);
+
+ ////////////////////
+ // Opening device //
+ ////////////////////
+
+ if ((data->socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_CUST))) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Are you logged as root?\n");
+ perror(filename);
+ return -1;
+ }
+
+ // ioctl to read the interface number
+ etiLog.printHeader(TcpLog::DBG, "Get index.\n");
+ memset(&ifr, 0, sizeof(struct ifreq));
+ strncpy(ifr.ifr_name, filename, sizeof(ifr.ifr_name));
+ if (ioctl(data->socket, SIOCGIFINDEX, (char *) &ifr) == -1) {
+ perror(filename);
+ return -1;
+ }
+
+ // Bind to the interface name
+ etiLog.printHeader(TcpLog::DBG, "Bind interface.\n");
+ memset(&saddr, 0, sizeof(struct sockaddr_ll));
+ saddr.sll_family = AF_PACKET;
+ saddr.sll_protocol = ARPHRD_RAWHDLC;
+ saddr.sll_ifindex = ifr.ifr_ifindex;
+ if (bind(data->socket, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Can't bind raw device!\n");
+ perror(filename);
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
+
+int dabOutputRawWrite(void* args, void* buffer, int size)
+{
+ dabOutputRawData* data = (dabOutputRawData*)args;
+
+ // Encoding data
+ memcpy(data->buffer, buffer, size);
+ memset(data->buffer + size, 0x55, 6144 - size);
+ for (int i = 0; i < 6144; ++i) {
+ data->buffer[i] = revTable[data->buffer[i]];
+ }
+
+ // Writting data
+#ifdef _WIN32
+ DWORD result;
+ if(!DeviceIoControl(data->socket, IoctlCodeTxFrame, data->buffer, 6144,
+ NULL, 0, &result, NULL)) {
+ goto RAW_WRITE_ERROR;
+ }
+#else
+ /*
+ if (write(data->socket, data->buffer + 1, 6143) != 6143) {
+ goto RAW_WRITE_ERROR;
+ }
+ */
+ if (data->isCyclades) {
+ if (write(data->socket, data->buffer + 1, 6143) != 6143) {
+ goto RAW_WRITE_ERROR;
+ }
+ } else {
+ int ret = send(data->socket, data->buffer, 6144, 0);
+ if (ret != 6144) {
+ fprintf(stderr, "%i/6144 bytes written\n", ret);
+ goto RAW_WRITE_ERROR;
+ }
+ }
+#endif
+
+ return size;
+
+RAW_WRITE_ERROR:
+#ifdef _WIN32
+ DWORD err = GetLastError();
+ LPSTR errMsg;
+ if(FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ err,
+ 0,
+ (LPTSTR)&errMsg,
+ 0,
+ NULL) == 0) {
+ fprintf(stderr, "Error while writting to raw socket: %i\n", err);
+ } else {
+ fprintf(stderr, "Error while writting to raw socket: %s\n", errMsg);
+ LocalFree(errMsg);
+ }
+#else
+ perror("Error while writting to raw socket");
+#endif
+
+ return -1;
+}
+
+
+int dabOutputRawClose(void* args)
+{
+ dabOutputRawData* data = (dabOutputRawData*)args;
+
+#ifdef _WIN32
+ CancelIo(data->socket);
+ CloseHandle(data->socket);
+ return 0;
+#else
+ if (close(data->socket) == 0) {
+ data->socket = -1;
+ return 0;
+ }
+ perror("Can't close raw socket");
+#endif
+
+ return -1;
+}
+
+
+int dabOutputRawClean(void** args)
+{
+ dabOutputRawData* data = *((dabOutputRawData**)args);
+
+ delete []data->buffer;
+ delete data;
+ return 0;
+}
+
+
+struct dabOutputOperations dabOutputRawOperations = {
+ dabOutputRawInit,
+ dabOutputRawOpen,
+ dabOutputRawWrite,
+ dabOutputRawClose,
+ dabOutputRawClean
+};
+
+
+struct dabOutputUdpData {
+ UdpSocket* socket;
+ UdpPacket* packet;
+};
+
+
+int dabOutputUdpInit(void** args)
+{
+ dabOutputUdpData* data = new dabOutputUdpData;
+
+ *args = data;
+ UdpSocket::init();
+ data->packet = new UdpPacket(6144);
+ data->socket = new UdpSocket();
+
+ return 0;
+}
+
+
+int dabOutputUdpOpen(void* args, const char* filename)
+{
+ dabOutputUdpData* data = (dabOutputUdpData*)args;
+ filename = strdup(filename);
+
+ char* address;
+ long port;
+ address = strchr((char*)filename, ':');
+ if (address == NULL) {
+ etiLog.printHeader(TcpLog::ERR,
+ "\"%s\" is an invalid format for udp address: "
+ "should be [address]:port - > aborting\n",
+ filename);
+ return -1;
+ }
+ *(address++) = 0;
+ port = strtol(address, (char **)NULL, 10);
+ if ((port == LONG_MIN) || (port == LONG_MAX)) {
+ etiLog.printHeader(TcpLog::ERR,
+ "can't convert port number in udp address %s\n", address);
+ return -1;
+ }
+ if (port == 0) {
+ etiLog.printHeader(TcpLog::ERR,
+ "can't use port number 0 in udp address\n");
+ return -1;
+ }
+ address = (char*)filename;
+ if (strlen(address) > 0) {
+ if (data->packet->getAddress().setAddress(address) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "can't set address %s (%s: %s) "
+ "-> aborting\n", address, inetErrDesc, inetErrMsg);
+ return -1;
+ }
+ }
+ data->packet->getAddress().setPort(port);
+
+ if (data->socket->create() == -1) {
+ etiLog.printHeader(TcpLog::ERR, "can't create Udp socket (%s: %s) "
+ "-> aborting\n)", inetErrDesc, inetErrMsg);
+ return -1;
+ }
+
+ //sprintf(filename, "%s:%i", data->packet->getAddress().getHostAddress(),
+ // data->packet->getAddress().getPort());
+ return 0;
+}
+
+
+int dabOutputUdpWrite(void* args, void* buffer, int size)
+{
+ dabOutputUdpData* data = (dabOutputUdpData*)args;
+
+ data->packet->setLength(0);
+ data->packet->addData(buffer, size);
+ return data->socket->send(*data->packet);
+}
+
+
+int dabOutputUdpClose(void* args)
+{
+ //dabOutputUdpData* data = (dabOutputUdpData*)args;
+
+ return 0;
+}
+
+
+int dabOutputUdpClean(void** args)
+{
+ dabOutputUdpData* data = *((dabOutputUdpData**)args);
+
+ delete data->socket;
+ delete data->packet;
+ delete data;
+
+ return 0;
+}
+
+
+struct dabOutputOperations dabOutputUdpOperations = {
+ dabOutputUdpInit,
+ dabOutputUdpOpen,
+ dabOutputUdpWrite,
+ dabOutputUdpClose,
+ dabOutputUdpClean
+};
+
+
+#include "TcpServer.h"
+struct dabOutputTcpData {
+ TcpServer* server;
+ TcpSocket* client;
+ pthread_t thread;
+};
+
+
+int dabOutputTcpInit(void** args)
+{
+ dabOutputTcpData* data = new dabOutputTcpData;
+
+ *args = data;
+ TcpSocket::init();
+ data->server = new TcpServer();
+ data->client = NULL;
+
+ return 0;
+}
+
+
+void* dabOutputTcpThread(void* args)
+{
+ dabOutputTcpData* data = (dabOutputTcpData*)args;
+ TcpSocket* client;
+
+ while ((client = data->server->accept()) != NULL) {
+ etiLog.print(TcpLog::INFO, "TCP server got a new client.\n");
+ if (data->client != NULL) {
+ delete data->client;
+ }
+ data->client = client;
+ }
+ etiLog.print(TcpLog::ERR, "TCP thread can't accept new client (%s)\n",
+ inetErrDesc, inetErrMsg);
+
+ return NULL;
+}
+
+
+int dabOutputTcpOpen(void* args, const char* filename)
+{
+ dabOutputTcpData* data = (dabOutputTcpData*)args;
+ filename = strdup(filename);
+
+ char* address;
+ long port;
+ address = strchr((char*)filename, ':');
+ if (address == NULL) {
+ etiLog.printHeader(TcpLog::ERR,
+ "\"%s\" is an invalid format for tcp address: "
+ "should be [address]:port - > aborting\n",
+ filename);
+ return -1;
+ }
+ *(address++) = 0;
+ port = strtol(address, (char **)NULL, 10);
+ if ((port == LONG_MIN) || (port == LONG_MAX)) {
+ etiLog.printHeader(TcpLog::ERR,
+ "can't convert port number in tcp address %s\n", address);
+ return -1;
+ }
+ if (port == 0) {
+ etiLog.printHeader(TcpLog::ERR,
+ "can't use port number 0 in tcp address\n");
+ return -1;
+ }
+ address = (char*)filename;
+ if (strlen(address) > 0) {
+ if (data->server->create(port, address) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Can't create Tcp server on %s:%i "
+ "(%s: %s) -> aborting\n",
+ address, port, inetErrDesc, inetErrMsg);
+ return -1;
+ }
+ } else {
+ if (data->server->create(port) == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Can't create Tcp server on :%i "
+ "(%s: %s) -> aborting\n",
+ port, inetErrDesc, inetErrMsg);
+ return -1;
+ }
+ }
+
+ //sprintf(filename, "%s:%i", data->packet->getAddress().getHostAddress(),
+ // data->packet->getAddress().getPort());
+
+ if (data->server->listen() == -1) {
+ etiLog.printHeader(TcpLog::ERR, "Can't listen on Tcp socket (%s: %s)\n",
+ inetErrDesc, inetErrMsg);
+ return -1;
+ }
+#ifdef _WIN32
+ data->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)dabOutputTcpThread, data, 0, NULL);
+ if (data->thread == NULL) {
+ fprintf(stderr, "Can't create TCP child");
+ return -1;
+ }
+#else
+ if (pthread_create(&data->thread, NULL, dabOutputTcpThread, data)) {
+ perror("Can't create TCP child");
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
+
+int dabOutputTcpWrite(void* args, void* buffer, int size)
+{
+ dabOutputTcpData* data = (dabOutputTcpData*)args;
+
+ if (data->client != NULL) {
+ if (data->client->write(&size, 2) == 2) {
+ if (data->client->write(buffer, size) != size) {
+ return size;
+ }
+ }
+ else {
+ etiLog.print(TcpLog::INFO, "TCP server client disconnected.\n");
+ delete data->client;
+ data->client = NULL;
+ }
+ }
+ return size;
+}
+
+
+#include <signal.h>
+int dabOutputTcpClose(void* args)
+{
+ dabOutputTcpData* data = (dabOutputTcpData*)args;
+
+ data->server->close();
+ if( data->client != NULL )
+ data->client->close();
+#ifdef WIN32
+ DWORD status;
+ for (int i = 0; i < 5; ++i) {
+ if (GetExitCodeThread(data->thread, &status)) {
+ break;
+ }
+ Sleep(100);
+ }
+ TerminateThread(data->thread, 1);
+#else
+ pthread_kill(data->thread, SIGPIPE);
+#endif
+
+ return 0;
+}
+
+
+int dabOutputTcpClean(void** args)
+{
+ dabOutputTcpData* data = *((dabOutputTcpData**)args);
+
+#ifdef _WIN32
+ CloseHandle(data->thread);
+#endif
+
+ delete data->server;
+ delete data->client;
+ delete data;
+
+ return 0;
+}
+
+
+struct dabOutputOperations dabOutputTcpOperations = {
+ dabOutputTcpInit,
+ dabOutputTcpOpen,
+ dabOutputTcpWrite,
+ dabOutputTcpClose,
+ dabOutputTcpClean
+};
+
+
+struct dabOutputSimulData {
+#ifdef _WIN32
+ DWORD startTime;
+#else
+ timeval startTime;
+#endif
+};
+
+
+int dabOutputSimulInit(void** args) {
+ dabOutputSimulData* data = new dabOutputSimulData;
+
+ *args = data;
+
+ return 0;
+}
+
+
+int dabOutputSimulOpen(void* args, const char* filename)
+{
+ dabOutputSimulData* data = (dabOutputSimulData*)args;
+
+#ifdef _WIN32
+ data->startTime = GetTickCount();
+#else
+ gettimeofday(&data->startTime, NULL);
+#endif
+
+ return 0;
+}
+
+
+int dabOutputSimulWrite(void* args, void* buffer, int size)
+{
+ dabOutputSimulData* data = (dabOutputSimulData*)args;
+
+ unsigned long current;
+ unsigned long start;
+ unsigned long waiting;
+
+#ifdef _WIN32
+ current = GetTickCount();
+ start = data->startTime;
+ if (current < start) {
+ waiting = start - current + 24;
+ Sleep(waiting);
+ } else {
+ waiting = 24 - (current - start);
+ if ((current - start) < 24) {
+ Sleep(waiting);
+ }
+ }
+ data->startTime += 24;
+#else
+ timeval curTime;
+ gettimeofday(&curTime, NULL);
+ current = (1000000ul * curTime.tv_sec) + curTime.tv_usec;
+ start = (1000000ul * data->startTime.tv_sec) + data->startTime.tv_usec;
+ waiting = 24000ul - (current - start);
+ if ((current - start) < 24000ul) {
+ usleep(waiting);
+ }
+
+ data->startTime.tv_usec += 24000;
+ if (data->startTime.tv_usec >= 1000000) {
+ data->startTime.tv_usec -= 1000000;
+ ++data->startTime.tv_sec;
+ }
+#endif
+
+ return size;
+}
+
+
+int dabOutputSimulClose(void* args)
+{
+ //dabOutputSimulData* data = (dabOutputSimulData*)args);
+
+ return 0;
+}
+
+
+int dabOutputSimulClean(void** args)
+{
+ dabOutputSimulData* data = *((dabOutputSimulData**)args);
+
+ delete data;
+
+ return 0;
+}
+
+
+struct dabOutputOperations dabOutputSimulOperations = {
+ dabOutputSimulInit,
+ dabOutputSimulOpen,
+ dabOutputSimulWrite,
+ dabOutputSimulClose,
+ dabOutputSimulClean
+};
+
+
diff --git a/src/dabOutput.h b/src/dabOutput.h
new file mode 100644
index 0000000..26c154a
--- /dev/null
+++ b/src/dabOutput.h
@@ -0,0 +1,72 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in
+ Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _DABOUTPUT
+#define _DABOUTPUT
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+struct dabOutputOperations {
+ int (*init)(void** args);
+ int (*open)(void* args, const char* name);
+ int (*write)(void* args, void* buffer, int size);
+ int (*close)(void* args);
+ int (*clean)(void** args);
+};
+
+extern struct dabOutputOperations dabOutputDefaultOperations;
+
+#if defined(HAVE_OUTPUT_FILE)
+extern struct dabOutputOperations dabOutputFileOperations;
+#endif // defined(HAVE_OUTPUT_FILE)
+
+#if defined(HAVE_OUTPUT_FIFO)
+extern struct dabOutputOperations dabOutputFifoOperations;
+#endif // defined(HAVE_OUTPUT_FIFO)
+
+#if defined(HAVE_OUTPUT_UDP)
+extern struct dabOutputOperations dabOutputUdpOperations;
+#endif // defined(HAVE_OUTPUT_UDP)
+
+#if defined(HAVE_OUTPUT_TCP)
+extern struct dabOutputOperations dabOutputTcpOperations;
+#endif // defined(HAVE_OUTPUT_TCP)
+
+#if defined(HAVE_OUTPUT_RAW)
+extern struct dabOutputOperations dabOutputRawOperations;
+#endif // defined(HAVE_OUTPUT_RAW)
+
+#if defined(HAVE_OUTPUT_SIMUL)
+extern struct dabOutputOperations dabOutputSimulOperations;
+#endif // defined(HAVE_OUTPUT_SIMUL)
+
+
+extern const unsigned char revTable[];
+
+
+#include "TcpLog.h"
+extern TcpLog etiLog;
+
+
+#endif // _DABOUTPUT
diff --git a/src/dabUtils.cpp b/src/dabUtils.cpp
new file mode 100644
index 0000000..693d300
--- /dev/null
+++ b/src/dabUtils.cpp
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
+ Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "dabUtils.h"
+
+long gregorian2mjd(int year,int month,int day)
+{
+ long MJD;
+
+ //This is the algorithm for the JD, just substract 2400000.5 for MJD
+ year += 8000;
+ if(month < 3) {
+ year--;
+ month += 12;
+ }
+ MJD = (year * 365) + (year / 4) - (year / 100) + (year / 400) - 1200820
+ + ((month * 153 + 3) / 5) - 92 + (day - 1);
+
+ return (long)(MJD - 2400000.5); //truncation, loss of data OK!
+}
+
+
+void dumpBytes(void* data, int size, FILE* out)
+{
+ fprintf(out, "Packet of %i bytes", size);
+
+ for (int index = 0; index < size; ++index) {
+ if ((index % 8) == 0) {
+ fprintf(out, "\n 0x%.4x(%.4i):", index, index);
+ }
+ fprintf(out, " 0x%.2x", ((unsigned char*)data)[index]);
+ }
+ fprintf(out, "\n\n");
+}
diff --git a/src/dabUtils.h b/src/dabUtils.h
new file mode 100644
index 0000000..04bb468
--- /dev/null
+++ b/src/dabUtils.h
@@ -0,0 +1,35 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the
+ Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DABUTILS
+#define DABUTILS
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+long gregorian2mjd(int year,int month,int day);
+void dumpBytes(void* data, int size, FILE* out = stdout);
+
+
+#endif // DABUTILS
diff --git a/src/mpeg.c b/src/mpeg.c
new file mode 100644
index 0000000..57f4231
--- /dev/null
+++ b/src/mpeg.c
@@ -0,0 +1,221 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty
+ the Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mpeg.h"
+
+#include <stdio.h>
+#include <errno.h>
+
+
+const static short bitrateArray[4][4][16] = {
+ { // MPEG 2.5
+ { -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1 }, // layer invalid
+ { 0, 8, 16, 24, 32, 40, 48, 56,
+ 64, 80, 96, 112, 128, 144, 160, -1 }, // layer 3
+ { 0, 8, 16, 24, 32, 40, 48, 56,
+ 64, 80, 96, 112, 128, 144, 160, -1 }, // layer 2
+ { 0, 32, 48, 56, 64, 80, 96, 112,
+ 128, 144, 160, 176, 192, 224, 256, -1 } // layer 1
+ },
+ {
+ { -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1 }, // MPEG invalid
+ { -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1 },
+ { -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1 },
+ { -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1 }
+ },
+ {
+ { -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1 }, // MPEG 2
+ { 0, 8, 16, 24, 32, 40, 48, 56,
+ 64, 80, 96, 112, 128, 144, 160, -1 },
+ { 0, 8, 16, 24, 32, 40, 48, 56,
+ 64, 80, 96, 112, 128, 144, 160, -1 },
+ { 0, 32, 48, 56, 64, 80, 96, 112,
+ 128, 144, 160, 176, 192, 224, 256, -1 }
+ },
+ {
+ { -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1 }, // MPEG 1
+ { 0, 32, 40, 48, 56, 64, 80, 96,
+ 112, 128, 160, 192, 224, 256, 320, -1 },
+ { 0, 32, 48, 56, 64, 80, 96, 112,
+ 128, 160, 192, 224, 256, 320, 384, -1 },
+ { 0, 32, 64, 96, 128, 160, 192, 224,
+ 256, 288, 320, 352, 384, 416, 448, -1 }
+ }
+};
+
+
+const static int samplingrateArray[4][4] = {
+ { 11025, 12000, 8000, 0 }, // MPEG 2.5
+ { -1, -1, -1, -1 }, // MPEG invalid
+ { 22050, 24000, 16000, 0 }, // MPEG 2
+ { 44100, 48000, 32000, 0 } // MPEG 1
+};
+
+
+short getMpegBitrate(void* data)
+{
+ mpegHeader* header = (mpegHeader*)data;
+ return bitrateArray[header->id][header->layer][header->bitrate];
+}
+
+
+int getMpegFrequency(void* data)
+{
+ mpegHeader* header = (mpegHeader*)data;
+ return samplingrateArray[header->id][header->samplingrate];
+}
+
+
+int getMpegFrameLength(mpegHeader* header)
+{
+ short bitrate = getMpegBitrate(header);
+ int samplingrate = getMpegFrequency(header);
+ int framelength = -1;
+
+
+ if (bitrate <= 0) {
+ return -1;
+ }
+ if (samplingrate <= 0) {
+ return -1;
+ }
+
+ switch (header->layer) {
+ case 1: // layer III
+ case 2: // layer II
+ framelength = (int)144000 * bitrate / samplingrate + header->padding;
+ break;
+ case 3: // layer I
+ framelength = (12 * bitrate / samplingrate + header->padding) * 4;
+ break;
+ default:
+ framelength = -1;
+ }
+ return framelength;
+}
+
+
+/**
+ * This function replace the read function by trying many times a reading.
+ * It tries to read until all bytes are read. Very useful when reading from a
+ * pipe because sometimes 2 pass is necessary to read all bytes.
+ * @param file File descriptor.
+ * @param data Address of the buffer to write data into.
+ * @param size Number of bytes to read.
+ * @param tries Max number of tries to read.
+ * @return Same as read function:
+ * Nb of bytes read.
+ * -1 if error.
+ */
+ssize_t readData(int file, void* data, size_t size, unsigned int tries)
+{
+ ssize_t result;
+ size_t offset = 0;
+ if (size == 0) return 0;
+ if (tries == 0) return 0;
+ result = read(file, data, size);
+ if (result == -1) {
+ if (errno == EAGAIN) {
+ return readData(file, data, size, tries - 1);
+ }
+ return -1;
+ }
+ offset = result;
+ size -= offset;
+ data = (char*)data + offset;
+ result = readData(file, data, size, tries - 1);
+ if (result == -1) {
+ return -1;
+ }
+ offset += result;
+ return offset;
+}
+
+
+int readMpegHeader(int file, void* data, int size)
+{
+ // Max byte reading for searching sync
+ unsigned int flagmax = 0;
+ unsigned long* syncword = (unsigned long*)data;
+ int result;
+
+ if (size < 4) return MPEG_BUFFER_OVERFLOW;
+ // Mpeg header reading
+ result = readData(file, data, 4, 2);
+ if (result == 0) return MPEG_FILE_EMPTY;
+ if (result == -1) {
+ fprintf(stderr, "header\n");
+ return MPEG_FILE_ERROR;
+ }
+ if (result < 4) {
+ return MPEG_BUFFER_UNDERFLOW;
+ }
+ while ((*syncword & 0xe0ff) != 0xe0ff) {
+ *syncword >>= 8;
+ result = readData(file, (char*)data + 3, 1, 2);
+ if (result == 0) {
+ return MPEG_FILE_EMPTY;
+ } else if (result == -1) {
+ return MPEG_FILE_ERROR;
+ }
+ if (++flagmax > 1200) {
+ return MPEG_SYNC_NOT_FOUND;
+ }
+ }
+ return 4;
+}
+
+
+int readMpegFrame(int file, void* data, int size)
+{
+ mpegHeader* header = (mpegHeader*)data;
+ int framelength;
+ int result;
+
+ framelength = getMpegFrameLength(header);
+ if (framelength < 0) return MPEG_INVALID_FRAME;
+ if (framelength > size) {
+ //lseek(file, framelength - 4, SEEK_CUR);
+ //return MPEG_BUFFER_OVERFLOW;
+ result = readData(file, ((char*)data) + 4, size - 4, 2);
+ if (size == 4) {
+ lseek(file, framelength - size, SEEK_CUR);
+ result = framelength - 4;
+ }
+ } else {
+ result = readData(file, ((char*)data) + 4, framelength - 4, 2);
+ }
+ if (result == 0) return MPEG_FILE_EMPTY;
+ if (result == -1) {
+ return MPEG_FILE_ERROR;
+ }
+ if (result < framelength - 4) {
+ return MPEG_BUFFER_UNDERFLOW;
+ }
+ return framelength;
+}
diff --git a/src/mpeg.h b/src/mpeg.h
new file mode 100644
index 0000000..d892225
--- /dev/null
+++ b/src/mpeg.h
@@ -0,0 +1,82 @@
+/*
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty
+ the Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MPEG
+#define _MPEG
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef _WIN32
+# include <stddef.h>
+# include <basetsd.h>
+# include <io.h>
+
+# define ssize_t SSIZE_T
+#else
+# include <unistd.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ unsigned long sync1:8;
+
+ unsigned long protection:1;
+ unsigned long layer:2;
+ unsigned long id:2;
+ unsigned long sync2:3;
+
+ unsigned long priv:1;
+ unsigned long padding:1;
+ unsigned long samplingrate:2;
+ unsigned long bitrate:4;
+
+ unsigned long emphasis:2;
+ unsigned long original:1;
+ unsigned long copyright:1;
+ unsigned long mode:2;
+ unsigned long channel:2;
+} mpegHeader;
+
+
+extern short getMpegBitrate(void* data);
+extern int getMpegFrequency(void* data);
+int getMpegFrameLength(mpegHeader* header);
+ssize_t readData(int file, void* data, size_t size, unsigned int tries);
+
+#define MPEG_BUFFER_OVERFLOW -2
+#define MPEG_FILE_EMPTY -3
+#define MPEG_FILE_ERROR -4
+#define MPEG_SYNC_NOT_FOUND -5
+#define MPEG_INVALID_FRAME -6
+#define MPEG_BUFFER_UNDERFLOW -7
+int readMpegHeader(int file, void* data, int size);
+int readMpegFrame(int file, void* data, int size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _MPEG
diff --git a/src/prbs.c b/src/prbs.c
new file mode 100644
index 0000000..8a11266
--- /dev/null
+++ b/src/prbs.c
@@ -0,0 +1,140 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right
+ of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "prbs.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+
+
+/*
+ * 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.h b/src/prbs.h
new file mode 100644
index 0000000..827ded6
--- /dev/null
+++ b/src/prbs.h
@@ -0,0 +1,61 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in Right
+ of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DabMux.
+
+ CRC-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.
+
+ CRC-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 CRC-DabMux. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PRBS
+#define _PRBS
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" { // }
+#endif
+
+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
+
+#endif // _PRBS