get_dvb_firmware 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. #!/usr/bin/perl
  2. # DVB firmware extractor
  3. #
  4. # (c) 2004 Andrew de Quincey
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. #
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. use File::Temp qw/ tempdir /;
  21. use IO::Handle;
  22. @components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
  23. "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002",
  24. "or51211", "or51132_qam", "or51132_vsb");
  25. # Check args
  26. syntax() if (scalar(@ARGV) != 1);
  27. $cid = $ARGV[0];
  28. # Do it!
  29. for ($i=0; $i < scalar(@components); $i++) {
  30. if ($cid eq $components[$i]) {
  31. $outfile = eval($cid);
  32. die $@ if $@;
  33. print STDERR "Firmware $outfile extracted successfully. Now copy it to either /lib/firmware or /usr/lib/hotplug/firmware/ (depending on your hotplug version).\n";
  34. exit(0);
  35. }
  36. }
  37. # If we get here, it wasn't found
  38. print STDERR "Unknown component \"$cid\"\n";
  39. syntax();
  40. # ---------------------------------------------------------------
  41. # Firmware-specific extraction subroutines
  42. sub sp8870 {
  43. my $sourcefile = "tt_Premium_217g.zip";
  44. my $url = "http://www.technotrend.de/new/217g/$sourcefile";
  45. my $hash = "53970ec17a538945a6d8cb608a7b3899";
  46. my $outfile = "dvb-fe-sp8870.fw";
  47. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  48. checkstandard();
  49. wgetfile($sourcefile, $url);
  50. unzip($sourcefile, $tmpdir);
  51. verify("$tmpdir/software/OEM/HE/App/boot/SC_MAIN.MC", $hash);
  52. copy("$tmpdir/software/OEM/HE/App/boot/SC_MAIN.MC", $outfile);
  53. $outfile;
  54. }
  55. sub sp887x {
  56. my $sourcefile = "Dvbt1.3.57.6.zip";
  57. my $url = "http://www.avermedia.com/software/$sourcefile";
  58. my $cabfile = "DVBT Net Ver1.3.57.6/disk1/data1.cab";
  59. my $hash = "237938d53a7f834c05c42b894ca68ac3";
  60. my $outfile = "dvb-fe-sp887x.fw";
  61. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  62. checkstandard();
  63. checkunshield();
  64. wgetfile($sourcefile, $url);
  65. unzip($sourcefile, $tmpdir);
  66. unshield("$tmpdir/$cabfile", $tmpdir);
  67. verify("$tmpdir/ZEnglish/sc_main.mc", $hash);
  68. copy("$tmpdir/ZEnglish/sc_main.mc", $outfile);
  69. $outfile;
  70. }
  71. sub tda10045 {
  72. my $sourcefile = "tt_budget_217g.zip";
  73. my $url = "http://www.technotrend.de/new/217g/$sourcefile";
  74. my $hash = "2105fd5bf37842fbcdfa4bfd58f3594a";
  75. my $outfile = "dvb-fe-tda10045.fw";
  76. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  77. checkstandard();
  78. wgetfile($sourcefile, $url);
  79. unzip($sourcefile, $tmpdir);
  80. extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x37ef9, 30555, "$tmpdir/fwtmp");
  81. verify("$tmpdir/fwtmp", $hash);
  82. copy("$tmpdir/fwtmp", $outfile);
  83. $outfile;
  84. }
  85. sub tda10046 {
  86. my $sourcefile = "tt_budget_217g.zip";
  87. my $url = "http://www.technotrend.de/new/217g/$sourcefile";
  88. my $hash = "6a7e1e2f2644b162ff0502367553c72d";
  89. my $outfile = "dvb-fe-tda10046.fw";
  90. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  91. checkstandard();
  92. wgetfile($sourcefile, $url);
  93. unzip($sourcefile, $tmpdir);
  94. extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24478, "$tmpdir/fwtmp");
  95. verify("$tmpdir/fwtmp", $hash);
  96. copy("$tmpdir/fwtmp", $outfile);
  97. $outfile;
  98. }
  99. sub av7110 {
  100. my $sourcefile = "dvb-ttpci-01.fw-261d";
  101. my $url = "http://www.linuxtv.org/downloads/firmware/$sourcefile";
  102. my $hash = "603431b6259715a8e88f376a53b64e2f";
  103. my $outfile = "dvb-ttpci-01.fw";
  104. checkstandard();
  105. wgetfile($sourcefile, $url);
  106. verify($sourcefile, $hash);
  107. copy($sourcefile, $outfile);
  108. $outfile;
  109. }
  110. sub dec2000t {
  111. my $sourcefile = "dec217g.exe";
  112. my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
  113. my $hash = "bd86f458cee4a8f0a8ce2d20c66215a9";
  114. my $outfile = "dvb-ttusb-dec-2000t.fw";
  115. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  116. checkstandard();
  117. wgetfile($sourcefile, $url);
  118. unzip($sourcefile, $tmpdir);
  119. verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_T.bin", $hash);
  120. copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_T.bin", $outfile);
  121. $outfile;
  122. }
  123. sub dec2540t {
  124. my $sourcefile = "dec217g.exe";
  125. my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
  126. my $hash = "53e58f4f5b5c2930beee74a7681fed92";
  127. my $outfile = "dvb-ttusb-dec-2540t.fw";
  128. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  129. checkstandard();
  130. wgetfile($sourcefile, $url);
  131. unzip($sourcefile, $tmpdir);
  132. verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_X.bin", $hash);
  133. copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_X.bin", $outfile);
  134. $outfile;
  135. }
  136. sub dec3000s {
  137. my $sourcefile = "dec217g.exe";
  138. my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
  139. my $hash = "b013ececea83f4d6d8d2a29ac7c1b448";
  140. my $outfile = "dvb-ttusb-dec-3000s.fw";
  141. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  142. checkstandard();
  143. wgetfile($sourcefile, $url);
  144. unzip($sourcefile, $tmpdir);
  145. verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_S.bin", $hash);
  146. copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_S.bin", $outfile);
  147. $outfile;
  148. }
  149. sub vp7041 {
  150. my $sourcefile = "2.422.zip";
  151. my $url = "http://www.twinhan.com/files/driver/USB-Ter/$sourcefile";
  152. my $hash = "e88c9372d1f66609a3e7b072c53fbcfe";
  153. my $outfile = "dvb-vp7041-2.422.fw";
  154. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  155. checkstandard();
  156. wgetfile($sourcefile, $url);
  157. unzip($sourcefile, $tmpdir);
  158. extract("$tmpdir/VisionDTV/Drivers/Win2K&XP/UDTTload.sys", 12503, 3036, "$tmpdir/fwtmp1");
  159. extract("$tmpdir/VisionDTV/Drivers/Win2K&XP/UDTTload.sys", 2207, 10274, "$tmpdir/fwtmp2");
  160. my $CMD = "\000\001\000\222\177\000";
  161. my $PAD = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";
  162. my ($FW);
  163. open $FW, ">$tmpdir/fwtmp3";
  164. print $FW "$CMD\001$PAD";
  165. print $FW "$CMD\001$PAD";
  166. appendfile($FW, "$tmpdir/fwtmp1");
  167. print $FW "$CMD\000$PAD";
  168. print $FW "$CMD\001$PAD";
  169. appendfile($FW, "$tmpdir/fwtmp2");
  170. print $FW "$CMD\001$PAD";
  171. print $FW "$CMD\000$PAD";
  172. close($FW);
  173. verify("$tmpdir/fwtmp3", $hash);
  174. copy("$tmpdir/fwtmp3", $outfile);
  175. $outfile;
  176. }
  177. sub dibusb {
  178. my $url = "http://www.linuxtv.org/downloads/firmware/dvb-dibusb-5.0.0.11.fw";
  179. my $outfile = "dvb-dibusb-5.0.0.11.fw";
  180. my $hash = "fa490295a527360ca16dcdf3224ca243";
  181. checkstandard();
  182. wgetfile($outfile, $url);
  183. verify($outfile,$hash);
  184. $outfile;
  185. }
  186. sub nxt2002 {
  187. my $sourcefile = "Broadband4PC_4_2_11.zip";
  188. my $url = "http://www.bbti.us/download/windows/$sourcefile";
  189. my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a";
  190. my $outfile = "dvb-fe-nxt2002.fw";
  191. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  192. checkstandard();
  193. wgetfile($sourcefile, $url);
  194. unzip($sourcefile, $tmpdir);
  195. verify("$tmpdir/SkyNETU.sys", $hash);
  196. extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile);
  197. $outfile;
  198. }
  199. sub or51211 {
  200. my $fwfile = "dvb-fe-or51211.fw";
  201. my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
  202. my $hash = "d830949c771a289505bf9eafc225d491";
  203. checkstandard();
  204. wgetfile($fwfile, $url);
  205. verify($fwfile, $hash);
  206. $fwfile;
  207. }
  208. sub or51132_qam {
  209. my $fwfile = "dvb-fe-or51132-qam.fw";
  210. my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
  211. my $hash = "7702e8938612de46ccadfe9b413cb3b5";
  212. checkstandard();
  213. wgetfile($fwfile, $url);
  214. verify($fwfile, $hash);
  215. $fwfile;
  216. }
  217. sub or51132_vsb {
  218. my $fwfile = "dvb-fe-or51132-vsb.fw";
  219. my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
  220. my $hash = "c16208e02f36fc439a557ad4c613364a";
  221. checkstandard();
  222. wgetfile($fwfile, $url);
  223. verify($fwfile, $hash);
  224. $fwfile;
  225. }
  226. # ---------------------------------------------------------------
  227. # Utilities
  228. sub checkstandard {
  229. if (system("which unzip > /dev/null 2>&1")) {
  230. die "This firmware requires the unzip command - see ftp://ftp.info-zip.org/pub/infozip/UnZip.html\n";
  231. }
  232. if (system("which md5sum > /dev/null 2>&1")) {
  233. die "This firmware requires the md5sum command - see http://www.gnu.org/software/coreutils/\n";
  234. }
  235. if (system("which wget > /dev/null 2>&1")) {
  236. die "This firmware requires the wget command - see http://wget.sunsite.dk/\n";
  237. }
  238. }
  239. sub checkunshield {
  240. if (system("which unshield > /dev/null 2>&1")) {
  241. die "This firmware requires the unshield command - see http://sourceforge.net/projects/synce/\n";
  242. }
  243. }
  244. sub wgetfile {
  245. my ($sourcefile, $url) = @_;
  246. if (! -f $sourcefile) {
  247. system("wget -O \"$sourcefile\" \"$url\"") and die "wget failed - unable to download firmware";
  248. }
  249. }
  250. sub unzip {
  251. my ($sourcefile, $todir) = @_;
  252. $status = system("unzip -q -o -d \"$todir\" \"$sourcefile\" 2>/dev/null" );
  253. if ((($status >> 8) > 2) || (($status & 0xff) != 0)) {
  254. die ("unzip failed - unable to extract firmware");
  255. }
  256. }
  257. sub unshield {
  258. my ($sourcefile, $todir) = @_;
  259. system("unshield x -d \"$todir\" \"$sourcefile\" > /dev/null" ) and die ("unshield failed - unable to extract firmware");
  260. }
  261. sub verify {
  262. my ($filename, $hash) = @_;
  263. my ($testhash);
  264. open(CMD, "md5sum \"$filename\"|");
  265. $testhash = <CMD>;
  266. $testhash =~ /([a-zA-Z0-9]*)/;
  267. $testhash = $1;
  268. close CMD;
  269. die "Hash of extracted file does not match!\n" if ($testhash ne $hash);
  270. }
  271. sub copy {
  272. my ($from, $to) = @_;
  273. system("cp -f \"$from\" \"$to\"") and die ("cp failed");
  274. }
  275. sub extract {
  276. my ($infile, $offset, $length, $outfile) = @_;
  277. my ($chunklength, $buf, $rcount);
  278. open INFILE, "<$infile";
  279. open OUTFILE, ">$outfile";
  280. sysseek(INFILE, $offset, SEEK_SET);
  281. while($length > 0) {
  282. # Calc chunk size
  283. $chunklength = 2048;
  284. $chunklength = $length if ($chunklength > $length);
  285. $rcount = sysread(INFILE, $buf, $chunklength);
  286. die "Ran out of data\n" if ($rcount != $chunklength);
  287. syswrite(OUTFILE, $buf);
  288. $length -= $rcount;
  289. }
  290. close INFILE;
  291. close OUTFILE;
  292. }
  293. sub appendfile {
  294. my ($FH, $infile) = @_;
  295. my ($buf);
  296. open INFILE, "<$infile";
  297. while(1) {
  298. $rcount = sysread(INFILE, $buf, 2048);
  299. last if ($rcount == 0);
  300. print $FH $buf;
  301. }
  302. close(INFILE);
  303. }
  304. sub syntax() {
  305. print STDERR "syntax: get_dvb_firmware <component>\n";
  306. print STDERR "Supported components:\n";
  307. for($i=0; $i < scalar(@components); $i++) {
  308. print STDERR "\t" . $components[$i] . "\n";
  309. }
  310. exit(1);
  311. }