MythTV  master
dtvconfparser.cpp
Go to the documentation of this file.
1 /*
2  * vim: set expandtab tabstop=4 shiftwidth=4:
3  *
4  * Original Project
5  * MythTV http://www.mythtv.org
6  *
7  * Author(s):
8  * John Pullan (john@pullan.org)
9  *
10  * Description:
11  * Collection of classes to provide dvb channel scanning
12  * functionallity
13  *
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
29  *
30  */
31 
32 // Qt headers
33 #include <QTextStream>
34 #include <QFile>
35 
36 // MythTV headers
37 #include "libmythbase/mythdbcon.h"
39 #include "dtvconfparser.h"
40 #include "channelutil.h"
41 
42 // NOLINTBEGIN(cppcoreguidelines-macro-usage)
43 #define PARSE_SKIP(VAR) do { \
44  if (it == tokens.end()) return false; \
45  ++it; } while(false)
46 
47 #define PARSE_CONF(VAR) do { \
48  if (it == tokens.end()) return false; \
49  if (!(VAR).ParseConf(*it)) return false; \
50  it++; } while(false)
51 
52 #define PARSE_STR(VAR) do { \
53  if (it != tokens.end()) (VAR) = *it++; else return false; } while(false)
54 
55 #define PARSE_UINT(VAR) do { \
56  if (it != tokens.end()) \
57  (VAR) = (*it++).toUInt(); else return false; } while(false)
58 
59 #define PARSE_UINT_1000(VAR) do { \
60  if (it != tokens.end()) \
61  (VAR) = (*it++).toUInt() * 1000ULL; else return false; } while(false)
62 // NOLINTEND(cppcoreguidelines-macro-usage)
63 
64 
65 QString DTVChannelInfo::toString() const
66 {
67  return QString("%1 %2 %3 ").arg(m_name).arg(m_serviceid).arg(m_lcn);
68 }
69 
71 {
72  m_channels.clear();
73 
74  QFile file(m_filename);
75  if (!file.open(QIODevice::ReadOnly))
76  return return_t::ERROR_OPEN;
77 
78  bool ok = true;
79  QTextStream stream(&file);
80  QString line;
81  while (!stream.atEnd())
82  {
83  line = stream.readLine(); // line of text excluding '\n'
84  line = line.trimmed();
85  if (line.startsWith("#"))
86  continue;
87 
88  QStringList list = line.split(":", Qt::SkipEmptyParts);
89  if (list.empty())
90  continue;
91 
92  QString str = list[0];
93  int channelNo = -1;
94 
95  if ((str.length() >= 1) && (str.at(0) == '@'))
96  {
97  channelNo = str.mid(1).toInt();
98  line = stream.readLine();
99  list = line.split(":", Qt::SkipEmptyParts);
100  }
101 
102  if (list.size() < 4)
103  continue;
104 
105  str = list[3];
106 
107  if ((str == "T") || (str == "C") || (str == "S"))
108  {
109  if (((m_type == cardtype_t::OFDM) && (str == "T")) ||
110  ((m_type == cardtype_t::QPSK || m_type == cardtype_t::DVBS2) && (str == "S")) ||
111  ((m_type == cardtype_t::QAM) && (str == "C")))
112  ok &= ParseVDR(list, channelNo);
113  }
114  else if (m_type == cardtype_t::OFDM)
115  {
116  ok &= ParseConfOFDM(list);
117  }
118  else if (m_type == cardtype_t::ATSC)
119  {
120  ok &= ParseConfATSC(list);
121  }
123  {
124  ok &= ParseConfQPSK(list);
125  }
126  else if (m_type == cardtype_t::QAM)
127  {
128  ok &= ParseConfQAM(list);
129  }
130  }
131  file.close();
132 
133  return (ok) ? return_t::OK : return_t::ERROR_PARSE;
134 }
135 
136 bool DTVConfParser::ParseConfOFDM(const QStringList &tokens)
137 {
138  DTVChannelInfo chan;
139  DTVMultiplex mux;
140 
141  QStringList::const_iterator it = tokens.begin();
142 
143  PARSE_SKIP(unknown);
144  PARSE_UINT(mux.m_frequency);
145  PARSE_CONF(mux.m_inversion);
146  PARSE_CONF(mux.m_bandwidth);
150  PARSE_CONF(mux.m_transMode);
152  PARSE_CONF(mux.m_hierarchy);
153  PARSE_SKIP(unknown);
154  PARSE_SKIP(unknown);
155  PARSE_UINT(chan.m_serviceid);
156 
157  AddChannel(mux, chan);
158 
159  return true;
160 }
161 
162 bool DTVConfParser::ParseConfATSC(const QStringList &tokens)
163 {
164  DTVChannelInfo chan;
165  DTVMultiplex mux;
166 
167  QStringList::const_iterator it = tokens.begin();
168 
169  PARSE_STR(chan.m_name);
170  PARSE_UINT(mux.m_frequency);
172  PARSE_SKIP(Ignore_Video_PID);
173  PARSE_SKIP(Ignore_Audio_PID);
174  PARSE_UINT(chan.m_serviceid);
175 
176  AddChannel(mux, chan);
177 
178  return true;
179 }
180 
181 bool DTVConfParser::ParseConfQAM(const QStringList &tokens)
182 {
183  DTVChannelInfo chan;
184  DTVMultiplex mux;
185 
186  QStringList::const_iterator it = tokens.begin();
187 
188  PARSE_SKIP(unknown);
189  PARSE_UINT(mux.m_frequency);
190  PARSE_CONF(mux.m_inversion);
192  PARSE_CONF(mux.m_fec);
194  PARSE_SKIP(unknown);
195  PARSE_SKIP(unknown);
196  PARSE_UINT(chan.m_serviceid);
197 
198  AddChannel(mux, chan);
199 
200  return true;
201 }
202 
203 bool DTVConfParser::ParseConfQPSK(const QStringList &tokens)
204 {
205  DTVChannelInfo chan;
206  DTVMultiplex mux;
207 
208  QStringList::const_iterator it = tokens.begin();
209 
210  PARSE_STR(chan.m_name);
212  PARSE_CONF(mux.m_polarity);
213  PARSE_SKIP(Satelite_Number);
215  PARSE_SKIP(unknown);
216  PARSE_SKIP(unknown);
217  PARSE_UINT(chan.m_serviceid);
218 
219  AddChannel(mux, chan);
220 
221  return true;
222 }
223 
224 bool DTVConfParser::ParseVDR(const QStringList &tokens, int channelNo)
225 {
226  DTVChannelInfo chan;
227  DTVMultiplex mux;
228 
229  QStringList::const_iterator it = tokens.begin();
230 
231  chan.m_lcn = channelNo;
232 
233 // BBC ONE:754166:I999B8C34D34M16T2G32Y0:T:27500:600:601, 602:0:0:4168:0:0:0
234 
235  PARSE_SKIP(unknown);
236 
238 
239  if (it == tokens.end())
240  return false;
241 
242  QString params = (*it++);
243  while (!params.isEmpty())
244  {
245  QString ori = params;
246  int s = (int) (params.toLatin1().constData()[0]);
247  params = params.mid(1);
248  switch (s)
249  {
250  case 'I':
251  mux.m_inversion.ParseVDR(params);
252  break;
253  case 'B':
254  mux.m_bandwidth.ParseVDR(params);
255  break;
256  case 'C':
257  mux.m_hpCodeRate.ParseVDR(params);
258  break;
259  case 'D':
260  mux.m_lpCodeRate.ParseVDR(params);
261  break;
262  case 'M':
263  mux.m_modulation.ParseVDR(params);
264  break;
265  case 'T':
266  mux.m_transMode.ParseVDR(params);
267  break;
268  case 'G':
269  mux.m_guardInterval.ParseVDR(params);
270  break;
271  case 'Y':
272  mux.m_hierarchy.ParseVDR(params);
273  break;
274  case 'V':
275  case 'H':
276  case 'R':
277  case 'L':
278  mux.m_polarity.ParseVDR(ori);
279  break;
280  case 'S':
281  mux.m_modSys.ParseVDR(params);
282  break;
283  case 'O':
284  mux.m_rolloff.ParseVDR(params);
285  break;
286  default:
287  return false;
288  }
289  }
290 
291  for (uint i = 0; i < 6; i++)
292  PARSE_SKIP(unknown);
293 
294  PARSE_UINT(chan.m_serviceid);
295 
296  AddChannel(mux, chan);
297 
298  return true;
299 }
300 
302 {
303  for (auto & channel : m_channels)
304  {
305  if (channel == mux)
306  {
307  channel.channels.push_back(chan);
308 
309  LOG(VB_GENERAL, LOG_INFO, "Imported channel: " + chan.toString() +
310  " on " + mux.toString());
311  return;
312  }
313  }
314 
315  m_channels.emplace_back(mux);
316  m_channels.back().channels.push_back(chan);
317 
318  LOG(VB_GENERAL, LOG_INFO, "Imported channel: " + chan.toString() +
319  " on " + mux.toString());
320 }
DTVInversion::ParseVDR
bool ParseVDR(const QString &_value)
Definition: dtvconfparserhelpers.h:200
DTVMultiplex::m_frequency
uint64_t m_frequency
Definition: dtvmultiplex.h:94
DTVConfParser::cardtype_t::QPSK
@ QPSK
DTVMultiplex
Definition: dtvmultiplex.h:24
DTVRollOff::ParseVDR
bool ParseVDR(const QString &_value)
Definition: dtvconfparserhelpers.h:763
DTVMultiplex::m_rolloff
DTVRollOff m_rolloff
Definition: dtvmultiplex.h:107
DTVModulationSystem::ParseVDR
bool ParseVDR(const QString &_value)
Definition: dtvconfparserhelpers.h:714
DTVConfParser::ParseConfATSC
bool ParseConfATSC(const QStringList &tokens)
Definition: dtvconfparser.cpp:162
mythdbcon.h
DTVChannelInfo::toString
QString toString() const
Definition: dtvconfparser.cpp:65
DTVMultiplex::m_hierarchy
DTVHierarchy m_hierarchy
Definition: dtvmultiplex.h:103
DTVConfParser::cardtype_t::QAM
@ QAM
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
DTVPolarity::ParseVDR
bool ParseVDR(const QString &_value)
Definition: dtvconfparserhelpers.h:627
DTVMultiplex::m_bandwidth
DTVBandwidth m_bandwidth
Definition: dtvmultiplex.h:97
build_compdb.file
file
Definition: build_compdb.py:55
DTVConfParser::cardtype_t::ATSC
@ ATSC
DTVConfParser::return_t::ERROR_OPEN
@ ERROR_OPEN
DTVConfParser::return_t::OK
@ OK
DTVMultiplex::m_inversion
DTVInversion m_inversion
Definition: dtvmultiplex.h:96
DTVConfParser::ParseConfQPSK
bool ParseConfQPSK(const QStringList &tokens)
Definition: dtvconfparser.cpp:203
DTVConfParser::return_t::ERROR_PARSE
@ ERROR_PARSE
mythlogging.h
DTVMultiplex::m_guardInterval
DTVGuardInterval m_guardInterval
Definition: dtvmultiplex.h:102
DTVGuardInterval::ParseVDR
bool ParseVDR(const QString &_value)
Definition: dtvconfparserhelpers.h:535
DTVChannelInfo::m_name
QString m_name
Definition: dtvconfparser.h:54
DTVChannelInfo::m_serviceid
uint m_serviceid
Definition: dtvconfparser.h:55
DTVConfParser::m_filename
QString m_filename
Definition: dtvconfparser.h:98
DTVMultiplex::m_hpCodeRate
DTVCodeRate m_hpCodeRate
Definition: dtvmultiplex.h:98
DTVBandwidth::ParseVDR
bool ParseVDR(const QString &_value)
Definition: dtvconfparserhelpers.h:263
PARSE_STR
#define PARSE_STR(VAR)
Definition: dtvconfparser.cpp:52
DTVModulation::ParseVDR
bool ParseVDR(const QString &_value)
Definition: dtvconfparserhelpers.h:407
DTVMultiplex::m_modSys
DTVModulationSystem m_modSys
Definition: dtvmultiplex.h:106
DTVConfParser::m_type
cardtype_t m_type
Definition: dtvconfparser.h:96
DTVMultiplex::m_fec
DTVCodeRate m_fec
Definition: dtvmultiplex.h:105
DTVMultiplex::toString
QString toString() const
Definition: dtvmultiplex.cpp:35
DTVConfParser::cardtype_t::OFDM
@ OFDM
channelutil.h
DTVTransmitMode::ParseVDR
bool ParseVDR(const QString &_value)
Definition: dtvconfparserhelpers.h:470
DTVMultiplex::m_symbolRate
uint64_t m_symbolRate
Definition: dtvmultiplex.h:95
PARSE_UINT_1000
#define PARSE_UINT_1000(VAR)
Definition: dtvconfparser.cpp:59
DTVConfParser::AddChannel
void AddChannel(const DTVMultiplex &mux, DTVChannelInfo &chan)
Definition: dtvconfparser.cpp:301
DTVHierarchy::ParseVDR
bool ParseVDR(const QString &_value)
Definition: dtvconfparserhelpers.h:588
DTVConfParser::Parse
return_t Parse(void)
Definition: dtvconfparser.cpp:70
DTVCodeRate::ParseVDR
bool ParseVDR(const QString &_value)
Definition: dtvconfparserhelpers.h:336
DTVConfParser::m_channels
DTVChannelList m_channels
Definition: dtvconfparser.h:102
DTVConfParser::return_t
return_t
Definition: dtvconfparser.h:76
DTVMultiplex::m_modulation
DTVModulation m_modulation
Definition: dtvmultiplex.h:100
PARSE_CONF
#define PARSE_CONF(VAR)
Definition: dtvconfparser.cpp:47
DTVMultiplex::m_polarity
DTVPolarity m_polarity
Definition: dtvmultiplex.h:104
DTVChannelInfo::m_lcn
int m_lcn
Definition: dtvconfparser.h:56
dtvconfparser.h
PARSE_UINT
#define PARSE_UINT(VAR)
Definition: dtvconfparser.cpp:55
DTVConfParser::ParseConfQAM
bool ParseConfQAM(const QStringList &tokens)
Definition: dtvconfparser.cpp:181
DTVConfParser::cardtype_t::DVBS2
@ DVBS2
DTVMultiplex::m_transMode
DTVTransmitMode m_transMode
Definition: dtvmultiplex.h:101
uint
unsigned int uint
Definition: freesurround.h:24
DTVChannelInfo
Definition: dtvconfparser.h:47
PARSE_SKIP
#define PARSE_SKIP(VAR)
Definition: dtvconfparser.cpp:43
DTVConfParser::ParseVDR
bool ParseVDR(const QStringList &tokens, int channelNo=-1)
Definition: dtvconfparser.cpp:224
DTVConfParser::ParseConfOFDM
bool ParseConfOFDM(const QStringList &tokens)
Definition: dtvconfparser.cpp:136
DTVMultiplex::m_lpCodeRate
DTVCodeRate m_lpCodeRate
Definition: dtvmultiplex.h:99