summaryrefslogtreecommitdiff
path: root/Tools/statdvb2vdr/ch.pl
blob: 91e918d2761ecf0820e301779584517f0e0a5d91 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#!/usr/bin/perl

# Reads the file statdvb.dat produced by the Siemens windows 
# software (1.50), which contains the scanned channels of an
# DVB-C (-S). The file ist located in the windows directory.
#
# Output is suitable for VDR (channels.conf). Only tested for
# the cable version. Should work with slight modifications for
# the sat version.
#
# 8. März 2001 - Hans-Peter Raschke


# file structure derived from "DvbGlobalDef.h" of the Siemens
# DVB kit.

# typedef int TABLETYPE;
# enum TunStandard
# {
# 	PAL_BG,     //B/G stereo or mono
# 	PAL_I,      //I mono (with Nicam stereo)
# 	PAL_DK,     //D/K mono
# 	SECAM_L,    //L mono (with Nicam stereo)
# 	SECAM_LI,	//Secam L’ (with Nicam stereo)
# 	SECAM_DK,
# 	SECAM_BG,
# 	NTSC_M,
# 	DVB_C,
# 	DVB_S,
# 	DVB_T
# };
# 
# typedef struct TunProgDataTag //xx bytes+1string
# {
# 	int 	nNumber;				//logical number of the program
# 	DWORD   dwFrequency;				//frequency in khz
# 	CString 	csName;				//name of the program
# 	TunStandard	eStandard;			//standard of the program
# 	DWORD	dwExtraInfo;				//specific info, like teletext,reserved data
# 							//0x8 == external input 1-CVBS
# 							//0x10 == external input 2-Y/C
# 							//0x20 == scrambled Program stream
# 							//0x40 == ASTRA Sattable
# 							//0x80 == Eutelsat Sattable
# 							//0xC0 == Sattable from File
# 							//0x100 == Pulsed switch to other satellite dish
# 							//0x1000-0xF000 = Other Satellite Nr(if Sattable from File)
# //Digital only params beginning from here
# 	WORD ProgNr;					//DVB Nr for the prog (PAS related)
# 	WORD wTS_ID;					//Transport-Stream ID orig.
# 	WORD wNW_ID;					//Network ID orig.
# 	WORD wService_ID;				//Service /Programm Id
# 	BYTE nModulation;				//Modulation-Type QAM,QPSK,other
# 	BYTE nFEC_outerinner;				//outer(high nibble) and inner(low n.)
# 	DWORD dwSymbolrate;				//in symbol/s
# 	BOOL b22kHz;					//east or west(TRUE) position in Sat
# 	BOOL bVertical_pos;				//horizontal or vertical(TRUE) position in SAT
# 	BYTE nProgtype;					//type of service (e.g. tv, radio)
# 	WORD wVideo_PID;				//video-pid of the channel
# 	WORD wAudio_PID;				//audio-pid of the channel
# 	WORD wPMT_PID;					//PID of the associated PMT
# 	WORD wTxt_PID;					//teletext PID for the program
# 	WORD wSubtitling_PID;				//subtitling PID for the program
# 	WORD wData_PID;					//PID for data broadcast
# 	BYTE nIPFilter;					//filter for different ip's
# 	DWORD dwReserved1;				//Shows some extended Information LOWORD=DataBroadcast_Id, 
# 							//MSB showing Databroadcast, (HIWORD & 0xFF)=ComponentTag from the stream ident desc
# 	DWORD dwReserved2;				//reserved dword
# }DVBTunProgData;
# 

use strict;
use FileHandle;

# for a full dump
my @varNames	= ("nNumber",			# logical number of the program 
                   "dwFrequency",		# frequency in khz
	           "csName",			# name of the program
	           "eStandard",			# standard of the program
	  	   "dwExtraInfo",		# specific info, like teletext,reserved data
						# 0x8 == external input 1-CVBS
						# 0x10 == external input 2-Y/C
						# 0x20 == scrambled Program stream
						# 0x40 == ASTRA Sattable
						# 0x80 == Eutelsat Sattable
						# 0xC0 == Sattable from File
						# 0x100 == Pulsed switch to other satellite dish
						# 0x1000-0xF000 = Other Satellite Nr(if Sattable from File)
	           "ProgNr",			# DVB Nr for the prog (PAS related)
	           "wTS_ID",			# Transport-Stream ID orig.
	           "wNW_ID",			# Network ID orig.
	           "wService_ID",		# Service /Programm Id
	           "nModulation",		# Modulation-Type QAM,QPSK,other
	           "nFEC_outerinner",		# outer(high nibble) and inner(low n.)
	           "dwSymbolrate",		# in symbol/s
	           "b22kHz",			# east or west(TRUE) position in Sat
	           "bVertical_pos",		# horizontal or vertical(TRUE) position in SAT
	           "nProgtype",			# type of service (e.g. tv, radio)
	           "wVideo_PID",		# video-pid of the channel
	           "wAudio_PID",		# audio-pid of the channel
	           "wPMT_PID",			# PID of the associated PMT
	           "wTxt_PID",			# teletext PID for the program
	           "wSubtitling_PID",	  	# subtitling PID for the program
	           "wData_PID");		# PID for data broadcast

