1 /*
2 * dvbtransponder.cpp
3 *
4 * Copyright (C) 2007-2011 Christoph Pfister <christophpfister@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include <QDataStream>
22 #include <QTextStream>
23 #include <stdint.h>
24
25 #include "dvbtransponder.h"
26
enumToLinuxtv(DvbTransponderBase::FecRate fecRate)27 static const char *enumToLinuxtv(DvbTransponderBase::FecRate fecRate)
28 {
29 switch (fecRate) {
30 case DvbTransponderBase::FecNone: return "NONE";
31 case DvbTransponderBase::Fec1_2: return "1/2";
32 case DvbTransponderBase::Fec1_3: return "1/3";
33 case DvbTransponderBase::Fec1_4: return "1/4";
34 case DvbTransponderBase::Fec2_3: return "2/3";
35 case DvbTransponderBase::Fec2_5: return "2/5";
36 case DvbTransponderBase::Fec3_4: return "3/4";
37 case DvbTransponderBase::Fec3_5: return "3/5";
38 case DvbTransponderBase::Fec4_5: return "4/5";
39 case DvbTransponderBase::Fec5_6: return "5/6";
40 case DvbTransponderBase::Fec6_7: return "6/7";
41 case DvbTransponderBase::Fec7_8: return "7/8";
42 case DvbTransponderBase::Fec8_9: return "8/9";
43 case DvbTransponderBase::Fec9_10: return "9/10";
44 case DvbTransponderBase::FecAuto: return "AUTO";
45 }
46
47 return NULL;
48 }
49
enumToLinuxtv(DvbCTransponder::Modulation modulation)50 static const char *enumToLinuxtv(DvbCTransponder::Modulation modulation)
51 {
52 switch (modulation) {
53 case DvbCTransponder::Qam16: return "QAM16";
54 case DvbCTransponder::Qam32: return "QAM32";
55 case DvbCTransponder::Qam64: return "QAM64";
56 case DvbCTransponder::Qam128: return "QAM128";
57 case DvbCTransponder::Qam256: return "QAM256";
58 case DvbCTransponder::ModulationAuto: return "AUTO";
59 }
60
61 return NULL;
62 }
63
enumToLinuxtv(DvbSTransponder::Polarization polarization)64 static const char *enumToLinuxtv(DvbSTransponder::Polarization polarization)
65 {
66 switch (polarization) {
67 case DvbSTransponder::Horizontal: return "H";
68 case DvbSTransponder::Vertical: return "V";
69 case DvbSTransponder::CircularLeft: return "L";
70 case DvbSTransponder::CircularRight: return "R";
71 case DvbSTransponder::Off: return "-";
72 }
73
74 return NULL;
75 }
76
enumToLinuxtv(DvbS2Transponder::Modulation modulation)77 static const char *enumToLinuxtv(DvbS2Transponder::Modulation modulation)
78 {
79 switch (modulation) {
80 case DvbS2Transponder::Qpsk: return "QPSK";
81 case DvbS2Transponder::Psk8: return "8PSK";
82 case DvbS2Transponder::Apsk16: return "16APSK";
83 case DvbS2Transponder::Apsk32: return "32APSK";
84 case DvbS2Transponder::ModulationAuto: return "AUTO";
85 }
86
87 return NULL;
88 }
89
enumToLinuxtv(DvbS2Transponder::RollOff rollOff)90 static const char *enumToLinuxtv(DvbS2Transponder::RollOff rollOff)
91 {
92 switch (rollOff) {
93 case DvbS2Transponder::RollOff20: return "20";
94 case DvbS2Transponder::RollOff25: return "25";
95 case DvbS2Transponder::RollOff35: return "35";
96 case DvbS2Transponder::RollOffAuto: return "AUTO";
97 }
98
99 return NULL;
100 }
101
enumToLinuxtv(DvbTTransponder::Bandwidth bandwidth)102 static const char *enumToLinuxtv(DvbTTransponder::Bandwidth bandwidth)
103 {
104 switch (bandwidth) {
105 case DvbTTransponder::Bandwidth5MHz: return "5MHz";
106 case DvbTTransponder::Bandwidth6MHz: return "6MHz";
107 case DvbTTransponder::Bandwidth7MHz: return "7MHz";
108 case DvbTTransponder::Bandwidth8MHz: return "8MHz";
109 case DvbTTransponder::BandwidthAuto: return "AUTO";
110 }
111
112 return NULL;
113 }
114
enumToLinuxtv(DvbTTransponder::Modulation modulation)115 static const char *enumToLinuxtv(DvbTTransponder::Modulation modulation)
116 {
117 switch (modulation) {
118 case DvbTTransponder::Qpsk: return "QPSK";
119 case DvbTTransponder::Qam16: return "QAM16";
120 case DvbTTransponder::Qam64: return "QAM64";
121 case DvbTTransponder::ModulationAuto: return "AUTO";
122 }
123
124 return NULL;
125 }
126
enumToLinuxtv(DvbTTransponder::TransmissionMode transmissionMode)127 static const char *enumToLinuxtv(DvbTTransponder::TransmissionMode transmissionMode)
128 {
129 switch (transmissionMode) {
130 case DvbTTransponder::TransmissionMode2k: return "2k";
131 case DvbTTransponder::TransmissionMode4k: return "4k";
132 case DvbTTransponder::TransmissionMode8k: return "8k";
133 case DvbTTransponder::TransmissionModeAuto: return "AUTO";
134 }
135
136 return NULL;
137 }
138
enumToLinuxtv(DvbTTransponder::GuardInterval guardInterval)139 static const char *enumToLinuxtv(DvbTTransponder::GuardInterval guardInterval)
140 {
141 switch (guardInterval) {
142 case DvbTTransponder::GuardInterval1_4: return "1/4";
143 case DvbTTransponder::GuardInterval1_8: return "1/8";
144 case DvbTTransponder::GuardInterval1_16: return "1/16";
145 case DvbTTransponder::GuardInterval1_32: return "1/32";
146 case DvbTTransponder::GuardIntervalAuto: return "AUTO";
147 }
148
149 return NULL;
150 }
151
enumToLinuxtv(DvbTTransponder::Hierarchy hierarchy)152 static const char *enumToLinuxtv(DvbTTransponder::Hierarchy hierarchy)
153 {
154 switch (hierarchy) {
155 case DvbTTransponder::HierarchyNone: return "NONE";
156 case DvbTTransponder::Hierarchy1: return "1";
157 case DvbTTransponder::Hierarchy2: return "2";
158 case DvbTTransponder::Hierarchy4: return "4";
159 case DvbTTransponder::HierarchyAuto: return "AUTO";
160 }
161
162 return NULL;
163 }
164
enumToLinuxtv(DvbT2Transponder::Bandwidth bandwidth)165 static const char *enumToLinuxtv(DvbT2Transponder::Bandwidth bandwidth)
166 {
167 switch (bandwidth) {
168 case DvbT2Transponder::Bandwidth1_7MHz: return "1.7MHz";
169 case DvbT2Transponder::Bandwidth5MHz: return "5MHz";
170 case DvbT2Transponder::Bandwidth6MHz: return "6MHz";
171 case DvbT2Transponder::Bandwidth7MHz: return "7MHz";
172 case DvbT2Transponder::Bandwidth8MHz: return "8MHz";
173 case DvbT2Transponder::Bandwidth10MHz: return "10MHz";
174 case DvbT2Transponder::BandwidthAuto: return "AUTO";
175 }
176
177 return NULL;
178 }
179
enumToLinuxtv(DvbT2Transponder::Modulation modulation)180 static const char *enumToLinuxtv(DvbT2Transponder::Modulation modulation)
181 {
182 switch (modulation) {
183 case DvbT2Transponder::Qpsk: return "QPSK";
184 case DvbT2Transponder::Qam16: return "QAM16";
185 case DvbT2Transponder::Qam64: return "QAM64";
186 case DvbT2Transponder::Qam256: return "QAM256";
187 case DvbT2Transponder::ModulationAuto: return "AUTO";
188 }
189
190 return NULL;
191 }
192
enumToLinuxtv(DvbT2Transponder::TransmissionMode transmissionMode)193 static const char *enumToLinuxtv(DvbT2Transponder::TransmissionMode transmissionMode)
194 {
195 switch (transmissionMode) {
196 case DvbT2Transponder::TransmissionMode1k: return "1k";
197 case DvbT2Transponder::TransmissionMode2k: return "2k";
198 case DvbT2Transponder::TransmissionMode4k: return "4k";
199 case DvbT2Transponder::TransmissionMode8k: return "8k";
200 case DvbT2Transponder::TransmissionMode16k: return "16k";
201 case DvbT2Transponder::TransmissionMode32k: return "32k";
202 case DvbT2Transponder::TransmissionModeAuto: return "AUTO";
203 }
204
205 return NULL;
206 }
207
enumToLinuxtv(DvbT2Transponder::GuardInterval guardInterval)208 static const char *enumToLinuxtv(DvbT2Transponder::GuardInterval guardInterval)
209 {
210 switch (guardInterval) {
211 case DvbT2Transponder::GuardInterval1_4: return "1/4";
212 case DvbT2Transponder::GuardInterval19_128: return "19/128";
213 case DvbT2Transponder::GuardInterval1_8: return "1/8";
214 case DvbT2Transponder::GuardInterval19_256: return "19/256";
215 case DvbT2Transponder::GuardInterval1_16: return "1/16";
216 case DvbT2Transponder::GuardInterval1_32: return "1/32";
217 case DvbT2Transponder::GuardInterval1_128: return "1/128";
218 case DvbT2Transponder::GuardIntervalAuto: return "AUTO";
219 }
220
221 return NULL;
222 }
223
enumToLinuxtv(DvbT2Transponder::Hierarchy hierarchy)224 static const char *enumToLinuxtv(DvbT2Transponder::Hierarchy hierarchy)
225 {
226 switch (hierarchy) {
227 case DvbT2Transponder::HierarchyNone: return "NONE";
228 case DvbT2Transponder::Hierarchy1: return "1";
229 case DvbT2Transponder::Hierarchy2: return "2";
230 case DvbT2Transponder::Hierarchy4: return "4";
231 case DvbT2Transponder::HierarchyAuto: return "AUTO";
232 }
233
234 return NULL;
235 }
236
enumToLinuxtv(IsdbTTransponder::Bandwidth bandwidth)237 static const char *enumToLinuxtv(IsdbTTransponder::Bandwidth bandwidth)
238 {
239 switch (bandwidth) {
240 case IsdbTTransponder::Bandwidth6MHz: return "6MHz";
241 case IsdbTTransponder::Bandwidth7MHz: return "7MHz";
242 case IsdbTTransponder::Bandwidth8MHz: return "8MHz";
243 }
244
245 return NULL;
246 }
247
enumToLinuxtv(IsdbTTransponder::Modulation modulation)248 static const char *enumToLinuxtv(IsdbTTransponder::Modulation modulation)
249 {
250 switch (modulation) {
251 case IsdbTTransponder::Qpsk: return "QPSK";
252 case IsdbTTransponder::Dqpsk: return "DQPSK";
253 case IsdbTTransponder::Qam16: return "QAM16";
254 case IsdbTTransponder::Qam64: return "QAM64";
255 case IsdbTTransponder::ModulationAuto: return "AUTO";
256 }
257
258 return NULL;
259 }
260
enumToLinuxtv(IsdbTTransponder::TransmissionMode transmissionMode)261 static const char *enumToLinuxtv(IsdbTTransponder::TransmissionMode transmissionMode)
262 {
263 switch (transmissionMode) {
264 case IsdbTTransponder::TransmissionMode2k: return "2k";
265 case IsdbTTransponder::TransmissionMode4k: return "4k";
266 case IsdbTTransponder::TransmissionMode8k: return "8k";
267 case IsdbTTransponder::TransmissionModeAuto: return "AUTO";
268 }
269
270 return NULL;
271 }
272
enumToLinuxtv(IsdbTTransponder::GuardInterval guardInterval)273 static const char *enumToLinuxtv(IsdbTTransponder::GuardInterval guardInterval)
274 {
275 switch (guardInterval) {
276 case IsdbTTransponder::GuardInterval1_4: return "1/4";
277 case IsdbTTransponder::GuardInterval1_8: return "1/8";
278 case IsdbTTransponder::GuardInterval1_16: return "1/16";
279 case IsdbTTransponder::GuardInterval1_32: return "1/32";
280 case IsdbTTransponder::GuardIntervalAuto: return "AUTO";
281 }
282
283 return NULL;
284 }
285
enumToLinuxtv(IsdbTTransponder::Interleaving interleaving)286 static const char *enumToLinuxtv(IsdbTTransponder::Interleaving interleaving)
287 {
288 switch (interleaving) {
289 case IsdbTTransponder::I_0: return "0";
290 case IsdbTTransponder::I_1: return "1";
291 case IsdbTTransponder::I_2: return "2";
292 case IsdbTTransponder::I_4: return "4";
293 case IsdbTTransponder::I_8: return "8";
294 case IsdbTTransponder::I_16: return "16";
295 case IsdbTTransponder::I_AUTO: return "AUTO";
296 }
297
298 return NULL;
299 }
300
enumToLinuxtv(IsdbTTransponder::PartialReception partialReception)301 static const char *enumToLinuxtv(IsdbTTransponder::PartialReception partialReception)
302 {
303 switch (partialReception) {
304 case IsdbTTransponder::PR_disabled: return "0";
305 case IsdbTTransponder::PR_enabled: return "1";
306 case IsdbTTransponder::PR_AUTO: return "AUTO";
307 }
308
309 return NULL;
310 }
311
enumToLinuxtv(IsdbTTransponder::SoundBroadcasting soundBroadcasting)312 static const char *enumToLinuxtv(IsdbTTransponder::SoundBroadcasting soundBroadcasting)
313 {
314 switch (soundBroadcasting) {
315 case IsdbTTransponder::SB_disabled: return "0";
316 case IsdbTTransponder::SB_enabled: return "1";
317 case IsdbTTransponder::SB_AUTO: return "AUTO";
318 }
319
320 return NULL;
321 }
322
enumToLinuxtv(AtscTransponder::Modulation modulation)323 static const char *enumToLinuxtv(AtscTransponder::Modulation modulation)
324 {
325 switch (modulation) {
326 case AtscTransponder::Qam64: return "QAM64";
327 case AtscTransponder::Qam256: return "QAM256";
328 case AtscTransponder::Vsb8: return "8VSB";
329 case AtscTransponder::Vsb16: return "16VSB";
330 case AtscTransponder::ModulationAuto: return "AUTO";
331 }
332
333 return NULL;
334 }
335
readEnum(QDataStream & stream)336 template<class T> static T readEnum(QDataStream &stream)
337 {
338 int intValue;
339 stream >> intValue;
340 T value = static_cast<T>(intValue);
341
342 if ((value != intValue) || (enumToLinuxtv(value) == NULL)) {
343 stream.setStatus(QDataStream::ReadCorruptData);
344 }
345
346 return value;
347 }
348
349 class DvbChannelStringReader
350 {
351 public:
DvbChannelStringReader(const QString & string_)352 explicit DvbChannelStringReader(const QString &string_) : string(string_)
353 {
354 stream.setString(&string);
355 stream.setIntegerBase(10);
356 }
357
~DvbChannelStringReader()358 ~DvbChannelStringReader() { }
359
isValid() const360 bool isValid() const
361 {
362 return (stream.status() == QTextStream::Ok);
363 }
364
readInt(int & value)365 void readInt(int &value)
366 {
367 stream >> value;
368 }
369
readEnum()370 template<class T> T readEnum()
371 {
372 QString token;
373 stream >> token;
374
375 for (int i = 0;; ++i) {
376 T value = static_cast<T>(i);
377
378 if (value != i) {
379 break;
380 }
381
382 const char *entry = enumToLinuxtv(value);
383
384 if (entry == NULL) {
385 break;
386 }
387
388 if (token == QLatin1String(entry)) {
389 return value;
390 }
391 }
392
393 stream.setStatus(QTextStream::ReadCorruptData);
394 return T();
395 }
396
checkChar(const QChar & value)397 void checkChar(const QChar &value)
398 {
399 QString token;
400 stream >> token;
401
402 if (token != value) {
403 stream.setStatus(QTextStream::ReadCorruptData);
404 }
405 }
406
checkString(const QString & value)407 void checkString(const QString &value)
408 {
409 QString token;
410 stream >> token;
411
412 if (token != value) {
413 stream.setStatus(QTextStream::ReadCorruptData);
414 }
415 }
416
417 private:
418 QString string;
419 QTextStream stream;
420 };
421
422 class DvbChannelStringWriter
423 {
424 public:
DvbChannelStringWriter()425 DvbChannelStringWriter()
426 {
427 stream.setString(&string);
428 }
429
~DvbChannelStringWriter()430 ~DvbChannelStringWriter() { }
431
getString()432 QString getString()
433 {
434 string.chop(1);
435 return string;
436 }
437
writeInt(int value)438 void writeInt(int value)
439 {
440 stream << value << ' ';
441 }
442
writeEnum(T value)443 template<class T> void writeEnum(T value)
444 {
445 stream << enumToLinuxtv(value) << ' ';
446 }
447
writeChar(const QChar & value)448 void writeChar(const QChar &value)
449 {
450 stream << value << ' ';
451 }
452
writeString(const QString & value)453 void writeString(const QString &value)
454 {
455 stream << value << ' ';
456 }
457
458 private:
459 QString string;
460 QTextStream stream;
461 };
462
readTransponder(QDataStream & stream)463 void DvbCTransponder::readTransponder(QDataStream &stream)
464 {
465 stream >> frequency;
466 stream >> symbolRate;
467 modulation = readEnum<Modulation>(stream);
468 fecRate = readEnum<FecRate>(stream);
469 }
470
fromString(const QString & string)471 bool DvbCTransponder::fromString(const QString &string)
472 {
473 DvbChannelStringReader reader(string);
474 reader.checkChar(QLatin1Char('C'));
475 reader.readInt(frequency);
476 reader.readInt(symbolRate);
477 fecRate = reader.readEnum<FecRate>();
478 modulation = reader.readEnum<Modulation>();
479 return reader.isValid();
480 }
481
toString() const482 QString DvbCTransponder::toString() const
483 {
484 DvbChannelStringWriter writer;
485 writer.writeChar(QLatin1Char('C'));
486 writer.writeInt(frequency);
487 writer.writeInt(symbolRate);
488 writer.writeEnum(fecRate);
489 writer.writeEnum(modulation);
490 return writer.getString();
491 }
492
corresponds(const DvbTransponder & transponder) const493 bool DvbCTransponder::corresponds(const DvbTransponder &transponder) const
494 {
495 const DvbCTransponder *dvbCTransponder = transponder.as<DvbCTransponder>();
496
497 return ((dvbCTransponder != NULL) &&
498 (qAbs(dvbCTransponder->frequency - frequency) <= 2000000));
499 }
500
readTransponder(QDataStream & stream)501 void DvbSTransponder::readTransponder(QDataStream &stream)
502 {
503 polarization = readEnum<Polarization>(stream);
504 stream >> frequency;
505 stream >> symbolRate;
506 fecRate = readEnum<FecRate>(stream);
507 }
508
fromString(const QString & string)509 bool DvbSTransponder::fromString(const QString &string)
510 {
511 DvbChannelStringReader reader(string);
512 reader.checkChar(QLatin1Char('S'));
513 reader.readInt(frequency);
514 polarization = reader.readEnum<Polarization>();
515 reader.readInt(symbolRate);
516 fecRate = reader.readEnum<FecRate>();
517 return reader.isValid();
518 }
519
toString() const520 QString DvbSTransponder::toString() const
521 {
522 DvbChannelStringWriter writer;
523 writer.writeChar(QLatin1Char('S'));
524 writer.writeInt(frequency);
525 writer.writeEnum(polarization);
526 writer.writeInt(symbolRate);
527 writer.writeEnum(fecRate);
528 return writer.getString();
529 }
530
corresponds(const DvbTransponder & transponder) const531 bool DvbSTransponder::corresponds(const DvbTransponder &transponder) const
532 {
533 const DvbSTransponder *dvbSTransponder = transponder.as<DvbSTransponder>();
534
535 return ((dvbSTransponder != NULL) &&
536 (dvbSTransponder->polarization == polarization) &&
537 (qAbs(dvbSTransponder->frequency - frequency) <= 2000));
538 }
539
readTransponder(QDataStream & stream)540 void DvbS2Transponder::readTransponder(QDataStream &stream)
541 {
542 polarization = readEnum<Polarization>(stream);
543 stream >> frequency;
544 stream >> symbolRate;
545 fecRate = readEnum<FecRate>(stream);
546 modulation = readEnum<Modulation>(stream);
547 rollOff = readEnum<RollOff>(stream);
548 }
549
fromString(const QString & string)550 bool DvbS2Transponder::fromString(const QString &string)
551 {
552 DvbChannelStringReader reader(string);
553 reader.checkString(QLatin1String("S2"));
554 reader.readInt(frequency);
555 polarization = reader.readEnum<Polarization>();
556 reader.readInt(symbolRate);
557 fecRate = reader.readEnum<FecRate>();
558 rollOff = reader.readEnum<RollOff>();
559 modulation = reader.readEnum<Modulation>();
560 return reader.isValid();
561 }
562
toString() const563 QString DvbS2Transponder::toString() const
564 {
565 DvbChannelStringWriter writer;
566 writer.writeString(QLatin1String("S2"));
567 writer.writeInt(frequency);
568 writer.writeEnum(polarization);
569 writer.writeInt(symbolRate);
570 writer.writeEnum(fecRate);
571 writer.writeEnum(rollOff);
572 writer.writeEnum(modulation);
573 return writer.getString();
574 }
575
corresponds(const DvbTransponder & transponder) const576 bool DvbS2Transponder::corresponds(const DvbTransponder &transponder) const
577 {
578 const DvbS2Transponder *dvbS2Transponder = transponder.as<DvbS2Transponder>();
579
580 return ((dvbS2Transponder != NULL) &&
581 (dvbS2Transponder->polarization == polarization) &&
582 (qAbs(dvbS2Transponder->frequency - frequency) <= 2000));
583 }
584
readTransponder(QDataStream & stream)585 void DvbTTransponder::readTransponder(QDataStream &stream)
586 {
587 stream >> frequency;
588 bandwidth = readEnum<Bandwidth>(stream);
589 modulation = readEnum<Modulation>(stream);
590 fecRateHigh = readEnum<FecRate>(stream);
591 fecRateLow = readEnum<FecRate>(stream);
592 transmissionMode = readEnum<TransmissionMode>(stream);
593 guardInterval = readEnum<GuardInterval>(stream);
594 hierarchy = readEnum<Hierarchy>(stream);
595 }
596
fromString(const QString & string)597 bool DvbTTransponder::fromString(const QString &string)
598 {
599 DvbChannelStringReader reader(string);
600 reader.checkChar(QLatin1Char('T'));
601 reader.readInt(frequency);
602 bandwidth = reader.readEnum<Bandwidth>();
603 fecRateHigh = reader.readEnum<FecRate>();
604 fecRateLow = reader.readEnum<FecRate>();
605 modulation = reader.readEnum<Modulation>();
606 transmissionMode = reader.readEnum<TransmissionMode>();
607 guardInterval = reader.readEnum<GuardInterval>();
608 hierarchy = reader.readEnum<Hierarchy>();
609 return reader.isValid();
610 }
611
toString() const612 QString DvbTTransponder::toString() const
613 {
614 DvbChannelStringWriter writer;
615 writer.writeChar(QLatin1Char('T'));
616 writer.writeInt(frequency);
617 writer.writeEnum(bandwidth);
618 writer.writeEnum(fecRateHigh);
619 writer.writeEnum(fecRateLow);
620 writer.writeEnum(modulation);
621 writer.writeEnum(transmissionMode);
622 writer.writeEnum(guardInterval);
623 writer.writeEnum(hierarchy);
624 return writer.getString();
625 }
626
corresponds(const DvbTransponder & transponder) const627 bool DvbTTransponder::corresponds(const DvbTransponder &transponder) const
628 {
629 const DvbTTransponder *dvbTTransponder = transponder.as<DvbTTransponder>();
630
631 return ((dvbTTransponder != NULL) &&
632 (qAbs(dvbTTransponder->frequency - frequency) <= 2000000));
633 }
634
readTransponder(QDataStream & stream)635 void DvbT2Transponder::readTransponder(QDataStream &stream)
636 {
637 stream >> frequency;
638 bandwidth = readEnum<Bandwidth>(stream);
639 modulation = readEnum<Modulation>(stream);
640 fecRateHigh = readEnum<FecRate>(stream);
641 fecRateLow = readEnum<FecRate>(stream);
642 transmissionMode = readEnum<TransmissionMode>(stream);
643 guardInterval = readEnum<GuardInterval>(stream);
644 hierarchy = readEnum<Hierarchy>(stream);
645 stream >> streamId;
646 }
647
fromString(const QString & string)648 bool DvbT2Transponder::fromString(const QString &string)
649 {
650 DvbChannelStringReader reader(string);
651 reader.checkString(QLatin1String("T2"));
652 reader.readInt(frequency);
653 bandwidth = reader.readEnum<Bandwidth>();
654 fecRateHigh = reader.readEnum<FecRate>();
655 fecRateLow = reader.readEnum<FecRate>();
656 modulation = reader.readEnum<Modulation>();
657 transmissionMode = reader.readEnum<TransmissionMode>();
658 guardInterval = reader.readEnum<GuardInterval>();
659 hierarchy = reader.readEnum<Hierarchy>();
660 reader.readInt(streamId);
661 return reader.isValid();
662 }
663
toString() const664 QString DvbT2Transponder::toString() const
665 {
666 DvbChannelStringWriter writer;
667 writer.writeString(QLatin1String("T2"));
668 writer.writeInt(frequency);
669 writer.writeEnum(bandwidth);
670 writer.writeEnum(fecRateHigh);
671 writer.writeEnum(fecRateLow);
672 writer.writeEnum(modulation);
673 writer.writeEnum(transmissionMode);
674 writer.writeEnum(guardInterval);
675 writer.writeEnum(hierarchy);
676 writer.writeInt(streamId);
677 return writer.getString();
678 }
679
corresponds(const DvbTransponder & transponder) const680 bool DvbT2Transponder::corresponds(const DvbTransponder &transponder) const
681 {
682 const DvbT2Transponder *dvbT2Transponder = transponder.as<DvbT2Transponder>();
683
684 return ((dvbT2Transponder != NULL) &&
685 (qAbs(dvbT2Transponder->frequency - frequency) <= 2000000) &&
686 (dvbT2Transponder->streamId == streamId));
687 }
688
readTransponder(QDataStream & stream)689 void AtscTransponder::readTransponder(QDataStream &stream)
690 {
691 stream >> frequency;
692 modulation = readEnum<Modulation>(stream);
693 }
694
fromString(const QString & string)695 bool AtscTransponder::fromString(const QString &string)
696 {
697 DvbChannelStringReader reader(string);
698 reader.checkChar(QLatin1Char('A'));
699 reader.readInt(frequency);
700 modulation = reader.readEnum<Modulation>();
701 return reader.isValid();
702 }
703
toString() const704 QString AtscTransponder::toString() const
705 {
706 DvbChannelStringWriter writer;
707 writer.writeChar(QLatin1Char('A'));
708 writer.writeInt(frequency);
709 writer.writeEnum(modulation);
710 return writer.getString();
711 }
712
corresponds(const DvbTransponder & transponder) const713 bool AtscTransponder::corresponds(const DvbTransponder &transponder) const
714 {
715 const AtscTransponder *atscTransponder = transponder.as<AtscTransponder>();
716
717 return ((atscTransponder != NULL) &&
718 (qAbs(atscTransponder->frequency - frequency) <= 2000000));
719 }
720
readTransponder(QDataStream & stream)721 void IsdbTTransponder::readTransponder(QDataStream &stream)
722 {
723 int layers;
724 stream >> frequency;
725 bandwidth = readEnum<Bandwidth>(stream);
726 transmissionMode = readEnum<TransmissionMode>(stream);
727 guardInterval = readEnum<GuardInterval>(stream);
728 partialReception = readEnum<PartialReception>(stream);
729 soundBroadcasting = readEnum<SoundBroadcasting>(stream);
730 stream >> subChannelId;
731 stream >> sbSegmentCount;
732 stream >> subChannelId;
733
734 stream >> layers;
735 for (int i = 0; i < 3; i ++) {
736 if ((1 << i) & layers)
737 layerEnabled[i] = true;
738 else
739 layerEnabled[i] = false;
740
741 modulation[i] = readEnum<Modulation>(stream);
742 fecRate[i] = readEnum<FecRate>(stream);
743 stream >> segmentCount[i];
744 interleaving[i] = readEnum<Interleaving>(stream);
745 }
746
747 // Sanity check: if no labels are enabled, enable them all
748 if (!(layers & 7)) {
749 layers = 7;
750 for (int i = 0; i < 3; i ++) {
751 layerEnabled[i] = true;
752 modulation[i] = IsdbTTransponder::ModulationAuto;
753 fecRate[i] = IsdbTTransponder::FecAuto;
754 interleaving[i] = IsdbTTransponder::I_AUTO;
755 segmentCount[i] = 15;
756 }
757 }
758 }
759
fromString(const QString & string)760 bool IsdbTTransponder::fromString(const QString &string)
761 {
762 int layers;
763 DvbChannelStringReader reader(string);
764 reader.checkChar(QLatin1Char('I'));
765 reader.readInt(frequency);
766 bandwidth = reader.readEnum<Bandwidth>();
767 transmissionMode = reader.readEnum<TransmissionMode>();
768 guardInterval = reader.readEnum<GuardInterval>();
769 partialReception = reader.readEnum<PartialReception>();
770 soundBroadcasting = reader.readEnum<SoundBroadcasting>();
771 reader.readInt(subChannelId);
772 reader.readInt(sbSegmentCount);
773 reader.readInt(subChannelId);
774
775 reader.readInt(layers);
776 for (int i = 0; i < 3; i ++) {
777 if ((1 << i) & layers)
778 layerEnabled[i] = true;
779 else
780 layerEnabled[i] = false;
781
782 modulation[i] = reader.readEnum<Modulation>();
783 fecRate[i] = reader.readEnum<FecRate>();
784 reader.readInt(segmentCount[i]);
785 interleaving[i] = reader.readEnum<Interleaving>();
786 }
787
788 // Sanity check: if no labels are enabled, enable them all
789 if (!(layers & 7)) {
790 layers = 7;
791 for (int i = 0; i < 3; i ++) {
792 layerEnabled[i] = true;
793 modulation[i] = IsdbTTransponder::ModulationAuto;
794 fecRate[i] = IsdbTTransponder::FecAuto;
795 interleaving[i] = IsdbTTransponder::I_AUTO;
796 segmentCount[i] = 15;
797 }
798 }
799
800 return reader.isValid();
801 }
802
toString() const803 QString IsdbTTransponder::toString() const
804 {
805 int layers = 0;
806 DvbChannelStringWriter writer;
807 writer.writeChar(QLatin1Char('I'));
808 writer.writeInt(frequency);
809 writer.writeEnum(bandwidth);
810 writer.writeEnum(transmissionMode);
811 writer.writeEnum(guardInterval);
812 writer.writeEnum(partialReception);
813 writer.writeEnum(soundBroadcasting);
814 writer.writeInt(subChannelId);
815 writer.writeInt(sbSegmentCount);
816 writer.writeInt(subChannelId);
817
818 for (int i = 0; i < 3; i ++) {
819 if (layerEnabled[i])
820 layers |= 1 << i;
821 }
822 writer.writeInt(layers);
823
824 for (int i = 0; i < 3; i ++) {
825 writer.writeEnum(modulation[i]);
826 writer.writeEnum(fecRate[i]);
827 writer.writeInt(segmentCount[i]);
828 writer.writeEnum(interleaving[i]);
829 }
830
831 return writer.getString();
832 }
833
corresponds(const DvbTransponder & transponder) const834 bool IsdbTTransponder::corresponds(const DvbTransponder &transponder) const
835 {
836 const IsdbTTransponder *dvbTTransponder = transponder.as<IsdbTTransponder>();
837
838 return ((dvbTTransponder != NULL) &&
839 (qAbs(dvbTTransponder->frequency - frequency) <= 2000000));
840 }
841
corresponds(const DvbTransponder & transponder) const842 bool DvbTransponder::corresponds(const DvbTransponder &transponder) const
843 {
844 switch (data.transmissionType) {
845 case DvbTransponderBase::Invalid:
846 break;
847 case DvbTransponderBase::DvbC:
848 return as<DvbCTransponder>()->corresponds(transponder);
849 case DvbTransponderBase::DvbS:
850 return as<DvbSTransponder>()->corresponds(transponder);
851 case DvbTransponderBase::DvbS2:
852 return as<DvbS2Transponder>()->corresponds(transponder);
853 case DvbTransponderBase::DvbT:
854 return as<DvbTTransponder>()->corresponds(transponder);
855 case DvbTransponderBase::DvbT2:
856 return as<DvbT2Transponder>()->corresponds(transponder);
857 case DvbTransponderBase::Atsc:
858 return as<AtscTransponder>()->corresponds(transponder);
859 case DvbTransponderBase::IsdbT:
860 return as<IsdbTTransponder>()->corresponds(transponder);
861 }
862
863 return false;
864 }
865
toString() const866 QString DvbTransponder::toString() const
867 {
868 switch (data.transmissionType) {
869 case DvbTransponderBase::Invalid:
870 break;
871 case DvbTransponderBase::DvbC:
872 return as<DvbCTransponder>()->toString();
873 case DvbTransponderBase::DvbS:
874 return as<DvbSTransponder>()->toString();
875 case DvbTransponderBase::DvbS2:
876 return as<DvbS2Transponder>()->toString();
877 case DvbTransponderBase::DvbT:
878 return as<DvbTTransponder>()->toString();
879 case DvbTransponderBase::DvbT2:
880 return as<DvbT2Transponder>()->toString();
881 case DvbTransponderBase::Atsc:
882 return as<AtscTransponder>()->toString();
883 case DvbTransponderBase::IsdbT:
884 return as<IsdbTTransponder>()->toString();
885 }
886
887 return QString();
888 }
889
frequency()890 int DvbTransponder::frequency()
891 {
892 switch (data.transmissionType) {
893 case DvbTransponderBase::Invalid:
894 return 0;
895 case DvbTransponderBase::DvbC:
896 return as<DvbCTransponder>()->frequency;
897 case DvbTransponderBase::DvbS:
898 return as<DvbSTransponder>()->frequency;
899 case DvbTransponderBase::DvbS2:
900 return as<DvbS2Transponder>()->frequency;
901 case DvbTransponderBase::DvbT:
902 return as<DvbTTransponder>()->frequency;
903 case DvbTransponderBase::DvbT2:
904 return as<DvbT2Transponder>()->frequency;
905 case DvbTransponderBase::Atsc:
906 return as<AtscTransponder>()->frequency;
907 case DvbTransponderBase::IsdbT:
908 return as<IsdbTTransponder>()->frequency;
909 }
910
911 return 0;
912 }
913
fromString(const QString & string)914 DvbTransponder DvbTransponder::fromString(const QString &string)
915 {
916 if (string.size() >= 2) {
917 switch (string.at(0).unicode()) {
918 case 'C': {
919 DvbTransponder transponder(DvbTransponderBase::DvbC);
920
921 if (transponder.as<DvbCTransponder>()->fromString(string)) {
922 return transponder;
923 }
924
925 break;
926 }
927 case 'S':
928 if (string.at(1) != QLatin1Char('2')) {
929 DvbTransponder transponder(DvbTransponderBase::DvbS);
930
931 if (transponder.as<DvbSTransponder>()->fromString(string)) {
932 return transponder;
933 }
934 } else {
935 DvbTransponder transponder(DvbTransponderBase::DvbS2);
936
937 if (transponder.as<DvbS2Transponder>()->fromString(string)) {
938 return transponder;
939 }
940 }
941
942 break;
943 case 'T': {
944 if (string.at(1) != QLatin1Char('2')) {
945 DvbTransponder transponder(DvbTransponderBase::DvbT);
946
947 if (transponder.as<DvbTTransponder>()->fromString(string)) {
948 return transponder;
949 }
950
951 break;
952 } else {
953 DvbTransponder transponder(DvbTransponderBase::DvbT2);
954
955 if (transponder.as<DvbT2Transponder>()->fromString(string)) {
956 return transponder;
957 }
958
959 break;
960 }
961 }
962 case 'A': {
963 DvbTransponder transponder(DvbTransponderBase::Atsc);
964
965 if (transponder.as<AtscTransponder>()->fromString(string)) {
966 return transponder;
967 }
968
969 break;
970 }
971 case 'I': {
972 DvbTransponder transponder(DvbTransponderBase::IsdbT);
973
974 if (transponder.as<IsdbTTransponder>()->fromString(string)) {
975 return transponder;
976 }
977
978 break;
979 }
980 }
981 }
982
983 return DvbTransponder();
984 }
985