1 /*
2 * Simple MPEG/DVB parser to achieve network/service information without initial tuning data
3 *
4 * Copyright (C) 2006, 2007, 2008, 2009 Winfried Koehler
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (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
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 */
21
22 #include <strings.h>
23 #include "extended_frontend.h"
24 #include "scan.h"
25 #include "dvbscan.h"
26
27 #define STRUCT_COUNT(struct_list) (sizeof(struct_list)/sizeof(struct init_item))
28
29 /********************************************************************
30 * dvbscan.c
31 *
32 * import / export of initial_tuning_data for dvbscan
33 * see doc/README.file_formats
34 *
35 ********************************************************************/
36
37 /********************************************************************
38 * DVB-T
39 ********************************************************************/
40
41 struct init_item terr_bw_list[] = {
42 {"8MHz", 8000000},
43 {"7MHz", 7000000},
44 {"6MHz", 6000000},
45 {"5MHz", 5000000},
46 {"10MHz", 10000000},
47 {"1.712MHz", 1712000},
48 {"AUTO", 8000000}
49 };
50
51 struct init_item terr_fec_list[] = {
52 {"NONE", FEC_NONE},
53 {"1/2", FEC_1_2},
54 {"2/3", FEC_2_3},
55 {"3/4", FEC_3_4},
56 {"4/5", FEC_4_5},
57 {"5/6", FEC_5_6},
58 {"6/7", FEC_6_7},
59 {"7/8", FEC_7_8},
60 {"3/5", FEC_3_5},
61 {"4/5", FEC_4_5},
62 {"AUTO", FEC_AUTO}
63 };
64
65 struct init_item terr_mod_list[] = {
66 {"QPSK", QPSK},
67 {"QAM16", QAM_16},
68 {"QAM64", QAM_64},
69 {"QAM256", QAM_256},
70 {"AUTO", QAM_AUTO}
71 };
72
73 struct init_item terr_mod_list_v5[] = {
74 {"QPSK", QPSK},
75 {"QAM/16", QAM_16},
76 {"QAM/64", QAM_64},
77 {"QAM/256", QAM_256},
78 {"QAM/AUTO", QAM_AUTO}
79 };
80
81 struct init_item terr_transmission_list[] = {
82 {"2k", TRANSMISSION_MODE_2K},
83 {"8k", TRANSMISSION_MODE_8K},
84 {"4k", TRANSMISSION_MODE_4K},
85 {"1k", TRANSMISSION_MODE_1K},
86 {"16k", TRANSMISSION_MODE_16K},
87 {"32k", TRANSMISSION_MODE_32K},
88 {"AUTO", TRANSMISSION_MODE_AUTO}
89 };
90
91 struct init_item terr_guard_list[] = {
92 {"1/32", GUARD_INTERVAL_1_32},
93 {"1/16", GUARD_INTERVAL_1_16},
94 {"1/8", GUARD_INTERVAL_1_8},
95 {"1/4", GUARD_INTERVAL_1_4},
96 {"1/128", GUARD_INTERVAL_1_128},
97 {"19/128", GUARD_INTERVAL_19_128},
98 {"19/256", GUARD_INTERVAL_19_256},
99 {"AUTO", GUARD_INTERVAL_AUTO}
100 };
101
102 struct init_item terr_hierarchy_list[] = {
103 {"NONE", HIERARCHY_NONE},
104 {"1", HIERARCHY_1},
105 {"2", HIERARCHY_2},
106 {"4", HIERARCHY_4},
107 {"AUTO", HIERARCHY_AUTO}
108 };
109
110 /* convert text to identifiers */
111
txt_to_terr_bw(const char * txt)112 int txt_to_terr_bw(const char *txt)
113 {
114 unsigned int i;
115
116 for (i = 0; i < STRUCT_COUNT(terr_bw_list); i++)
117 if (!strcasecmp(txt, terr_bw_list[i].name))
118 return terr_bw_list[i].id;
119 return 8000000; // fallback. should never happen.
120 }
121
txt_to_terr_fec(const char * txt)122 int txt_to_terr_fec(const char *txt)
123 {
124 unsigned int i;
125
126 for (i = 0; i < STRUCT_COUNT(terr_fec_list); i++)
127 if (!strcasecmp(txt, terr_fec_list[i].name))
128 return terr_fec_list[i].id;
129 return FEC_AUTO; // fallback. should never happen.
130 }
131
txt_to_terr_mod(const char * txt)132 int txt_to_terr_mod(const char *txt)
133 {
134 unsigned int i;
135
136 for (i = 0; i < STRUCT_COUNT(terr_mod_list); i++)
137 if (!strcasecmp(txt, terr_mod_list[i].name))
138 return terr_mod_list[i].id;
139 return QAM_AUTO; // fallback. should never happen.
140 }
141
txt_to_terr_transmission(const char * txt)142 int txt_to_terr_transmission(const char *txt)
143 {
144 unsigned int i;
145
146 for (i = 0; i < STRUCT_COUNT(terr_transmission_list); i++)
147 if (!strcasecmp(txt, terr_transmission_list[i].name))
148 return terr_transmission_list[i].id;
149 return TRANSMISSION_MODE_AUTO; // fallback. should never happen.
150 }
151
txt_to_terr_guard(const char * txt)152 int txt_to_terr_guard(const char *txt)
153 {
154 unsigned int i;
155
156 for (i = 0; i < STRUCT_COUNT(terr_guard_list); i++)
157 if (!strcasecmp(txt, terr_guard_list[i].name))
158 return terr_guard_list[i].id;
159 return GUARD_INTERVAL_AUTO; // fallback. should never happen.
160 }
161
txt_to_terr_hierarchy(const char * txt)162 int txt_to_terr_hierarchy(const char *txt)
163 {
164 unsigned int i;
165
166 for (i = 0; i < STRUCT_COUNT(terr_hierarchy_list); i++)
167 if (!strcasecmp(txt, terr_hierarchy_list[i].name))
168 return terr_hierarchy_list[i].id;
169 return HIERARCHY_AUTO; // fallback. should never happen.
170 }
171
172 /*convert identifier to text */
173
terr_bw_to_txt(int id)174 const char *terr_bw_to_txt(int id)
175 {
176 unsigned int i;
177
178 for (i = 0; i < STRUCT_COUNT(terr_bw_list); i++)
179 if (id == terr_bw_list[i].id)
180 return terr_bw_list[i].name;
181 return "AUTO"; // fallback. should never happen.
182 }
183
terr_fec_to_txt(int id)184 const char *terr_fec_to_txt(int id)
185 {
186 unsigned int i;
187
188 for (i = 0; i < STRUCT_COUNT(terr_fec_list); i++)
189 if (id == terr_fec_list[i].id)
190 return terr_fec_list[i].name;
191 return "AUTO"; // fallback. should never happen.
192 }
193
terr_mod_to_txt(int id)194 const char *terr_mod_to_txt(int id)
195 {
196 unsigned int i;
197
198 for (i = 0; i < STRUCT_COUNT(terr_mod_list); i++)
199 if (id == terr_mod_list[i].id)
200 return terr_mod_list[i].name;
201 return "AUTO"; // fallback. should never happen.
202 }
203
terr_mod_to_txt_v5(int id)204 const char *terr_mod_to_txt_v5(int id)
205 {
206 unsigned int i;
207
208 for (i = 0; i < STRUCT_COUNT(terr_mod_list_v5); i++)
209 if (id == terr_mod_list_v5[i].id)
210 return terr_mod_list_v5[i].name;
211 return "QAM/AUTO"; // fallback. should never happen.
212 }
213
terr_transmission_to_txt(int id)214 const char *terr_transmission_to_txt(int id)
215 {
216 unsigned int i;
217
218 for (i = 0; i < STRUCT_COUNT(terr_transmission_list); i++)
219 if (id == terr_transmission_list[i].id)
220 return terr_transmission_list[i].name;
221 return "AUTO"; // fallback. should never happen.
222 }
223
terr_guard_to_txt(int id)224 const char *terr_guard_to_txt(int id)
225 {
226 unsigned int i;
227
228 for (i = 0; i < STRUCT_COUNT(terr_guard_list); i++)
229 if (id == terr_guard_list[i].id)
230 return terr_guard_list[i].name;
231 return "AUTO"; // fallback. should never happen.
232 }
233
terr_hierarchy_to_txt(int id)234 const char *terr_hierarchy_to_txt(int id)
235 {
236 unsigned int i;
237
238 for (i = 0; i < STRUCT_COUNT(terr_hierarchy_list); i++)
239 if (id == terr_hierarchy_list[i].id)
240 return terr_hierarchy_list[i].name;
241 return "AUTO"; // fallback. should never happen.
242 }
243
244 /********************************************************************
245 * DVB-C
246 ********************************************************************/
247
248 struct init_item cable_fec_list[] = {
249 {"NONE", FEC_NONE},
250 {"1/2", FEC_1_2},
251 {"2/3", FEC_2_3},
252 {"3/4", FEC_3_4},
253 {"4/5", FEC_4_5},
254 {"5/6", FEC_5_6},
255 {"6/7", FEC_6_7},
256 {"7/8", FEC_7_8},
257 {"8/9", FEC_8_9},
258 {"3/5", FEC_3_5},
259 {"9/10", FEC_9_10},
260 {"AUTO", FEC_AUTO}
261 };
262
263 struct init_item cable_mod_list[] = {
264 {"QAM16", QAM_16},
265 {"QAM32", QAM_32},
266 {"QAM64", QAM_64},
267 {"QAM128", QAM_128},
268 {"QAM256", QAM_256},
269 #ifdef SYS_DVBC2 //currently not supported by Linux DVB API
270 {"QAM512", QAM_512},
271 {"QAM1024", QAM_1024},
272 {"QAM4096", QAM_4096},
273 #endif
274 };
275
276 struct init_item cable_mod_list_v5[] = {
277 {"QAM/16", QAM_16},
278 {"QAM/32", QAM_32},
279 {"QAM/64", QAM_64},
280 {"QAM/128", QAM_128},
281 {"QAM/256", QAM_256},
282 #ifdef SYS_DVBC2 //currently not supported by Linux DVB API
283 {"QAM/512", QAM_512},
284 {"QAM/1024", QAM_1024},
285 {"QAM/4096", QAM_4096},
286 #endif
287 };
288
289 /* convert text to identifiers */
290
txt_to_cable_fec(const char * txt)291 int txt_to_cable_fec(const char *txt)
292 {
293 unsigned int i;
294
295 for (i = 0; i < STRUCT_COUNT(cable_fec_list); i++)
296 if (!strcasecmp(txt, cable_fec_list[i].name))
297 return cable_fec_list[i].id;
298 return FEC_AUTO; // fallback. should never happen.
299 }
300
txt_to_cable_mod(const char * txt)301 int txt_to_cable_mod(const char *txt)
302 {
303 unsigned int i;
304
305 for (i = 0; i < STRUCT_COUNT(cable_mod_list); i++)
306 if (!strcasecmp(txt, cable_mod_list[i].name))
307 return cable_mod_list[i].id;
308 return QAM_AUTO; // fallback. should never happen.
309 }
310
311 /*convert identifier to text */
312
cable_fec_to_txt(int id)313 const char *cable_fec_to_txt(int id)
314 {
315 unsigned int i;
316
317 for (i = 0; i < STRUCT_COUNT(cable_fec_list); i++)
318 if (id == cable_fec_list[i].id)
319 return cable_fec_list[i].name;
320 return "AUTO"; // fallback. should never happen.
321 }
322
cable_mod_to_txt(int id)323 const char *cable_mod_to_txt(int id)
324 {
325 unsigned int i;
326
327 for (i = 0; i < STRUCT_COUNT(cable_mod_list); i++)
328 if (id == cable_mod_list[i].id)
329 return cable_mod_list[i].name;
330 return "AUTO"; // fallback. should never happen.
331 }
332
cable_mod_to_txt_v5(int id)333 const char *cable_mod_to_txt_v5(int id)
334 {
335 unsigned int i;
336
337 for (i = 0; i < STRUCT_COUNT(cable_mod_list_v5); i++)
338 if (id == cable_mod_list_v5[i].id)
339 return cable_mod_list_v5[i].name;
340 return "QAM/AUTO"; // fallback. should never happen.
341 }
342
343 /********************************************************************
344 * ATSC
345 ********************************************************************/
346
347 struct init_item atsc_mod_list[] = {
348 {"QAM64", QAM_64},
349 {"QAM256", QAM_256},
350 {"8VSB", VSB_8},
351 {"16VSB", VSB_16},
352 };
353
354 struct init_item atsc_mod_list_v5[] = {
355 {"QAM/64", QAM_64},
356 {"QAM/256", QAM_256},
357 {"VSB/8", VSB_8},
358 {"VSB/16", VSB_16},
359 };
360
361 /* convert text to identifiers */
362
txt_to_atsc_mod(const char * txt)363 int txt_to_atsc_mod(const char *txt)
364 {
365 unsigned int i;
366
367 for (i = 0; i < STRUCT_COUNT(atsc_mod_list); i++)
368 if (!strcasecmp(txt, atsc_mod_list[i].name))
369 return atsc_mod_list[i].id;
370 return QAM_AUTO; // fallback. should never happen.
371 }
372
373 /*convert identifier to text */
374
atsc_mod_to_txt(int id)375 const char *atsc_mod_to_txt(int id)
376 {
377 unsigned int i;
378
379 for (i = 0; i < STRUCT_COUNT(atsc_mod_list); i++)
380 if (id == atsc_mod_list[i].id)
381 return atsc_mod_list[i].name;
382 return "AUTO"; // fallback. should never happen.
383 }
384
atsc_mod_to_txt_v5(int id)385 const char *atsc_mod_to_txt_v5(int id)
386 {
387 unsigned int i;
388
389 for (i = 0; i < STRUCT_COUNT(atsc_mod_list_v5); i++)
390 if (id == atsc_mod_list_v5[i].id)
391 return atsc_mod_list_v5[i].name;
392 return "QAM/AUTO"; // fallback. should never happen.
393 }
394
395 /********************************************************************
396 * DVB-S
397 ********************************************************************/
398
399 struct init_item sat_delivery_system_list[] = {
400 {"S", SYS_DVBS},
401 {"S1", SYS_DVBS},
402 {"S2", SYS_DVBS2},
403 };
404
405 struct init_item sat_pol_list[] = {
406 {"H", POLARIZATION_HORIZONTAL},
407 {"V", POLARIZATION_VERTICAL},
408 {"R", POLARIZATION_CIRCULAR_RIGHT},
409 {"L", POLARIZATION_CIRCULAR_LEFT},
410 }; // NOTE: no AUTO used here.
411
412 struct init_item sat_pol_list_v5[] = {
413 {"HORIZONTAL", POLARIZATION_HORIZONTAL},
414 {"VERTICAL", POLARIZATION_VERTICAL},
415 {"RIGHT", POLARIZATION_CIRCULAR_RIGHT},
416 {"LEFT", POLARIZATION_CIRCULAR_LEFT},
417 }; // NOTE: no AUTO used here.
418
419 struct init_item sat_fec_list[] = {
420 {"NONE", FEC_NONE},
421 {"1/2", FEC_1_2},
422 {"2/3", FEC_2_3},
423 {"3/4", FEC_3_4},
424 {"4/5", FEC_4_5},
425 {"5/6", FEC_5_6},
426 {"6/7", FEC_6_7},
427 {"7/8", FEC_7_8},
428 {"8/9", FEC_8_9},
429 {"3/5", FEC_3_5}, //S2
430 {"9/10", FEC_9_10}, //S2
431 {"AUTO", FEC_AUTO}
432 };
433
434 struct init_item sat_rolloff_list[] = {
435 {"35", ROLLOFF_35},
436 {"25", ROLLOFF_25},
437 {"20", ROLLOFF_20},
438 {"AUTO", ROLLOFF_AUTO},
439 }; // NOTE: "AUTO" == 0,35 in w_scan2 !
440
441 struct init_item sat_mod_list[] = {
442 {"QPSK", QPSK},
443 {"8PSK", PSK_8},
444 {"16APSK", APSK_16},
445 {"32APSK", APSK_32},
446 {"AUTO", QPSK},
447 }; // NOTE: "AUTO" == QPSK in w_scan2 !
448
449 struct init_item sat_mod_list_v5[] = {
450 {"QPSK", QPSK},
451 {"PSK/8", PSK_8},
452 {"APSK/16", APSK_16},
453 {"APSK/32", APSK_32},
454 {"AUTO", QPSK},
455 }; // NOTE: "AUTO" == QPSK in w_scan2 !
456
457 /* convert text to identifiers */
458
txt_to_sat_delivery_system(const char * txt)459 int txt_to_sat_delivery_system(const char *txt)
460 {
461 unsigned int i;
462
463 for (i = 0; i < STRUCT_COUNT(sat_delivery_system_list); i++)
464 if (!strcasecmp(txt, sat_delivery_system_list[i].name))
465 return sat_delivery_system_list[i].id;
466 return SYS_DVBS; // fallback. should never happen.
467 }
468
txt_to_sat_pol(const char * txt)469 int txt_to_sat_pol(const char *txt)
470 {
471 unsigned int i;
472
473 for (i = 0; i < STRUCT_COUNT(sat_pol_list); i++)
474 if (!strcasecmp(txt, sat_pol_list[i].name))
475 return sat_pol_list[i].id;
476 return POLARIZATION_HORIZONTAL; // fallback. should never happen.
477 }
478
txt_to_sat_fec(const char * txt)479 int txt_to_sat_fec(const char *txt)
480 {
481 unsigned int i;
482
483 for (i = 0; i < STRUCT_COUNT(sat_fec_list); i++)
484 if (!strcasecmp(txt, sat_fec_list[i].name))
485 return sat_fec_list[i].id;
486 return FEC_AUTO; // fallback. should never happen.
487 }
488
txt_to_sat_rolloff(const char * txt)489 int txt_to_sat_rolloff(const char *txt)
490 {
491 unsigned int i;
492
493 for (i = 0; i < STRUCT_COUNT(sat_rolloff_list); i++)
494 if (!strcasecmp(txt, sat_rolloff_list[i].name))
495 return sat_rolloff_list[i].id;
496 return ROLLOFF_35; // fallback. should never happen.
497 }
498
txt_to_sat_mod(const char * txt)499 int txt_to_sat_mod(const char *txt)
500 {
501 unsigned int i;
502
503 for (i = 0; i < STRUCT_COUNT(sat_mod_list); i++)
504 if (!strcasecmp(txt, sat_mod_list[i].name))
505 return sat_mod_list[i].id;
506 return QPSK; // fallback. should never happen.
507 }
508
509 /*convert identifier to text */
510
sat_delivery_system_to_txt(int id)511 const char *sat_delivery_system_to_txt(int id)
512 {
513 unsigned int i;
514
515 for (i = 0; i < STRUCT_COUNT(sat_delivery_system_list); i++)
516 if (id == sat_delivery_system_list[i].id)
517 return sat_delivery_system_list[i].name;
518 return "S"; // fallback. should never happen.
519 }
520
sat_pol_to_txt(int id)521 const char *sat_pol_to_txt(int id)
522 {
523 unsigned int i;
524
525 for (i = 0; i < STRUCT_COUNT(sat_pol_list); i++)
526 if (id == sat_pol_list[i].id)
527 return sat_pol_list[i].name;
528 return "H"; // fallback. should never happen.
529 }
530
sat_pol_to_txt_v5(int id)531 const char *sat_pol_to_txt_v5(int id)
532 {
533 unsigned int i;
534
535 for (i = 0; i < STRUCT_COUNT(sat_pol_list_v5); i++)
536 if (id == sat_pol_list_v5[i].id)
537 return sat_pol_list_v5[i].name;
538 return "HORIZONTAL"; // fallback. should never happen.
539 }
540
sat_fec_to_txt(int id)541 const char *sat_fec_to_txt(int id)
542 {
543 unsigned int i;
544
545 for (i = 0; i < STRUCT_COUNT(sat_fec_list); i++)
546 if (id == sat_fec_list[i].id)
547 return sat_fec_list[i].name;
548 return "AUTO"; // fallback. should never happen.
549 }
550
sat_rolloff_to_txt(int id)551 const char *sat_rolloff_to_txt(int id)
552 {
553 unsigned int i;
554
555 for (i = 0; i < STRUCT_COUNT(sat_rolloff_list); i++)
556 if (id == sat_rolloff_list[i].id)
557 return sat_rolloff_list[i].name;
558 return "35"; // fallback. should never happen.
559 }
560
sat_mod_to_txt(int id)561 const char *sat_mod_to_txt(int id)
562 {
563 unsigned int i;
564
565 for (i = 0; i < STRUCT_COUNT(sat_mod_list); i++)
566 if (id == sat_mod_list[i].id)
567 return sat_mod_list[i].name;
568 return "QPSK"; // fallback. should never happen.
569 }
570
sat_mod_to_txt_v5(int id)571 const char *sat_mod_to_txt_v5(int id)
572 {
573 unsigned int i;
574
575 for (i = 0; i < STRUCT_COUNT(sat_mod_list_v5); i++)
576 if (id == sat_mod_list_v5[i].id)
577 return sat_mod_list_v5[i].name;
578 return "QPSK"; // fallback. should never happen.
579 }
580
581 /********************************************************************
582 * non-frontend specific part
583 *
584 ********************************************************************/
585
586 struct init_item scantype_list[] = {
587 {"TERRCABLE_ATSC", SCAN_TERRCABLE_ATSC},
588 {"CABLE", SCAN_CABLE},
589 {"TERRESTRIAL", SCAN_TERRESTRIAL},
590 {"SATELLITE", SCAN_SATELLITE},
591 }; // NOTE: "AUTO" == SCAN_TERRESTRIAL in w_scan2 !
592
593 /* convert text to identifiers */
594
txt_to_scantype(const char * txt)595 int txt_to_scantype(const char *txt)
596 {
597 unsigned int i;
598
599 for (i = 0; i < STRUCT_COUNT(scantype_list); i++)
600 if (!strcasecmp(txt, scantype_list[i].name))
601 return scantype_list[i].id;
602 return SCAN_TERRESTRIAL; // fallback. should never happen.
603 }
604
605 /*convert identifier to text */
606
scantype_to_txt(int id)607 const char *scantype_to_txt(int id)
608 {
609 unsigned int i;
610
611 for (i = 0; i < STRUCT_COUNT(scantype_list); i++)
612 if (id == scantype_list[i].id)
613 return scantype_list[i].name;
614 return "TERRESTRIAL"; // fallback. should never happen.
615 }
616