my @outVar = ("csName", 
              "dwFrequency", 
	      "bVertical_pos", 
	      "b22kHz", 
	      "dwSymbolrate",
	      "wVideo_PID",
	      "wAudio_PID",
	      "wTxt_PID",
	      "dwExtraInfo",
	      "ProgNr");

# channels that need a valid smartcard
my @addCrypted = ("Extreme Sport",
                  "Bloomberg",
                  "Fashion TV",
                  "BET ON JAZZ",
                  "LANDSCAPE",
                  "Einstein",
                  "Single TV");
	      
my @chNames	= ();				# list of scanned channels
my $camNo	= 1;				# number of CI/CAM to use
my %chData;					# all channel data
my $buff;					# input buffer
my $fh		= new FileHandle("$ARGV[0]")	or die "Datei $ARGV[0] nicht gefunden!";

binmode($fh);					# could be run on windows
$fh->seek(4, 0);				# skip id

my $chCnt	= 0;
while (!$fh->eof()) {
  $chCnt++;

  last 					if ($fh->read($buff, 7) != 7);
  my ($nNumber, 
      $dwFrequency,
      $sLen
     )		= unpack("SLC", $buff);
  
  last 					if ($fh->read($buff, $sLen) != $sLen);
  my ($csName)	= unpack("A$sLen", $buff);
  $csName	=~ s/:/./g;
  $csName	=~ s/^\s+//;
  $csName	=~ s/\s+$//;

  last 					if ($fh->read($buff, 54) != 54);
  my ($eStandard,
      $dwExtraInfo,
      $ProgNr,
      $wTS_ID,
      $wNW_ID,
      $wService_ID,
      $nModulation,
      $nFEC_outerinner,
      $dwSymbolrate,
      $b22kHz,
      $bVertical_pos,
      $nProgtype,
      $wVideo_PID,
      $wAudio_PID,
      $wPMT_PID,
      $wTxt_PID,
      $wSubtitling_PID,
      $wData_PID
     )		= unpack("LLSSSSCCLLLCSSSSSS", $buff);

  # some modifications for VDR  
  $dwFrequency 	 /= 1000;
  $bVertical_pos = $bVertical_pos ? "v" : "h";
  $dwSymbolrate	 /= 1000;
  $dwExtraInfo	 = ($dwExtraInfo == 32 || grep(($_ cmp $csName) == 0, @addCrypted)) ? $camNo : 0;

  my $x		= 1;
  my $orgName	= $csName;
  while (exists($chData{$csName})) {
    $csName	 = "$orgName" . "_$x";
    $x++;
  }
  push(@chNames, $csName);

  my %tmp = ("nNumber"		=> $nNumber,			
             "dwFrequency"	=> $dwFrequency,		
	     "csName"		=> $orgName,			
	     "eStandard"	=> $eStandard,			
	     "dwExtraInfo"	=> $dwExtraInfo,		
	     "ProgNr"		=> $ProgNr,			
	     "wTS_ID"		=> $wTS_ID,			
	     "wNW_ID"		=> $wNW_ID,			
	     "wService_ID"	=> $wService_ID,		
	     "nModulation"	=> $nModulation,		
	     "nFEC_outerinner"	=> $nFEC_outerinner,		
	     "dwSymbolrate"	=> $dwSymbolrate,		
	     "b22kHz"		=> $b22kHz,			
	     "bVertical_pos"	=> $bVertical_pos,		
	     "nProgtype"	=> $nProgtype,			
	     "wVideo_PID"	=> $wVideo_PID,		
	     "wAudio_PID"	=> $wAudio_PID,		
	     "wPMT_PID"		=> $wPMT_PID,			
	     "wTxt_PID"		=> $wTxt_PID,			
	     "wSubtitling_PID"	=> $wSubtitling_PID,	  	
	     "wData_PID"	=> $wData_PID);		
  $chData{$csName}	= {%tmp};
}

print STDERR "$chCnt channels found!\n";

# now we print the channels.conf	      
# crypted TV
print ":verschlüsselte Fernsehprogramme\n";
for my $n (@chNames) {
  my %tmp	= %{$chData{$n}};
  printChannel($chData{$n})		if ($tmp{"nProgtype"} == 1 && $tmp{"dwExtraInfo"});
}

# TV
print ":Fernsehprogramme\n";
for my $n (@chNames) {
  my %tmp	= %{$chData{$n}};
  printChannel($chData{$n})		if ($tmp{"nProgtype"} == 1 && !$tmp{"dwExtraInfo"});
}

# crypted radio
print ":verschlüsselte Radioprogramme\n";
for my $n (@chNames) {
  my %tmp	= %{$chData{$n}};
  printChannel($chData{$n})		if ($tmp{"nProgtype"} == 2 && $tmp{"dwExtraInfo"});
}

# radio
print ":Radioprogramme\n";
for my $n (@chNames) {
  my %tmp	= %{$chData{$n}};
  printChannel($chData{$n})		if ($tmp{"nProgtype"} == 2 && !$tmp{"dwExtraInfo"});
}

sub printChannel {
  my $p		= shift;
  my @tmp	= ();

  for my $n (@outVar) {
    push(@tmp, ${$p}{$n});
  }
  
  print join(":", @tmp), "\n";
}