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 "mythcontext.h"
38 #include "mythdbcon.h"
39 #include "mythlogging.h"
40 #include "dtvconfparser.h"
41 #include "channelutil.h"
42 
43 #define PARSE_SKIP(VAR) do { \
44  if (it == tokens.end()) return false; ++it; } while(false)
45 
46 #define PARSE_CONF(VAR) do { \
47  if (it == tokens.end() || !(VAR).ParseConf(*it++)) \
48  return false; } while(false)
49 
50 #define PARSE_STR(VAR) do { \
51  if (it != tokens.end()) (VAR) = *it++; else return false; } while(false)
52 
53 #define PARSE_UINT(VAR) do { \
54  if (it != tokens.end()) \
55  (VAR) = (*it++).toUInt(); else return false; } while(false)
56 
57 #define PARSE_UINT_1000(VAR) do { \
58  if (it != tokens.end()) \
59  (VAR) = (*it++).toUInt() * 1000ULL; else return false; } while(false)
60 
61 
62 QString DTVChannelInfo::toString() const
63 {
64  return QString("%1 %2 %3 ").arg(m_name).arg(m_serviceid).arg(m_lcn);
65 }
66 
68 {
69  m_channels.clear();
70 
71  QFile file(m_filename);
72  if (!file.open(QIODevice::ReadOnly))
73  return ERROR_OPEN;
74 
75  bool ok = true;
76  QTextStream stream(&file);
77  QString line;
78  while (!stream.atEnd())
79  {
80  line = stream.readLine(); // line of text excluding '\n'
81  line = line.trimmed();
82  if (line.startsWith("#"))
83  continue;
84 
85  QStringList list = line.split(":", QString::SkipEmptyParts);
86 
87  if (list.empty())
88  continue;
89 
90  QString str = list[0];
91  int channelNo = -1;
92 
93  if ((str.length() >= 1) && (str.at(0) == '@'))
94  {
95  channelNo = str.mid(1).toInt();
96  line = stream.readLine();
97  list = line.split(":", QString::SkipEmptyParts);
98  }
99 
100  if (list.size() < 4)
101  continue;
102 
103  str = list[3];
104 
105  if ((str == "T") || (str == "C") || (str == "S"))
106  {
107  if (((m_type == OFDM) && (str == "T")) ||
108  ((m_type == QPSK || m_type == DVBS2) && (str == "S")) ||
109  ((m_type == QAM) && (str == "C")))
110  ok &= ParseVDR(list, channelNo);
111  }
112  else if (m_type == OFDM)
113  ok &= ParseConfOFDM(list);
114  else if (m_type == ATSC)
115  ok &= ParseConfATSC(list);
116  else if (m_type == QPSK || m_type == DVBS2)
117  ok &= ParseConfQPSK(list);
118  else if (m_type == QAM)
119  ok &= ParseConfQAM(list);
120  }
121  file.close();
122 
123  return (ok) ? OK : ERROR_PARSE;
124 }
125 
126 bool DTVConfParser::ParseConfOFDM(const QStringList &tokens)
127 {
128  DTVChannelInfo chan;
129  DTVMultiplex mux;
130 
131  QStringList::const_iterator it = tokens.begin();
132 
133  PARSE_SKIP(unknown);
134  PARSE_UINT(mux.m_frequency);
135  PARSE_CONF(mux.m_inversion);
136  PARSE_CONF(mux.m_bandwidth);
140  PARSE_CONF(mux.m_transMode);
142  PARSE_CONF(mux.m_hierarchy);
143  PARSE_SKIP(unknown);
144  PARSE_SKIP(unknown);
145  PARSE_UINT(chan.m_serviceid);
146 
147  AddChannel(mux, chan);
148 
149  return true;
150 }
151 
152 bool DTVConfParser::ParseConfATSC(const QStringList &tokens)
153 {
154  DTVChannelInfo chan;
155  DTVMultiplex mux;
156 
157  QStringList::const_iterator it = tokens.begin();
158 
159  PARSE_STR(chan.m_name);
160  PARSE_UINT(mux.m_frequency);
162  PARSE_SKIP(Ignore_Video_PID);
163  PARSE_SKIP(Ignore_Audio_PID);
164  PARSE_UINT(chan.m_serviceid);
165 
166  AddChannel(mux, chan);
167 
168  return true;
169 }
170 
171 bool DTVConfParser::ParseConfQAM(const QStringList &tokens)
172 {
173  DTVChannelInfo chan;
174  DTVMultiplex mux;
175 
176  QStringList::const_iterator it = tokens.begin();
177 
178  PARSE_SKIP(unknown);
179  PARSE_UINT(mux.m_frequency);
180  PARSE_CONF(mux.m_inversion);
182  PARSE_CONF(mux.m_fec);
184  PARSE_SKIP(unknown);
185  PARSE_SKIP(unknown);
186  PARSE_UINT(chan.m_serviceid);
187 
188  AddChannel(mux, chan);
189 
190  return true;
191 }
192 
193 bool DTVConfParser::ParseConfQPSK(const QStringList &tokens)
194 {
195  DTVChannelInfo chan;
196  DTVMultiplex mux;
197 
198  QStringList::const_iterator it = tokens.begin();
199 
200  PARSE_STR(chan.m_name);
202  PARSE_CONF(mux.m_polarity);
203  PARSE_SKIP(Satelite_Number);
205  PARSE_SKIP(unknown);
206  PARSE_SKIP(unknown);
207  PARSE_UINT(chan.m_serviceid);
208 
209  AddChannel(mux, chan);
210 
211  return true;
212 }
213 
214 bool DTVConfParser::ParseVDR(const QStringList &tokens, int channelNo)
215 {
216  DTVChannelInfo chan;
217  DTVMultiplex mux;
218 
219  QStringList::const_iterator it = tokens.begin();
220 
221  chan.m_lcn = channelNo;
222 
223 // BBC ONE:754166:I999B8C34D34M16T2G32Y0:T:27500:600:601, 602:0:0:4168:0:0:0
224 
225  PARSE_SKIP(unknown);
226 
228 
229  if (it == tokens.end())
230  return false;
231 
232  QString params = (*it++);
233  while (!params.isEmpty())
234  {
235  QString ori = params;
236  int s = (int) (params.toLatin1().constData()[0]);
237  params = params.mid(1);
238  switch (s)
239  {
240  case 'I':
241  mux.m_inversion.ParseVDR(params);
242  break;
243  case 'B':
244  mux.m_bandwidth.ParseVDR(params);
245  break;
246  case 'C':
247  mux.m_hpCodeRate.ParseVDR(params);
248  break;
249  case 'D':
250  mux.m_lpCodeRate.ParseVDR(params);
251  break;
252  case 'M':
253  mux.m_modulation.ParseVDR(params);
254  break;
255  case 'T':
256  mux.m_transMode.ParseVDR(params);
257  break;
258  case 'G':
259  mux.m_guardInterval.ParseVDR(params);
260  break;
261  case 'Y':
262  mux.m_hierarchy.ParseVDR(params);
263  break;
264  case 'V':
265  case 'H':
266  case 'R':
267  case 'L':
268  mux.m_polarity.ParseVDR(ori);
269  break;
270  case 'S':
271  mux.m_modSys.ParseVDR(params);
272  break;
273  case 'O':
274  mux.m_rolloff.ParseVDR(params);
275  break;
276  default:
277  return false;
278  }
279  }
280 
281  for (uint i = 0; i < 6; i++)
282  PARSE_SKIP(unknown);
283 
284  PARSE_UINT(chan.m_serviceid);
285 
286  AddChannel(mux, chan);
287 
288  return true;
289 }
290 
292 {
293  for (auto & channel : m_channels)
294  {
295  if (channel == mux)
296  {
297  channel.channels.push_back(chan);
298 
299  LOG(VB_GENERAL, LOG_INFO, "Imported channel: " + chan.toString() +
300  " on " + mux.toString());
301  return;
302  }
303  }
304 
305  m_channels.push_back(DTVTransport(mux));
306  m_channels.back().channels.push_back(chan);
307 
308  LOG(VB_GENERAL, LOG_INFO, "Imported channel: " + chan.toString() +
309  " on " + mux.toString());
310 }
cardtype_t m_type
Definition: dtvconfparser.h:99
bool ParseConfQPSK(const QStringList &tokens)
DTVGuardInterval m_guardInterval
Definition: dtvmultiplex.h:102
uint64_t m_symbolRate
Definition: dtvmultiplex.h:95
DTVBandwidth m_bandwidth
Definition: dtvmultiplex.h:97
DTVHierarchy m_hierarchy
Definition: dtvmultiplex.h:103
#define PARSE_SKIP(VAR)
DTVPolarity m_polarity
Definition: dtvmultiplex.h:104
bool ParseVDR(const QString &_value)
bool ParseVDR(const QString &_value)
return_t Parse(void)
bool ParseVDR(const QString &_value)
bool ParseConfQAM(const QStringList &tokens)
DTVInversion m_inversion
Definition: dtvmultiplex.h:96
bool ParseConfATSC(const QStringList &tokens)
bool ParseConfOFDM(const QStringList &tokens)
QString toString() const
DTVCodeRate m_fec
Inner Forward Error Correction rate.
Definition: dtvmultiplex.h:105
#define PARSE_STR(VAR)
DTVModulation m_modulation
Definition: dtvmultiplex.h:100
QString m_filename
unsigned int uint
Definition: compat.h:140
bool ParseVDR(const QString &_value)
bool ParseVDR(const QString &_value)
DTVTransmitMode m_transMode
Definition: dtvmultiplex.h:101
bool ParseVDR(const QString &_value)
DTVRollOff m_rolloff
Definition: dtvmultiplex.h:107
#define PARSE_CONF(VAR)
#define PARSE_UINT(VAR)
void AddChannel(const DTVMultiplex &mux, DTVChannelInfo &chan)
#define PARSE_UINT_1000(VAR)
DTVCodeRate m_hpCodeRate
High Priority FEC rate.
Definition: dtvmultiplex.h:98
bool ParseVDR(const QStringList &tokens, int channelNo=-1)
bool ParseVDR(const QString &_value)
bool ParseVDR(const QString &_value)
QString toString() const
DTVCodeRate m_lpCodeRate
Low Priority FEC rate.
Definition: dtvmultiplex.h:99
DTVModulationSystem m_modSys
Modulation system.
Definition: dtvmultiplex.h:106
DTVChannelList m_channels
uint64_t m_frequency
Definition: dtvmultiplex.h:94
bool ParseVDR(const QString &_value)
bool ParseVDR(const QString &_value)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23