Back to home page

LXR

 
 

    


0001 #!/usr/bin/perl
0002 #     DVB firmware extractor
0003 #
0004 #     (c) 2004 Andrew de Quincey
0005 #
0006 #     This program is free software; you can redistribute it and/or modify
0007 #       it under the terms of the GNU General Public License as published by
0008 #       the Free Software Foundation; either version 2 of the License, or
0009 #       (at your option) any later version.
0010 #
0011 #     This program is distributed in the hope that it will be useful,
0012 #       but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 #       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 #
0015 #     GNU General Public License for more details.
0016 #
0017 #     You should have received a copy of the GNU General Public License
0018 #       along with this program; if not, write to the Free Software
0019 #       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
0020 
0021 use File::Temp qw/ tempdir /;
0022 use IO::Handle;
0023 
0024 @components = ( "sp8870", "sp887x", "tda10045", "tda10046",
0025         "tda10046lifeview", "av7110", "dec2000t", "dec2540t",
0026         "dec3000s", "vp7041", "vp7049", "dibusb", "nxt2002", "nxt2004",
0027         "or51211", "or51132_qam", "or51132_vsb", "bluebird",
0028         "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
0029         "af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
0030         "lme2510c_s7395_old", "drxk", "drxk_terratec_h5",
0031         "drxk_hauppauge_hvr930c", "tda10071", "it9135", "drxk_pctv",
0032         "drxk_terratec_htc_stick", "sms1xxx_hcw", "si2165");
0033 
0034 # Check args
0035 syntax() if (scalar(@ARGV) != 1);
0036 $cid = $ARGV[0];
0037 
0038 # Do it!
0039 for ($i=0; $i < scalar(@components); $i++) {
0040     if ($cid eq $components[$i]) {
0041     $outfile = eval($cid);
0042     die $@ if $@;
0043     print STDERR <<EOF;
0044 Firmware(s) $outfile extracted successfully.
0045 Now copy it(them) to either /usr/lib/hotplug/firmware or /lib/firmware
0046 (depending on configuration of firmware hotplug).
0047 EOF
0048     exit(0);
0049     }
0050 }
0051 
0052 # If we get here, it wasn't found
0053 print STDERR "Unknown component \"$cid\"\n";
0054 syntax();
0055 
0056 
0057 
0058 
0059 # ---------------------------------------------------------------
0060 # Firmware-specific extraction subroutines
0061 
0062 sub sp8870 {
0063     my $sourcefile = "tt_Premium_217g.zip";
0064     my $url = "http://www.softwarepatch.pl/9999ccd06a4813cb827dbb0005071c71/$sourcefile";
0065     my $hash = "53970ec17a538945a6d8cb608a7b3899";
0066     my $outfile = "dvb-fe-sp8870.fw";
0067     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0068 
0069     checkstandard();
0070 
0071     wgetfile($sourcefile, $url);
0072     unzip($sourcefile, $tmpdir);
0073     verify("$tmpdir/software/OEM/HE/App/boot/SC_MAIN.MC", $hash);
0074     copy("$tmpdir/software/OEM/HE/App/boot/SC_MAIN.MC", $outfile);
0075 
0076     $outfile;
0077 }
0078 
0079 sub sp887x {
0080     my $sourcefile = "Dvbt1.3.57.6.zip";
0081     my $url = "http://www.avermedia.com/software/$sourcefile";
0082     my $cabfile = "DVBT Net  Ver1.3.57.6/disk1/data1.cab";
0083     my $hash = "237938d53a7f834c05c42b894ca68ac3";
0084     my $outfile = "dvb-fe-sp887x.fw";
0085     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0086 
0087     checkstandard();
0088     checkunshield();
0089 
0090     wgetfile($sourcefile, $url);
0091     unzip($sourcefile, $tmpdir);
0092     unshield("$tmpdir/$cabfile", $tmpdir);
0093     verify("$tmpdir/ZEnglish/sc_main.mc", $hash);
0094     copy("$tmpdir/ZEnglish/sc_main.mc", $outfile);
0095 
0096     $outfile;
0097 }
0098 
0099 sub tda10045 {
0100     my $sourcefile = "tt_budget_217g.zip";
0101     my $url = "http://www.technotrend.de/new/217g/$sourcefile";
0102     my $hash = "2105fd5bf37842fbcdfa4bfd58f3594a";
0103     my $outfile = "dvb-fe-tda10045.fw";
0104     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0105 
0106     checkstandard();
0107 
0108     wgetfile($sourcefile, $url);
0109     unzip($sourcefile, $tmpdir);
0110     extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x37ef9, 30555, "$tmpdir/fwtmp");
0111     verify("$tmpdir/fwtmp", $hash);
0112     copy("$tmpdir/fwtmp", $outfile);
0113 
0114     $outfile;
0115 }
0116 
0117 sub tda10046 {
0118     my $sourcefile = "TT_PCI_2.19h_28_11_2006.zip";
0119     my $url = "http://technotrend.com.ua/download/software/219/$sourcefile";
0120     my $hash = "6a7e1e2f2644b162ff0502367553c72d";
0121     my $outfile = "dvb-fe-tda10046.fw";
0122     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0123 
0124     checkstandard();
0125 
0126     wgetfile($sourcefile, $url);
0127     unzip($sourcefile, $tmpdir);
0128     extract("$tmpdir/TT_PCI_2.19h_28_11_2006/software/OEM/PCI/App/ttlcdacc.dll", 0x65389, 24478, "$tmpdir/fwtmp");
0129     verify("$tmpdir/fwtmp", $hash);
0130     copy("$tmpdir/fwtmp", $outfile);
0131 
0132     $outfile;
0133 }
0134 
0135 sub tda10046lifeview {
0136     my $sourcefile = "7%5Cdrv_2.11.02.zip";
0137     my $url = "http://www.lifeview.hk/dbimages/document/$sourcefile";
0138     my $hash = "1ea24dee4eea8fe971686981f34fd2e0";
0139     my $outfile = "dvb-fe-tda10046.fw";
0140     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0141 
0142     checkstandard();
0143 
0144     wgetfile($sourcefile, $url);
0145     unzip($sourcefile, $tmpdir);
0146     extract("$tmpdir/LVHybrid.sys", 0x8b088, 24602, "$tmpdir/fwtmp");
0147     verify("$tmpdir/fwtmp", $hash);
0148     copy("$tmpdir/fwtmp", $outfile);
0149 
0150     $outfile;
0151 }
0152 
0153 sub av7110 {
0154     my $sourcefile = "dvb-ttpci-01.fw-261d";
0155     my $url = "https://linuxtv.org/downloads/firmware/$sourcefile";
0156     my $hash = "603431b6259715a8e88f376a53b64e2f";
0157     my $outfile = "dvb-ttpci-01.fw";
0158 
0159     checkstandard();
0160 
0161     wgetfile($sourcefile, $url);
0162     verify($sourcefile, $hash);
0163     copy($sourcefile, $outfile);
0164 
0165     $outfile;
0166 }
0167 
0168 sub dec2000t {
0169     my $sourcefile = "dec217g.exe";
0170     my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
0171     my $hash = "bd86f458cee4a8f0a8ce2d20c66215a9";
0172     my $outfile = "dvb-ttusb-dec-2000t.fw";
0173     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0174 
0175     checkstandard();
0176 
0177     wgetfile($sourcefile, $url);
0178     unzip($sourcefile, $tmpdir);
0179     verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_T.bin", $hash);
0180     copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_T.bin", $outfile);
0181 
0182     $outfile;
0183 }
0184 
0185 sub dec2540t {
0186     my $sourcefile = "dec217g.exe";
0187     my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
0188     my $hash = "53e58f4f5b5c2930beee74a7681fed92";
0189     my $outfile = "dvb-ttusb-dec-2540t.fw";
0190     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0191 
0192     checkstandard();
0193 
0194     wgetfile($sourcefile, $url);
0195     unzip($sourcefile, $tmpdir);
0196     verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_X.bin", $hash);
0197     copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_X.bin", $outfile);
0198 
0199     $outfile;
0200 }
0201 
0202 sub dec3000s {
0203     my $sourcefile = "dec217g.exe";
0204     my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
0205     my $hash = "b013ececea83f4d6d8d2a29ac7c1b448";
0206     my $outfile = "dvb-ttusb-dec-3000s.fw";
0207     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0208 
0209     checkstandard();
0210 
0211     wgetfile($sourcefile, $url);
0212     unzip($sourcefile, $tmpdir);
0213     verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_S.bin", $hash);
0214     copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_S.bin", $outfile);
0215 
0216     $outfile;
0217 }
0218 sub opera1{
0219     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 0);
0220 
0221     checkstandard();
0222     my $fwfile1="dvb-usb-opera1-fpga-01.fw";
0223     my $fwfile2="dvb-usb-opera-01.fw";
0224     extract("2830SCap2.sys", 0x62e8, 55024, "$tmpdir/opera1-fpga.fw");
0225     extract("2830SLoad2.sys",0x3178,0x3685-0x3178,"$tmpdir/fw1part1");
0226     extract("2830SLoad2.sys",0x0980,0x3150-0x0980,"$tmpdir/fw1part2");
0227     delzero("$tmpdir/fw1part1","$tmpdir/fw1part1-1");
0228     delzero("$tmpdir/fw1part2","$tmpdir/fw1part2-1");
0229     verify("$tmpdir/fw1part1-1","5e0909858fdf0b5b09ad48b9fe622e70");
0230     verify("$tmpdir/fw1part2-1","d6e146f321427e931df2c6fcadac37a1");
0231     verify("$tmpdir/opera1-fpga.fw","0f8133f5e9051f5f3c1928f7e5a1b07d");
0232 
0233     my $RES1="\x01\x92\x7f\x00\x01\x00";
0234     my $RES0="\x01\x92\x7f\x00\x00\x00";
0235     my $DAT1="\x01\x00\xe6\x00\x01\x00";
0236     my $DAT0="\x01\x00\xe6\x00\x00\x00";
0237     open FW,">$tmpdir/opera.fw";
0238     print FW "$RES1";
0239     print FW "$DAT1";
0240     print FW "$RES1";
0241     print FW "$DAT1";
0242     appendfile(FW,"$tmpdir/fw1part1-1");
0243     print FW "$RES0";
0244     print FW "$DAT0";
0245     print FW "$RES1";
0246     print FW "$DAT1";
0247     appendfile(FW,"$tmpdir/fw1part2-1");
0248     print FW "$RES1";
0249     print FW "$DAT1";
0250     print FW "$RES0";
0251     print FW "$DAT0";
0252     copy ("$tmpdir/opera1-fpga.fw",$fwfile1);
0253     copy ("$tmpdir/opera.fw",$fwfile2);
0254 
0255     $fwfile1.",".$fwfile2;
0256 }
0257 
0258 sub vp7041 {
0259     my $sourcefile = "2.422.zip";
0260     my $url = "http://www.twinhan.com/files/driver/USB-Ter/$sourcefile";
0261     my $hash = "e88c9372d1f66609a3e7b072c53fbcfe";
0262     my $outfile = "dvb-vp7041-2.422.fw";
0263     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0264 
0265     checkstandard();
0266 
0267     wgetfile($sourcefile, $url);
0268     unzip($sourcefile, $tmpdir);
0269     extract("$tmpdir/VisionDTV/Drivers/Win2K&XP/UDTTload.sys", 12503, 3036, "$tmpdir/fwtmp1");
0270     extract("$tmpdir/VisionDTV/Drivers/Win2K&XP/UDTTload.sys", 2207, 10274, "$tmpdir/fwtmp2");
0271 
0272     my $CMD = "\000\001\000\222\177\000";
0273     my $PAD = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";
0274     my ($FW);
0275     open $FW, ">$tmpdir/fwtmp3";
0276     print $FW "$CMD\001$PAD";
0277     print $FW "$CMD\001$PAD";
0278     appendfile($FW, "$tmpdir/fwtmp1");
0279     print $FW "$CMD\000$PAD";
0280     print $FW "$CMD\001$PAD";
0281     appendfile($FW, "$tmpdir/fwtmp2");
0282     print $FW "$CMD\001$PAD";
0283     print $FW "$CMD\000$PAD";
0284     close($FW);
0285 
0286     verify("$tmpdir/fwtmp3", $hash);
0287     copy("$tmpdir/fwtmp3", $outfile);
0288 
0289     $outfile;
0290 }
0291 
0292 sub vp7049 {
0293     my $fwfile = "dvb-usb-vp7049-0.95.fw";
0294     my $url = "http://ao2.it/sites/default/files/blog/2012/11/06/linux-support-digicom-digitune-s-vp7049-udtt7049/$fwfile";
0295     my $hash = "5609fd295168aea88b25ff43a6f79c36";
0296 
0297     checkstandard();
0298 
0299     wgetfile($fwfile, $url);
0300     verify($fwfile, $hash);
0301 
0302     $fwfile;
0303 }
0304 
0305 sub dibusb {
0306     my $url = "https://linuxtv.org/downloads/firmware/dvb-usb-dibusb-5.0.0.11.fw";
0307     my $outfile = "dvb-dibusb-5.0.0.11.fw";
0308     my $hash = "fa490295a527360ca16dcdf3224ca243";
0309 
0310     checkstandard();
0311 
0312     wgetfile($outfile, $url);
0313     verify($outfile,$hash);
0314 
0315     $outfile;
0316 }
0317 
0318 sub nxt2002 {
0319     my $sourcefile = "Technisat_DVB-PC_4_4_COMPACT.zip";
0320     my $url = "http://www.bbti.us/download/windows/$sourcefile";
0321     my $hash = "476befae8c7c1bb9648954060b1eec1f";
0322     my $outfile = "dvb-fe-nxt2002.fw";
0323     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0324 
0325     checkstandard();
0326 
0327     wgetfile($sourcefile, $url);
0328     unzip($sourcefile, $tmpdir);
0329     verify("$tmpdir/SkyNET.sys", $hash);
0330     extract("$tmpdir/SkyNET.sys", 331624, 5908, $outfile);
0331 
0332     $outfile;
0333 }
0334 
0335 sub nxt2004 {
0336     my $sourcefile = "AVerTVHD_MCE_A180_Drv_v1.2.2.16.zip";
0337     my $url = "http://www.avermedia-usa.com/support/Drivers/$sourcefile";
0338     my $hash = "111cb885b1e009188346d72acfed024c";
0339     my $outfile = "dvb-fe-nxt2004.fw";
0340     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0341 
0342     checkstandard();
0343 
0344     wgetfile($sourcefile, $url);
0345     unzip($sourcefile, $tmpdir);
0346     verify("$tmpdir/3xHybrid.sys", $hash);
0347     extract("$tmpdir/3xHybrid.sys", 465304, 9584, $outfile);
0348 
0349     $outfile;
0350 }
0351 
0352 sub or51211 {
0353     my $fwfile = "dvb-fe-or51211.fw";
0354     my $url = "https://linuxtv.org/downloads/firmware/$fwfile";
0355     my $hash = "d830949c771a289505bf9eafc225d491";
0356 
0357     checkstandard();
0358 
0359     wgetfile($fwfile, $url);
0360     verify($fwfile, $hash);
0361 
0362     $fwfile;
0363 }
0364 
0365 sub cx231xx {
0366     my $fwfile = "v4l-cx231xx-avcore-01.fw";
0367     my $url = "https://linuxtv.org/downloads/firmware/$fwfile";
0368     my $hash = "7d3bb956dc9df0eafded2b56ba57cc42";
0369 
0370     checkstandard();
0371 
0372     wgetfile($fwfile, $url);
0373     verify($fwfile, $hash);
0374 
0375     $fwfile;
0376 }
0377 
0378 sub cx18 {
0379     my $url = "https://linuxtv.org/downloads/firmware/";
0380 
0381     my %files = (
0382     'v4l-cx23418-apu.fw' => '588f081b562f5c653a3db1ad8f65939a',
0383     'v4l-cx23418-cpu.fw' => 'b6c7ed64bc44b1a6e0840adaeac39d79',
0384     'v4l-cx23418-dig.fw' => '95bc688d3e7599fd5800161e9971cc55',
0385     );
0386 
0387     checkstandard();
0388 
0389     my $allfiles;
0390     foreach my $fwfile (keys %files) {
0391     wgetfile($fwfile, "$url/$fwfile");
0392     verify($fwfile, $files{$fwfile});
0393     $allfiles .= " $fwfile";
0394     }
0395 
0396     $allfiles =~ s/^\s//;
0397 
0398     $allfiles;
0399 }
0400 
0401 sub mpc718 {
0402     my $archive = 'Yuan MPC718 TV Tuner Card 2.13.10.1016.zip';
0403     my $url = "ftp://ftp.work.acer-euro.com/desktop/aspire_idea510/vista/Drivers/$archive";
0404     my $fwfile = "dvb-cx18-mpc718-mt352.fw";
0405     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0406 
0407     checkstandard();
0408     wgetfile($archive, $url);
0409     unzip($archive, $tmpdir);
0410 
0411     my $sourcefile = "$tmpdir/Yuan MPC718 TV Tuner Card 2.13.10.1016/mpc718_32bit/yuanrap.sys";
0412     my $found = 0;
0413 
0414     open IN, '<', $sourcefile or die "Couldn't open $sourcefile to extract $fwfile data\n";
0415     binmode IN;
0416     open OUT, '>', $fwfile;
0417     binmode OUT;
0418     {
0419     # Block scope because we change the line terminator variable $/
0420     my $prevlen = 0;
0421     my $currlen;
0422 
0423     # Buried in the data segment are 3 runs of almost identical
0424     # register-value pairs that end in 0x5d 0x01 which is a "TUNER GO"
0425     # command for the MT352.
0426     # Pull out the middle run (because it's easy) of register-value
0427     # pairs to make the "firmware" file.
0428 
0429     local $/ = "\x5d\x01"; # MT352 "TUNER GO"
0430 
0431     while (<IN>) {
0432         $currlen = length($_);
0433         if ($prevlen == $currlen && $currlen <= 64) {
0434         chop; chop; # Get rid of "TUNER GO"
0435         s/^\0\0//;  # get rid of leading 00 00 if it's there
0436         printf OUT "$_";
0437         $found = 1;
0438         last;
0439         }
0440         $prevlen = $currlen;
0441     }
0442     }
0443     close OUT;
0444     close IN;
0445     if (!$found) {
0446     unlink $fwfile;
0447     die "Couldn't find valid register-value sequence in $sourcefile for $fwfile\n";
0448     }
0449     $fwfile;
0450 }
0451 
0452 sub cx23885 {
0453     my $url = "https://linuxtv.org/downloads/firmware/";
0454 
0455     my %files = (
0456     'v4l-cx23885-avcore-01.fw' => 'a9f8f5d901a7fb42f552e1ee6384f3bb',
0457     'v4l-cx23885-enc.fw'       => 'a9f8f5d901a7fb42f552e1ee6384f3bb',
0458     );
0459 
0460     checkstandard();
0461 
0462     my $allfiles;
0463     foreach my $fwfile (keys %files) {
0464     wgetfile($fwfile, "$url/$fwfile");
0465     verify($fwfile, $files{$fwfile});
0466     $allfiles .= " $fwfile";
0467     }
0468 
0469     $allfiles =~ s/^\s//;
0470 
0471     $allfiles;
0472 }
0473 
0474 sub pvrusb2 {
0475     my $url = "https://linuxtv.org/downloads/firmware/";
0476 
0477     my %files = (
0478     'v4l-cx25840.fw'           => 'dadb79e9904fc8af96e8111d9cb59320',
0479     );
0480 
0481     checkstandard();
0482 
0483     my $allfiles;
0484     foreach my $fwfile (keys %files) {
0485     wgetfile($fwfile, "$url/$fwfile");
0486     verify($fwfile, $files{$fwfile});
0487     $allfiles .= " $fwfile";
0488     }
0489 
0490     $allfiles =~ s/^\s//;
0491 
0492     $allfiles;
0493 }
0494 
0495 sub or51132_qam {
0496     my $fwfile = "dvb-fe-or51132-qam.fw";
0497     my $url = "https://linuxtv.org/downloads/firmware/$fwfile";
0498     my $hash = "7702e8938612de46ccadfe9b413cb3b5";
0499 
0500     checkstandard();
0501 
0502     wgetfile($fwfile, $url);
0503     verify($fwfile, $hash);
0504 
0505     $fwfile;
0506 }
0507 
0508 sub or51132_vsb {
0509     my $fwfile = "dvb-fe-or51132-vsb.fw";
0510     my $url = "https://linuxtv.org/downloads/firmware/$fwfile";
0511     my $hash = "c16208e02f36fc439a557ad4c613364a";
0512 
0513     checkstandard();
0514 
0515     wgetfile($fwfile, $url);
0516     verify($fwfile, $hash);
0517 
0518     $fwfile;
0519 }
0520 
0521 sub bluebird {
0522     my $url = "https://linuxtv.org/download/dvb/firmware/dvb-usb-bluebird-01.fw";
0523     my $outfile = "dvb-usb-bluebird-01.fw";
0524     my $hash = "658397cb9eba9101af9031302671f49d";
0525 
0526     checkstandard();
0527 
0528     wgetfile($outfile, $url);
0529     verify($outfile,$hash);
0530 
0531     $outfile;
0532 }
0533 
0534 sub af9015 {
0535     my $sourcefile = "download.ashx?file=57";
0536     my $url = "http://www.ite.com.tw/EN/Services/$sourcefile";
0537     my $hash = "e3f08935158038d385ad382442f4bb2d";
0538     my $outfile = "dvb-usb-af9015.fw";
0539     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0540     my $fwoffset = 0x25690;
0541     my $fwlength = 18725;
0542     my ($chunklength, $buf, $rcount);
0543 
0544     checkstandard();
0545 
0546     wgetfile($sourcefile, $url);
0547     unzip($sourcefile, $tmpdir);
0548     verify("$tmpdir/Driver/Files/AF15BDA.sys", $hash);
0549 
0550     open INFILE, '<', "$tmpdir/Driver/Files/AF15BDA.sys";
0551     open OUTFILE, '>', $outfile;
0552 
0553     sysseek(INFILE, $fwoffset, SEEK_SET);
0554     while($fwlength > 0) {
0555         $chunklength = 55;
0556         $chunklength = $fwlength if ($chunklength > $fwlength);
0557         $rcount = sysread(INFILE, $buf, $chunklength);
0558         die "Ran out of data\n" if ($rcount != $chunklength);
0559         syswrite(OUTFILE, $buf);
0560         sysread(INFILE, $buf, 8);
0561         $fwlength -= $rcount + 8;
0562     }
0563 
0564     close OUTFILE;
0565     close INFILE;
0566 }
0567 
0568 sub ngene {
0569     my $url = "http://www.digitaldevices.de/download/";
0570     my $file1 = "ngene_15.fw";
0571     my $hash1 = "d798d5a757121174f0dbc5f2833c0c85";
0572     my $file2 = "ngene_17.fw";
0573     my $hash2 = "26b687136e127b8ac24b81e0eeafc20b";
0574     my $url2 = "http://l4m-daten.de/downloads/firmware/dvb-s2/linux/all/";
0575     my $file3 = "ngene_18.fw";
0576     my $hash3 = "ebce3ea769a53e3e0b0197c3b3f127e3";
0577 
0578     checkstandard();
0579 
0580     wgetfile($file1, $url . $file1);
0581     verify($file1, $hash1);
0582 
0583     wgetfile($file2, $url . $file2);
0584     verify($file2, $hash2);
0585 
0586     wgetfile($file3, $url2 . $file3);
0587     verify($file3, $hash3);
0588 
0589     "$file1, $file2, $file3";
0590 }
0591 
0592 sub az6027{
0593     my $firmware = "dvb-usb-az6027-03.fw";
0594     my $url = "http://linux.terratec.de/files/TERRATEC_S7/$firmware";
0595 
0596     wgetfile($firmware, $url);
0597 
0598     $firmware;
0599 }
0600 
0601 sub lme2510_lg {
0602     my $sourcefile = "LMEBDA_DVBS.sys";
0603     my $hash = "fc6017ad01e79890a97ec53bea157ed2";
0604     my $outfile = "dvb-usb-lme2510-lg.fw";
0605     my $hasho = "caa065d5fdbd2c09ad57b399bbf55cad";
0606 
0607     checkstandard();
0608 
0609     verify($sourcefile, $hash);
0610     extract($sourcefile, 4168, 3841, $outfile);
0611     verify($outfile, $hasho);
0612     $outfile;
0613 }
0614 
0615 sub lme2510c_s7395 {
0616     my $sourcefile = "US2A0D.sys";
0617     my $hash = "b0155a8083fb822a3bd47bc360e74601";
0618     my $outfile = "dvb-usb-lme2510c-s7395.fw";
0619     my $hasho = "3a3cf1aeebd17b6ddc04cebe131e94cf";
0620 
0621     checkstandard();
0622 
0623     verify($sourcefile, $hash);
0624     extract($sourcefile, 37248, 3720, $outfile);
0625     verify($outfile, $hasho);
0626     $outfile;
0627 }
0628 
0629 sub lme2510c_s7395_old {
0630     my $sourcefile = "LMEBDA_DVBS7395C.sys";
0631     my $hash = "7572ae0eb9cdf91baabd7c0ba9e09b31";
0632     my $outfile = "dvb-usb-lme2510c-s7395.fw";
0633     my $hasho = "90430c5b435eb5c6f88fd44a9d950674";
0634 
0635     checkstandard();
0636 
0637     verify($sourcefile, $hash);
0638     extract($sourcefile, 4208, 3881, $outfile);
0639     verify($outfile, $hasho);
0640     $outfile;
0641 }
0642 
0643 sub drxk {
0644     my $url = "http://l4m-daten.de/files/";
0645     my $zipfile = "DDTuner.zip";
0646     my $hash = "f5a37b9a20a3534997997c0b1382a3e5";
0647     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0648     my $drvfile = "DDTuner.sys";
0649     my $fwfile = "drxk_a3.mc";
0650 
0651     checkstandard();
0652 
0653     wgetfile($zipfile, $url . $zipfile);
0654     verify($zipfile, $hash);
0655     unzip($zipfile, $tmpdir);
0656     extract("$tmpdir/$drvfile", 0x14dd8, 15634, "$fwfile");
0657 
0658     "$fwfile"
0659 }
0660 
0661 sub drxk_hauppauge_hvr930c {
0662     my $url = "http://www.wintvcd.co.uk/drivers/";
0663     my $zipfile = "HVR-9x0_5_10_325_28153_SIGNED.zip";
0664     my $hash = "83ab82e7e9480ec8bf1ae0155ca63c88";
0665     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0666     my $drvfile = "HVR-900/emOEM.sys";
0667     my $fwfile = "dvb-usb-hauppauge-hvr930c-drxk.fw";
0668 
0669     checkstandard();
0670 
0671     wgetfile($zipfile, $url . $zipfile);
0672     verify($zipfile, $hash);
0673     unzip($zipfile, $tmpdir);
0674     extract("$tmpdir/$drvfile", 0x117b0, 42692, "$fwfile");
0675 
0676     "$fwfile"
0677 }
0678 
0679 sub drxk_terratec_h5 {
0680     my $url = "https://linuxtv.org/downloads/firmware/";
0681     my $hash = "19000dada8e2741162ccc50cc91fa7f1";
0682     my $fwfile = "dvb-usb-terratec-h5-drxk.fw";
0683 
0684     checkstandard();
0685 
0686     wgetfile($fwfile, $url . $fwfile);
0687     verify($fwfile, $hash);
0688 
0689     "$fwfile"
0690 }
0691 
0692 sub drxk_terratec_htc_stick {
0693     my $url = "http://ftp.terratec.de/Receiver/Cinergy_HTC_Stick/Updates/History/";
0694     my $zipfile = "Cinergy_HTC_Stick_Drv_5.09.1202.00_XP_Vista_7.exe";
0695     my $hash = "6722a2442a05423b781721fbc069ed5e";
0696     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 0);
0697     my $drvfile = "Cinergy HTC Stick/BDA Driver 5.09.1202.00/Windows 32 Bit/emOEM.sys";
0698     my $fwfile = "dvb-usb-terratec-htc-stick-drxk.fw";
0699 
0700     checkstandard();
0701 
0702     wgetfile($zipfile, $url . $zipfile);
0703     verify($zipfile, $hash);
0704     unzip($zipfile, $tmpdir);
0705     extract("$tmpdir/$drvfile", 0x4e5c0, 42692, "$fwfile");
0706 
0707     "$fwfile"
0708 }
0709 
0710 sub it9135 {
0711     my $url = "http://www.ite.com.tw/uploads/firmware/v3.25.0.0/";
0712     my $file1 = "dvb-usb-it9135-01.zip";
0713     my $fwfile1 = "dvb-usb-it9135-01.fw";
0714     my $hash1 = "02fcf11174eda84745dae7e61c5ff9ba";
0715     my $file2 = "dvb-usb-it9135-02.zip";
0716     my $fwfile2 = "dvb-usb-it9135-02.fw";
0717     my $hash2 = "d5e1437dc24358578e07999475d4cac9";
0718 
0719     checkstandard();
0720 
0721     wgetfile($file1, $url . $file1);
0722     unzip($file1, "");
0723     verify("$fwfile1", $hash1);
0724 
0725     wgetfile($file2, $url . $file2);
0726     unzip($file2, "");
0727     verify("$fwfile2", $hash2);
0728 
0729     "$file1 $file2"
0730 }
0731 
0732 sub tda10071 {
0733     my $sourcefile = "PCTV_460e_reference.zip";
0734     my $url = "ftp://ftp.pctvsystems.com/TV/driver/PCTV%2070e%2080e%20100e%20320e%20330e%20800e/";
0735     my $hash = "4403de903bf2593464c8d74bbc200a57";
0736     my $fwfile = "dvb-fe-tda10071.fw";
0737     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0738 
0739     checkstandard();
0740 
0741     wgetfile($sourcefile, $url . $sourcefile);
0742     verify($sourcefile, $hash);
0743     unzip($sourcefile, $tmpdir);
0744     extract("$tmpdir/PCTV\ 70e\ 80e\ 100e\ 320e\ 330e\ 800e/32\ bit/emOEM.sys", 0x67d38, 40504, $fwfile);
0745 
0746     "$fwfile";
0747 }
0748 
0749 sub drxk_pctv {
0750     my $sourcefile = "PCTV_460e_reference.zip";
0751     my $url = "ftp://ftp.pctvsystems.com/TV/driver/PCTV%2070e%2080e%20100e%20320e%20330e%20800e/";
0752     my $hash = "4403de903bf2593464c8d74bbc200a57";
0753     my $fwfile = "dvb-demod-drxk-pctv.fw";
0754     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0755 
0756     checkstandard();
0757 
0758     wgetfile($sourcefile, $url . $sourcefile);
0759     verify($sourcefile, $hash);
0760     unzip($sourcefile, $tmpdir);
0761     extract("$tmpdir/PCTV\ 70e\ 80e\ 100e\ 320e\ 330e\ 800e/32\ bit/emOEM.sys", 0x72b80, 42692, $fwfile);
0762 
0763     "$fwfile";
0764 }
0765 
0766 sub sms1xxx_hcw {
0767     my $url = "http://steventoth.net/linux/sms1xxx/";
0768     my %files = (
0769     'sms1xxx-hcw-55xxx-dvbt-01.fw'  => "afb6f9fb9a71d64392e8564ef9577e5a",
0770     'sms1xxx-hcw-55xxx-dvbt-02.fw'  => "b44807098ba26e52cbedeadc052ba58f",
0771     'sms1xxx-hcw-55xxx-isdbt-02.fw' => "dae934eeea85225acbd63ce6cfe1c9e4",
0772     );
0773 
0774     checkstandard();
0775 
0776     my $allfiles;
0777     foreach my $fwfile (keys %files) {
0778     wgetfile($fwfile, "$url/$fwfile");
0779     verify($fwfile, $files{$fwfile});
0780     $allfiles .= " $fwfile";
0781     }
0782 
0783     $allfiles =~ s/^\s//;
0784 
0785     $allfiles;
0786 }
0787 
0788 sub si2165 {
0789     my $sourcefile = "model_111xxx_122xxx_driver_6_0_119_31191_WHQL.zip";
0790     my $url = "http://www.hauppauge.de/files/drivers/";
0791     my $hash = "76633e7c76b0edee47c3ba18ded99336";
0792     my $fwfile = "dvb-demod-si2165.fw";
0793     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
0794 
0795     checkstandard();
0796 
0797     wgetfile($sourcefile, $url . $sourcefile);
0798     verify($sourcefile, $hash);
0799     unzip($sourcefile, $tmpdir);
0800     extract("$tmpdir/Driver10/Hcw10bda.sys", 0x80788, 0x81E08-0x80788, "$tmpdir/fw1");
0801 
0802     delzero("$tmpdir/fw1","$tmpdir/fw1-1");
0803     #verify("$tmpdir/fw1","5e0909858fdf0b5b09ad48b9fe622e70");
0804 
0805     my $CRC="\x0A\xCC";
0806     my $BLOCKS_MAIN="\x27";
0807     open FW,">$fwfile";
0808     print FW "\x01\x00"; # just a version id for the driver itself
0809     print FW "\x9A"; # fw version
0810     print FW "\x00"; # padding
0811     print FW "$BLOCKS_MAIN"; # number of blocks of main part
0812     print FW "\x00"; # padding
0813     print FW "$CRC"; # 16bit crc value of main part
0814     appendfile(FW,"$tmpdir/fw1");
0815 
0816     "$fwfile";
0817 }
0818 
0819 # ---------------------------------------------------------------
0820 # Utilities
0821 
0822 sub checkstandard {
0823     if (system("which unzip > /dev/null 2>&1")) {
0824     die "This firmware requires the unzip command - see ftp://ftp.info-zip.org/pub/infozip/UnZip.html\n";
0825     }
0826     if (system("which md5sum > /dev/null 2>&1")) {
0827     die "This firmware requires the md5sum command - see http://www.gnu.org/software/coreutils/\n";
0828     }
0829     if (system("which wget > /dev/null 2>&1")) {
0830     die "This firmware requires the wget command - see http://wget.sunsite.dk/\n";
0831     }
0832 }
0833 
0834 sub checkunshield {
0835     if (system("which unshield > /dev/null 2>&1")) {
0836     die "This firmware requires the unshield command - see http://sourceforge.net/projects/synce/\n";
0837     }
0838 }
0839 
0840 sub wgetfile {
0841     my ($sourcefile, $url) = @_;
0842 
0843     if (! -f $sourcefile) {
0844     system("wget -O \"$sourcefile\" \"$url\"") and die "wget failed - unable to download firmware";
0845     }
0846 }
0847 
0848 sub unzip {
0849     my ($sourcefile, $todir) = @_;
0850 
0851     $status = system("unzip -q -o -d \"$todir\" \"$sourcefile\" 2>/dev/null" );
0852     if ((($status >> 8) > 2) || (($status & 0xff) != 0)) {
0853     die ("unzip failed - unable to extract firmware");
0854     }
0855 }
0856 
0857 sub unshield {
0858     my ($sourcefile, $todir) = @_;
0859 
0860     system("unshield x -d \"$todir\" \"$sourcefile\" > /dev/null" ) and die ("unshield failed - unable to extract firmware");
0861 }
0862 
0863 sub verify {
0864     my ($filename, $hash) = @_;
0865     my ($testhash);
0866 
0867     open(CMD, "md5sum \"$filename\"|");
0868     $testhash = <CMD>;
0869     $testhash =~ /([a-zA-Z0-9]*)/;
0870     $testhash = $1;
0871     close CMD;
0872     die "Hash of extracted file does not match!\n" if ($testhash ne $hash);
0873 }
0874 
0875 sub copy {
0876     my ($from, $to) = @_;
0877 
0878     system("cp -f \"$from\" \"$to\"") and die ("cp failed");
0879 }
0880 
0881 sub extract {
0882     my ($infile, $offset, $length, $outfile) = @_;
0883     my ($chunklength, $buf, $rcount);
0884 
0885     open INFILE, "<$infile";
0886     open OUTFILE, ">$outfile";
0887     sysseek(INFILE, $offset, SEEK_SET);
0888     while($length > 0) {
0889     # Calc chunk size
0890     $chunklength = 2048;
0891     $chunklength = $length if ($chunklength > $length);
0892 
0893     $rcount = sysread(INFILE, $buf, $chunklength);
0894     die "Ran out of data\n" if ($rcount != $chunklength);
0895     syswrite(OUTFILE, $buf);
0896     $length -= $rcount;
0897     }
0898     close INFILE;
0899     close OUTFILE;
0900 }
0901 
0902 sub appendfile {
0903     my ($FH, $infile) = @_;
0904     my ($buf);
0905 
0906     open INFILE, "<$infile";
0907     while(1) {
0908     $rcount = sysread(INFILE, $buf, 2048);
0909     last if ($rcount == 0);
0910     print $FH $buf;
0911     }
0912     close(INFILE);
0913 }
0914 
0915 sub delzero{
0916     my ($infile,$outfile) =@_;
0917 
0918     open INFILE,"<$infile";
0919     open OUTFILE,">$outfile";
0920     while (1){
0921         $rcount=sysread(INFILE,$buf,22);
0922         $len=ord(substr($buf,0,1));
0923         print OUTFILE substr($buf,0,1);
0924         print OUTFILE substr($buf,2,$len+3);
0925     last if ($rcount<1);
0926     printf OUTFILE "%c",0;
0927 #print $len." ".length($buf)."\n";
0928 
0929     }
0930     close(INFILE);
0931     close(OUTFILE);
0932 }
0933 
0934 sub syntax() {
0935     print STDERR "syntax: get_dvb_firmware <component>\n";
0936     print STDERR "Supported components:\n";
0937     @components = sort @components;
0938     for($i=0; $i < scalar(@components); $i++) {
0939     print STDERR "\t" . $components[$i] . "\n";
0940     }
0941     exit(1);
0942 }