diff --git a/data/Makefile.am b/data/Makefile.am
index 7519719cd..3ba17d519 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -5,4 +5,4 @@ SUBDIRS += lcd
endif
configdir = $(CONFIGDIR)
-config_DATA = cables.xml satellites.xml encoding.conf tobackup.conf providermap.xml
+config_DATA = cables.xml satellites.xml encoding.conf tobackup.conf providermap.xml terrestrial.xml
diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale
index 5128ccb86..ecf5dde3f 100644
--- a/data/locale/deutsch.locale
+++ b/data/locale/deutsch.locale
@@ -1187,6 +1187,7 @@ scants.abort_body Scanvorgang wirklich abbrechen?
scants.abort_header breche Scan ab...
scants.actcable Kabelnetz:
scants.actsatellite Satellit:
+scants.actterrestrial Terrestrisch:
scants.bouquet Bouquets
scants.bouquet_create neu erstellen
scants.bouquet_erase löschen
@@ -1274,6 +1275,7 @@ stringinput.caps Groß-/Kleinbuchstaben
stringinput.clear Alles löschen
subtitles.head Untertitel
subtitles.stop Untertitel aus
+terrestrialsetup.provider DVB-T Region
timer.eventrecord.msg Die Sendung wurde zur Aufnahme vorgemerkt.
timer.eventrecord.title Aufnahme vormerken
timer.eventtimed.msg Die Sendung wurde vorgemerkt.
diff --git a/data/locale/english.locale b/data/locale/english.locale
index d4fef7366..226e52712 100644
--- a/data/locale/english.locale
+++ b/data/locale/english.locale
@@ -1188,6 +1188,7 @@ scants.abort_body Should the search really be aborted?
scants.abort_header Abortion of channel scan
scants.actcable Cable:
scants.actsatellite Satellite:
+scants.actterrestrial Terrestrial:
scants.bouquet Bouquet
scants.bouquet_create create new
scants.bouquet_erase erase all
@@ -1275,6 +1276,7 @@ stringinput.caps caps / no caps
stringinput.clear clear all
subtitles.head Subtitles
subtitles.stop Stop subtitles
+terrestrialsetup.provider Terrestrial Provider
timer.eventrecord.msg ... TO be DONE, or not to be done
timer.eventrecord.title Schedule Record
timer.eventtimed.msg The event is scheduled.\nThe box will power on and \nswitch to this channel at the given time.
diff --git a/data/mk_terrestrial_xml.pl b/data/mk_terrestrial_xml.pl
new file mode 100755
index 000000000..e008f25ec
--- /dev/null
+++ b/data/mk_terrestrial_xml.pl
@@ -0,0 +1,92 @@
+#!/usr/bin/perl -w
+#
+# create a terrestrial.xml for neutrino from the data installed by the
+# dvb utils
+# the behaviour is similar to the "scan" program form the dvb utils.
+#
+# Released under the GPL V2 or later
+# (C) 2009-2012 Stefan Seyfried
+
+use strict;
+my $srcdir = "/usr/share/dvb/dvb-t";
+
+# can be given as "de-*"
+my $scanfile = shift;
+$scanfile = "auto-Default" unless (defined $scanfile);
+
+my @sourcefiles = glob($srcdir . "/" . $scanfile);
+my ($sourcefile, $basename, $line, $k);
+my ($freq, $bw, $cr_hp, $cr_lp, $mod, $tmode, $gint, $hier);
+
+# from /usr/include/linux/dvb/frontend.h
+# inversion is not used in the scan files
+my %INV = ("INVERSION_OFF" => 0, "INVERSION_ON" => 1, "INVERSION_AUTO" => 2);
+my %CODE_RATE = ("NONE" => 0, "1/2" => 1, "2/3" => 2, "3/4" => 3, "4/5" => 4,
+ "5/6" => 5, "6/7" => 6, "7/8" => 7, "8/9" => 8, "AUTO" => 9);
+my %MODULATION = ("QPSK" => 0, "QAM16" => 1, "QAM32" => 2, "QAM64" => 3,
+ "QAM128" => 4, "QAM256" => 5, "AUTO" => 6);
+my %T_MODE = ("2k" => 0, "8k" => 1, "AUTO" => 2);
+my %BWIDTH = ("8MHz" => 0, "7MHz" => 1, "6MHz" => 2, "AUTO" => 3);
+my %GINTERVAL = ("1/32" => 0, "1/16" => 1, "1/8" => 2, "1/4" => 3, "AUTO" => 4);
+my %HIERARCHY = ("NONE" => 0, "1" => 1, "2" => 2, "4" => 3, "AUTO" => 4);
+
+
+# print the header
+print("\n");
+print("\n\n");
+print("\n");
+#
+# explain the parameters
+print("\n\n");
+# header ends...
+
+print("\n");
+foreach $sourcefile (@sourcefiles)
+{
+ open(FILE, "< $sourcefile") or die "can't open $sourcefile: $!\n";
+ $basename = $sourcefile;
+ $basename =~ s#^.*/##;
+ print("\t\n");
+ while ($line = )
+ { # T 184500000 7MHz 3/4 NONE QAM16 8k 1/4 NONE
+ next unless ($line =~ m/^T\s+(\d+)\s+(\dMHz)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/);
+ $freq = $1; $bw = $2; $cr_hp = $3; $cr_lp = $4; $mod = $5; $tmode = $6; $gint = $7; $hier = $8;
+ unless (defined($CODE_RATE{$cr_hp})) { warn "$basename: illegal cr_hp: $cr_hp, using AUTO\n"; $cr_hp="AUTO" };
+ unless (defined($CODE_RATE{$cr_lp})) { warn "$basename: illegal cr_lp: $cr_lp, using AUTO\n"; $cr_lp="AUTO" };
+ unless (defined($MODULATION{$mod})) { die "$basename: illegal mod: $mod\n" }; # no errors in those (yet).
+ unless (defined($T_MODE{$tmode})) { die "$basename: illegal tmode: $tmode\n" };
+ unless (defined($GINTERVAL{$gint})) { die "$basename: illegal gint: $gint\n" };
+ unless (defined($HIERARCHY{$hier})) { die "$basename: illegal hier: $hier\n" };
+ unless (defined($BWIDTH{$bw})) { die "$basename: illegal bw: $bw\n" };
+ if ($cr_hp eq "NONE") { $cr_hp="AUTO" }; # same as scan.c
+ if ($cr_lp eq "NONE") { $cr_lp="AUTO" }; # same as scan.c
+ printf("\t\t\n",
+ $freq / 1000, $BWIDTH{$bw}, $MODULATION{$mod},
+ $T_MODE{$tmode}, $CODE_RATE{$cr_hp}, $CODE_RATE{$cr_lp},
+ $GINTERVAL{$gint}, $HIERARCHY{$hier});
+ }
+ print("\t\n");
+}
+print("\n");
diff --git a/data/terrestrial.xml b/data/terrestrial.xml
new file mode 100644
index 000000000..6c03dd07e
--- /dev/null
+++ b/data/terrestrial.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/gui/scan.cpp b/src/gui/scan.cpp
index 2a36740f8..371239b25 100644
--- a/src/gui/scan.cpp
+++ b/src/gui/scan.cpp
@@ -202,6 +202,18 @@ int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey)
TP.feparams.dvb_feparams.u.qpsk.symbol_rate = atoi(scansettings.TP_rate);
TP.feparams.dvb_feparams.u.qpsk.fec_inner = (fe_code_rate_t) scansettings.TP_fec;
TP.polarization = scansettings.TP_pol;
+ } else if (g_info.delivery_system == DVB_T) {
+ /* DVB-T. TODO: proper menu and parameter setup, not all "AUTO" */
+ if (TP.feparams.dvb_feparams.frequency < 300000)
+ TP.feparams.dvb_feparams.u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
+ else
+ TP.feparams.dvb_feparams.u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
+ TP.feparams.dvb_feparams.u.ofdm.code_rate_HP = FEC_AUTO;
+ TP.feparams.dvb_feparams.u.ofdm.code_rate_LP = FEC_AUTO;
+ TP.feparams.dvb_feparams.u.ofdm.constellation = QAM_AUTO;
+ TP.feparams.dvb_feparams.u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
+ TP.feparams.dvb_feparams.u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
+ TP.feparams.dvb_feparams.u.ofdm.hierarchy_information = HIERARCHY_AUTO;
} else {
TP.feparams.dvb_feparams.u.qam.symbol_rate = atoi(scansettings.TP_rate);
TP.feparams.dvb_feparams.u.qam.fec_inner = (fe_code_rate_t)scansettings.TP_fec;
diff --git a/src/gui/scan_setup.cpp b/src/gui/scan_setup.cpp
index 56198127c..b14e73628 100644
--- a/src/gui/scan_setup.cpp
+++ b/src/gui/scan_setup.cpp
@@ -218,7 +218,19 @@ CScanSetup::CScanSetup(bool wizard_mode)
is_wizard = wizard_mode;
//define caption of some forwarders and widgets depends of current receiver type
- satprov_locale = (r_system == DVB_S) ? LOCALE_SATSETUP_SATELLITE : LOCALE_CABLESETUP_PROVIDER;
+ switch (r_system)
+ {
+ case DVB_S:
+ satprov_locale = LOCALE_SATSETUP_SATELLITE;
+ break;
+ case DVB_T:
+ satprov_locale = LOCALE_TERRESTRIALSETUP_PROVIDER;
+ break;
+ case DVB_C:
+ default:
+ satprov_locale = LOCALE_CABLESETUP_PROVIDER;
+ break;
+ }
satSelect = NULL;
frontendSetup = NULL;
@@ -368,7 +380,7 @@ int CScanSetup::showScanMenu()
/* add configured satellites to satSelect */
fillSatSelect();
}
- else if (r_system == DVB_C) //cable
+ else if (r_system == DVB_C || r_system == DVB_T) //cable
{
//--------------------------------------------------------------
settings->addItem(GenericMenuSeparatorLine);
@@ -848,15 +860,20 @@ int CScanSetup::addScanOptionsItems(CMenuWidget *options_menu, const int &shortc
printf("[neutrino] CScanSetup call %s...\n", __FUNCTION__);
int shortCut = shortcut;
+ CMenuOptionChooser *fec = NULL;
+ CMenuOptionChooser *mod_pol= NULL;
+ CStringInput *rate = NULL;
+ CMenuForwarder *Rate = NULL;
+
CStringInput *freq = new CStringInput(LOCALE_EXTRA_TP_FREQ, (char *) scansettings.TP_freq, freq_length, NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, "0123456789");
CMenuForwarder *Freq = new CMenuDForwarder(LOCALE_EXTRA_TP_FREQ, true, scansettings.TP_freq, freq, "", CRCInput::convertDigitToKey(shortCut++));
- CStringInput *rate = new CStringInput(LOCALE_EXTRA_TP_RATE, (char *) scansettings.TP_rate, 8, NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, "0123456789");
- CMenuForwarder *Rate = new CMenuDForwarder(LOCALE_EXTRA_TP_RATE, true, scansettings.TP_rate, rate, "", CRCInput::convertDigitToKey(shortCut++));
+ if (r_system != DVB_T) {
+ rate = new CStringInput(LOCALE_EXTRA_TP_RATE, (char *) scansettings.TP_rate, 8, NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, "0123456789");
+ Rate = new CMenuDForwarder(LOCALE_EXTRA_TP_RATE, true, scansettings.TP_rate, rate, "", CRCInput::convertDigitToKey(shortCut++));
+ }
- CMenuOptionChooser *fec = NULL;
-
- CMenuOptionChooser *mod_pol= NULL;
+ /* TODO: DVB-T scan options */
if (r_system == DVB_S) {
fec = new CMenuOptionChooser(LOCALE_EXTRA_TP_FEC, (int *)&scansettings.TP_fec, SATSETUP_SCANTP_FEC, fec_count, true, NULL, CRCInput::convertDigitToKey(shortCut++), "", true);
mod_pol = new CMenuOptionChooser(LOCALE_EXTRA_TP_POL, (int *)&scansettings.TP_pol, SATSETUP_SCANTP_POL, SATSETUP_SCANTP_POL_COUNT, true, NULL, CRCInput::convertDigitToKey(shortCut++));
@@ -865,10 +882,12 @@ int CScanSetup::addScanOptionsItems(CMenuWidget *options_menu, const int &shortc
}
options_menu->addItem(Freq);
- options_menu->addItem(Rate);
- if (r_system == DVB_S)
+ if (Rate)
+ options_menu->addItem(Rate);
+ if (fec)
options_menu->addItem(fec);
- options_menu->addItem(mod_pol);
+ if (mod_pol)
+ options_menu->addItem(mod_pol);
return shortCut;
}
diff --git a/src/neutrino.cpp b/src/neutrino.cpp
index 37f2daa01..b8dc9b6bd 100644
--- a/src/neutrino.cpp
+++ b/src/neutrino.cpp
@@ -1869,7 +1869,18 @@ fprintf(stderr, "[neutrino start] %d -> %5ld ms\n", __LINE__, time_monotonic_ms
cpuFreq = new cCpuFreqManager();
cpuFreq->SetCpuFreq(g_settings.cpufreq * 1000 * 1000);
- g_info.delivery_system = CFEManager::getInstance()->getLiveFE()->getInfo()->type == FE_QPSK ? DVB_S : DVB_C;
+ switch (CFEManager::getInstance()->getLiveFE()->getInfo()->type) {
+ case FE_QPSK:
+ g_info.delivery_system = DVB_S;
+ break;
+ case FE_OFDM:
+ g_info.delivery_system = DVB_T;
+ break;
+ case FE_QAM:
+ default:
+ g_info.delivery_system = DVB_C;
+ break;
+ }
#if HAVE_COOL_HARDWARE
/* only SAT-hd1 before rev 8 has fan */
g_info.has_fan = (cs_get_revision() < 8 && g_info.delivery_system == DVB_S);
diff --git a/src/system/locals.h b/src/system/locals.h
index e013eccf4..b29c95e3a 100644
--- a/src/system/locals.h
+++ b/src/system/locals.h
@@ -1215,6 +1215,7 @@ typedef enum
LOCALE_SCANTS_ABORT_HEADER,
LOCALE_SCANTS_ACTCABLE,
LOCALE_SCANTS_ACTSATELLITE,
+ LOCALE_SCANTS_ACTTERRESTRIAL,
LOCALE_SCANTS_BOUQUET,
LOCALE_SCANTS_BOUQUET_CREATE,
LOCALE_SCANTS_BOUQUET_ERASE,
@@ -1302,6 +1303,7 @@ typedef enum
LOCALE_STRINGINPUT_CLEAR,
LOCALE_SUBTITLES_HEAD,
LOCALE_SUBTITLES_STOP,
+ LOCALE_TERRESTRIALSETUP_PROVIDER,
LOCALE_TIMER_EVENTRECORD_MSG,
LOCALE_TIMER_EVENTRECORD_TITLE,
LOCALE_TIMER_EVENTTIMED_MSG,
diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h
index fffc15c75..a0d883ef9 100644
--- a/src/system/locals_intern.h
+++ b/src/system/locals_intern.h
@@ -1215,6 +1215,7 @@ const char * locale_real_names[] =
"scants.abort_header",
"scants.actcable",
"scants.actsatellite",
+ "scants.actterrestrial",
"scants.bouquet",
"scants.bouquet_create",
"scants.bouquet_erase",
@@ -1302,6 +1303,7 @@ const char * locale_real_names[] =
"stringinput.clear",
"subtitles.head",
"subtitles.stop",
+ "terrestrialsetup.provider",
"timer.eventrecord.msg",
"timer.eventrecord.title",
"timer.eventtimed.msg",
diff --git a/src/zapit/include/zapit/getservices.h b/src/zapit/include/zapit/getservices.h
index 7783bcfbb..10d6deef0 100644
--- a/src/zapit/include/zapit/getservices.h
+++ b/src/zapit/include/zapit/getservices.h
@@ -88,7 +88,7 @@ class CServiceManager
sat_transponder_map_t satelliteTransponders;
bool ParseScanXml();
- void ParseTransponders(xmlNodePtr node, t_satellite_position satellitePosition, bool cable);
+ void ParseTransponders(xmlNodePtr node, t_satellite_position satellitePosition, fe_type fe);
void ParseChannels(xmlNodePtr node, const t_transport_stream_id transport_stream_id, const t_original_network_id original_network_id, t_satellite_position satellitePosition, freq_id_t freq, uint8_t polarization);
void FindTransponder(xmlNodePtr search);
void ParseSatTransponders(fe_type_t frontendType, xmlNodePtr search, t_satellite_position satellitePosition);
diff --git a/src/zapit/include/zapit/scan.h b/src/zapit/include/zapit/scan.h
index 36a6f5b54..b298a9469 100644
--- a/src/zapit/include/zapit/scan.h
+++ b/src/zapit/include/zapit/scan.h
@@ -60,7 +60,6 @@ class CServiceScan : public OpenThreads::Thread
private:
bool started;
bool running;
- bool cable;
bool abort_scan;
scan_type_t scan_mode;
int flags;
diff --git a/src/zapit/include/zapit/settings.h b/src/zapit/include/zapit/settings.h
index b72dc214f..4f5192ad7 100644
--- a/src/zapit/include/zapit/settings.h
+++ b/src/zapit/include/zapit/settings.h
@@ -47,6 +47,7 @@
#define CABLES_XML CONFIGDIR "/cables.xml"
#define SATELLITES_XML CONFIGDIR "/satellites.xml"
+#define TERRESTRIAL_XML CONFIGDIR "/terrestrial.xml"
#if HAVE_TRIPLEDRAGON == 0
#define AUDIO_DEVICE "/dev/dvb/adapter0/audio0"
diff --git a/src/zapit/src/frontend.cpp b/src/zapit/src/frontend.cpp
index 8cac24368..318418b4e 100644
--- a/src/zapit/src/frontend.cpp
+++ b/src/zapit/src/frontend.cpp
@@ -52,17 +52,27 @@ extern int zapit_debug;
#define FREQUENCY 1
#define MODULATION 2
#define INVERSION 3
+// common to S/S2/C
#define SYMBOL_RATE 4
#define DELIVERY_SYSTEM 5
#define INNER_FEC 6
// DVB-S/S2 specific
#define PILOTS 7
#define ROLLOFF 8
+// DVB-T specific
+#define BANDWIDTH 4
+#define CODE_RATE_HP 6
+#define CODE_RATE_LP 7
+#define TRANSMISSION_MODE 8
+#define GUARD_INTERVAL 9
+#define HIERARCHY 10
+
#define FE_COMMON_PROPS 2
#define FE_DVBS_PROPS 6
#define FE_DVBS2_PROPS 8
#define FE_DVBC_PROPS 6
+#define FE_DVBT_PROPS 10
/* stolen from dvb.c from vlc */
static const struct dtv_property dvbs_cmdargs[] = {
@@ -100,6 +110,21 @@ static const struct dtv_property dvbc_cmdargs[] = {
{ DTV_TUNE, {}, { 0 }, 0},
};
+static const struct dtv_property dvbt_cmdargs[] = {
+ { DTV_CLEAR, {0,0,0}, { 0 } ,0},
+ { DTV_FREQUENCY, {}, { 0 } ,0},
+ { DTV_MODULATION, {}, { QAM_AUTO } ,0},
+ { DTV_INVERSION, {}, { INVERSION_AUTO } ,0},
+ { DTV_BANDWIDTH_HZ, {}, { 8000000 } ,0},
+ { DTV_DELIVERY_SYSTEM, {}, { SYS_DVBT } ,0},
+ { DTV_CODE_RATE_HP, {}, { FEC_AUTO } ,0},
+ { DTV_CODE_RATE_LP, {}, { FEC_AUTO } ,0},
+ { DTV_TRANSMISSION_MODE,{}, { TRANSMISSION_MODE_AUTO}, 0},
+ { DTV_GUARD_INTERVAL, {}, { GUARD_INTERVAL_AUTO}, 0},
+ { DTV_HIERARCHY, {}, { HIERARCHY_AUTO }, 0},
+ { DTV_TUNE, {}, { 0 }, 0},
+};
+
#define diff(x,y) (max(x,y) - min(x,y))
@@ -528,7 +553,8 @@ void CFrontend::getDelSys(int f, int m, char *&fec, char *&sys, char *&mod)
void CFrontend::getDelSys(uint8_t type, int f, int m, char *&fec, char *&sys, char *&mod)
{
- if (type == FE_QPSK) {
+ switch (type) {
+ case FE_QPSK:
if (f < FEC_S2_QPSK_1_2) {
sys = (char *)"DVB";
mod = (char *)"QPSK";
@@ -539,7 +565,9 @@ void CFrontend::getDelSys(uint8_t type, int f, int m, char *&fec, char *&sys, ch
sys = (char *)"DVB-S2";
mod = (char *)"8PSK";
}
- } else if (type == FE_QAM) {
+ break;
+ case FE_QAM:
+ case FE_OFDM:
sys = (char *)"DVB";
switch (m) {
case QAM_16:
@@ -557,11 +585,23 @@ void CFrontend::getDelSys(uint8_t type, int f, int m, char *&fec, char *&sys, ch
case QAM_256:
mod = (char *)"QAM_256";
break;
+ case QPSK:
+ if (type == FE_OFDM) {
+ mod = (char *)"QPSK";
+ break;
+ }
+ /* fallthrouh for FE_QAM... */
case QAM_AUTO:
default:
mod = (char *)"QAM_AUTO";
break;
}
+ break;
+ default:
+ printf("[frontend] unknown type %d!\n", type);
+ sys = (char *)"UNKNOWN";
+ mod = (char *)"UNKNOWN";
+ break;
}
switch (f) {
@@ -641,6 +681,11 @@ bool CFrontend::buildProperties(const FrontendParameters *feparams, struct dtv_p
modulation = feparams->dvb_feparams.u.qam.modulation;
delsys = SYS_DVBC_ANNEX_AC;
break;
+ case FE_OFDM:
+ fec_inner = FEC_AUTO; /* dummy, for next switch statement */
+ modulation = feparams->dvb_feparams.u.ofdm.constellation;
+ delsys = SYS_DVBT;
+ break;
default:
printf("frontend: unknown frontend type, exiting\n");
return 0;
@@ -739,6 +784,36 @@ bool CFrontend::buildProperties(const FrontendParameters *feparams, struct dtv_p
cmdseq.props[INNER_FEC].u.data = fec_inner;
nrOfProps = FE_DVBC_PROPS;
break;
+ case FE_OFDM:
+ memcpy(cmdseq.props, dvbt_cmdargs, sizeof(dvbt_cmdargs));
+ nrOfProps = FE_DVBT_PROPS;
+ cmdseq.props[FREQUENCY].u.data = feparams->dvb_feparams.frequency;
+ cmdseq.props[MODULATION].u.data = modulation;
+ cmdseq.props[INVERSION].u.data = feparams->dvb_feparams.inversion;
+ cmdseq.props[CODE_RATE_HP].u.data = feparams->dvb_feparams.u.ofdm.code_rate_HP;
+ cmdseq.props[CODE_RATE_LP].u.data = feparams->dvb_feparams.u.ofdm.code_rate_LP;
+ cmdseq.props[TRANSMISSION_MODE].u.data = feparams->dvb_feparams.u.ofdm.transmission_mode;
+ cmdseq.props[GUARD_INTERVAL].u.data = feparams->dvb_feparams.u.ofdm.guard_interval;
+ cmdseq.props[HIERARCHY].u.data = feparams->dvb_feparams.u.ofdm.hierarchy_information;
+ switch (feparams->dvb_feparams.u.ofdm.bandwidth) {
+ case BANDWIDTH_6_MHZ:
+ cmdseq.props[BANDWIDTH].u.data = 6000000;
+ break;
+ case BANDWIDTH_7_MHZ:
+ cmdseq.props[BANDWIDTH].u.data = 7000000;
+ break;
+ case BANDWIDTH_8_MHZ:
+ cmdseq.props[BANDWIDTH].u.data = 8000000;
+ break;
+ default:
+ printf("[fe%d] unknown bandwidth for OFDM %d\n",
+ fenumber, feparams->dvb_feparams.u.ofdm.bandwidth);
+ /* fallthrough */
+ case BANDWIDTH_AUTO:
+ cmdseq.props[BANDWIDTH].u.data = 0;
+ break;
+ }
+ break;
default:
printf("frontend: unknown frontend type, exiting\n");
return false;
@@ -758,7 +833,7 @@ bool CFrontend::buildProperties(const FrontendParameters *feparams, struct dtv_p
int CFrontend::setFrontend(const FrontendParameters *feparams, bool /*nowait*/)
{
- struct dtv_property cmdargs[FE_COMMON_PROPS + FE_DVBS2_PROPS]; // WARNING: increase when needed more space
+ struct dtv_property cmdargs[FE_COMMON_PROPS + FE_DVBT_PROPS]; // WARNING: increase when needed more space
struct dtv_properties cmdseq;
cmdseq.num = FE_COMMON_PROPS;
@@ -1143,10 +1218,10 @@ int CFrontend::setParameters(TP_params *TP, bool /*nowait*/)
feparams = &currTP.feparams;
freq = (int) feparams->dvb_feparams.frequency;
char * f, *s, *m;
+ bool high_band;
- if (info.type == FE_QPSK) {
- bool high_band;
-
+ switch (info.type) {
+ case FE_QPSK:
if (freq < lnbSwitch) {
high_band = false;
freq_offset = lnbOffsetLow;
@@ -1158,7 +1233,8 @@ int CFrontend::setParameters(TP_params *TP, bool /*nowait*/)
feparams->dvb_feparams.frequency = abs(freq - freq_offset);
setSec(TP->diseqc, TP->polarization, high_band);
getDelSys(feparams->dvb_feparams.u.qpsk.fec_inner, dvbs_get_modulation(feparams->dvb_feparams.u.qpsk.fec_inner), f, s, m);
- } else if (info.type == FE_QAM) {
+ break;
+ case FE_QAM:
if (freq < 1000*1000)
feparams->dvb_feparams.frequency = freq * 1000;
getDelSys(feparams->dvb_feparams.u.qam.fec_inner,feparams->dvb_feparams.u.qam.modulation, f, s, m);
@@ -1173,6 +1249,14 @@ int CFrontend::setParameters(TP_params *TP, bool /*nowait*/)
break;
}
#endif
+ case FE_OFDM:
+ if (freq < 1000*1000)
+ feparams->dvb_feparams.frequency = freq * 1000;
+ getDelSys(feparams->dvb_feparams.u.ofdm.code_rate_HP,feparams->dvb_feparams.u.ofdm.constellation, f, s, m);
+ break;
+ default:
+ printf("[fe%d] unknown type %d\n", fenumber, info.type);
+ break;
}
//printf("[fe%d] tuner to frequency %d (offset %d timeout %d)\n", fenumber, feparams->dvb_feparams.frequency, freq_offset, TIMEOUT_MAX_MS);
diff --git a/src/zapit/src/getservices.cpp b/src/zapit/src/getservices.cpp
index b773d6469..e9c6cfe12 100644
--- a/src/zapit/src/getservices.cpp
+++ b/src/zapit/src/getservices.cpp
@@ -70,11 +70,12 @@ bool CServiceManager::ParseScanXml(void)
case FE_QPSK:
scanInputParser = parseXmlFile(SATELLITES_XML);
break;
-
case FE_QAM:
scanInputParser = parseXmlFile(CABLES_XML);
break;
-
+ case FE_OFDM:
+ scanInputParser = parseXmlFile(TERRESTRIAL_XML);
+ break;
default:
WARN("Unknown type %d", frontendType);
return false;
@@ -291,7 +292,7 @@ std::string CServiceManager::GetServiceName(t_channel_id channel_id)
return "";
}
-void CServiceManager::ParseTransponders(xmlNodePtr node, t_satellite_position satellitePosition, bool cable)
+void CServiceManager::ParseTransponders(xmlNodePtr node, t_satellite_position satellitePosition, fe_type fe)
{
uint8_t polarization = 0;
@@ -304,14 +305,18 @@ void CServiceManager::ParseTransponders(xmlNodePtr node, t_satellite_position sa
feparams.dvb_feparams.frequency = xmlGetNumericAttribute(node, "frq", 0);
feparams.dvb_feparams.inversion = (fe_spectral_inversion) xmlGetNumericAttribute(node, "inv", 0);
- if(cable) {
+ switch (fe) {
+ case FE_QAM:
feparams.dvb_feparams.u.qam.symbol_rate = xmlGetNumericAttribute(node, "sr", 0);
feparams.dvb_feparams.u.qam.fec_inner = (fe_code_rate_t) xmlGetNumericAttribute(node, "fec", 0);
feparams.dvb_feparams.u.qam.modulation = (fe_modulation_t) xmlGetNumericAttribute(node, "mod", 0);
if (feparams.dvb_feparams.frequency > 1000*1000)
feparams.dvb_feparams.frequency = feparams.dvb_feparams.frequency/1000; //transponderlist was read from tuxbox
- } else {
+ break;
+ case FE_OFDM:
+ break;
+ default:
feparams.dvb_feparams.u.qpsk.fec_inner = (fe_code_rate_t) xmlGetNumericAttribute(node, "fec", 0);
feparams.dvb_feparams.u.qpsk.symbol_rate = xmlGetNumericAttribute(node, "sr", 0);
@@ -325,7 +330,8 @@ void CServiceManager::ParseTransponders(xmlNodePtr node, t_satellite_position sa
else
feparams.dvb_feparams.frequency = (int) 1000 * (int) round ((double) feparams.dvb_feparams.frequency / (double) 1000);
}
- freq_id_t freq = CREATE_FREQ_ID(feparams.dvb_feparams.frequency, cable);
+
+ freq_id_t freq = CREATE_FREQ_ID(feparams.dvb_feparams.frequency, fe != FE_QPSK);
transponder_id_t tid = CREATE_TRANSPONDER_ID64(freq, satellitePosition,original_network_id,transport_stream_id);
transponder t(frontendType, tid, feparams, polarization);
@@ -438,18 +444,19 @@ void CServiceManager::ParseChannels(xmlNodePtr node, const t_transport_stream_id
void CServiceManager::FindTransponder(xmlNodePtr search)
{
while (search) {
- bool cable = false;
+ bool sat = false;
- if (!(strcmp(xmlGetName(search), "cable")))
- cable = true;
- else if ((strcmp(xmlGetName(search), "sat"))) {
+ if (!(strcmp(xmlGetName(search), "sat")))
+ sat = true;
+ else if (strcmp(xmlGetName(search), "cable") && strcmp(xmlGetName(search), "terrestrial")) {
search = search->xmlNextNode;
continue;
}
t_satellite_position satellitePosition = xmlGetSignedNumericAttribute(search, "position", 10);
DBG("going to parse dvb-%c provider %s\n", xmlGetName(search)[0], xmlGetAttribute(search, "name"));
- ParseTransponders(search->xmlChildrenNode, satellitePosition, cable);
+ /* ParseTransponders is only interested in sat / not sat, sp the real type does not matter */
+ ParseTransponders(search->xmlChildrenNode, satellitePosition, sat ? FE_QPSK : FE_QAM);
newfound++;
search = search->xmlNextNode;
}
@@ -490,7 +497,28 @@ void CServiceManager::ParseSatTransponders(fe_type_t fType, xmlNodePtr search, t
feparams.dvb_feparams.u.qpsk.fec_inner = (fe_code_rate_t) xml_fec;
feparams.dvb_feparams.frequency = (int) 1000 * (int) round ((double) feparams.dvb_feparams.frequency / (double) 1000);
}
- freq_id_t freq = CREATE_FREQ_ID(feparams.dvb_feparams.frequency, fType == FE_QAM);
+ else if (fType == FE_OFDM) {
+ feparams.dvb_feparams.u.ofdm.bandwidth = (fe_bandwidth_t)
+ xmlGetNumericAttribute(tps, "bandwidth", 0);
+ feparams.dvb_feparams.u.ofdm.constellation = (fe_modulation_t)
+ xmlGetNumericAttribute(tps, "constellation", 0);
+ feparams.dvb_feparams.u.ofdm.transmission_mode = (fe_transmit_mode_t)
+ xmlGetNumericAttribute(tps, "transmission_mode", 0);
+ feparams.dvb_feparams.u.ofdm.code_rate_HP = (fe_code_rate_t)
+ xmlGetNumericAttribute(tps, "code_rate_HP", 0);
+ feparams.dvb_feparams.u.ofdm.code_rate_LP = (fe_code_rate_t)
+ xmlGetNumericAttribute(tps, "code_rate_LP", 0);
+ feparams.dvb_feparams.u.ofdm.guard_interval = (fe_guard_interval_t)
+ xmlGetNumericAttribute(tps, "guard_interval", 0);
+ feparams.dvb_feparams.u.ofdm.hierarchy_information = (fe_hierarchy_t)
+ xmlGetNumericAttribute(tps, "hierarchy", 0);
+ if (feparams.dvb_feparams.frequency > 1000*1000)
+ feparams.dvb_feparams.frequency /= 1000; // old transponder list
+ }
+ else /* we'll probably crash sooner or later, so write to STDERR... */
+ fprintf(stderr, "[getservices] %s: unknown frontend type %d!\n", __func__, fType);
+
+ freq_id_t freq = CREATE_FREQ_ID(feparams.dvb_feparams.frequency, fType != FE_QPSK);
polarization &= 7;
transponder_id_t tid = CREATE_TRANSPONDER_ID64(freq, satellitePosition, fake_nid, fake_tid);
@@ -636,7 +664,8 @@ bool CServiceManager::LoadServices(bool only_current)
position = xmlGetSignedNumericAttribute(search, "position", 10);
char * name = xmlGetAttribute(search, "name");
InitSatPosition(position, name);
- } else if(!(strcmp(xmlGetName(search), "cable"))) {
+ } else if (!strcmp(xmlGetName(search), "cable") ||
+ !strcmp(xmlGetName(search), "terrestrial")) {
char * name = xmlGetAttribute(search, "name");
InitSatPosition(position, name);
}
@@ -726,7 +755,9 @@ void CServiceManager::WriteSatHeader(FILE * fd, sat_config_t &config)
case FE_QAM: /* cable */
fprintf(fd, "\t\n", config.name.c_str(), config.position);
break;
- case FE_OFDM:
+ case FE_OFDM: /* terrestrial */
+ fprintf(fd, "\t\n", config.name.c_str(), config.position);
+ break;
default:
break;
}
@@ -792,6 +823,9 @@ void CServiceManager::SaveServices(bool tocopy, bool if_changed)
case FE_QAM:
fprintf(fd, "\t\n");
break;
+ case FE_OFDM:
+ fprintf(fd, "\t\n");
+ break;
default:
break;
}
@@ -913,6 +947,8 @@ bool CServiceManager::SaveCurrentServices(transponder_id_t tpid)
sprintf(satstr, "\t<%s name=\"%s\"\n", "cable", spos_it->second.name.c_str());
break;
case FE_OFDM:
+ sprintf(satstr, "\t<%s name=\"%s\"\n", "terrestrial", spos_it->second.name.c_str());
+ break;
default:
break;
}
diff --git a/src/zapit/src/scan.cpp b/src/zapit/src/scan.cpp
index b7143a7e4..f82d2dcf9 100644
--- a/src/zapit/src/scan.cpp
+++ b/src/zapit/src/scan.cpp
@@ -282,7 +282,7 @@ _repeat:
}
}
- freq_id_t freq = CREATE_FREQ_ID(tI->second.feparams.dvb_feparams.frequency, cable);
+ freq_id_t freq = CREATE_FREQ_ID(tI->second.feparams.dvb_feparams.frequency, frontendType != FE_QPSK);
CNit nit(satellitePosition, freq, cable_nid);
if(flags & SCAN_NIT)
@@ -489,7 +489,6 @@ bool CServiceScan::SetFrontend(t_satellite_position satellitePosition)
frontend = fe;
CFEManager::getInstance()->setLiveFE(frontend);
frontendType = frontend->getInfo()->type;
- cable = (frontend->getInfo()->type == FE_QAM);//FIXME
return true;
}
@@ -601,9 +600,10 @@ bool CServiceScan::ScanTransponder()
printf("[scan] NIT %s, fta only: %s, satellites %s\n", flags & SCAN_NIT ? "yes" : "no",
flags & SCAN_FTA ? "yes" : "no", scanProviders.size() == 1 ? "single" : "multi");
- freq_id_t freq = CREATE_FREQ_ID(TP->feparams.dvb_feparams.frequency, cable);
+ freq_id_t freq = CREATE_FREQ_ID(TP->feparams.dvb_feparams.frequency, frontendType != FE_QPSK);
fake_tid++; fake_nid++;
+
transponder_id_t tid = CREATE_TRANSPONDER_ID64(freq, satellitePosition, fake_nid, fake_tid);
transponder t(frontendType, tid, TP->feparams, TP->polarization);
t.dump("[scan]");
@@ -643,7 +643,7 @@ bool CServiceScan::ReplaceTransponderParams(freq_id_t freq, t_satellite_position
bool ret = false;
for (transponder_list_t::iterator tI = transponders.begin(); tI != transponders.end(); ++tI) {
if (tI->second.satellitePosition == satellitePosition) {
- freq_id_t newfreq = CREATE_FREQ_ID(tI->second.feparams.dvb_feparams.frequency, cable);
+ freq_id_t newfreq = CREATE_FREQ_ID(tI->second.feparams.dvb_feparams.frequency, frontendType != FE_QPSK);
if (freq == newfreq) {
memcpy(&tI->second.feparams, feparams, sizeof(struct dvb_frontend_parameters));
tI->second.polarization = polarization;
@@ -659,7 +659,7 @@ bool CServiceScan::ReplaceTransponderParams(freq_id_t freq, t_satellite_position
void CServiceScan::SendTransponderInfo(transponder &t)
{
uint32_t actual_freq = t.feparams.dvb_feparams.frequency;
- if (!cable)
+ if (frontendType == FE_QAM)
actual_freq /= 1000;
CZapit::getInstance()->SendEvent(CZapitClient::EVT_SCAN_REPORT_FREQUENCY, &actual_freq,sizeof(actual_freq));
@@ -667,7 +667,7 @@ void CServiceScan::SendTransponderInfo(transponder &t)
CZapit::getInstance()->SendEvent(CZapitClient::EVT_SCAN_PROVIDER, (void *) " ", 2);
CZapit::getInstance()->SendEvent(CZapitClient::EVT_SCAN_SERVICENAME, (void *) " ", 2);
- if (!cable) {
+ if (frontendType == FE_QPSK) {
uint32_t actual_polarisation = ((t.feparams.dvb_feparams.u.qpsk.symbol_rate/1000) << 16) | (t.feparams.dvb_feparams.u.qpsk.fec_inner << 8) | (uint)t.polarization;
CZapit::getInstance()->SendEvent(CZapitClient::EVT_SCAN_REPORT_FREQUENCYP, &actual_polarisation,sizeof(actual_polarisation));
}
diff --git a/src/zapit/src/transponder.cpp b/src/zapit/src/transponder.cpp
index 0db0d34bb..147b327b8 100644
--- a/src/zapit/src/transponder.cpp
+++ b/src/zapit/src/transponder.cpp
@@ -52,13 +52,20 @@ transponder::transponder()
bool transponder::operator==(const transponder& t) const
{
- return (
+ if (type != FE_OFDM)
+ return (
(satellitePosition == t.satellitePosition) &&
//(transport_stream_id == t.transport_stream_id) &&
//(original_network_id == t.original_network_id) &&
((polarization & 1) == (t.polarization & 1)) &&
(abs((int) feparams.dvb_feparams.frequency - (int)t.feparams.dvb_feparams.frequency) <= 3000)
);
+ return ((satellitePosition == t.satellitePosition) &&
+ //(transport_stream_id == t.transport_stream_id) &&
+ //(original_network_id == t.original_network_id) &&
+ ((polarization & 1) == (t.polarization & 1)) &&
+ (abs((int) feparams.dvb_feparams.frequency - (int)t.feparams.dvb_feparams.frequency) <= 100)
+ );
}
bool transponder::compare(const transponder& t) const
@@ -76,13 +83,23 @@ bool transponder::compare(const transponder& t) const
(dvb_feparams1->u.qam.modulation == dvb_feparams2->u.qam.modulation ||
dvb_feparams1->u.qam.modulation == QAM_AUTO || dvb_feparams2->u.qam.modulation == QAM_AUTO)
);
- } else {
+ } else if (type == FE_QPSK) {
ret = (
(t == (*this)) &&
(dvb_feparams1->u.qpsk.symbol_rate == dvb_feparams2->u.qpsk.symbol_rate) &&
(dvb_feparams1->u.qpsk.fec_inner == dvb_feparams2->u.qpsk.fec_inner ||
dvb_feparams1->u.qpsk.fec_inner == FEC_AUTO || dvb_feparams2->u.qpsk.fec_inner == FEC_AUTO)
);
+ } else if (type == FE_OFDM) {
+ ret = ( (t == (*this)) &&
+ (dvb_feparams1->u.ofdm.bandwidth == dvb_feparams2->u.ofdm.bandwidth) &&
+ (dvb_feparams1->u.ofdm.code_rate_HP == dvb_feparams2->u.ofdm.code_rate_HP ||
+ dvb_feparams1->u.ofdm.code_rate_HP == FEC_AUTO || dvb_feparams2->u.ofdm.code_rate_HP == FEC_AUTO) &&
+ (dvb_feparams1->u.ofdm.code_rate_LP == dvb_feparams2->u.ofdm.code_rate_LP ||
+ dvb_feparams1->u.ofdm.code_rate_LP == FEC_AUTO || dvb_feparams2->u.ofdm.code_rate_LP == FEC_AUTO) &&
+ (dvb_feparams1->u.ofdm.constellation == dvb_feparams2->u.ofdm.constellation ||
+ dvb_feparams1->u.ofdm.constellation == QAM_AUTO || dvb_feparams2->u.ofdm.constellation == QAM_AUTO)
+ );
}
return ret;
}
@@ -98,12 +115,20 @@ void transponder::dumpServiceXml(FILE * fd)
dvb_feparams->u.qam.symbol_rate, dvb_feparams->u.qam.fec_inner,
dvb_feparams->u.qam.modulation);
- } else {
+ } else if (type == FE_QPSK) {
fprintf(fd, "\t\t\n",
transport_stream_id, original_network_id,
dvb_feparams->frequency, dvb_feparams->inversion,
dvb_feparams->u.qpsk.symbol_rate, dvb_feparams->u.qpsk.fec_inner,
polarization);
+ } else if (type == FE_OFDM) {
+ fprintf(fd, "\t\t\n",
+ transport_stream_id, original_network_id,
+ dvb_feparams->frequency, dvb_feparams->inversion,
+ dvb_feparams->u.ofdm.bandwidth, dvb_feparams->u.ofdm.code_rate_HP,
+ dvb_feparams->u.ofdm.code_rate_LP, dvb_feparams->u.ofdm.constellation,
+ dvb_feparams->u.ofdm.transmission_mode, dvb_feparams->u.ofdm.guard_interval,
+ dvb_feparams->u.ofdm.hierarchy_information);
}
}
@@ -115,10 +140,14 @@ void transponder::dump(std::string label)
printf("%s tp-id %016llx freq %d rate %d fec %d mod %d\n", label.c_str(),
transponder_id, dvb_feparams->frequency, dvb_feparams->u.qam.symbol_rate,
dvb_feparams->u.qam.fec_inner, dvb_feparams->u.qam.modulation);
- else
+ else if (type == FE_QPSK)
printf("%s tp-id %016llx freq %d rate %d fec %d pol %d\n", label.c_str(),
transponder_id, dvb_feparams->frequency, dvb_feparams->u.qpsk.symbol_rate,
dvb_feparams->u.qpsk.fec_inner, polarization);
+ else if (type == FE_OFDM)
+ printf("%s tp-id %016llx freq %d bw %d coderate %d\n", label.c_str(),
+ transponder_id, dvb_feparams->frequency, dvb_feparams->u.ofdm.bandwidth,
+ dvb_feparams->u.ofdm.code_rate_HP);
}
void transponder::ddump(std::string label)
@@ -142,8 +171,10 @@ char transponder::pol(unsigned char p)
std::string transponder::description()
{
char buf[128] = {0};
- char * f, *s, *m;
+ char *f, *s, *m, *f2;
struct dvb_frontend_parameters *dvb_feparams = &feparams.dvb_feparams;
+ const char *bw[4] = { "8MHz", "7MHz", "6MHz", "auto" };
+ int b;
switch(type) {
case FE_QPSK:
@@ -155,7 +186,15 @@ std::string transponder::description()
snprintf(buf, sizeof(buf), "%d %d %s %s %s ", dvb_feparams->frequency/1000, dvb_feparams->u.qam.symbol_rate/1000, f, s, m);
break;
case FE_OFDM:
+ CFrontend::getDelSys(type, dvb_feparams->u.ofdm.code_rate_HP, dvb_feparams->u.ofdm.constellation, f, s, m);
+ CFrontend::getDelSys(type, dvb_feparams->u.ofdm.code_rate_LP, dvb_feparams->u.ofdm.constellation, f2, s, m);
+ b = dvb_feparams->u.ofdm.bandwidth;
+ if (b > 3)
+ b = 3;
+ snprintf(buf, sizeof(buf), "%d %s %s %s %s ", dvb_feparams->frequency, bw[b], f, f2, m);
+ break;
case FE_ATSC:
+ snprintf(buf, sizeof(buf), "ATSC not yet supported ");
break;
}
return std::string(buf);