diff options
| author | etobi <git@e-tobi.net> | 2013-09-03 09:48:40 +0200 | 
|---|---|---|
| committer | etobi <git@e-tobi.net> | 2013-09-03 09:48:40 +0200 | 
| commit | 6b350466c4902c5b137e0efaf1d189128a7f18f5 (patch) | |
| tree | a7cf91f9896c0f8c9d8b291114e51f1373940c70 /util | |
| parent | 6e40287e2f39a80fc72bd8d0fbc1a8334d688c2d (diff) | |
| download | linux-dvb-apps-6b350466c4902c5b137e0efaf1d189128a7f18f5.tar.gz | |
Imported Upstream version 1.1.1upstream/1.1.1
Diffstat (limited to '')
28 files changed, 2109 insertions, 66 deletions
| diff --git a/util/dvbnet/dvbnet.c b/util/dvbnet/dvbnet.c index 573fa59..a58f156 100644 --- a/util/dvbnet/dvbnet.c +++ b/util/dvbnet/dvbnet.c @@ -38,7 +38,7 @@  #include <version.h>  #ifndef VERSION_INFO -#define VERSION_INFO "1.1.0" +#define VERSION_INFO "1.1.1"  #endif  #define OK    0 diff --git a/util/scan/Makefile b/util/scan/Makefile index a82d865..4b29842 100644 --- a/util/scan/Makefile +++ b/util/scan/Makefile @@ -1,9 +1,9 @@  CC = gcc -CFLAGS = -MD -g -Wall -O2 -I../../include -I../lib +CFLAGS = -MD -g -Wall -O2 -I../../include  LFLAGS = -g -Wall -OBJS = diseqc.o dump-zap.o dump-vdr.o scan.o ../lib/lnb.o +OBJS = diseqc.o dump-zap.o dump-vdr.o scan.o lnb.o section.o atsc_psip_section.o  SRCS = $(OBJS:.o=.c)  TARGET = scan diff --git a/util/scan/atsc/us-ATSC-center-frequencies-8VSB b/util/scan/atsc/us-ATSC-center-frequencies-8VSB new file mode 100644 index 0000000..ffd0b02 --- /dev/null +++ b/util/scan/atsc/us-ATSC-center-frequencies-8VSB @@ -0,0 +1,71 @@ +# US ATSC center frequencies, use if in doubt + +A  57028615 8VSB +A  63028615 8VSB +A  69028615 8VSB +A  79028615 8VSB +A  85028615 8VSB +A 177028615 8VSB +A 183028615 8VSB +A 189028615 8VSB +A 195028615 8VSB +A 201028615 8VSB +A 207028615 8VSB +A 213028615 8VSB +A 473028615 8VSB +A 479028615 8VSB +A 485028615 8VSB +A 491028615 8VSB +A 497028615 8VSB +A 503028615 8VSB +A 509028615 8VSB +A 515028615 8VSB +A 521028615 8VSB +A 527028615 8VSB +A 533028615 8VSB +A 539028615 8VSB +A 545028615 8VSB +A 551028615 8VSB +A 557028615 8VSB +A 563028615 8VSB +A 569028615 8VSB +A 575028615 8VSB +A 581028615 8VSB +A 587028615 8VSB +A 593028615 8VSB +A 599028615 8VSB +A 605028615 8VSB +A 611028615 8VSB +A 617028615 8VSB +A 623028615 8VSB +A 629028615 8VSB +A 635028615 8VSB +A 641028615 8VSB +A 647028615 8VSB +A 653028615 8VSB +A 659028615 8VSB +A 665028615 8VSB +A 671028615 8VSB +A 677028615 8VSB +A 683028615 8VSB +A 689028615 8VSB +A 695028615 8VSB +A 701028615 8VSB +A 707028615 8VSB +A 713028615 8VSB +A 719028615 8VSB +A 725028615 8VSB +A 731028615 8VSB +A 737028615 8VSB +A 743028615 8VSB +A 749028615 8VSB +A 755028615 8VSB +A 761028615 8VSB +A 767028615 8VSB +A 773028615 8VSB +A 779028615 8VSB +A 785028615 8VSB +A 791028615 8VSB +A 797028615 8VSB +A 803028615 8VSB + diff --git a/util/scan/atsc/us-CA-SF-Bay-Area b/util/scan/atsc/us-CA-SF-Bay-Area new file mode 100644 index 0000000..8cca4e0 --- /dev/null +++ b/util/scan/atsc/us-CA-SF-Bay-Area @@ -0,0 +1,16 @@ +# initial tuning data for some frequencies of for the San Francisco Bay Area +# includes San Francisco, San Jose, Oakland... + +A 503000000 8VSB +A 551000000 8VSB +A 563000000 8VSB +A 593000000 8VSB +A 623000000 8VSB +A 635000000 8VSB +A 647000000 8VSB +A 659000000 8VSB +A 683000000 8VSB +A 689000000 8VSB +A 701000000 8VSB +A 725000000 8VSB +A 731000000 8VSB diff --git a/util/scan/atsc/us-Cable-EIA-542-HRC-center-frequencies-QAM256 b/util/scan/atsc/us-Cable-EIA-542-HRC-center-frequencies-QAM256 new file mode 100644 index 0000000..c0afed9 --- /dev/null +++ b/util/scan/atsc/us-Cable-EIA-542-HRC-center-frequencies-QAM256 @@ -0,0 +1,142 @@ +# US EIA-542 Cable center frequencies +# Harmonically Related Carriers (HRC) +# Channels 1 to 125 are in ascending EIA/NCTA channel designation order + +#1 +A  73753600 QAM256 +A  55752700 QAM256 +A  61753000 QAM256 +A  67753300 QAM256 +A  77753900 QAM256 +A  83754200 QAM256 +A 175758700 QAM256 +A 181759000 QAM256 +A 187759300 QAM256 +#10 +A 193759600 QAM256 +A 199759900 QAM256 +A 205760200 QAM256 +A 211760500 QAM256 +A 121756000 QAM256 +A 127756300 QAM256 +A 133756600 QAM256 +A 139756900 QAM256 +A 145757200 QAM256 +A 151757500 QAM256 +#20 +A 157757800 QAM256 +A 163758100 QAM256 +A 169758400 QAM256 +A 217760800 QAM256 +A 223761100 QAM256 +A 229761400 QAM256 +A 235761700 QAM256 +A 241762000 QAM256 +A 247762300 QAM256 +A 253762600 QAM256 +#30 +A 259762900 QAM256 +A 265763200 QAM256 +A 271763500 QAM256 +A 277763800 QAM256 +A 283764100 QAM256 +A 289764400 QAM256 +A 295764700 QAM256 +A 301765000 QAM256 +A 307765300 QAM256 +A 313765600 QAM256 +#40 +A 319765900 QAM256 +A 325766200 QAM256 +A 331766500 QAM256 +A 337766800 QAM256 +A 343767100 QAM256 +A 349767400 QAM256 +A 355767700 QAM256 +A 361768000 QAM256 +A 367768300 QAM256 +A 373768600 QAM256 +#50 +A 379768900 QAM256 +A 385769200 QAM256 +A 391769500 QAM256 +A 397769800 QAM256 +A 403770100 QAM256 +A 409770400 QAM256 +A 415770700 QAM256 +A 421771000 QAM256 +A 427771300 QAM256 +A 433771600 QAM256 +#60 +A 439771900 QAM256 +A 445772200 QAM256 +A 451772500 QAM256 +A 457772800 QAM256 +A 463773100 QAM256 +A 469773400 QAM256 +A 475773700 QAM256 +A 481774000 QAM256 +A 487774300 QAM256 +A 493774600 QAM256 +#70 +A 499774900 QAM256 +A 505775200 QAM256 +A 511775500 QAM256 +A 517775800 QAM256 +A 523776100 QAM256 +A 529776400 QAM256 +A 535776700 QAM256 +A 541777000 QAM256 +A 547777300 QAM256 +A 553777600 QAM256 +#80 +A 559777900 QAM256 +A 565778200 QAM256 +A 571778500 QAM256 +A 577778800 QAM256 +A 583779100 QAM256 +A 589779400 QAM256 +A 595779700 QAM256 +A 601780000 QAM256 +A 607780300 QAM256 +A 613780600 QAM256 +#90 +A 619780900 QAM256 +A 625781200 QAM256 +A 631781500 QAM256 +A 637781800 QAM256 +A 643782100 QAM256 +A  91754500 QAM256 +A  97754800 QAM256 +A 103755100 QAM256 +A 109775000 QAM256 +A 115775000 QAM256 +#100 +A 649782400 QAM256 +A 655782700 QAM256 +A 661783000 QAM256 +A 667783300 QAM256 +A 673783600 QAM256 +A 679783900 QAM256 +A 685784200 QAM256 +A 691784500 QAM256 +A 697784800 QAM256 +A 703785100 QAM256 +#110 +A 709785400 QAM256 +A 715785700 QAM256 +A 721786000 QAM256 +A 727786300 QAM256 +A 733786600 QAM256 +A 739786900 QAM256 +A 745787200 QAM256 +A 751787500 QAM256 +A 757787800 QAM256 +A 763788100 QAM256 +#120 +A 769788400 QAM256 +A 775788700 QAM256 +A 781789000 QAM256 +A 787789300 QAM256 +A 793789600 QAM256 +A 799789900 QAM256 diff --git a/util/scan/atsc/us-Cable-EIA-542-IRC-center_frequencies-QAM256 b/util/scan/atsc/us-Cable-EIA-542-IRC-center_frequencies-QAM256 new file mode 100644 index 0000000..f18d5e5 --- /dev/null +++ b/util/scan/atsc/us-Cable-EIA-542-IRC-center_frequencies-QAM256 @@ -0,0 +1,142 @@ +# US Cable EIA-542 center frequencies +# Incrementally Related Carriers (IRC) +# Channels 1-125 are in ascending EIA/NCTA channel designation order + +#1 +A  75012500 QAM256 +A  57025000 QAM256 +A  63012500 QAM256 +A  69012500 QAM256 +A  79012500 QAM256 +A  85012500 QAM256 +A 177012500 QAM256 +A 183012500 QAM256 +A 189012500 QAM256 +#10 +A 195012500 QAM256 +A 201012500 QAM256 +A 207012500 QAM256 +A 213012500 QAM256 +A 123012500 QAM256 +A 129012500 QAM256 +A 135012500 QAM256 +A 141012500 QAM256 +A 147012500 QAM256 +A 153012500 QAM256 +#20 +A 159012500 QAM256 +A 165012500 QAM256 +A 171012500 QAM256 +A 219012500 QAM256 +A 225012500 QAM256 +A 231012500 QAM256 +A 237012500 QAM256 +A 243012500 QAM256 +A 249012500 QAM256 +A 255012500 QAM256 +#30 +A 261012500 QAM256 +A 267012500 QAM256 +A 273012500 QAM256 +A 279012500 QAM256 +A 285012500 QAM256 +A 291012500 QAM256 +A 297012500 QAM256 +A 303012500 QAM256 +A 309012500 QAM256 +A 315012500 QAM256 +#40 +A 321012500 QAM256 +A 327012500 QAM256 +A 333025000 QAM256 +A 339012500 QAM256 +A 345012500 QAM256 +A 351012500 QAM256 +A 357012500 QAM256 +A 363012500 QAM256 +A 369012500 QAM256 +A 375012500 QAM256 +#50 +A 381012500 QAM256 +A 387012500 QAM256 +A 393012500 QAM256 +A 399012500 QAM256 +A 405012500 QAM256 +A 411012500 QAM256 +A 417012500 QAM256 +A 423012500 QAM256 +A 429012500 QAM256 +A 435012500 QAM256 +#60 +A 441012500 QAM256 +A 447012500 QAM256 +A 453012500 QAM256 +A 459012500 QAM256 +A 465012500 QAM256 +A 471012500 QAM256 +A 477012500 QAM256 +A 483012500 QAM256 +A 489012500 QAM256 +A 495012500 QAM256 +#70 +A 501012500 QAM256 +A 507012500 QAM256 +A 513012500 QAM256 +A 519012500 QAM256 +A 525012500 QAM256 +A 531012500 QAM256 +A 537012500 QAM256 +A 543012500 QAM256 +A 549012500 QAM256 +A 555012500 QAM256 +#80 +A 561012500 QAM256 +A 567012500 QAM256 +A 573012500 QAM256 +A 579012500 QAM256 +A 585012500 QAM256 +A 591012500 QAM256 +A 597012500 QAM256 +A 603012500 QAM256 +A 609012500 QAM256 +A 615012500 QAM256 +#90 +A 621012500 QAM256 +A 627012500 QAM256 +A 633012500 QAM256 +A 639012500 QAM256 +A 645012500 QAM256 +A  93012500 QAM256 +A  99012500 QAM256 +A 105012500 QAM256 +A 111012500 QAM256 +A 117012500 QAM256 +#100 +A 651012500 QAM256 +A 657012500 QAM256 +A 663012500 QAM256 +A 669012500 QAM256 +A 675012500 QAM256 +A 681012500 QAM256 +A 687012500 QAM256 +A 693012500 QAM256 +A 699012500 QAM256 +A 705012500 QAM256 +#110 +A 711012500 QAM256 +A 717012500 QAM256 +A 723012500 QAM256 +A 729012500 QAM256 +A 735012500 QAM256 +A 741012500 QAM256 +A 747012500 QAM256 +A 753012500 QAM256 +A 759012500 QAM256 +A 765012500 QAM256 +#120 +A 771012500 QAM256 +A 777012500 QAM256 +A 783012500 QAM256 +A 789012500 QAM256 +A 795012500 QAM256 +A 801012500 QAM256 diff --git a/util/scan/atsc/us-Cable-HRC-center-frequencies-QAM256 b/util/scan/atsc/us-Cable-HRC-center-frequencies-QAM256 new file mode 100644 index 0000000..2bc3838 --- /dev/null +++ b/util/scan/atsc/us-Cable-HRC-center-frequencies-QAM256 @@ -0,0 +1,142 @@ +# US Cable center frequencies +# Harmonically Related Carriers (HRC) +# Channels are in ascending EIA/NCTA channel designation order + +#1 +A  73753600 QAM256 +A  55752700 QAM256 +A  61753000 QAM256 +A  67753300 QAM256 +A  77753900 QAM256 +A  83754200 QAM256 +A 175758700 QAM256 +A 181759000 QAM256 +A 187759300 QAM256 +#10 +A 193759600 QAM256 +A 199759900 QAM256 +A 205760200 QAM256 +A 211760500 QAM256 +A 121756000 QAM256 +A 127756300 QAM256 +A 133756600 QAM256 +A 139756900 QAM256 +A 145757200 QAM256 +A 151757500 QAM256 +#20 +A 157757800 QAM256 +A 163758100 QAM256 +A 169758400 QAM256 +A 217760800 QAM256 +A 223761100 QAM256 +A 229761400 QAM256 +A 235761700 QAM256 +A 241762000 QAM256 +A 247762300 QAM256 +A 253762600 QAM256 +#30 +A 259762900 QAM256 +A 265763200 QAM256 +A 271763500 QAM256 +A 277763800 QAM256 +A 283764100 QAM256 +A 289764400 QAM256 +A 295764700 QAM256 +A 301765000 QAM256 +A 307765300 QAM256 +A 313765600 QAM256 +#40 +A 319765900 QAM256 +A 325766200 QAM256 +A 331766500 QAM256 +A 337766800 QAM256 +A 343767100 QAM256 +A 349767400 QAM256 +A 355767700 QAM256 +A 361768000 QAM256 +A 367768300 QAM256 +A 373768600 QAM256 +#50 +A 379768900 QAM256 +A 385769200 QAM256 +A 391769500 QAM256 +A 397769800 QAM256 +A 403770100 QAM256 +A 409770400 QAM256 +A 415770700 QAM256 +A 421771000 QAM256 +A 427771300 QAM256 +A 433771600 QAM256 +#60 +A 439771900 QAM256 +A 445772200 QAM256 +A 451772500 QAM256 +A 457772800 QAM256 +A 463773100 QAM256 +A 469773400 QAM256 +A 475773700 QAM256 +A 481774000 QAM256 +A 487774300 QAM256 +A 493774600 QAM256 +#70 +A 499774900 QAM256 +A 505775200 QAM256 +A 511775500 QAM256 +A 517775800 QAM256 +A 523776100 QAM256 +A 529776400 QAM256 +A 535776700 QAM256 +A 541777000 QAM256 +A 547777300 QAM256 +A 553777600 QAM256 +#80 +A 559777900 QAM256 +A 565778200 QAM256 +A 571778500 QAM256 +A 577778800 QAM256 +A 583779100 QAM256 +A 589779400 QAM256 +A 595779700 QAM256 +A 601780000 QAM256 +A 607780300 QAM256 +A 613780600 QAM256 +#90 +A 619780900 QAM256 +A 625781200 QAM256 +A 631781500 QAM256 +A 637781800 QAM256 +A 643782100 QAM256 +A  91754500 QAM256 +A  97754800 QAM256 +A 103755100 QAM256 +A 109755400 QAM256 +A 115755700 QAM256 +#100 +A 649782400 QAM256 +A 655782700 QAM256 +A 661783000 QAM256 +A 667783300 QAM256 +A 673783600 QAM256 +A 679783900 QAM256 +A 685784200 QAM256 +A 691784500 QAM256 +A 697784800 QAM256 +A 703785100 QAM256 +#110 +A 709785400 QAM256 +A 715785700 QAM256 +A 721786000 QAM256 +A 727786300 QAM256 +A 733786600 QAM256 +A 739786900 QAM256 +A 745787200 QAM256 +A 751787500 QAM256 +A 757787800 QAM256 +A 763788100 QAM256 +#120 +A 769788400 QAM256 +A 775788700 QAM256 +A 781789000 QAM256 +A 787789300 QAM256 +A 793789600 QAM256 +A 799789900 QAM256 diff --git a/util/scan/atsc/us-Cable-IRC-center-frequencies-QAM256 b/util/scan/atsc/us-Cable-IRC-center-frequencies-QAM256 new file mode 100644 index 0000000..72842e0 --- /dev/null +++ b/util/scan/atsc/us-Cable-IRC-center-frequencies-QAM256 @@ -0,0 +1,142 @@ +# US Cable center frequencies +# Incrementally Related Carriers (IRC) +# Channels are in ascending EIA/NCTA channel designation order + +#1 +A  75000000 QAM256 +A  57000000 QAM256 +A  63000000 QAM256 +A  69000000 QAM256 +A  79000000 QAM256 +A  85000000 QAM256 +A 177000000 QAM256 +A 183000000 QAM256 +A 189000000 QAM256 +#10 +A 195000000 QAM256 +A 201000000 QAM256 +A 207000000 QAM256 +A 213000000 QAM256 +A 123000000 QAM256 +A 129000000 QAM256 +A 135000000 QAM256 +A 141000000 QAM256 +A 147000000 QAM256 +A 153000000 QAM256 +#20 +A 159000000 QAM256 +A 165000000 QAM256 +A 171000000 QAM256 +A 219000000 QAM256 +A 225000000 QAM256 +A 231000000 QAM256 +A 237000000 QAM256 +A 243000000 QAM256 +A 249000000 QAM256 +A 255000000 QAM256 +#30 +A 261000000 QAM256 +A 267000000 QAM256 +A 273000000 QAM256 +A 279000000 QAM256 +A 285000000 QAM256 +A 291000000 QAM256 +A 297000000 QAM256 +A 303000000 QAM256 +A 309000000 QAM256 +A 315000000 QAM256 +#40 +A 321000000 QAM256 +A 327000000 QAM256 +A 333000000 QAM256 +A 339000000 QAM256 +A 345000000 QAM256 +A 351000000 QAM256 +A 357000000 QAM256 +A 363000000 QAM256 +A 369000000 QAM256 +A 375000000 QAM256 +#50 +A 381000000 QAM256 +A 387000000 QAM256 +A 393000000 QAM256 +A 399000000 QAM256 +A 405000000 QAM256 +A 411000000 QAM256 +A 417000000 QAM256 +A 423000000 QAM256 +A 429000000 QAM256 +A 435000000 QAM256 +#60 +A 441000000 QAM256 +A 447000000 QAM256 +A 453000000 QAM256 +A 459000000 QAM256 +A 465000000 QAM256 +A 471000000 QAM256 +A 477000000 QAM256 +A 483000000 QAM256 +A 489000000 QAM256 +A 495000000 QAM256 +#70 +A 501000000 QAM256 +A 507000000 QAM256 +A 513000000 QAM256 +A 519000000 QAM256 +A 525000000 QAM256 +A 531000000 QAM256 +A 537000000 QAM256 +A 543000000 QAM256 +A 549000000 QAM256 +A 555000000 QAM256 +#80 +A 561000000 QAM256 +A 567000000 QAM256 +A 573000000 QAM256 +A 579000000 QAM256 +A 585000000 QAM256 +A 591000000 QAM256 +A 597000000 QAM256 +A 603000000 QAM256 +A 609000000 QAM256 +A 615000000 QAM256 +#90 +A 621000000 QAM256 +A 627000000 QAM256 +A 633000000 QAM256 +A 639000000 QAM256 +A 645000000 QAM256 +A  93000000 QAM256 +A  99000000 QAM256 +A 105000000 QAM256 +A 111000000 QAM256 +A 117000000 QAM256 +#100 +A 651000000 QAM256 +A 657000000 QAM256 +A 663000000 QAM256 +A 669000000 QAM256 +A 675000000 QAM256 +A 681000000 QAM256 +A 687000000 QAM256 +A 693000000 QAM256 +A 699000000 QAM256 +A 705000000 QAM256 +#110 +A 711000000 QAM256 +A 717000000 QAM256 +A 723000000 QAM256 +A 729000000 QAM256 +A 735000000 QAM256 +A 741000000 QAM256 +A 747000000 QAM256 +A 753000000 QAM256 +A 759000000 QAM256 +A 765000000 QAM256 +#120 +A 771000000 QAM256 +A 777000000 QAM256 +A 783000000 QAM256 +A 789000000 QAM256 +A 795000000 QAM256 +A 801000000 QAM256 diff --git a/util/scan/atsc/us-Cable-Standard-center-frequencies-QAM256 b/util/scan/atsc/us-Cable-Standard-center-frequencies-QAM256 new file mode 100644 index 0000000..4367e7a --- /dev/null +++ b/util/scan/atsc/us-Cable-Standard-center-frequencies-QAM256 @@ -0,0 +1,140 @@ +# US EIA/NCTA Standard Cable center frequencies +# Channels are in ascending EIA/NCTA channel designation order + +#2 +A  57000000 QAM256 +A  63000000 QAM256 +A  69000000 QAM256 +A  79000000 QAM256 +A  85000000 QAM256 +A 177000000 QAM256 +A 183000000 QAM256 +A 189000000 QAM256 +#10 +A 195000000 QAM256 +A 201000000 QAM256 +A 207000000 QAM256 +A 213000000 QAM256 +A 123012500 QAM256 +A 129012500 QAM256 +A 135012500 QAM256 +A 141000000 QAM256 +A 147000000 QAM256 +A 153000000 QAM256 +#20 +A 159000000 QAM256 +A 165000000 QAM256 +A 171000000 QAM256 +A 219000000 QAM256 +A 225000000 QAM256 +A 231012500 QAM256 +A 237012500 QAM256 +A 243012500 QAM256 +A 249012500 QAM256 +A 255012500 QAM256 +#30 +A 261012500 QAM256 +A 267012500 QAM256 +A 273012500 QAM256 +A 279012500 QAM256 +A 285012500 QAM256 +A 291012500 QAM256 +A 297012500 QAM256 +A 303012500 QAM256 +A 309012500 QAM256 +A 315012500 QAM256 +#40 +A 321012500 QAM256 +A 327012500 QAM256 +A 333025000 QAM256 +A 339012500 QAM256 +A 345012500 QAM256 +A 351012500 QAM256 +A 357012500 QAM256 +A 363012500 QAM256 +A 369012500 QAM256 +A 375012500 QAM256 +#50 +A 381012500 QAM256 +A 387012500 QAM256 +A 393012500 QAM256 +A 399012500 QAM256 +A 405000000 QAM256 +A 411000000 QAM256 +A 417000000 QAM256 +A 423000000 QAM256 +A 429000000 QAM256 +A 435000000 QAM256 +#60 +A 441000000 QAM256 +A 447000000 QAM256 +A 453000000 QAM256 +A 459000000 QAM256 +A 465000000 QAM256 +A 471000000 QAM256 +A 477000000 QAM256 +A 483000000 QAM256 +A 489000000 QAM256 +A 495000000 QAM256 +#70 +A 501000000 QAM256 +A 507000000 QAM256 +A 513000000 QAM256 +A 519000000 QAM256 +A 525000000 QAM256 +A 531000000 QAM256 +A 537000000 QAM256 +A 543000000 QAM256 +A 549000000 QAM256 +A 555000000 QAM256 +#80 +A 561000000 QAM256 +A 567000000 QAM256 +A 573000000 QAM256 +A 579000000 QAM256 +A 585000000 QAM256 +A 591000000 QAM256 +A 597000000 QAM256 +A 603000000 QAM256 +A 609000000 QAM256 +A 615000000 QAM256 +#90 +A 621000000 QAM256 +A 627000000 QAM256 +A 633000000 QAM256 +A 639000000 QAM256 +A 645000000 QAM256 +A  93000000 QAM256 +A  99000000 QAM256 +A 105000000 QAM256 +A 111025000 QAM256 +A 117025000 QAM256 +#100 +A 651000000 QAM256 +A 657000000 QAM256 +A 663000000 QAM256 +A 669000000 QAM256 +A 675000000 QAM256 +A 681000000 QAM256 +A 687000000 QAM256 +A 693000000 QAM256 +A 699000000 QAM256 +A 705000000 QAM256 +#110 +A 711000000 QAM256 +A 717000000 QAM256 +A 723000000 QAM256 +A 729000000 QAM256 +A 735000000 QAM256 +A 741000000 QAM256 +A 747000000 QAM256 +A 753000000 QAM256 +A 759000000 QAM256 +A 765000000 QAM256 +#120 +A 771000000 QAM256 +A 777000000 QAM256 +A 783000000 QAM256 +A 789000000 QAM256 +A 795000000 QAM256 +A 801000000 QAM256 diff --git a/util/scan/atsc/us-ID-Boise b/util/scan/atsc/us-ID-Boise new file mode 100644 index 0000000..9fe7cd2 --- /dev/null +++ b/util/scan/atsc/us-ID-Boise @@ -0,0 +1,8 @@ +# Boise, ID, USA +# A freq mod +A 195000000 8VSB +A 213000000 8VSB +A 515000000 8VSB +A 533000000 8VSB +A 545000000 8VSB +A 557000000 8VSB diff --git a/util/scan/atsc/us-MA-Boston b/util/scan/atsc/us-MA-Boston new file mode 100644 index 0000000..05f170a --- /dev/null +++ b/util/scan/atsc/us-MA-Boston @@ -0,0 +1,13 @@ +# initial tuning data for Boston, MA + +A 503000000 8VSB +A 509000000 8VSB +A 527000000 8VSB +A 563000000 8VSB +A 569000000 8VSB +A 575000000 8VSB +A 581000000 8VSB +A 623000000 8VSB +A 635000000 8VSB +A 641000000 8VSB +A 647000000 8VSB diff --git a/util/scan/atsc/us-MI-Lansing b/util/scan/atsc/us-MI-Lansing new file mode 100644 index 0000000..167555f --- /dev/null +++ b/util/scan/atsc/us-MI-Lansing @@ -0,0 +1,7 @@ +# initial tuning data for Lansing, MI + +A 617000000 8VSB +A 695000000 8VSB +A 719000000 8VSB +A 731000000 8VSB +A 743000000 8VSB diff --git a/util/scan/atsc/us-NTSC-center-frequencies-8VSB b/util/scan/atsc/us-NTSC-center-frequencies-8VSB new file mode 100644 index 0000000..d21f9ae --- /dev/null +++ b/util/scan/atsc/us-NTSC-center-frequencies-8VSB @@ -0,0 +1,71 @@ +# US NTSC center frequencies, use if in doubt + +A  57000000 8VSB +A  63000000 8VSB +A  69000000 8VSB +A  79000000 8VSB +A  85000000 8VSB +A 177000000 8VSB +A 183000000 8VSB +A 189000000 8VSB +A 195000000 8VSB +A 201000000 8VSB +A 207000000 8VSB +A 213000000 8VSB +A 473000000 8VSB +A 479000000 8VSB +A 485000000 8VSB +A 491000000 8VSB +A 497000000 8VSB +A 503000000 8VSB +A 509000000 8VSB +A 515000000 8VSB +A 521000000 8VSB +A 527000000 8VSB +A 533000000 8VSB +A 539000000 8VSB +A 545000000 8VSB +A 551000000 8VSB +A 557000000 8VSB +A 563000000 8VSB +A 569000000 8VSB +A 575000000 8VSB +A 581000000 8VSB +A 587000000 8VSB +A 593000000 8VSB +A 599000000 8VSB +A 605000000 8VSB +A 611000000 8VSB +A 617000000 8VSB +A 623000000 8VSB +A 629000000 8VSB +A 635000000 8VSB +A 641000000 8VSB +A 647000000 8VSB +A 653000000 8VSB +A 659000000 8VSB +A 665000000 8VSB +A 671000000 8VSB +A 677000000 8VSB +A 683000000 8VSB +A 689000000 8VSB +A 695000000 8VSB +A 701000000 8VSB +A 707000000 8VSB +A 713000000 8VSB +A 719000000 8VSB +A 725000000 8VSB +A 731000000 8VSB +A 737000000 8VSB +A 743000000 8VSB +A 749000000 8VSB +A 755000000 8VSB +A 761000000 8VSB +A 767000000 8VSB +A 773000000 8VSB +A 779000000 8VSB +A 785000000 8VSB +A 791000000 8VSB +A 797000000 8VSB +A 803000000 8VSB + diff --git a/util/scan/atsc/us-NY-TWC-NYC b/util/scan/atsc/us-NY-TWC-NYC new file mode 100644 index 0000000..0ad6e48 --- /dev/null +++ b/util/scan/atsc/us-NY-TWC-NYC @@ -0,0 +1,53 @@ +#initial tuning data for Time Warner Cable in New York City
 +
 +#80
 +A 561000000 QAM256
 +A 567000000 QAM256
 +A 573000000 QAM256
 +A 579000000 QAM256
 +A 585000000 QAM256
 +A 591000000 QAM256
 +A 597000000 QAM256
 +A 603000000 QAM256
 +A 609000000 QAM256
 +A 615000000 QAM256
 +#90
 +A 621000000 QAM256
 +A 627000000 QAM256
 +A 633000000 QAM256
 +A 639000000 QAM256
 +A 645000000 QAM256
 +A  93000000 QAM256
 +A  99000000 QAM256
 +A 105000000 QAM256
 +A 111025000 QAM256
 +A 117025000 QAM256
 +#100
 +A 651000000 QAM256
 +A 657000000 QAM256
 +A 663000000 QAM256
 +A 669000000 QAM256
 +A 675000000 QAM256
 +A 681000000 QAM256
 +A 687000000 QAM256
 +A 693000000 QAM256
 +A 699000000 QAM256
 +A 705000000 QAM256
 +#110
 +A 711000000 QAM256
 +A 717000000 QAM256
 +A 723000000 QAM256
 +A 729000000 QAM256
 +A 735000000 QAM256
 +A 741000000 QAM256
 +A 747000000 QAM256
 +A 753000000 QAM256
 +A 759000000 QAM256
 +A 765000000 QAM256
 +#120
 +A 771000000 QAM256
 +A 777000000 QAM256
 +A 783000000 QAM256
 +A 789000000 QAM256
 +A 795000000 QAM256
 +A 801000000 QAM256
 diff --git a/util/scan/atsc/us-PA-Philadelphia b/util/scan/atsc/us-PA-Philadelphia new file mode 100644 index 0000000..eea9685 --- /dev/null +++ b/util/scan/atsc/us-PA-Philadelphia @@ -0,0 +1,16 @@ +# US NY state + +#A 183000000 8VSB +#A 515000000 8VSB +#A 545000000 8VSB +#A 551000000 8VSB +A 575000000 8VSB +A 581000000 8VSB +A 593000000 8VSB +#A 641000000 8VSB +A 647000000 8VSB +A 713000000 8VSB +#A 719000000 8VSB +A 773000000 8VSB +A 785000000 8VSB +A 791000000 8VSB diff --git a/util/scan/atsc_psip_section.c b/util/scan/atsc_psip_section.c new file mode 100644 index 0000000..0c50014 --- /dev/null +++ b/util/scan/atsc_psip_section.c @@ -0,0 +1,62 @@ +#include "atsc_psip_section.h" + +struct ATSC_extended_channel_name_descriptor read_ATSC_extended_channel_name_descriptor(const u8 *b) +{ +	struct ATSC_extended_channel_name_descriptor v; +	v.descriptor_tag            = getBits(b,  0, 8); +	v.descriptor_length         = getBits(b,  8, 8); +	v.TODO                      = getBits(b, 16, 1); +	return v; +} + +struct ATSC_service_location_descriptor read_ATSC_service_location_descriptor(const u8 *b) +{ +	struct ATSC_service_location_descriptor v; +	v.descriptor_tag            = getBits(b,  0, 8); +	v.descriptor_length         = getBits(b,  8, 8); +	v.reserved                  = getBits(b, 16, 3); +	v.PCR_PID                   = getBits(b, 19,13); +	v.number_elements           = getBits(b, 32, 8); +	return v; +} + +struct ATSC_service_location_element read_ATSC_service_location_element(const u8 *b) +{ +	struct ATSC_service_location_element v; +	v.stream_type               = getBits(b,  0, 8); +	v.reserved                  = getBits(b,  8, 3); +	v.elementary_PID            = getBits(b, 11,13); +	v.ISO_639_language_code     = getBits(b, 24,24); +	return v; +} + +struct tvct_channel read_tvct_channel(const u8 *b) +{ +	struct tvct_channel v; +	v.short_name0               = getBits(b,  0,16); +	v.short_name1               = getBits(b, 16,16); +	v.short_name2               = getBits(b, 32,16); +	v.short_name3               = getBits(b, 48,16); +	v.short_name4               = getBits(b, 64,16); +	v.short_name5               = getBits(b, 80,16); +	v.short_name6               = getBits(b, 96,16); +	v.reserved0                 = getBits(b,112, 4); +	v.major_channel_number      = getBits(b,116,10); +	v.minor_channel_number      = getBits(b,126,10); +	v.modulation_mode           = getBits(b,136, 8); +	v.carrier_frequency         = getBits(b,144,32); +	v.channel_TSID              = getBits(b,176,16); +	v.program_number            = getBits(b,192,16); +	v.ETM_location              = getBits(b,208, 2); +	v.access_controlled         = getBits(b,210, 1); +	v.hidden                    = getBits(b,211, 1); +	v.reserved1                 = getBits(b,212, 2); +	v.hide_guide                = getBits(b,214, 1); +	v.reserved2                 = getBits(b,215, 3); +	v.service_type              = getBits(b,218, 6); +	v.source_id                 = getBits(b,224,16); +	v.reserved3                 = getBits(b,240, 6); +	v.descriptors_length        = getBits(b,246,10); +	return v; +} + diff --git a/util/scan/atsc_psip_section.h b/util/scan/atsc_psip_section.h new file mode 100644 index 0000000..c76bce7 --- /dev/null +++ b/util/scan/atsc_psip_section.h @@ -0,0 +1,60 @@ +#ifndef __ATSC_PSIP_SECTION_H_ +#define __ATSC_PSIP_SECTION_H_ + +#include "section.h" + +#define ATSC_EXTENDED_CHANNEL_NAME_DESCRIPTOR_ID 0xA0 +struct ATSC_extended_channel_name_descriptor { +		u8  descriptor_tag            : 8; +		u8  descriptor_length         : 8; +		u8  TODO                      : 1; +} PACKED; +struct ATSC_extended_channel_name_descriptor read_ATSC_extended_channel_name_descriptor(const u8 *); + +#define ATSC_SERVICE_LOCATION_DESCRIPTOR_ID 0xA1 +struct ATSC_service_location_descriptor { +		u8  descriptor_tag            : 8; +		u8  descriptor_length         : 8; +		u8  reserved                  : 3; +		u16 PCR_PID                   :13; +		u8  number_elements           : 8; +} PACKED; +struct ATSC_service_location_descriptor read_ATSC_service_location_descriptor(const u8 *); + +struct ATSC_service_location_element { +		u8  stream_type               : 8; +		u8  reserved                  : 3; +		u16 elementary_PID            :13; +		u32 ISO_639_language_code     :24; +} PACKED; +struct ATSC_service_location_element read_ATSC_service_location_element(const u8 *); + +struct tvct_channel { +		u16 short_name0               :16; +		u16 short_name1               :16; +		u16 short_name2               :16; +		u16 short_name3               :16; +		u16 short_name4               :16; +		u16 short_name5               :16; +		u16 short_name6               :16; +		u8  reserved0                 : 4; +		u16 major_channel_number      :10; +		u16 minor_channel_number      :10; +		u8  modulation_mode           : 8; +		u32 carrier_frequency         :32; +		u16 channel_TSID              :16; +		u16 program_number            :16; +		u8  ETM_location              : 2; +		u8  access_controlled         : 1; +		u8  hidden                    : 1; +		u8  reserved1                 : 2; +		u8  hide_guide                : 1; +		u8  reserved2                 : 3; +		u8  service_type              : 6; +		u16 source_id                 :16; +		u8  reserved3                 : 6; +		u16 descriptors_length        :10; +} PACKED; +struct tvct_channel read_tvct_channel(const u8 *); + +#endif diff --git a/util/scan/diseqc.c b/util/scan/diseqc.c index c763261..a337e0a 100644 --- a/util/scan/diseqc.c +++ b/util/scan/diseqc.c @@ -93,7 +93,7 @@ int setup_switch (int frontend_fd, int switch_pos, int voltage_18, int hiband)  	verbose("DiSEqC: switch pos %i, %sV, %sband (index %d)\n",  	    switch_pos, voltage_18 ? "18" : "13", hiband ? "hi" : "lo", i); -	if (i < 0 || i >= sizeof(switch_cmds)/sizeof(struct diseqc_cmd)) +	if (i < 0 || i >= (int) (sizeof(switch_cmds)/sizeof(struct diseqc_cmd)))  		return -EINVAL;  	cmd[0] = &switch_cmds[i]; diff --git a/util/scan/dump-vdr.c b/util/scan/dump-vdr.c index 8f86654..f030c93 100644 --- a/util/scan/dump-vdr.c +++ b/util/scan/dump-vdr.c @@ -101,6 +101,11 @@ void vdr_dump_dvb_parameters (FILE *f, fe_type_t type,  		fprintf (f, ":T:27500:");  		break; +	case FE_ATSC: +		fprintf (f, "%i:", p->frequency / 1000); +		fprintf (f, "VDR does not support ATSC at this time"); +		break; +  	default:  		;  	}; @@ -115,6 +120,7 @@ void vdr_dump_service_parameter_set (FILE *f,  				 int video_pid,  				 int pcr_pid,  				 uint16_t *audio_pid, +				 char audio_lang[][4],                                   int audio_num,  				 int teletext_pid,  				 int scrambled, @@ -133,26 +139,42 @@ void vdr_dump_service_parameter_set (FILE *f,          int i;  	if ((video_pid || audio_pid[0]) && ((ca_select > 0) || ((ca_select == 0) && (scrambled == 0)))) { +		if (vdr_version <= 2) { +			audio_lang = NULL; +			network_id = 0; +			transport_stream_id = 0; +		}  		if ((dump_channum == 1) && (channel_num > 0))  			fprintf(f, ":@%i\n", channel_num); -		if (dump_provider == 1) -			fprintf (f, "%s - ", provider_name); -		fprintf (f, "%s:", service_name); +		if (vdr_version >= 3) +			fprintf (f, "%s;%s:", service_name, provider_name); +		else +		  { +		    if (dump_provider == 1) +		      fprintf (f, "%s - ", provider_name); +		    fprintf (f, "%s:", service_name); +		  }  		vdr_dump_dvb_parameters (f, type, p, polarity, orbital_pos, we_flag);  		if ((pcr_pid != video_pid) && (video_pid > 0))  			fprintf (f, "%i+%i:", video_pid, pcr_pid);  		else  			fprintf (f, "%i:", video_pid);  		fprintf (f, "%i", audio_pid[0]); +		if (audio_lang && audio_lang[0][0]) +			fprintf (f, "=%.4s", audio_lang[0]);  	        for (i = 1; i < audio_num; i++) +	        {  			fprintf (f, ",%i", audio_pid[i]); +			if (audio_lang && audio_lang[i][0]) +				fprintf (f, "=%.4s", audio_lang[i]); +		}  		if (ac3_pid) +	        {  			fprintf (f, ";%i", ac3_pid); +			if (audio_lang && audio_lang[0][0]) +				fprintf (f, "=%.4s", audio_lang[0]); + 		}  		if (scrambled == 1) scrambled = ca_select; -		if (vdr_version == 2) { -			network_id = 0; -			transport_stream_id = 0; -		}   		fprintf (f, ":%d:%d:%d:%d:%d:0", teletext_pid, scrambled,  				service_id, network_id, transport_stream_id);  		fprintf (f, "\n"); diff --git a/util/scan/dump-vdr.h b/util/scan/dump-vdr.h index 0602026..13bd05a 100644 --- a/util/scan/dump-vdr.h +++ b/util/scan/dump-vdr.h @@ -19,6 +19,7 @@ void vdr_dump_service_parameter_set (FILE *f,  				 int video_pid,  				 int pcr_pid,  				 uint16_t *audio_pid, +				 char audio_lang[][4],                                   int audio_num,  				 int teletext_pid,  				 int scrambled, diff --git a/util/scan/dump-zap.c b/util/scan/dump-zap.c index fb46a2a..83505b9 100644 --- a/util/scan/dump-zap.c +++ b/util/scan/dump-zap.c @@ -29,7 +29,9 @@ static const char *qam_name [] = {  	"QAM_64",  	"QAM_128",  	"QAM_256", -	"QAM_AUTO" +	"QAM_AUTO", +	"8VSB", +	"16VSB",  }; @@ -96,12 +98,17 @@ void zap_dump_dvb_parameters (FILE *f, fe_type_t type, struct dvb_frontend_param  		fprintf (f, "%s", hierarchy_name[p->u.ofdm.hierarchy_information]);  		break; +	case FE_ATSC: +		fprintf (f, "%i:", p->frequency); +		fprintf (f, "%s", qam_name[p->u.vsb.modulation]); +		break; +  	default:  		;  	};  } -void zap_dump_service_parameter_set (FILE *f,  +void zap_dump_service_parameter_set (FILE *f,  				 const char *service_name,  				 fe_type_t type,  				 struct dvb_frontend_parameters *p, diff --git a/util/scan/lnb.c b/util/scan/lnb.c new file mode 100644 index 0000000..e30c1d6 --- /dev/null +++ b/util/scan/lnb.c @@ -0,0 +1,108 @@ +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include "lnb.h" + +static char *univ_desc[] = { +		"Europe", +		"10800 to 11800 MHz and 11600 to 12700 Mhz", +		"Dual LO, loband 9750, hiband 10600 MHz", +		(char *)NULL }; + +static char *dbs_desc[] = { +		"Expressvu, North America", +		"12200 to 12700 MHz", +		"Single LO, 11250 MHz", +		(char *)NULL }; + +static char *standard_desc[] = { +		"10945 to 11450 Mhz", +		"Single LO, 10000 Mhz", +		(char *)NULL }; + +static char *enhan_desc[] = { +		"Astra", +		"10700 to 11700 MHz", +		"Single LO, 9750 MHz", +		(char *)NULL }; + +static char *cband_desc[] = { +		"Big Dish - Monopoint LNBf", +		"3700 to 4200 MHz", +		"Single LO, 5150 Mhz", +		(char *)NULL }; + +static char *cmulti_desc[] = { +		"Big Dish - Multipoint LNBf", +		"3700 to 4200 MHz", +		"Dual LO, 5150/5750 Mhz", +		(char *)NULL }; + +static struct lnb_types_st lnbs[] = { +	{"UNIVERSAL",	univ_desc,		9750, 10600, 11700 }, + 	{"DBS",		dbs_desc, 		11250, 0, 0 }, +	{"STANDARD",	standard_desc,		10000, 0, 0 }, +	{"ENHANCED",	enhan_desc,		9750, 0, 0 }, +	{"C-BAND",	cband_desc,		5150, 0, 0 }, +	{"C-MULTI",	cmulti_desc,		5150, 5750, 0 } +}; + +/* Enumerate through standard types of LNB's until NULL returned. + * Increment curno each time + */ + +struct lnb_types_st * +lnb_enum(int curno) +{ +	if (curno >= (int) (sizeof(lnbs) / sizeof(lnbs[0]))) +		return (struct lnb_types_st *)NULL; +	return &lnbs[curno]; +} + +/* Decode an lnb type, for example given on a command line + * If alpha and standard type, e.g. "Universal" then match that + * otherwise low[,high[,switch]] + */ + +int +lnb_decode(char *str, struct lnb_types_st *lnbp) +{ +int i; +char *cp, *np; + +	memset(lnbp, 0, sizeof(*lnbp)); +	cp = str; +	while(*cp && isspace(*cp)) +		cp++; +	if (isalpha(*cp)) { +		for (i = 0; i < (int) (sizeof(lnbs) / sizeof(lnbs[0])); i++) { +			if (!strcasecmp(lnbs[i].name, cp)) { +				*lnbp = lnbs[i]; +				return 1; +			} +		} +		return -1; +	} +	if (*cp == '\0' || !isdigit(*cp)) +		return -1; +	lnbp->low_val = strtoul(cp, &np, 0); +	if (lnbp->low_val == 0) +		return -1; +	cp = np; +	while(*cp && (isspace(*cp) || *cp == ',')) +		cp++; +	if (*cp == '\0') +		return 1; +	if (!isdigit(*cp)) +		return -1; +	lnbp->high_val = strtoul(cp, &np, 0); +	cp = np; +	while(*cp && (isspace(*cp) || *cp == ',')) +		cp++; +	if (*cp == '\0') +		return 1; +	if (!isdigit(*cp)) +		return -1; +	lnbp->switch_val = strtoul(cp, NULL, 0); +	return 1; +} diff --git a/util/scan/lnb.h b/util/scan/lnb.h new file mode 100644 index 0000000..f78b7a6 --- /dev/null +++ b/util/scan/lnb.h @@ -0,0 +1,24 @@ + +struct lnb_types_st { +	char	*name; +	char	**desc; +	unsigned long	low_val; +	unsigned long	high_val;	/* zero indicates no hiband */ +	unsigned long	switch_val;	/* zero indicates no hiband */ +}; + +/* Enumerate through standard types of LNB's until NULL returned. + * Increment curno each time + */ + +struct lnb_types_st * +lnb_enum(int curno); + +/* Decode an lnb type, for example given on a command line + * If alpha and standard type, e.g. "Universal" then match that + * otherwise low[,high[,switch]] + */ + +int +lnb_decode(char *str, struct lnb_types_st *lnbp); + diff --git a/util/scan/scan.c b/util/scan/scan.c index 30d77a5..350d9c9 100644 --- a/util/scan/scan.c +++ b/util/scan/scan.c @@ -1,4 +1,4 @@ -/** +/*   *  Simple MPEG parser to achieve network/service information.   *   *  refered standards: @@ -7,6 +7,15 @@   *    ETSI TR 101 211   *    ETSI ETR 211   *    ITU-T H.222.0 + * + * 2005-05-10 - Basic ATSC PSIP parsing support added + *    ATSC Standard Revision B (A65/B) + * + * Thanks to Sean Device from Triveni for providing access to ATSC signals + *    and to Kevin Fowlks for his independent ATSC scanning tool. + * + * Please contribute: It is possible that some descriptors for ATSC are + *        not parsed yet and thus the result won't be complete.   */  #include <stdlib.h> @@ -22,6 +31,8 @@  #include <errno.h>  #include <signal.h>  #include <assert.h> +#include <glob.h> +#include <ctype.h>  #include <linux/dvb/frontend.h>  #include <linux/dvb/dmx.h> @@ -33,6 +44,7 @@  #include "scan.h"  #include "lnb.h" +#include "atsc_psip_section.h"  static char demux_devname[80]; @@ -47,10 +59,13 @@ static int current_tp_only;  static int get_other_nits;  static int vdr_dump_provider;  static int vdr_dump_channum; +static int no_ATSC_PSIP; +static int ATSC_type=1;  static int ca_select = 1;  static int serv_select = 7;  static int vdr_version = 2;  static struct lnb_types_st lnb_type; +static int unique_anon_services;  static enum fe_spectral_inversion spectral_inversion = INVERSION_AUTO; @@ -67,6 +82,7 @@ enum format {  	OUTPUT_PIDS  };  static enum format output_format = OUTPUT_ZAP; +static int output_format_set = 0;  enum polarisation { @@ -123,6 +139,7 @@ struct transponder {  	unsigned int scan_done		  : 1;  	unsigned int last_tuning_failed	  : 1;  	unsigned int other_frequency_flag : 1;	/* DVB-T */ +	unsigned int wrong_frequency	  : 1;	/* DVB-T with other_frequency_flag */  	int n_other_f;  	uint32_t *other_f;			/* DVB-T freqeuency-list descriptor */  }; @@ -157,14 +174,16 @@ static struct transponder *current_tp;  static void dump_dvb_parameters (FILE *f, struct transponder *p);  static void setup_filter (struct section_buf* s, const char *dmx_devname, -		          int pid, int tid, int run_once, int segmented, int timeout); +		          int pid, int tid, int tid_ext, +			  int run_once, int segmented, int timeout);  static void add_filter (struct section_buf *s); +static const char * fe_type2str(fe_type_t t);  /* According to the DVB standards, the combination of network_id and   * transport_stream_id should be unique, but in real life the satellite   * operators and broadcasters don't care enough to coordinate - * the numbering. Thus we identify TPs by frequency (scan handles only + * the numbering. Thus we identify TPs by frequency (dvbscan handles only   * one satellite at a time). Further complication: Different NITs on   * one satellite sometimes list the same TP with slightly different   * frequencies, so we have to search within some bandwidth. @@ -201,6 +220,8 @@ static struct transponder *find_transponder(uint32_t frequency)  	list_for_each(pos, &scanned_transponders) {  		tp = list_entry(pos, struct transponder, list); +		if (current_tp_only) +			return tp;  		if (is_same_transponder(tp->param.frequency, frequency))  			return tp;  	} @@ -242,6 +263,7 @@ static struct service *alloc_service(struct transponder *tp, int service_id)  	struct service *s = calloc(1, sizeof(*s));  	INIT_LIST_HEAD(&s->list);  	s->service_id = service_id; +	s->transport_stream_id = tp->transport_stream_id;  	list_add_tail(&s->list, &tp->services);  	return s;  } @@ -264,7 +286,7 @@ static void parse_ca_identifier_descriptor (const unsigned char *buf,  				     struct service *s)  {  	unsigned char len = buf [1]; -	int i; +	unsigned int i;  	buf += 2; @@ -302,6 +324,8 @@ static void parse_iso639_language_descriptor (const unsigned char *buf, struct s  static void parse_network_name_descriptor (const unsigned char *buf, void *dummy)  { +	(void)dummy; +  	unsigned char len = buf [1];  	info("Network Name '%.*s'\n", len, buf + 2); @@ -309,6 +333,8 @@ static void parse_network_name_descriptor (const unsigned char *buf, void *dummy  static void parse_terrestrial_uk_channel_number (const unsigned char *buf, void *dummy)  { +	(void)dummy; +  	int i, n, channel_num, service_id;  	struct list_head *p1, *p2;  	struct transponder *t; @@ -323,7 +349,7 @@ static void parse_terrestrial_uk_channel_number (const unsigned char *buf, void  	buf += 2;  	for (i = 0; i < n; i++) {  		service_id = (buf[0]<<8)|(buf[1]&0xff); -		channel_num = (buf[2]&0x03<<8)|(buf[3]&0xff); +		channel_num = ((buf[2]&0x03)<<8)|(buf[3]&0xff);  		debug("Service ID 0x%x has channel number %d ", service_id, channel_num);  		list_for_each(p1, &scanned_transponders) {  			t = list_entry(p1, struct transponder, list); @@ -381,7 +407,7 @@ static void parse_cable_delivery_system_descriptor (const unsigned char *buf,  	t->param.inversion = spectral_inversion;  	if (verbosity >= 5) { -		debug("0x%#04x/0x%#04x ", t->network_id, t->transport_stream_id); +		debug("%#04x/%#04x ", t->network_id, t->transport_stream_id);  		dump_dvb_parameters (stderr, t);  		if (t->scan_done)  			dprintf(5, " (done)"); @@ -413,7 +439,7 @@ static void parse_satellite_delivery_system_descriptor (const unsigned char *buf  	t->we_flag = buf[8] >> 7;  	if (verbosity >= 5) { -		debug("0x%#04x/0x%#04x ", t->network_id, t->transport_stream_id); +		debug("%#04x/%#04x ", t->network_id, t->transport_stream_id);  		dump_dvb_parameters (stderr, t);  		if (t->scan_done)  			dprintf(5, " (done)"); @@ -467,7 +493,7 @@ static void parse_terrestrial_delivery_system_descriptor (const unsigned char *b  	t->other_frequency_flag = (buf[8] & 0x01);  	if (verbosity >= 5) { -		debug("0x%#04x/0x%#04x ", t->network_id, t->transport_stream_id); +		debug("%#04x/%#04x ", t->network_id, t->transport_stream_id);  		dump_dvb_parameters (stderr, t);  		if (t->scan_done)  			dprintf(5, " (done)"); @@ -525,7 +551,7 @@ static void parse_service_descriptor (const unsigned char *buf, struct service *  	/* remove control characters (FIXME: handle short/long name) */  	/* FIXME: handle character set correctly (e.g. via iconv)  	 * c.f. EN 300 468 annex A */ -	for (src = dest = s->provider_name; *src; src++) +	for (src = dest = (unsigned char *) s->provider_name; *src; src++)  		if (*src >= 0x20 && (*src < 0x80 || *src > 0x9f))  			*dest++ = *src;  	*dest = '\0'; @@ -549,7 +575,7 @@ static void parse_service_descriptor (const unsigned char *buf, struct service *  	/* remove control characters (FIXME: handle short/long name) */  	/* FIXME: handle character set correctly (e.g. via iconv)  	 * c.f. EN 300 468 annex A */ -	for (src = dest = s->service_name; *src; src++) +	for (src = dest = (unsigned char *) s->service_name; *src; src++)  		if (*src >= 0x20 && (*src < 0x80 || *src > 0x9f))  			*dest++ = *src;  	*dest = '\0'; @@ -672,15 +698,15 @@ static void parse_descriptors(enum table_type t, const unsigned char *buf,  static void parse_pat(const unsigned char *buf, int section_length,  		      int transport_stream_id)  { +	(void)transport_stream_id; +  	while (section_length > 0) {  		struct service *s;  		int service_id = (buf[0] << 8) | buf[1]; -		if (service_id == 0) { -			buf += 4;		/*  skip nit pid entry... */ -			section_length -= 4; -			continue; -		} +		if (service_id == 0) +			goto skip;	/* nit pid entry */ +  		/* SDT might have been parsed first... */  		s = find_service(current_tp, service_id);  		if (!s) @@ -689,11 +715,12 @@ static void parse_pat(const unsigned char *buf, int section_length,  		if (!s->priv && s->pmt_pid) {  			s->priv = malloc(sizeof(struct section_buf));  			setup_filter(s->priv, demux_devname, -				     s->pmt_pid, 0x02, 1, 0, 5); +				     s->pmt_pid, 0x02, s->service_id, 1, 0, 5);  			add_filter (s->priv);  		} +skip:  		buf += 4;  		section_length -= 4;  	}; @@ -721,7 +748,7 @@ static void parse_pmt (const unsigned char *buf, int section_length, int service  	buf += program_info_len + 4;  	section_length -= program_info_len + 4; -	while (section_length > 0) { +	while (section_length >= 5) {  		int ES_info_len = ((buf[3] & 0x0f) << 8) | buf[4];  		int elementary_pid = ((buf[1] & 0x1f) << 8) | buf[2]; @@ -733,6 +760,7 @@ static void parse_pmt (const unsigned char *buf, int section_length, int service  				s->video_pid = elementary_pid;  			break;  		case 0x03: +		case 0x81: /* Audio per ATSC A/53B [2] Annex B */  		case 0x04:  			moreverbose("  AUDIO     : PID 0x%04x\n", elementary_pid);  			if (s->audio_num < AUDIO_CHAN_MAX) { @@ -775,8 +803,8 @@ static void parse_pmt (const unsigned char *buf, int section_length, int service  	}; -        tmp = msg_buf; -        tmp += sprintf(tmp, "0x%04x (%.4s)", s->audio_pid[0], s->audio_lang[0]); +	tmp = msg_buf; +	tmp += sprintf(tmp, "0x%04x (%.4s)", s->audio_pid[0], s->audio_lang[0]);  	if (s->audio_num > AUDIO_CHAN_MAX) {  		warning("more than %i audio channels: %i, truncating to %i\n", @@ -846,16 +874,18 @@ static void parse_nit (const unsigned char *buf, int section_length, int network  		section_length -= descriptors_loop_len + 6;  		buf += descriptors_loop_len + 6; -	}; +	}  }  static void parse_sdt (const unsigned char *buf, int section_length,  		int transport_stream_id)  { +	(void)transport_stream_id; +  	buf += 3;	       /*  skip original network id + reserved field */ -	while (section_length > 4) { +	while (section_length >= 5) {  		int service_id = (buf[0] << 8) | buf[1];  		int descriptors_loop_len = ((buf[3] & 0x0f) << 8) | buf[4];  		struct service *s; @@ -884,6 +914,159 @@ static void parse_sdt (const unsigned char *buf, int section_length,  	};  } +/* ATSC PSIP VCT */ +static void parse_atsc_service_loc_desc(struct service *s,const unsigned char *buf) +{ +	struct ATSC_service_location_descriptor d = read_ATSC_service_location_descriptor(buf); +	int i; +	unsigned char *b = (unsigned char *) buf+5; + +	s->pcr_pid = d.PCR_PID; +	for (i=0; i < d.number_elements; i++) { +		struct ATSC_service_location_element e = read_ATSC_service_location_element(b); +		switch (e.stream_type) { +			case 0x02: /* video */ +				s->video_pid = e.elementary_PID; +				moreverbose("  VIDEO     : PID 0x%04x\n", e.elementary_PID); +				break; +			case 0x81: /* ATSC audio */ +				if (s->audio_num < AUDIO_CHAN_MAX) { +					s->audio_pid[s->audio_num] = e.elementary_PID; +					s->audio_lang[s->audio_num][0] = (e.ISO_639_language_code >> 16) & 0xff; +					s->audio_lang[s->audio_num][1] = (e.ISO_639_language_code >> 8)  & 0xff; +					s->audio_lang[s->audio_num][2] =  e.ISO_639_language_code        & 0xff; +					s->audio_num++; +				} +				moreverbose("  AUDIO     : PID 0x%04x lang: %s\n",e.elementary_PID,s->audio_lang[s->audio_num-1]); + +				break; +			default: +				warning("unhandled stream_type: %x\n",e.stream_type); +				break; +		}; +		b += 6; +	} +} + +static void parse_atsc_ext_chan_name_desc(struct service *s,const unsigned char *buf) +{ +	unsigned char *b = (unsigned char *) buf+2; +	int i,j; +	int num_str = b[0]; + +	b++; +	for (i = 0; i < num_str; i++) { +		int num_seg = b[3]; +		b += 4; /* skip lang code */ +		for (j = 0; j < num_seg; j++) { +			int comp_type = b[0],/* mode = b[1],*/ num_bytes = b[2]; + +			switch (comp_type) { +				case 0x00: +					if (s->service_name) +						free(s->service_name); +					s->service_name = malloc(num_bytes * sizeof(char) + 1); +					memcpy(s->service_name,&b[3],num_bytes); +					s->service_name[num_bytes] = '\0'; +					break; +				default: +					warning("compressed strings are not supported yet\n"); +					break; +			} +			b += 3 + num_bytes; +		} +	} +} + +static void parse_psip_descriptors(struct service *s,const unsigned char *buf,int len) +{ +	unsigned char *b = (unsigned char *) buf; +	int desc_len; +	while (len > 0) { +		desc_len = b[1]; +		switch (b[0]) { +			case ATSC_SERVICE_LOCATION_DESCRIPTOR_ID: +				parse_atsc_service_loc_desc(s,b); +				break; +			case ATSC_EXTENDED_CHANNEL_NAME_DESCRIPTOR_ID: +				parse_atsc_ext_chan_name_desc(s,b); +				break; +			default: +				warning("unhandled psip descriptor: %02x\n",b[0]); +				break; +		} +		b += 2 + desc_len; +		len -= 2 + desc_len; +	} +} + +static void parse_psip_vct (const unsigned char *buf, int section_length, +		int table_id, int transport_stream_id) +{ +	(void)section_length; +	(void)table_id; +	(void)transport_stream_id; + +/*	int protocol_version = buf[0];*/ +	int num_channels_in_section = buf[1]; +	int i; +	int pseudo_id = 0xffff; +	unsigned char *b = (unsigned char *) buf + 2; + +	for (i = 0; i < num_channels_in_section; i++) { +		struct service *s; +		struct tvct_channel ch = read_tvct_channel(b); + +		switch (ch.service_type) { +			case 0x01: +				info("analog channels won't be put info channels.conf\n"); +				break; +			case 0x02: /* ATSC TV */ +			case 0x03: /* ATSC Radio */ +				break; +			case 0x04: /* ATSC Data */ +			default: +				continue; +		} + +		if (ch.program_number == 0) +			ch.program_number = --pseudo_id; + +		s = find_service(current_tp, ch.program_number); +		if (!s) +			s = alloc_service(current_tp, ch.program_number); + +		if (s->service_name) +			free(s->service_name); + +		s->service_name = malloc(7*sizeof(unsigned char)); +		/* TODO find a better solution to convert UTF-16 */ +		s->service_name[0] = ch.short_name0; +		s->service_name[1] = ch.short_name1; +		s->service_name[2] = ch.short_name2; +		s->service_name[3] = ch.short_name3; +		s->service_name[4] = ch.short_name4; +		s->service_name[5] = ch.short_name5; +		s->service_name[6] = ch.short_name6; + +		parse_psip_descriptors(s,&b[32],ch.descriptors_length); + +		s->channel_num = ch.major_channel_number << 10 | ch.minor_channel_number; + +		if (ch.hidden) { +			s->running = RM_NOT_RUNNING; +			info("service is not running, pseudo program_number."); +		} else { +			s->running = RM_RUNNING; +			info("service is running."); +		} + +		info(" Channel number: %d:%d. Name: '%s'\n", +			ch.major_channel_number, ch.minor_channel_number,s->service_name); + +		b += 32 + ch.descriptors_length; +	} +}  static int get_bit (uint8_t *bitfield, int bit)  { @@ -917,7 +1100,7 @@ static int parse_section (struct section_buf *s)  	if (s->table_id != table_id)  		return -1; -	section_length = (((buf[1] & 0x0f) << 8) | buf[2]) - 11; +	section_length = ((buf[1] & 0x0f) << 8) | buf[2];  	table_id_ext = (buf[3] << 8) | buf[4];  	section_version_number = (buf[5] >> 1) & 0x1f; @@ -960,7 +1143,13 @@ static int parse_section (struct section_buf *s)  		s->next_seg = next_seg;  	} -	buf += 8; +	buf += 8;			/* past generic table header */ +	section_length -= 5 + 4;	/* header + crc */ +	if (section_length < 0) { +		warning("truncated section (PID 0x%04x, lenght %d)", +			s->pid, section_length + 9); +		return 0; +	}  	if (!get_bit(s->section_done, section_number)) {  		set_bit (s->section_done, section_number); @@ -994,6 +1183,11 @@ static int parse_section (struct section_buf *s)  			parse_sdt (buf, section_length, table_id_ext);  			break; +		case 0xc8: +		case 0xc9: +			verbose("ATSC VCT\n"); +			parse_psip_vct(buf, section_length, table_id, table_id_ext); +			break;  		default:  			;  		}; @@ -1054,13 +1248,14 @@ static int read_sections (struct section_buf *s)  static LIST_HEAD(running_filters);  static LIST_HEAD(waiting_filters);  static int n_running; -#define MAX_RUNNING 32 +#define MAX_RUNNING 27  static struct pollfd poll_fds[MAX_RUNNING];  static struct section_buf* poll_section_bufs[MAX_RUNNING];  static void setup_filter (struct section_buf* s, const char *dmx_devname, -			  int pid, int tid, int run_once, int segmented, int timeout) +			  int pid, int tid, int tid_ext, +			  int run_once, int segmented, int timeout)  {  	memset (s, 0, sizeof(struct section_buf)); @@ -1077,7 +1272,7 @@ static void setup_filter (struct section_buf* s, const char *dmx_devname,  	else  		s->timeout = timeout; -	s->table_id_ext = -1; +	s->table_id_ext = tid_ext;  	s->section_version_number = -1;  	INIT_LIST_HEAD (&s->list); @@ -1129,6 +1324,12 @@ static int start_filter (struct section_buf* s)  		f.filter.filter[0] = (uint8_t) s->table_id;  		f.filter.mask[0]   = 0xff;  	} +	if (s->table_id_ext < 0x10000 && s->table_id_ext > 0) { +		f.filter.filter[1] = (uint8_t) ((s->table_id_ext >> 8) & 0xff); +		f.filter.filter[2] = (uint8_t) (s->table_id_ext & 0xff); +		f.filter.mask[1] = 0xff; +		f.filter.mask[2] = 0xff; +	}  	f.timeout = 0;  	f.flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC; @@ -1226,7 +1427,7 @@ static void read_filters (void)  static int mem_is_zero (const void *mem, int size)  {  	const char *p = mem; -	unsigned long i; +	int i;  	for (i=0; i<size; i++) {  		if (p[i] != 0x00) @@ -1314,6 +1515,8 @@ static int tune_to_transponder (int frontend_fd, struct transponder *t)  	t->scan_done = 1;  	if (t->type != fe_info.type) { +		warning("frontend type (%s) is not compatible with requested tuning type (%s)\n", +				fe_type2str(fe_info.type),fe_type2str(t->type));  		/* ignore cable descriptors in sat NIT and vice versa */  		t->last_tuning_failed = 1;  		return -1; @@ -1329,18 +1532,32 @@ static int tune_to_transponder (int frontend_fd, struct transponder *t)  static int tune_to_next_transponder (int frontend_fd)  {  	struct list_head *pos, *tmp; -	struct transponder *t; +	struct transponder *t, *to; +	uint32_t freq;  	list_for_each_safe(pos, tmp, &new_transponders) {  		t = list_entry (pos, struct transponder, list);  retry:  		if (tune_to_transponder (frontend_fd, t) == 0)  			return 0; -		if (t->other_frequency_flag && -				t->other_f && -				t->n_other_f) { -			t->param.frequency = t->other_f[t->n_other_f - 1]; +next: +		if (t->other_frequency_flag && t->other_f && t->n_other_f) { +			/* check if the alternate freqeuncy is really new to us */ +			freq = t->other_f[t->n_other_f - 1];  			t->n_other_f--; +			if (find_transponder(freq)) +				goto next; + +			/* remember tuning to the old frequency failed */ +			to = calloc(1, sizeof(*to)); +			to->param.frequency = t->param.frequency; +			to->wrong_frequency = 1; +			INIT_LIST_HEAD(&to->list); +			INIT_LIST_HEAD(&to->services); +			list_add_tail(&to->list, &scanned_transponders); +			copy_transponder(to, t); + +			t->param.frequency = freq;  			info("retrying with f=%d\n", t->param.frequency);  			goto retry;  		} @@ -1363,6 +1580,17 @@ static int str2enum(const char *str, const struct strtab *tab, int deflt)  	return deflt;  } +static const char * enum2str(int v, const struct strtab *tab, const char *deflt) +{ +	while (tab->str) { +		if (v == tab->val) +			return tab->str; +		tab++; +	} +	error("invalid enum value '%d'\n", v); +	return deflt; +} +  static enum fe_code_rate str2fec(const char *fec)  {  	struct strtab fectab[] = { @@ -1391,6 +1619,8 @@ static enum fe_modulation str2qam(const char *qam)  		{ "QAM128", QAM_128 },  		{ "QAM256", QAM_256 },  		{ "AUTO",   QAM_AUTO }, +		{ "8VSB",   VSB_8 }, +		{ "16VSB",  VSB_16 },  		{ NULL, 0 }  	};  	return str2enum(qam, qamtab, QAM_AUTO); @@ -1445,6 +1675,19 @@ static enum fe_hierarchy str2hier(const char *hier)  	return str2enum(hier, hiertab, HIERARCHY_AUTO);  } +static const char * fe_type2str(fe_type_t t) +{ +	struct strtab typetab[] = { +		{ "QPSK", FE_QPSK,}, +		{ "QAM",  FE_QAM, }, +		{ "OFDM", FE_OFDM,}, +		{ "ATSC", FE_ATSC,}, +		{ NULL, 0 } +	}; + +	return enum2str(t, typetab, "UNK"); +} +  static int tune_initial (int frontend_fd, const char *initial)  {  	FILE *inif; @@ -1501,7 +1744,11 @@ static int tune_initial (int frontend_fd, const char *initial)  			t->param.inversion = spectral_inversion;  			t->param.u.ofdm.bandwidth = str2bandwidth(bw);  			t->param.u.ofdm.code_rate_HP = str2fec(fec); +			if (t->param.u.ofdm.code_rate_HP == FEC_NONE) +				t->param.u.ofdm.code_rate_HP = FEC_AUTO;  			t->param.u.ofdm.code_rate_LP = str2fec(fec2); +			if (t->param.u.ofdm.code_rate_LP == FEC_NONE) +				t->param.u.ofdm.code_rate_LP = FEC_AUTO;  			t->param.u.ofdm.constellation = str2qam(qam);  			t->param.u.ofdm.transmission_mode = str2mode(mode);  			t->param.u.ofdm.guard_interval = str2guard(guard); @@ -1516,7 +1763,12 @@ static int tune_initial (int frontend_fd, const char *initial)  					t->param.u.ofdm.guard_interval,  					t->param.u.ofdm.hierarchy_information);  		} -		else +		else if (sscanf(buf, "A %u %7s\n", +					&f,qam) == 2) { +			t = alloc_transponder(f); +			t->type = FE_ATSC; +			t->param.u.vsb.modulation = str2qam(qam); +		} else  			error("cannot parse'%s'\n", buf);  	} @@ -1526,7 +1778,33 @@ static int tune_initial (int frontend_fd, const char *initial)  } -static void scan_tp (void) +static void scan_tp_atsc(void) +{ +	struct section_buf s0,s1,s2; + +	if (no_ATSC_PSIP) { +		setup_filter(&s0, demux_devname, 0x00, 0x00, -1, 1, 0, 5); /* PAT */ +		add_filter(&s0); +	} else { +		if (ATSC_type & 0x1) { +			setup_filter(&s0, demux_devname, 0x1ffb, 0xc8, -1, 1, 0, 5); /* terrestrial VCT */ +			add_filter(&s0); +		} +		if (ATSC_type & 0x2) { +			setup_filter(&s1, demux_devname, 0x1ffb, 0xc9, -1, 1, 0, 5); /* cable VCT */ +			add_filter(&s1); +		} +		setup_filter(&s2, demux_devname, 0x00, 0x00, -1, 1, 0, 5); /* PAT */ +		add_filter(&s2); +	} + +	do { +		read_filters (); +	} while (!(list_empty(&running_filters) && +		   list_empty(&waiting_filters))); +} + +static void scan_tp_dvb (void)  {  	struct section_buf s0;  	struct section_buf s1; @@ -1536,21 +1814,21 @@ static void scan_tp (void)  	/**  	 *  filter timeouts > min repetition rates specified in ETR211  	 */ -	setup_filter (&s0, demux_devname, 0x00, 0x00, 1, 0, 5); /* PAT */ -	setup_filter (&s1, demux_devname, 0x11, 0x42, 1, 0, 5); /* SDT */ +	setup_filter (&s0, demux_devname, 0x00, 0x00, -1, 1, 0, 5); /* PAT */ +	setup_filter (&s1, demux_devname, 0x11, 0x42, -1, 1, 0, 5); /* SDT */  	add_filter (&s0);  	add_filter (&s1);  	if (!current_tp_only || output_format != OUTPUT_PIDS) { -		setup_filter (&s2, demux_devname, 0x10, 0x40, 1, 0, 15); /* NIT */ +		setup_filter (&s2, demux_devname, 0x10, 0x40, -1, 1, 0, 15); /* NIT */  		add_filter (&s2);  		if (get_other_nits) {  			/* get NIT-others  			 * Note: There is more than one NIT-other: one per  			 * network, separated by the network_id.  			 */ -			setup_filter (&s3, demux_devname, 0x10, 0x41, 1, 1, 15); +			setup_filter (&s3, demux_devname, 0x10, 0x41, -1, 1, 1, 15);  			add_filter (&s3);  		}  	} @@ -1561,6 +1839,22 @@ static void scan_tp (void)  		   list_empty(&waiting_filters)));  } +static void scan_tp(void) +{ +	switch(fe_info.type) { +		case FE_QPSK: +		case FE_QAM: +		case FE_OFDM: +			scan_tp_dvb(); +			break; +		case FE_ATSC: +			scan_tp_atsc(); +			break; +		default: +			break; +	} +} +  static void scan_network (int frontend_fd, const char *initial)  {  	if (tune_initial (frontend_fd, initial) < 0) { @@ -1616,6 +1910,8 @@ static char sat_polarisation (struct transponder *t)  static int sat_number (struct transponder *t)  { +	(void) t; +  	return switch_pos;  } @@ -1626,9 +1922,12 @@ static void dump_lists (void)  	struct service *s;  	int n = 0, i;  	char sn[20]; +        int anon_services = 0;  	list_for_each(p1, &scanned_transponders) {  		t = list_entry(p1, struct transponder, list); +		if (t->wrong_frequency) +			continue;  		list_for_each(p2, &t->services) {  			n++;  		} @@ -1637,13 +1936,21 @@ static void dump_lists (void)  	list_for_each(p1, &scanned_transponders) {  		t = list_entry(p1, struct transponder, list); +		if (t->wrong_frequency) +			continue;  		list_for_each(p2, &t->services) {  			s = list_entry(p2, struct service, list);  			if (!s->service_name) {  				/* not in SDT */ -				snprintf(sn, sizeof(sn), "[%04x]", s->service_id); +				if (unique_anon_services) +					snprintf(sn, sizeof(sn), "[%03x-%04x]", +						 anon_services, s->service_id); +				else +					snprintf(sn, sizeof(sn), "[%04x]", +						 s->service_id);  				s->service_name = strdup(sn); +				anon_services++;  			}  			/* ':' is field separator in szap and vdr service lists */  			for (i = 0; s->service_name[i]; i++) { @@ -1677,7 +1984,7 @@ static void dump_lists (void)  						    s->video_pid,  						    s->pcr_pid,  						    s->audio_pid, -						    //FIXME: s->audio_lang +						    s->audio_lang,  						    s->audio_num,  						    s->teletext_pid,  						    s->scrambled, @@ -1712,8 +2019,32 @@ static void dump_lists (void)  	info("Done.\n");  } +static void show_existing_tuning_data_files(void) +{ +#ifndef DATADIR +#define DATADIR "/usr/local/share" +#endif +	static const char* prefixlist[] = { DATADIR "/dvb", "/etc/dvb", +					    DATADIR "/doc/packages/dvb", 0 }; +	unsigned int i; +	const char **prefix; +	fprintf(stderr, "initial tuning data files:\n"); +	for (prefix = prefixlist; *prefix; prefix++) { +		glob_t globbuf; +		char* globspec = malloc (strlen(*prefix)+9); +		strcpy (globspec, *prefix); strcat (globspec, "/dvb-?/*"); +		if (! glob (globspec, 0, 0, &globbuf)) { +			for (i=0; i < globbuf.gl_pathc; i++) +				fprintf(stderr, " file: %s\n", globbuf.gl_pathv[i]); +		} +		free (globspec); +		globfree (&globbuf); +	} +} +  static void handle_sigint(int sig)  { +	(void)sig;  	error("interrupted by SIGINT, dumping partial result...\n");  	dump_lists();  	exit(2); @@ -1721,7 +2052,7 @@ static void handle_sigint(int sig)  static const char *usage = "\n"  	"usage: %s [options...] [-c | initial-tuning-data-file]\n" -	"	scan doesn't do frequency scans, hence it needs initial\n" +	"	atsc/dvbscan doesn't do frequency scans, hence it needs initial\n"  	"	tuning data for at least one transponder/channel.\n"  	"	-c	scan on currently tuned transponder only\n"  	"	-v 	verbose (repeat for more)\n" @@ -1743,22 +2074,31 @@ static const char *usage = "\n"  	"	-p	for vdr output format: dump provider name\n"  	"	-e N	VDR version, default 2 for VDR-1.2.x\n"  	"		ANYTHING ELSE GIVES NONZERO NIT and TID\n" +	"		Vdr version 1.3.x and up implies -p.\n"  	"	-l lnb-type (DVB-S Only) (use -l help to print types) or \n"  	"	-l low[,high[,switch]] in Mhz\n" -	"	-u      UK DVB-T Freeview channel numbering for VDR\n"; +	"	-u      UK DVB-T Freeview channel numbering for VDR\n\n" +	"	-P do not use ATSC PSIP tables for scanning\n" +	"	    (but only PAT and PMT) (applies for ATSC only)\n" +	"	-A N	check for ATSC 1=Terrestrial [default], 2=Cable or 3=both\n" +	"	-U	Uniquely name unknown services\n";  void -bad_usage(char *pname, int prlnb) +bad_usage(char *pname, int problem)  { -int i; -struct lnb_types_st *lnbp; -char **cp; +	int i; +	struct lnb_types_st *lnbp; +	char **cp; -	if (!prlnb) { +	switch (problem) { +	default: +	case 0:  		fprintf (stderr, usage, pname); -	} else { +		break; +	case 1:  		i = 0; -		fprintf(stderr, "-l <lnb-type> or -l low[,high[,switch]] in Mhz\nwhere <lnb-type> is:\n"); +		fprintf(stderr, "-l <lnb-type> or -l low[,high[,switch]] in Mhz\n" +			"where <lnb-type> is:\n");  		while(NULL != (lnbp = lnb_enum(i))) {  			fprintf (stderr, "%s\n", lnbp->name);  			for (cp = lnbp->desc; *cp ; cp++) { @@ -1766,6 +2106,10 @@ char **cp;  			}  			i++;  		} +		break; +	case 2: +		show_existing_tuning_data_files(); +		fprintf (stderr, usage, pname);  	}  } @@ -1778,16 +2122,22 @@ int main (int argc, char **argv)  	int fe_open_mode;  	const char *initial = NULL; +	if (argc <= 1) { +	    bad_usage(argv[0], 2); +	    return -1; +	} +  	/* start with default lnb type */  	lnb_type = *lnb_enum(0); -	while ((opt = getopt(argc, argv, "5cnpa:f:d:s:o:x:e:t:i:l:vq:u")) != -1) { +	while ((opt = getopt(argc, argv, "5cnpa:f:d:s:o:x:e:t:i:l:vquPA:U")) != -1) {  		switch (opt) {  		case 'a':  			adapter = strtoul(optarg, NULL, 0);  			break;  		case 'c':  			current_tp_only = 1; -			output_format = OUTPUT_PIDS; +			if (!output_format_set) +				output_format = OUTPUT_PIDS;  			break;  		case 'n':  			get_other_nits = 1; @@ -1812,6 +2162,7 @@ int main (int argc, char **argv)  				bad_usage(argv[0], 0);  				return -1;  			} +			output_format_set = 1;  			break;  		case '5':  			long_timeout = 1; @@ -1844,6 +2195,20 @@ int main (int argc, char **argv)  		case 'u':  			vdr_dump_channum = 1;  			break; +		case 'P': +			no_ATSC_PSIP = 1; +			break; +		case 'A': +			ATSC_type = strtoul(optarg,NULL,0); +			if (ATSC_type == 0 || ATSC_type > 3) { +				bad_usage(argv[0], 1); +				return -1; +			} + +			break; +		case 'U': +			unique_anon_services = 1; +			break;  		default:  			bad_usage(argv[0], 0);  			return -1; diff --git a/util/scan/section.c b/util/scan/section.c new file mode 100644 index 0000000..8e49947 --- /dev/null +++ b/util/scan/section.c @@ -0,0 +1,25 @@ +#include "section.h" + +/* shamelessly stolen from dvbsnoop, but modified */ +u32 getBits (const u8 *buf, int startbit, int bitlen) +{ +	const u8 *b; +	u32 mask,tmp_long; +	int bitHigh,i; + +	b = &buf[startbit / 8]; +	startbit %= 8; + +	bitHigh = 8; +	tmp_long = b[0]; +	for (i = 0; i < ((bitlen-1) >> 3); i++) { +		tmp_long <<= 8; +		tmp_long  |= b[i+1]; +		bitHigh   += 8; +	} + +	startbit = bitHigh - startbit - bitlen; +	tmp_long = tmp_long >> startbit; +	mask     = (1ULL << bitlen) - 1; +	return tmp_long & mask; +} diff --git a/util/scan/section.h b/util/scan/section.h new file mode 100644 index 0000000..88e9570 --- /dev/null +++ b/util/scan/section.h @@ -0,0 +1,14 @@ +#ifndef __SECTION_H__ +#define __SECTION_H__ + +#include <stdio.h> + +#define u8  unsigned char +#define u16 unsigned short +#define u32 unsigned int + +#define PACKED __attribute((packed)) + +u32 getBits (const u8 *buf, int startbit, int bitlen); + +#endif diff --git a/util/szap/Makefile b/util/szap/Makefile index 688c5d7..680793c 100644 --- a/util/szap/Makefile +++ b/util/szap/Makefile @@ -3,8 +3,8 @@ CFLAGS = -MD -Wall -g -O2 -I../../include -I../lib  LFLAGS = -Wall -g -O2  RM = rm -f -TARGETS = szap tzap czap femon -OBJS = szap.o tzap.o czap.o femon.o +TARGETS = szap tzap czap azap femon +OBJS = szap.o tzap.o czap.o azap.o femon.o  all: $(OBJS) $(TARGETS)  	@echo diff --git a/util/szap/azap.c b/util/szap/azap.c new file mode 100644 index 0000000..14a1c6a --- /dev/null +++ b/util/szap/azap.c @@ -0,0 +1,392 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include <fcntl.h> +#include <ctype.h> +#include <errno.h> + +#include <linux/dvb/frontend.h> +#include <linux/dvb/dmx.h> + +static char FRONTEND_DEV [80]; +static char DEMUX_DEV [80]; + +#define CHANNEL_FILE "/.azap/channels.conf" + +#define ERROR(x...)                                                     \ +        do {                                                            \ +                fprintf(stderr, "ERROR: ");                             \ +                fprintf(stderr, x);                                     \ +                fprintf (stderr, "\n");                                 \ +        } while (0) + +#define PERROR(x...)                                                    \ +        do {                                                            \ +                fprintf(stderr, "ERROR: ");                             \ +                fprintf(stderr, x);                                     \ +                fprintf (stderr, " (%s)\n", strerror(errno));		\ +        } while (0) + + +typedef struct { +	char *name; +	int value; +} Param; + +static const Param modulation_list [] = { +	{ "8VSB", VSB_8 }, +	{ "16VSB", VSB_16 }, +	{ "QAM_64", QAM_64 }, +	{ "QAM_256", QAM_256 }, +}; + +#define LIST_SIZE(x) sizeof(x)/sizeof(Param) + + +static +int parse_param (int fd, const Param * plist, int list_size, int *param) +{ +	char c; +	int character = 0; +	int _index = 0; + +	while (1) { +		if (read(fd, &c, 1) < 1) +			return -1;	/*  EOF? */ + +		if ((c == ':' || c == '\n') +		    && plist->name[character] == '\0') +			break; + +		while (toupper(c) != plist->name[character]) { +			_index++; +			plist++; +			if (_index >= list_size)	 /*  parse error, no valid */ +				return -2;	 /*  parameter name found  */ +		} + +		character++; +	} + +	*param = plist->value; + +	return 0; +} + + +static +int parse_int(int fd, int *val) +{ +	char number[11];	/* 2^32 needs 10 digits... */ +	int character = 0; + +	while (1) { +		if (read(fd, &number[character], 1) < 1) +			return -1;	/*  EOF? */ + +		if (number[character] == ':' || number[character] == '\n') { +			number[character] = '\0'; +			break; +		} + +		if (!isdigit(number[character])) +			return -2;	/*  parse error, not a digit... */ + +		character++; + +		if (character > 10)	/*  overflow, number too big */ +			return -3;	/*  to fit in 32 bit */ +	}; + +	*val = strtol(number, NULL, 10); + +	return 0; +} + + +static +int find_channel(int fd, const char *channel) +{ +	int character = 0; + +	while (1) { +		char c; + +		if (read(fd, &c, 1) < 1) +			return -1;	/*  EOF! */ + +		if (c == ':' && channel[character] == '\0') +			break; + +		if (toupper(c) == toupper(channel[character])) +			character++; +		else +			character = 0; +	}; + +	return 0; +} + + +static +int try_parse_int(int fd, int *val, const char *pname) +{ +	int err; + +	err = parse_int(fd, val); + +	if (err) +		ERROR("error while parsing %s (%s)", pname, +		      err == -1 ? "end of file" : +		      err == -2 ? "not a number" : "number too big"); + +	return err; +} + + +static +int try_parse_param(int fd, const Param * plist, int list_size, int *param, +		    const char *pname) +{ +	int err; + +	err = parse_param(fd, plist, list_size, param); + +	if (err) +		ERROR("error while parsing %s (%s)", pname, +		      err == -1 ? "end of file" : "syntax error"); + +	return err; +} + + +int parse(const char *fname, const char *channel, +	  struct dvb_frontend_parameters *frontend, int *vpid, int *apid) +{ +	int fd; +	int err; +	int tmp; + +	if ((fd = open(fname, O_RDONLY | O_NONBLOCK)) < 0) { +		PERROR ("could not open file '%s'", fname); +		perror (""); +		return -1; +	} + +	if (find_channel(fd, channel) < 0) { +		ERROR("could not find channel '%s' in channel list", channel); +		return -2; +	} + +	if ((err = try_parse_int(fd, &tmp, "frequency"))) +		return -3; +	frontend->frequency = tmp; + +	if ((err = try_parse_param(fd, +				   modulation_list, LIST_SIZE(modulation_list), +				   (int *) &frontend->u.vsb.modulation, +				   "modulation"))) +		return -4; + +	if ((err = try_parse_int(fd, vpid, "Video PID"))) +		return -5; + +	if ((err = try_parse_int(fd, apid, "Audio PID"))) +		return -6; + +	close(fd); + +	return 0; +} + + +static +int set_pesfilter (int fd, int pid, dmx_pes_type_t type, int dvr) +{ +        struct dmx_pes_filter_params pesfilter; + +        if (pid <= 0 || pid >= 0x1fff) +                return 0; + +        pesfilter.pid = pid; +        pesfilter.input = DMX_IN_FRONTEND; +        pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER; +        pesfilter.pes_type = type; +        pesfilter.flags = DMX_IMMEDIATE_START; + +        if (ioctl(fd, DMX_SET_PES_FILTER, &pesfilter) < 0) { +                PERROR ("ioctl(DMX_SET_PES_FILTER) for %s PID failed", +                        type == DMX_PES_AUDIO ? "Audio" : +                        type == DMX_PES_VIDEO ? "Video" : "??"); +                return -1; +        } + +        return 0; +} + + +static +int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend) +{ +	struct dvb_frontend_info fe_info; + +	if (ioctl(fe_fd, FE_GET_INFO, &fe_info) < 0) { +		PERROR("ioctl FE_GET_INFO failed"); +		return -1; +	} + +	if (fe_info.type != FE_ATSC) { +		ERROR ("frontend device is not an ATSC (VSB/QAM) device"); +		return -1; +	} + +	printf ("tuning to %i Hz\n", frontend->frequency); + +	if (ioctl(fe_fd, FE_SET_FRONTEND, frontend) < 0) { +		PERROR("ioctl FE_SET_FRONTEND failed"); +		return -1; +	} + +	return 0; +} + + +static +int check_frontend (int fe_fd) +{ +	fe_status_t status; +	uint16_t snr, signal; +	uint32_t ber, uncorrected_blocks; + +	do { +		ioctl(fe_fd, FE_READ_STATUS, &status); +		ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &signal); +		ioctl(fe_fd, FE_READ_SNR, &snr); +		ioctl(fe_fd, FE_READ_BER, &ber); +		ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks); + +		printf ("status %02x | signal %04x | snr %04x | " +			"ber %08x | unc %08x | ", +			status, signal, snr, ber, uncorrected_blocks); + +		if (status & FE_HAS_LOCK) +			printf("FE_HAS_LOCK"); + +		usleep(1000000); + +		printf("\n"); +	} while (1); + +	return 0; +} + + +static const char *usage = "\nusage: %s [-a adapter_num] [-f frontend_id] [-d demux_id] [-c conf_file] [-r] <channel name>\n\n"; + + +int main(int argc, char **argv) +{ +	struct dvb_frontend_parameters frontend_param; +	char *homedir = getenv ("HOME"); +	char *confname = NULL; +	char *channel = NULL; +	int adapter = 0, frontend = 0, demux = 0, dvr = 0; +	int vpid, apid; +	int frontend_fd, audio_fd, video_fd; +	int opt; + +	while ((opt = getopt(argc, argv, "hrn:a:f:d:c:")) != -1) { +		switch (opt) { +		case 'a': +			adapter = strtoul(optarg, NULL, 0); +			break; +		case 'f': +			frontend = strtoul(optarg, NULL, 0); +			break; +		case 'd': +			demux = strtoul(optarg, NULL, 0); +			break; +		case 'r': +			dvr = 1; +			break; +		case 'c': +			confname = optarg; +			break; +		case '?': +		case 'h': +		default: +			fprintf (stderr, usage, argv[0]); +			return -1; +		}; +	} + +	if (optind < argc) +		channel = argv[optind]; + +	if (!channel) { +		fprintf (stderr, usage, argv[0]); +		return -1; +	} + +	snprintf (FRONTEND_DEV, sizeof(FRONTEND_DEV), +		  "/dev/dvb/adapter%i/frontend%i", adapter, frontend); + +	snprintf (DEMUX_DEV, sizeof(DEMUX_DEV), +		  "/dev/dvb/adapter%i/demux%i", adapter, demux); + +	printf ("using '%s' and '%s'\n", FRONTEND_DEV, DEMUX_DEV); + +	if (!confname) +	{ +		if (!homedir) +			ERROR ("$HOME not set"); +		confname = malloc (strlen(homedir) + strlen(CHANNEL_FILE) + 1); +		memcpy (confname, homedir, strlen(homedir)); +		memcpy (confname + strlen(homedir), CHANNEL_FILE, +	        	strlen(CHANNEL_FILE) + 1); +	} + +	memset(&frontend_param, 0, sizeof(struct dvb_frontend_parameters)); + +	if (parse (confname, channel, &frontend_param, &vpid, &apid)) +		return -1; + +	if ((frontend_fd = open(FRONTEND_DEV, O_RDWR)) < 0) { +		PERROR ("failed opening '%s'", FRONTEND_DEV); +		return -1; +	} + +	if (setup_frontend (frontend_fd, &frontend_param) < 0) +		return -1; + +        if ((video_fd = open(DEMUX_DEV, O_RDWR)) < 0) { +                PERROR("failed opening '%s'", DEMUX_DEV); +                return -1; +        } + +	printf ("video pid 0x%04x, audio pid 0x%04x\n", vpid, apid); +	if (set_pesfilter (video_fd, vpid, DMX_PES_VIDEO, dvr) < 0) +		return -1; + +	if ((audio_fd = open(DEMUX_DEV, O_RDWR)) < 0) { +                PERROR("failed opening '%s'", DEMUX_DEV); +                return -1; +        } + +	if (set_pesfilter (audio_fd, apid, DMX_PES_AUDIO, dvr) < 0) +		return -1; + +	check_frontend (frontend_fd); + +	close (audio_fd); +	close (video_fd); +	close (frontend_fd); + +	return 0; +} + | 
