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 "countries.h"
23 #include "scan.h"
24 #include <stdio.h>
25 #include <string.h>
26 #include <strings.h>
27 #include <unistd.h>
28 #include <ctype.h>
29 #include <locale.h>
30 #include <stdlib.h>
31
32 #ifdef VDRVERSNUM
33 #include <linux/dvb/frontend.h>
34 namespace COUNTRY {
35 #else
36 #include "extended_frontend.h"
37 #endif
38
39 /**************************************************************************************************
40 * FREQUENCY CALCULATION SCHEME:
41 * each frequency used by w_scan2 is calculated as follows:
42 *
43 * frequency(channellist, channel, frequency_offset_index) =
44 * base_offset(channel, channellist) +
45 * channel * freq_step(channel, channellist) +
46 * freq_offset(channel, channellist, frequency_offset_index);
47 *
48 *
49 * - channellist is choosen by user, if not choosen defaults are used.
50 * - channel = 0..133 (might be extended if needed)
51 * - frequency_offset_index = 0 (no offset) -> 1 (pos offset) -> 2 (neg offset)
52 *
53 * if base_offset(channel, channellist) returns -1 this channel will be skipped.
54 * if freq_offset(channel, channellist, frequency_offset_index) returns -1 this offset will be skipped.
55 *
56 * example:
57 * channellist = 4; channel = 12
58 *
59 * base_offset(12, 4) = 142500000
60 * freq_step(12, 4) = 7000000
61 * freq_offset(12, 4, 0) = 0
62 * freq_offset(12, 4, 1) = -1
63 * freq_offset(12, 4, 2) = -1
64 *
65 * frequency = 142500000 + 12 * 7000000 = 226500000
66 * since freq_offset returns -1 for frequency_offset_index = (1,2) no frequency offset is applied.
67 *
68 * 20090101 -wk
69 **************************************************************************************************/
70
71 /*
72 * User selects a country specific channellist.
73 * therefore we know
74 * - frontend type DVB or ATSC
75 * - used frequency list (base_offsets, freq_step)
76 * - other country-specific things (transmission mode, frequency offsets from center..)
77 * use two letter uppercase for 'country', as defined by ISO 3166-1
78 */
choose_country(const char * country,int * atsc,int * dvb,uint16_t * scan_type,int * channellist)79 int choose_country(const char *country,
80 int *atsc, int *dvb, uint16_t *scan_type, int *channellist)
81 {
82 if (*channellist == USERLIST)
83 return 0;
84
85 if (strcasecmp(country_to_short_name(txt_to_country(country)), country)) {
86 warning
87 ("\n\nCOUNTRY CODE IS NOT DEFINED. FALLING BACK TO \"DE\"\n\n");
88 sleep(10);
89 }
90 info("using settings for %s\n",
91 country_to_full_name(txt_to_country(country)));
92
93 /*
94 * choose DVB or ATSC frontend type
95 */
96 switch (txt_to_country(country)) {
97
98 case AT: // AUSTRIA
99 case BE: // BELGIUM
100 case CH: // SWITZERLAND
101 case CO: // COLOMBIA, DVB-C + DVB-T2
102 case CZ: // CZECH REPUBLIC
103 case DE: // GERMANY
104 case DK: // DENMARK
105 case ES: // SPAIN
106 case FR: // FRANCE
107 case FI: // FINLAND
108 case GB: // UNITED KINGDOM
109 case GR: // GREECE
110 case HR: // CROATIA
111 case HK: // HONG KONG
112 case IL: // ISRAEL
113 case IS: // ICELAND
114 case IT: // ITALY
115 case LU: // LUXEMBOURG
116 case LV: // LATVIA
117 case NL: // NETHERLANDS
118 case NO: // NORWAY
119 case NZ: // NEW ZEALAND
120 case PL: // POLAND
121 case SE: // SWEDEN
122 case SK: // SLOVAKIA
123 case TW: // TAIWAN, DVB-T w. ATSC freq list (thanks for freqlist to mkrufky)
124 case AU: // AUSTRALIA, DVB-T w. 7MHz step
125 switch (*dvb) {
126 case SCAN_CABLE:
127 *scan_type = SCAN_CABLE;
128 info("DVB cable\n");
129 break;
130 default:
131 *scan_type = SCAN_TERRESTRIAL;
132 info("DVB aerial\n");
133 break;
134 }
135 break;
136
137 case BR: // Brazil
138 switch (*dvb) {
139 case SCAN_CABLE:
140 *scan_type = SCAN_CABLE;
141 info("DVB cable\n");
142 break;
143 default:
144 *scan_type = SCAN_TERRESTRIAL;
145 info("ISDB-T (SBTVD)\n");
146 break;
147 }
148 break;
149
150 case US: // UNITED STATES
151 case CA: // CANADA
152 *scan_type = SCAN_TERRCABLE_ATSC;
153 info("ATSC\n");
154 break;
155
156 default:
157 info("Country identifier %s not defined. Using defaults.\n",
158 country);
159 return -1;
160 break;
161 }
162
163 /*
164 * choose channellist name
165 */
166 switch (txt_to_country(country)) {
167 //**********DVB freq lists*******************************************//
168 case AT: // AUSTRIA
169 case BE: // BELGIUM
170 case CH: // SWITZERLAND
171 case DE: // GERMANY
172 case DK: // DENMARK
173 case ES: // SPAIN
174 case GR: // GREECE
175 case HR: // CROATIA
176 case HK: // HONG KONG
177 case IL: // ISRAEL
178 case IS: // ICELAND
179 case IT: // ITALY
180 case LU: // LUXEMBOURG
181 case LV: // LATVIA
182 case NL: // NETHERLANDS
183 case NO: // NORWAY
184 case NZ: // NEW ZEALAND
185 case PL: // POLAND
186 case SE: // SWEDEN
187 case SK: // SLOVAKIA
188 switch (*dvb) {
189 case SCAN_CABLE:
190 *channellist = DVBC_QAM;
191 info("DVB-C\n");
192 break;
193 default:
194 *channellist = DVBT_DE;
195 info("DVB-T Europe\n");
196 break;
197 }
198 break;
199 case CZ: // CZECH REPUBLIC
200 case FI: // FINLAND
201 switch (*dvb) {
202 case SCAN_CABLE:
203 *channellist = DVBC_FI;
204 info("DVB-C FI\n");
205 break;
206 default:
207 *channellist = DVBT_DE;
208 info("DVB-T Europe\n");
209 break;
210 }
211 break;
212 case FR: // FRANCE
213 switch (*dvb) {
214 case SCAN_CABLE:
215 *channellist = DVBC_FR;
216 info("DVB-C FR\n");
217 break;
218 default:
219 *channellist = DVBT_FR;
220 info("DVB-T FR\n");
221 break;
222 }
223 break;
224 case GB: // UNITED KINGDOM
225 switch (*dvb) {
226 case SCAN_CABLE:
227 *channellist = DVBC_QAM;
228 info("DVB-C\n");
229 break;
230 default:
231 *channellist = DVBT_GB;
232 info("DVB-T GB\n");
233 break;
234 }
235 break;
236 case AU: // AUSTRALIA
237 switch (*dvb) {
238 case SCAN_CABLE:
239 info("cable australia not yet defined.\n");
240 break;
241 default:
242 *channellist = DVBT_AU;
243 info("DVB-T AU\n");
244 break;
245 }
246 break;
247 //**********ATSC freq lists******************************************//
248 case US: // UNITED STATES
249 case CA: // CANADA
250 case TW: // TAIWAN, DVB-T w. ATSC freq list
251 if (atsc_is_vsb(*atsc)) {
252 *channellist = ATSC_VSB;
253 info("VSB US/CA, DVB-T TW\n");
254 }
255 if (atsc_is_qam(*atsc)) {
256 *channellist = ATSC_QAM;
257 info("QAM US/CA\n");
258 }
259 break;
260 case CO: // COLOMBIA, 6MHz offs 389MHz
261 switch (*dvb) {
262 case SCAN_CABLE:
263 info("cable colombia not yet defined.\n");
264 break;
265 default:
266 *channellist = DVBT2_CO;
267 info("DVB-T2 CO\n");
268 break;
269 }
270 break;
271 case BR: // BRAZIL, DVB-C/ISDB-T w. ATSC freq list
272 switch (*dvb) {
273 case SCAN_CABLE:
274 *channellist = DVBC_BR;
275 info("DVB-C BR\n");
276 break;
277 default:
278 *channellist = ISDBT_6MHZ;
279 info("ISDB-T, BR\n");
280 break;
281 }
282 break;
283 //******************************************************************//
284 default:
285 info("Country identifier %s not defined. Using default freq lists.\n", country);
286 return -1;
287 break;
288 }
289 return 0; // success
290 }
291
292 /*
293 * return the base offsets for specified channellist and channel.
294 */
base_offset(int channel,int channellist)295 int base_offset(int channel, int channellist)
296 {
297 switch (channellist) {
298 case ATSC_QAM: //ATSC cable, US EIA/NCTA Std Cable center freqs + IRC list
299 case DVBC_BR: //BRAZIL - same range as ATSC IRC
300 switch (channel) {
301 case 2 ... 4:
302 return 45000000;
303 case 5 ... 6:
304 return 49000000;
305 case 7 ... 13:
306 return 135000000;
307 case 14 ... 22:
308 return 39000000;
309 case 23 ... 94:
310 return 81000000;
311 case 95 ... 99:
312 return -477000000;
313 case 100 ... 133:
314 return 51000000;
315 default:
316 return SKIP_CHANNEL;
317 }
318 case ATSC_VSB: //ATSC terrestrial, US NTSC center freqs
319 switch (channel) {
320 case 2 ... 4:
321 return 45000000;
322 case 5 ... 6:
323 return 49000000;
324 case 7 ... 13:
325 return 135000000;
326 case 14 ... 69:
327 return 389000000;
328 default:
329 return SKIP_CHANNEL;
330 }
331 case DVBT2_CO: // DVB-T2 Colombia, 6 MHz step
332 switch (channel) {
333 //channels 21..51 are not stated as digital,
334 //however ch 27, 28, 43 are marked as T2 in other docs.
335 //scan up to ch 51 (end of band V)
336 case 14 ... 51:
337 return 389000000;
338 default:
339 return SKIP_CHANNEL;
340 }
341 case ISDBT_6MHZ: // ISDB-T, 6 MHz central frequencies
342 switch (channel) {
343 // Channels 7-13 are reserved but aren't used yet
344 //case 7 ... 13: return 135000000;
345 case 14 ... 69:
346 return 389000000;
347 default:
348 return SKIP_CHANNEL;
349 }
350 case DVBT_AU: //AUSTRALIA, 7MHz step list, offset 0/+125kHz
351 switch (channel) {
352 case 5 ... 12:
353 return 142500000;
354 case 21 ... 69:
355 return 333500000;
356 default:
357 return SKIP_CHANNEL;
358 }
359 case DVBT_DE: //GERMANY
360 case DVBT_FR: //FRANCE, +/- offset 166kHz & +offset 332kHz & +offset 498kHz
361 case DVBT_GB: //UNITED KINGDOM, +/- offset
362 switch (channel) {
363 case 5 ... 12:
364 // VHF making a comeback in Europe: https://tech.ebu.ch/docs/factsheets/ebu_tech_fs_use_of_band_III.pdf
365 return 142500000;
366 case 21 ... 69:
367 return 306000000;
368 default:
369 return SKIP_CHANNEL;
370 }
371
372 case DVBC_QAM: //EUROPE
373 switch (channel) {
374 case 0 ... 1:
375 case 5 ... 12:
376 return 73000000;
377 case 22 ... 90:
378 return 138000000;
379 default:
380 return SKIP_CHANNEL;
381 }
382 case DVBC_FI: //FINLAND, QAM128
383 switch (channel) {
384 case 1 ... 90:
385 return 138000000;
386 default:
387 return SKIP_CHANNEL;
388 }
389 case DVBC_FR: //FRANCE, needs user response.
390 switch (channel) {
391 case 1 ... 39:
392 return 107000000;
393 case 40 ... 89:
394 return 138000000;
395 default:
396 return SKIP_CHANNEL;
397 }
398 default:
399 fatal("%s: undefined channellist %d\n", __FUNCTION__,
400 channellist);
401 return SKIP_CHANNEL;
402 }
403 }
404
405 /*
406 * return the freq step size for specified channellist
407 */
freq_step(int channel,int channellist)408 int freq_step(int channel, int channellist)
409 {
410 switch (channellist) {
411 case ATSC_QAM:
412 case ATSC_VSB:
413 case DVBC_BR:
414 case DVBT2_CO:
415 case ISDBT_6MHZ:
416 return 6000000; // atsc region, 6MHz step
417 case DVBT_AU:
418 return 7000000; // dvb-t australia, 7MHz step
419 case DVBT_DE:
420 case DVBT_FR:
421 case DVBT_GB:
422 switch (channel) { // dvb-t europe, 7MHz VHF ch5..12, all other 8MHz
423 case 5 ... 12:
424 return 7000000;
425 case 21 ... 69:
426 return 8000000;
427 default:
428 return 8000000; // should be never reached.
429 }
430 case DVBC_QAM:
431 case DVBC_FI:
432 case DVBC_FR:
433 return 8000000; // dvb-c, 8MHz step
434 default:
435 fatal("%s: undefined channellist %d\n", __FUNCTION__,
436 channellist);
437 return SKIP_CHANNEL;
438 }
439 }
440
441 // EN300429 v1.2.1, chapter 9 Modulation p.16:
442 // "I and Q signals shall be square-root raised cosine filtered. The roll-off factor shall be 0,15"
443 #define DVBC_ROLLOFF 0.15
444 #define DVBC_SYMBOL_LEN (1.0 + DVBC_ROLLOFF)
445
max_dvbc_srate(int bandwidth)446 int max_dvbc_srate(int bandwidth)
447 {
448 switch (bandwidth) {
449 case 0 ... 6:
450 fatal("%s %d, using old style DVB API", __FUNCTION__, __LINE__);
451 return SKIP_CHANNEL;
452
453 case 8000000:
454 case 7000000:
455 case 6000000:
456 case 5000000:
457 return (int)(0.5 + ((double)bandwidth) / DVBC_SYMBOL_LEN);
458 default:
459 fatal("%s: unknown channel bandwidth %d\n", __FUNCTION__,
460 bandwidth);
461 return SKIP_CHANNEL;
462 }
463 }
464
bandwidth(int channel,int channellist)465 int bandwidth(int channel, int channellist)
466 {
467 return freq_step(channel, channellist);
468 }
469
470 /*
471 * some countries use constant offsets around center frequency.
472 * define them here.
473 */
freq_offset(int channel,int channellist,int index)474 int freq_offset(int channel, int channellist, int index)
475 {
476 switch (channellist) {
477 case USERLIST:
478 return 0;
479 case ATSC_QAM:
480 switch (channel) {
481 case 14 ... 16:
482 case 25 ... 53:
483 case 98 ... 99:
484 switch (index) {
485 case NO_OFFSET:
486 return 0; //Incrementally Related Carriers (IRC)
487 case POS_OFFSET:
488 return 12500; //US EIA/NCTA Standard Cable center frequencies
489 default:
490 return STOP_OFFSET_LOOP;
491 }
492 default: // IRC = standard cable center
493 switch (index) {
494 case NO_OFFSET:
495 return 0; //center freq
496 default:
497 return STOP_OFFSET_LOOP;
498 }
499 }
500 case DVBT_FR:
501 switch (channel) {
502 // see http://tvignaud.pagesperso-orange.fr/tv/canaux.htm
503 case 5 ... 12: //VHF channels not used in FR
504 return STOP_OFFSET_LOOP;
505 default: //UHF channels. - 0,166 MHz /+ 0,166 MHz /+ 0,332 MHz /+ 0,498 MHz
506 switch (index) {
507 case NO_OFFSET:
508 return 0; //center freq
509 case POS_OFFSET:
510 return +166000; //center+offset 166kHz
511 case NEG_OFFSET:
512 return -166000; //center-offset 166kHz
513 case POS_OFFSET_1:
514 return +332000; //center+offset 332kHz
515 case POS_OFFSET_2:
516 return +498000; //center+offset 498kHz
517 default:
518 return STOP_OFFSET_LOOP;
519 }
520 }
521 case DVBT_GB:
522 switch (channel) {
523 case 5 ... 12: //VHF channels
524 switch (index) {
525 case NO_OFFSET:
526 return 0; //no offset
527 default:
528 return STOP_OFFSET_LOOP;
529 }
530 default: //UHF channels
531 switch (index) {
532 case NO_OFFSET:
533 return 0; //center freq
534 case POS_OFFSET:
535 return +167000; //center+offset
536 case NEG_OFFSET:
537 return -167000; //center-offset
538 default:
539 return STOP_OFFSET_LOOP;
540 }
541 }
542 case DVBT_AU:
543 switch (index) {
544 case NO_OFFSET:
545 return 0; //center freq
546 case POS_OFFSET:
547 return +125000; //center+offset
548 default:
549 return STOP_OFFSET_LOOP;
550 }
551 case DVBC_FR:
552 switch (channel) {
553 case 1 ... 39:
554 switch (index) {
555 case NO_OFFSET:
556 return 0; //center freq
557 case POS_OFFSET:
558 return +125000; //center+offset
559 default:
560 return STOP_OFFSET_LOOP;
561 }
562 case 40 ... 89:
563 default:
564 switch (index) {
565 case NO_OFFSET:
566 return 0;
567 default:
568 return STOP_OFFSET_LOOP;
569 }
570 }
571 case ISDBT_6MHZ: // ISDB-T, 6 MHz central frequencies
572 switch (channel) {
573 // Channels 7-13 are reserved but aren't used yet
574 case 7 ... 13:
575 case 14 ... 69:
576 switch (index) {
577 case NO_OFFSET:
578 return SKIP_CHANNEL; //center freq
579 case POS_OFFSET:
580 return +142857; //center+offset
581 default:
582 return STOP_OFFSET_LOOP;
583 }
584 default:
585 return STOP_OFFSET_LOOP;
586 }
587 default:
588 switch (index) {
589 case NO_OFFSET:
590 return 0;
591 default:
592 return STOP_OFFSET_LOOP;
593 }
594 }
595 }
596
597 /*
598 * DVB-T: default value if transmission mode AUTO
599 * not supported
600 */
dvbt_transmission_mode(int channel,int channellist)601 int dvbt_transmission_mode(int channel, int channellist)
602 {
603 switch (channellist) {
604 // GB seems to use 8k since 12/2009
605 default:
606 return TRANSMISSION_MODE_8K;
607 }
608 }
609
610 /*
611 * some countries don't use legacy delsys anymore
612 */
delsysloop_min(int channel,int channellist,uint16_t delsys)613 int delsysloop_min(int channel, int channellist, uint16_t delsys)
614 {
615 switch (delsys) {
616 case SYS_UNDEFINED:
617 switch (channellist) {
618 case DVBT2_CO:
619 return 1; //DVB-T2 only.
620 default:
621 return 0;
622 }
623 case SYS_DVBT:
624 return 0;
625 case SYS_DVBT2:
626 return 1;
627 default: // not possible
628 return 0;
629 }
630 }
631
632 /*
633 * some countries don't use 2nd gen delsys yet
634 */
delsysloop_max(int channel,int channellist,uint16_t delsys)635 int delsysloop_max(int channel, int channellist, uint16_t delsys)
636 {
637 switch (delsys) {
638 case SYS_UNDEFINED:
639 switch (channellist) {
640 case ATSC_VSB:
641 case ATSC_QAM:
642 case DVBC_QAM:
643 case DVBC_FI:
644 case DVBC_FR:
645 case DVBC_BR:
646 case ISDBT_6MHZ:
647 case DAB_DE:
648 case USERLIST:
649 return 0;
650 default:
651 return 1;
652 }
653 case SYS_DVBT:
654 return 0;
655 case SYS_DVBT2:
656 return 1;
657 default: // not possible
658 return 0;
659 }
660 }
661
662 /*
663 * start/stop values for dvbc qam loop
664 * 0 == QAM_64, 1 == QAM_256, 2 == QAM_128
665 */
dvbc_qam_max(int channel,int channellist)666 int dvbc_qam_max(int channel, int channellist)
667 {
668 switch (channellist) {
669 case DVBC_FI:
670 return 2; //QAM128
671 case DVBC_BR:
672 case DVBC_FR:
673 case DVBC_QAM:
674 return 1; //QAM256
675 default:
676 return 0; //no qam loop
677 }
678 }
679
dvbc_qam_min(int channel,int channellist)680 int dvbc_qam_min(int channel, int channellist)
681 {
682 switch (channellist) {
683 case DVBC_FI:
684 case DVBC_BR:
685 case DVBC_FR:
686 case DVBC_QAM:
687 return 0; //QAM64
688 default:
689 return 0; //no qam loop
690 }
691 }
692
atsc_is_vsb(int atsc)693 int atsc_is_vsb(int atsc)
694 {
695 return (atsc & ATSC_VSB);
696 }
697
atsc_is_qam(int atsc)698 int atsc_is_qam(int atsc)
699 {
700 return (atsc & ATSC_QAM);
701 }
702
703 /*
704 * two letters constants from ISO 3166-1.
705 * sorted alphabetically by long country name
706 */
707
708 struct cCountry country_list[] = {
709 /*- ISO 3166-1 - unique id - long country name alpha-3 numeric */
710 {"AF", AF, "AFGHANISTAN"}, /*AFG, 4 }, */
711 {"AX", AX, "ÅLAND ISLANDS"}, /*ALA, 248}, */
712 {"AL", AL, "ALBANIA"}, /*ALB, 8 }, */
713 {"DZ", DZ, "ALGERIA"}, /*DZA, 12 }, */
714 {"AS", AS, "AMERICAN SAMOA"}, /*ASM, 16 }, */
715 {"AD", AD, "ANDORRA"}, /*AND, 20 }, */
716 {"AO", AO, "ANGOLA"}, /*AGO, 24 }, */
717 {"AI", AI, "ANGUILLA"}, /*AIA, 660}, */
718 {"AQ", AQ, "ANTARCTICA"}, /*ATA, 10 }, */
719 {"AG", AG, "ANTIGUA AND BARBUDA"}, /*ATG, 28 }, */
720 {"AR", AR, "ARGENTINA"}, /*ARG, 32 }, */
721 {"AM", AM, "ARMENIA"}, /*ARM, 51 }, */
722 {"AW", AW, "ARUBA"}, /*ABW, 533}, */
723 {"AU", AU, "AUSTRALIA"}, /*AUS, 36 }, */
724 {"AT", AT, "AUSTRIA"}, /*AUT, 40 }, */
725 {"AZ", AZ, "AZERBAIJAN"}, /*AZE, 31 }, */
726 {"BS", BS, "BAHAMAS"}, /*BHS, 44 }, */
727 {"BH", BH, "BAHRAIN"}, /*BHR, 48 }, */
728 {"BD", BD, "BANGLADESH"}, /*BGD, 50 }, */
729 {"BB", BB, "BARBADOS"}, /*BRB, 52 }, */
730 {"BY", BY, "BELARUS"}, /*BLR, 112}, */
731 {"BE", BE, "BELGIUM"}, /*BEL, 56 }, */
732 {"BZ", BZ, "BELIZE"}, /*BLZ, 84 }, */
733 {"BJ", BJ, "BENIN"}, /*BEN, 204}, */
734 {"BM", BM, "BERMUDA"}, /*BMU, 60 }, */
735 {"BT", BT, "BHUTAN"}, /*BTN, 64 }, */
736 {"BO", BO, "BOLIVIA"}, /*BOL, 68 }, */
737 {"BQ", BQ, "BONAIRE"}, /*BES, 535}, */
738 {"BA", BA, "BOSNIA AND HERZEGOVINA"}, /*BIH, 70 }, */
739 {"BW", BW, "BOTSWANA"}, /*BWA, 72 }, */
740 {"BV", BV, "BOUVET ISLAND"}, /*BVT, 74 }, */
741 {"BR", BR, "BRAZIL"}, /*BRA, 76 }, */
742 {"IO", IO, "BRITISH INDIAN OCEAN TERRITORY"}, /*IOT, 86 }, */
743 {"BN", BN, "BRUNEI DARUSSALAM"}, /*BRN, 96 }, */
744 {"BG", BG, "BULGARIA"}, /*BGR, 100}, */
745 {"BF", BF, "BURKINA FASO"}, /*BFA, 854}, */
746 {"BI", BI, "BURUNDI"}, /*BDI, 108}, */
747 {"KH", KH, "CAMBODIA"}, /*KHM, 116}, */
748 {"CM", CM, "CAMEROON"}, /*CMR, 120}, */
749 {"CA", CA, "CANADA"}, /*CAN, 124}, */
750 {"CV", CV, "CAPE VERDE"}, /*CPV, 132}, */
751 {"KY", KY, "CAYMAN ISLANDS"}, /*CYM, 136}, */
752 {"CF", CF, "CENTRAL AFRICAN REPUBLIC"}, /*CAF, 140}, */
753 {"TD", TD, "CHAD"}, /*TCD, 148}, */
754 {"CL", CL, "CHILE"}, /*CHL, 152}, */
755 {"CN", CN, "CHINA"}, /*CHN, 156}, */
756 {"CX", CX, "CHRISTMAS ISLAND"}, /*CXR, 162}, */
757 {"CC", CC, "COCOS (KEELING) ISLANDS"}, /*CCK, 166}, */
758 {"CO", CO, "COLOMBIA"}, /*COL, 170}, */
759 {"KM", KM, "COMOROS"}, /*COM, 174}, */
760 {"CG", CG, "CONGO"}, /*COG, 178}, */
761 {"CD", CD, "CONGO, THE DEMOCRATIC REPUBLIC OF THE"}, /*COD, 180}, */
762 {"CK", CK, "COOK ISLANDS"}, /*COK, 184}, */
763 {"CR", CR, "COSTA RICA"}, /*CRI, 188}, */
764 {"CI", CI, "CÔTE D'IVOIRE"}, /*CIV, 384}, */
765 {"HR", HR, "CROATIA"}, /*HRV, 191}, */
766 {"CU", CU, "CUBA"}, /*CUB, 192}, */
767 {"CW", CW, "CURAÇAO"}, /*CUW, 531}, */
768 {"CY", CY, "CYPRUS"}, /*CYP, 196}, */
769 {"CZ", CZ, "CZECH REPUBLIC"}, /*CZE, 203}, */
770 {"DK", DK, "DENMARK"}, /*DNK, 208}, */
771 {"DJ", DJ, "DJIBOUTI"}, /*DJI, 262}, */
772 {"DM", DM, "DOMINICA"}, /*DMA, 212}, */
773 {"DO", DO, "DOMINICAN REPUBLIC"}, /*DOM, 214}, */
774 {"EC", EC, "ECUADOR"}, /*ECU, 218}, */
775 {"EG", EG, "EGYPT"}, /*EGY, 818}, */
776 {"SV", SV, "EL SALVADOR"}, /*SLV, 222}, */
777 {"GQ", GQ, "EQUATORIAL GUINEA"}, /*GNQ, 226}, */
778 {"ER", ER, "ERITREA"}, /*ERI, 232}, */
779 {"EE", EE, "ESTONIA"}, /*EST, 233}, */
780 {"ET", ET, "ETHIOPIA"}, /*ETH, 231}, */
781 {"FK", FK, "FALKLAND ISLANDS (MALVINAS)"}, /*FLK, 238}, */
782 {"FO", FO, "FAROE ISLANDS"}, /*FRO, 234}, */
783 {"FJ", FJ, "FIJI"}, /*FJI, 242}, */
784 {"FI", FI, "FINLAND"}, /*FIN, 246}, */
785 {"FR", FR, "FRANCE"}, /*FRA, 250}, */
786 {"GF", GF, "FRENCH GUIANA"}, /*GUF, 254}, */
787 {"PF", PF, "FRENCH POLYNESIA"}, /*PYF, 258}, */
788 {"TF", TF, "FRENCH SOUTHERN TERRITORIES"}, /*ATF, 260}, */
789 {"GA", GA, "GABON"}, /*GAB, 266}, */
790 {"GM", GM, "GAMBIA"}, /*GMB, 270}, */
791 {"GE", GE, "GEORGIA"}, /*GEO, 268}, */
792 {"DE", DE, "GERMANY"}, /*DEU, 276}, */
793 {"GH", GH, "GHANA"}, /*GHA, 288}, */
794 {"GI", GI, "GIBRALTAR"}, /*GIB, 292}, */
795 {"GR", GR, "GREECE"}, /*GRC, 300}, */
796 {"GL", GL, "GREENLAND"}, /*GRL, 304}, */
797 {"GD", GD, "GRENADA"}, /*GRD, 308}, */
798 {"GP", GP, "GUADELOUPE"}, /*GLP, 312}, */
799 {"GU", GU, "GUAM"}, /*GUM, 316}, */
800 {"GT", GT, "GUATEMALA"}, /*GTM, 320}, */
801 {"GG", GG, "GUERNSEY"}, /*GGY, 831}, */
802 {"GN", GN, "GUINEA"}, /*GIN, 324}, */
803 {"GW", GW, "GUINEA-BISSAU"}, /*GNB, 624}, */
804 {"GY", GY, "GUYANA"}, /*GUY, 328}, */
805 {"HT", HT, "HAITI"}, /*HTI, 332}, */
806 {"HM", HM, "HEARD ISLAND AND MCDONALD ISLANDS"}, /*HMD, 334}, */
807 {"VA", VA, "HOLY SEE (VATICAN CITY STATE)"}, /*VAT, 336}, */
808 {"HN", HN, "HONDURAS"}, /*HND, 340}, */
809 {"HK", HK, "HONG KONG"}, /*HKG, 344}, */
810 {"HU", HU, "HUNGARY"}, /*HUN, 348}, */
811 {"IS", IS, "ICELAND"}, /*ISL, 352}, */
812 {"IN", IN, "INDIA"}, /*IND, 356}, */
813 {"ID", ID, "INDONESIA"}, /*IDN, 360}, */
814 {"IR", IR, "IRAN, ISLAMIC REPUBLIC OF"}, /*IRN, 364}, */
815 {"IQ", IQ, "IRAQ"}, /*IRQ, 368}, */
816 {"IE", IE, "IRELAND"}, /*IRL, 372}, */
817 {"IM", IM, "ISLE OF MAN"}, /*IMN, 833}, */
818 {"IL", IL, "ISRAEL"}, /*ISR, 376}, */
819 {"IT", IT, "ITALY"}, /*ITA, 380}, */
820 {"JM", JM, "JAMAICA"}, /*JAM, 388}, */
821 {"JP", JP, "JAPAN"}, /*JPN, 392}, */
822 {"JE", JE, "JERSEY"}, /*JEY, 832}, */
823 {"JO", JO, "JORDAN"}, /*JOR, 400}, */
824 {"KZ", KZ, "KAZAKHSTAN"}, /*KAZ, 398}, */
825 {"KE", KE, "KENYA"}, /*KEN, 404}, */
826 {"KI", KI, "KIRIBATI"}, /*KIR, 296}, */
827 {"KP", KP, "KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF"}, /*PRK, 408}, */
828 {"KR", KR, "KOREA, REPUBLIC OF"}, /*KOR, 410}, */
829 {"KW", KW, "KUWAIT"}, /*KWT, 414}, */
830 {"KG", KG, "KYRGYZSTAN"}, /*KGZ, 417}, */
831 {"LA", LA, "LAO PEOPLE'S DEMOCRATIC REPUBLIC"}, /*LAO, 418}, */
832 {"LV", LV, "LATVIA"}, /*LVA, 428}, */
833 {"LB", LB, "LEBANON"}, /*LBN, 422}, */
834 {"LS", LS, "LESOTHO"}, /*LSO, 426}, */
835 {"LR", LR, "LIBERIA"}, /*LBR, 430}, */
836 {"LY", LY, "LIBYAN ARAB JAMAHIRIYA"}, /*LBY, 434}, */
837 {"LI", LI, "LIECHTENSTEIN"}, /*LIE, 438}, */
838 {"LT", LT, "LITHUANIA"}, /*LTU, 440}, */
839 {"LU", LU, "LUXEMBOURG"}, /*LUX, 442}, */
840 {"MO", MO, "MACAO"}, /*MAC, 446}, */
841 {"MK", MK, "MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF"}, /*MKD, 807}, */
842 {"MG", MG, "MADAGASCAR"}, /*MDG, 450}, */
843 {"MW", MW, "MALAWI"}, /*MWI, 454}, */
844 {"MY", MY, "MALAYSIA"}, /*MYS, 458}, */
845 {"MV", MV, "MALDIVES"}, /*MDV, 462}, */
846 {"ML", ML, "MALI"}, /*MLI, 466}, */
847 {"MT", MT, "MALTA"}, /*MLT, 470}, */
848 {"MH", MH, "MARSHALL ISLANDS"}, /*MHL, 584}, */
849 {"MQ", MQ, "MARTINIQUE"}, /*MTQ, 474}, */
850 {"MR", MR, "MAURITANIA"}, /*MRT, 478}, */
851 {"MU", MU, "MAURITIUS"}, /*MUS, 480}, */
852 {"YT", YT, "MAYOTTE"}, /*MYT, 175}, */
853 {"MX", MX, "MEXICO"}, /*MEX, 484}, */
854 {"FM", FM, "MICRONESIA, FEDERATED STATES OF"}, /*FSM, 583}, */
855 {"MD", MD, "MOLDOVA"}, /*MDA, 498}, */
856 {"MC", MC, "MONACO"}, /*MCO, 492}, */
857 {"MN", MN, "MONGOLIA"}, /*MNG, 496}, */
858 {"ME", ME, "MONTENEGRO"}, /*MNE, 499}, */
859 {"MS", MS, "MONTSERRAT"}, /*MSR, 500}, */
860 {"MA", MA, "MOROCCO"}, /*MAR, 504}, */
861 {"MZ", MZ, "MOZAMBIQUE"}, /*MOZ, 508}, */
862 {"MM", MM, "MYANMAR"}, /*MMR, 104}, */
863 {"NA", NA, "NAMIBIA"}, /*NAM, 516}, */
864 {"NR", NR, "NAURU"}, /*NRU, 520}, */
865 {"NP", NP, "NEPAL"}, /*NPL, 524}, */
866 {"NL", NL, "NETHERLANDS"}, /*NLD, 528}, */
867 {"NC", NC, "NEW CALEDONIA"}, /*NCL, 540}, */
868 {"NZ", NZ, "NEW ZEALAND"}, /*NZL, 554}, */
869 {"NI", NI, "NICARAGUA"}, /*NIC, 558}, */
870 {"NE", NE, "NIGER"}, /*NER, 562}, */
871 {"NG", NG, "NIGERIA"}, /*NGA, 566}, */
872 {"NU", NU, "NIUE"}, /*NIU, 570}, */
873 {"NF", NF, "NORFOLK ISLAND"}, /*NFK, 574}, */
874 {"MP", MP, "NORTHERN MARIANA ISLANDS"}, /*MNP, 580}, */
875 {"NO", NO, "NORWAY"}, /*NOR, 578}, */
876 {"OM", OM, "OMAN"}, /*OMN, 512}, */
877 {"PK", PK, "PAKISTAN"}, /*PAK, 586}, */
878 {"PW", PW, "PALAU"}, /*PLW, 585}, */
879 {"PS", PS, "PALESTINIAN TERRITORY, OCCUPIED"}, /*PSE, 275}, */
880 {"PA", PA, "PANAMA"}, /*PAN, 591}, */
881 {"PG", PG, "PAPUA NEW GUINEA"}, /*PNG, 598}, */
882 {"PY", PY, "PARAGUAY"}, /*PRY, 600}, */
883 {"PE", PE, "PERU"}, /*PER, 604}, */
884 {"PH", PH, "PHILIPPINES"}, /*PHL, 608}, */
885 {"PN", PN, "PITCAIRN"}, /*PCN, 612}, */
886 {"PL", PL, "POLAND"}, /*POL, 616}, */
887 {"PT", PT, "PORTUGAL"}, /*PRT, 620}, */
888 {"PR", PR, "PUERTO RICO"}, /*PRI, 630}, */
889 {"QA", QA, "QATA"}, /*QAT, 634}, */
890 {"RE", RE, "RÉUNION"}, /*REU, 638}, */
891 {"RO", RO, "ROMANIA"}, /*ROU, 642}, */
892 {"RU", RU, "RUSSIAN FEDERATION"}, /*RUS, 643}, */
893 {"RW", RW, "RWANDA"}, /*RWA, 646}, */
894 {"BL", BL, "SAINT BARTHÉLEMY"}, /*BLM, 652}, */
895 {"SH", SH, "SAINT HELENA"}, /*SHN, 654}, */
896 {"KN", KN, "SAINT KITTS AND NEVIS"}, /*KNA, 659}, */
897 {"LC", LC, "SAINT LUCIA"}, /*LCA, 662}, */
898 {"MF", MF, "SAINT MARTIN"}, /*MAF, 663}, */
899 {"PM", PM, "SAINT PIERRE AND MIQUELON"}, /*SPM, 666}, */
900 {"VC", VC, "SAINT VINCENT AND THE GRENADINES"}, /*VCT, 670}, */
901 {"WS", WS, "SAMOA"}, /*WSM, 882}, */
902 {"SM", SM, "SAN MARINO"}, /*SMR, 674}, */
903 {"ST", ST, "SAO TOME AND PRINCIPE"}, /*STP, 678}, */
904 {"SA", SA, "SAUDI ARABIA"}, /*SAU, 682}, */
905 {"SN", SN, "SENEGAL"}, /*SEN, 686}, */
906 {"RS", RS, "SERBIA"}, /*SRB, 688}, */
907 {"SC", SC, "SEYCHELLES"}, /*SYC, 690}, */
908 {"SL", SL, "SIERRA LEONE"}, /*SLE, 694}, */
909 {"SX", SX, "SINT MAARTEN"}, /*SXM, 534}, */
910 {"SG", SG, "SINGAPORE"}, /*SGP, 702}, */
911 {"SK", SK, "SLOVAKIA"}, /*SVK, 703}, */
912 {"SI", SI, "SLOVENIA"}, /*SVN, 705}, */
913 {"SB", SB, "SOLOMON ISLANDS"}, /*SLB, 90 }, */
914 {"SO", SO, "SOMALIA"}, /*SOM, 706}, */
915 {"ZA", ZA, "SOUTH AFRICA"}, /*ZAF, 710}, */
916 {"GS", GS, "SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS"}, /*SGS, 239}, */
917 {"ES", ES, "SPAIN"}, /*ESP, 724}, */
918 {"LK", LK, "SRI LANKA"}, /*LKA, 144}, */
919 {"SD", SD, "SUDAN"}, /*SDN, 736}, */
920 {"SR", SR, "SURINAME"}, /*SUR, 740}, */
921 {"SJ", SJ, "SVALBARD AND JAN MAYEN"}, /*SJM, 744}, */
922 {"SZ", SZ, "SWAZILAND"}, /*SWZ, 748}, */
923 {"SE", SE, "SWEDEN"}, /*SWE, 752}, */
924 {"CH", CH, "SWITZERLAND"}, /*CHE, 756}, */
925 {"SY", SY, "SYRIAN ARAB REPUBLIC"}, /*SYR, 760}, */
926 {"TW", TW, "TAIWAN"}, /*TWN, 158}, */
927 {"TJ", TJ, "TAJIKISTAN"}, /*TJK, 762}, */
928 {"TZ", TZ, "TANZANIA, UNITED REPUBLIC OF"}, /*TZA, 834}, */
929 {"TH", TH, "THAILAND"}, /*THA, 764}, */
930 {"TL", TL, "TIMOR-LESTE"}, /*TLS, 626}, */
931 {"TG", TG, "TOGO"}, /*TGO, 768}, */
932 {"TK", TK, "TOKELAU"}, /*TKL, 772}, */
933 {"TO", TO, "TONGA"}, /*TON, 776}, */
934 {"TT", TT, "TRINIDAD AND TOBAGO"}, /*TTO, 780}, */
935 {"TN", TN, "TUNISIA"}, /*TUN, 788}, */
936 {"TR", TR, "TURKEY"}, /*TUR, 792}, */
937 {"TM", TM, "TURKMENISTAN"}, /*TKM, 795}, */
938 {"TC", TC, "TURKS AND CAICOS ISLANDS"}, /*TCA, 796}, */
939 {"TV", TV, "TUVALU"}, /*TUV, 798}, */
940 {"UG", UG, "UGANDA"}, /*UGA, 800}, */
941 {"UA", UA, "UKRAINE"}, /*UKR, 804}, */
942 {"AE", AE, "UNITED ARAB EMIRATES"}, /*ARE, 784}, */
943 {"GB", GB, "UNITED KINGDOM"}, /*GBR, 826}, */
944 {"US", US, "UNITED STATES"}, /*USA, 840}, */
945 {"UM", UM, "UNITED STATES MINOR OUTLYING ISLANDS"}, /*UMI, 581}, */
946 {"UY", UY, "URUGUAY"}, /*URY, 858}, */
947 {"UZ", UZ, "UZBEKISTAN"}, /*UZB, 860}, */
948 {"VU", VU, "VANUATU"}, /*VUT, 548}, */
949 {"VE", VE, "VENEZUELA"}, /*VEN, 862}, */
950 {"VN", VN, "VIET NAM"}, /*VNM, 704}, */
951 {"VG", VG, "VIRGIN ISLANDS, BRITISH"}, /*VGB, 92 }, */
952 {"VI", VI, "VIRGIN ISLANDS, U.S."}, /*VIR, 850}, */
953 {"WF", WF, "WALLIS AND FUTUNA"}, /*WLF, 876}, */
954 {"EH", EH, "WESTERN SAHARA"}, /*ESH, 732}, */
955 {"YE", YE, "YEMEN"}, /*YEM, 887}, */
956 {"ZM", ZM, "ZAMBIA"}, /*ZMB, 894}, */
957 {"ZW", ZW, "ZIMBABWE"} /*ZWE, 716}, */
958 };
959
960 /* convert ISO 3166-1 two-letter constant
961 * to index number
962 */
txt_to_country(const char * id)963 int txt_to_country(const char *id)
964 {
965 unsigned int i;
966 for (i = 0; i < COUNTRY_COUNT(country_list); i++)
967 if (!strcasecmp(id, country_list[i].short_name))
968 return country_list[i].id;
969 return DE; // w_scan2 defaults to DVB-t de_DE
970 }
971
972 /* convert index number
973 * to ISO 3166-1 two-letter constant
974 */
country_to_short_name(int idx)975 const char *country_to_short_name(int idx)
976 {
977 unsigned int i;
978 for (i = 0; i < COUNTRY_COUNT(country_list); i++)
979 if (idx == country_list[i].id)
980 return country_list[i].short_name;
981 return "DE"; // w_scan2 defaults to DVB-t de_DE
982 }
983
984 /* convert index number
985 * to country name
986 */
country_to_full_name(int idx)987 const char *country_to_full_name(int idx)
988 {
989 unsigned int i;
990 for (i = 0; i < COUNTRY_COUNT(country_list); i++)
991 if (idx == country_list[i].id)
992 return country_list[i].full_name;
993 warning("COUNTRY CODE NOT DEFINED. PLEASE RE-CHECK WETHER YOU TYPED CORRECTLY.\n");
994 usleep(5000000);
995 return "GERMANY"; // w_scan2 defaults to DVB-t de_DE
996 }
997
print_countries(void)998 void print_countries(void)
999 {
1000 unsigned int i;
1001 for (i = 0; i < COUNTRY_COUNT(country_list); i++)
1002 info("\t%s\t\t%s\n", country_list[i].short_name,
1003 country_list[i].full_name);
1004 }
1005
country_count()1006 int country_count()
1007 {
1008 return COUNTRY_COUNT(country_list);
1009 }
1010
1011 #define MIN(X,Y) (X < Y ? X : Y)
1012
get_user_country(void)1013 int get_user_country(void)
1014 {
1015 const int cats[] = { LC_CTYPE, LC_COLLATE, LC_MESSAGES };
1016 char *buf, *pch, *pbuf;
1017 unsigned cat, idx = 0xffff;
1018
1019 for (cat = 0; cat < sizeof(cats) / sizeof(cats[0]); cat++) {
1020
1021 // Note: program's locale is not changed here, since locale isn't given.
1022 // the returned char * should be "C", "POSIX" or something valid.
1023 // If valid, we can only *guess* which format is returned.
1024 // Assume here something like "de_DE.iso8859-1@euro" or "de_DE.utf-8"
1025 if (!(buf = setlocale(cats[cat], "")) || strlen(buf) < 2)
1026 continue;
1027
1028 buf = strdup(buf);
1029 pbuf = buf;
1030
1031 if (!strncmp(buf, "POSIX", MIN(strlen(buf), 5)) ||
1032 !(strncmp(buf, "en", MIN(strlen(buf), 2))
1033 && !isalpha(buf[2])))
1034 continue;
1035
1036 // assuming 'language_country.encoding@variant'
1037
1038 // country after '_', if given
1039 if ((pch = strchr(buf, '_')))
1040 pbuf = pch + 1;
1041
1042 // remove all after '@', including '@'
1043 if ((pch = strchr(pbuf, '@')))
1044 *pch = 0;
1045
1046 // remove all after '.', including '.'
1047 if ((pch = strchr(pbuf, '.')))
1048 *pch = 0;
1049
1050 if (strlen(pbuf) == 2) {
1051 unsigned int i;
1052 verbose("%s: lang id = %s\n", __FUNCTION__, pbuf);
1053 for (i = 0; i < COUNTRY_COUNT(country_list); i++)
1054 if (!strcasecmp
1055 (pbuf, country_list[i].short_name)) {
1056 idx = country_list[i].id;
1057 break;
1058 }
1059 }
1060 free(buf);
1061 if (idx != 0xffff)
1062 return idx;
1063 }
1064
1065 warning("could not guess your country. Falling back to 'DE'\n");
1066 return DE;
1067 }
1068
plp_id_loop_min(int country_id)1069 int plp_id_loop_min (int country_id)
1070 {
1071 switch (country_id) {
1072 case AT: // AUSTRIA
1073 return 0; // may be changed to 1, because it seems that only PLP 1 is used in Austria
1074 default:
1075 return 0;
1076 }
1077 }
1078
plp_id_loop_max(int country_id)1079 int plp_id_loop_max (int country_id)
1080 {
1081 switch (country_id) {
1082 case AT: // AUSTRIA
1083 return 1;
1084 default:
1085 return 0;
1086 }
1087 }
1088
1089 #ifdef VDRVERSNUM
1090 } // end namespace COUNTRY
1091 #endif
1092