get_dvb_firmware 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  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", "nxt2004",
  24. "or51211", "or51132_qam", "or51132_vsb", "bluebird");
  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 <<EOF;
  34. Firmware $outfile extracted successfully.
  35. Now copy it to either /usr/lib/hotplug/firmware or /lib/firmware
  36. (depending on configuration of firmware hotplug).
  37. EOF
  38. exit(0);
  39. }
  40. }
  41. # If we get here, it wasn't found
  42. print STDERR "Unknown component \"$cid\"\n";
  43. syntax();
  44. # ---------------------------------------------------------------
  45. # Firmware-specific extraction subroutines
  46. sub sp8870 {
  47. my $sourcefile = "tt_Premium_217g.zip";
  48. my $url = "http://www.technotrend.de/new/217g/$sourcefile";
  49. my $hash = "53970ec17a538945a6d8cb608a7b3899";
  50. my $outfile = "dvb-fe-sp8870.fw";
  51. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  52. checkstandard();
  53. wgetfile($sourcefile, $url);
  54. unzip($sourcefile, $tmpdir);
  55. verify("$tmpdir/software/OEM/HE/App/boot/SC_MAIN.MC", $hash);
  56. copy("$tmpdir/software/OEM/HE/App/boot/SC_MAIN.MC", $outfile);
  57. $outfile;
  58. }
  59. sub sp887x {
  60. my $sourcefile = "Dvbt1.3.57.6.zip";
  61. my $url = "http://www.avermedia.com/software/$sourcefile";
  62. my $cabfile = "DVBT Net Ver1.3.57.6/disk1/data1.cab";
  63. my $hash = "237938d53a7f834c05c42b894ca68ac3";
  64. my $outfile = "dvb-fe-sp887x.fw";
  65. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  66. checkstandard();
  67. checkunshield();
  68. wgetfile($sourcefile, $url);
  69. unzip($sourcefile, $tmpdir);
  70. unshield("$tmpdir/$cabfile", $tmpdir);
  71. verify("$tmpdir/ZEnglish/sc_main.mc", $hash);
  72. copy("$tmpdir/ZEnglish/sc_main.mc", $outfile);
  73. $outfile;
  74. }
  75. sub tda10045 {
  76. my $sourcefile = "tt_budget_217g.zip";
  77. my $url = "http://www.technotrend.de/new/217g/$sourcefile";
  78. my $hash = "2105fd5bf37842fbcdfa4bfd58f3594a";
  79. my $outfile = "dvb-fe-tda10045.fw";
  80. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  81. checkstandard();
  82. wgetfile($sourcefile, $url);
  83. unzip($sourcefile, $tmpdir);
  84. extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x37ef9, 30555, "$tmpdir/fwtmp");
  85. verify("$tmpdir/fwtmp", $hash);
  86. copy("$tmpdir/fwtmp", $outfile);
  87. $outfile;
  88. }
  89. sub tda10046 {
  90. my $sourcefile = "tt_budget_217g.zip";
  91. my $url = "http://www.technotrend.de/new/217g/$sourcefile";
  92. my $hash = "6a7e1e2f2644b162ff0502367553c72d";
  93. my $outfile = "dvb-fe-tda10046.fw";
  94. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  95. checkstandard();
  96. wgetfile($sourcefile, $url);
  97. unzip($sourcefile, $tmpdir);
  98. extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24478, "$tmpdir/fwtmp");
  99. verify("$tmpdir/fwtmp", $hash);
  100. copy("$tmpdir/fwtmp", $outfile);
  101. $outfile;
  102. }
  103. sub av7110 {
  104. my $sourcefile = "dvb-ttpci-01.fw-261d";
  105. my $url = "http://www.linuxtv.org/downloads/firmware/$sourcefile";
  106. my $hash = "603431b6259715a8e88f376a53b64e2f";
  107. my $outfile = "dvb-ttpci-01.fw";
  108. checkstandard();
  109. wgetfile($sourcefile, $url);
  110. verify($sourcefile, $hash);
  111. copy($sourcefile, $outfile);
  112. $outfile;
  113. }
  114. sub dec2000t {
  115. my $sourcefile = "dec217g.exe";
  116. my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
  117. my $hash = "bd86f458cee4a8f0a8ce2d20c66215a9";
  118. my $outfile = "dvb-ttusb-dec-2000t.fw";
  119. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  120. checkstandard();
  121. wgetfile($sourcefile, $url);
  122. unzip($sourcefile, $tmpdir);
  123. verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_T.bin", $hash);
  124. copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_T.bin", $outfile);
  125. $outfile;
  126. }
  127. sub dec2540t {
  128. my $sourcefile = "dec217g.exe";
  129. my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
  130. my $hash = "53e58f4f5b5c2930beee74a7681fed92";
  131. my $outfile = "dvb-ttusb-dec-2540t.fw";
  132. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  133. checkstandard();
  134. wgetfile($sourcefile, $url);
  135. unzip($sourcefile, $tmpdir);
  136. verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_X.bin", $hash);
  137. copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_X.bin", $outfile);
  138. $outfile;
  139. }
  140. sub dec3000s {
  141. my $sourcefile = "dec217g.exe";
  142. my $url = "http://hauppauge.lightpath.net/de/$sourcefile";
  143. my $hash = "b013ececea83f4d6d8d2a29ac7c1b448";
  144. my $outfile = "dvb-ttusb-dec-3000s.fw";
  145. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  146. checkstandard();
  147. wgetfile($sourcefile, $url);
  148. unzip($sourcefile, $tmpdir);
  149. verify("$tmpdir/software/OEM/STB/App/Boot/STB_PC_S.bin", $hash);
  150. copy("$tmpdir/software/OEM/STB/App/Boot/STB_PC_S.bin", $outfile);
  151. $outfile;
  152. }
  153. sub vp7041 {
  154. my $sourcefile = "2.422.zip";
  155. my $url = "http://www.twinhan.com/files/driver/USB-Ter/$sourcefile";
  156. my $hash = "e88c9372d1f66609a3e7b072c53fbcfe";
  157. my $outfile = "dvb-vp7041-2.422.fw";
  158. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  159. checkstandard();
  160. wgetfile($sourcefile, $url);
  161. unzip($sourcefile, $tmpdir);
  162. extract("$tmpdir/VisionDTV/Drivers/Win2K&XP/UDTTload.sys", 12503, 3036, "$tmpdir/fwtmp1");
  163. extract("$tmpdir/VisionDTV/Drivers/Win2K&XP/UDTTload.sys", 2207, 10274, "$tmpdir/fwtmp2");
  164. my $CMD = "\000\001\000\222\177\000";
  165. my $PAD = "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000";
  166. my ($FW);
  167. open $FW, ">$tmpdir/fwtmp3";
  168. print $FW "$CMD\001$PAD";
  169. print $FW "$CMD\001$PAD";
  170. appendfile($FW, "$tmpdir/fwtmp1");
  171. print $FW "$CMD\000$PAD";
  172. print $FW "$CMD\001$PAD";
  173. appendfile($FW, "$tmpdir/fwtmp2");
  174. print $FW "$CMD\001$PAD";
  175. print $FW "$CMD\000$PAD";
  176. close($FW);
  177. verify("$tmpdir/fwtmp3", $hash);
  178. copy("$tmpdir/fwtmp3", $outfile);
  179. $outfile;
  180. }
  181. sub dibusb {
  182. my $url = "http://www.linuxtv.org/downloads/firmware/dvb-dibusb-5.0.0.11.fw";
  183. my $outfile = "dvb-dibusb-5.0.0.11.fw";
  184. my $hash = "fa490295a527360ca16dcdf3224ca243";
  185. checkstandard();
  186. wgetfile($outfile, $url);
  187. verify($outfile,$hash);
  188. $outfile;
  189. }
  190. sub nxt2002 {
  191. my $sourcefile = "Broadband4PC_4_2_11.zip";
  192. my $url = "http://www.bbti.us/download/windows/$sourcefile";
  193. my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a";
  194. my $outfile = "dvb-fe-nxt2002.fw";
  195. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  196. checkstandard();
  197. wgetfile($sourcefile, $url);
  198. unzip($sourcefile, $tmpdir);
  199. verify("$tmpdir/SkyNETU.sys", $hash);
  200. extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile);
  201. $outfile;
  202. }
  203. sub nxt2004 {
  204. my $sourcefile = "AVerTVHD_MCE_A180_Drv_v1.2.2.16.zip";
  205. my $url = "http://www.aver.com/support/Drivers/$sourcefile";
  206. my $hash = "111cb885b1e009188346d72acfed024c";
  207. my $outfile = "dvb-fe-nxt2004.fw";
  208. my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
  209. checkstandard();
  210. wgetfile($sourcefile, $url);
  211. unzip($sourcefile, $tmpdir);
  212. verify("$tmpdir/3xHybrid.sys", $hash);
  213. extract("$tmpdir/3xHybrid.sys", 465304, 9584, $outfile);
  214. $outfile;
  215. }
  216. sub or51211 {
  217. my $fwfile = "dvb-fe-or51211.fw";
  218. my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
  219. my $hash = "d830949c771a289505bf9eafc225d491";
  220. checkstandard();
  221. wgetfile($fwfile, $url);
  222. verify($fwfile, $hash);
  223. $fwfile;
  224. }
  225. sub or51132_qam {
  226. my $fwfile = "dvb-fe-or51132-qam.fw";
  227. my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
  228. my $hash = "7702e8938612de46ccadfe9b413cb3b5";
  229. checkstandard();
  230. wgetfile($fwfile, $url);
  231. verify($fwfile, $hash);
  232. $fwfile;
  233. }
  234. sub or51132_vsb {
  235. my $fwfile = "dvb-fe-or51132-vsb.fw";
  236. my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
  237. my $hash = "c16208e02f36fc439a557ad4c613364a";
  238. checkstandard();
  239. wgetfile($fwfile, $url);
  240. verify($fwfile, $hash);
  241. $fwfile;
  242. }
  243. sub bluebird {
  244. my $url = "http://www.linuxtv.org/download/dvb/firmware/dvb-usb-bluebird-01.fw";
  245. my $outfile = "dvb-usb-bluebird-01.fw";
  246. my $hash = "658397cb9eba9101af9031302671f49d";
  247. checkstandard();
  248. wgetfile($outfile, $url);
  249. verify($outfile,$hash);
  250. $outfile;
  251. }
  252. # ---------------------------------------------------------------
  253. # Utilities
  254. sub checkstandard {
  255. if (system("which unzip > /dev/null 2>&1")) {
  256. die "This firmware requires the unzip command - see ftp://ftp.info-zip.org/pub/infozip/UnZip.html\n";
  257. }
  258. if (system("which md5sum > /dev/null 2>&1")) {
  259. die "This firmware requires the md5sum command - see http://www.gnu.org/software/coreutils/\n";
  260. }
  261. if (system("which wget > /dev/null 2>&1")) {
  262. die "This firmware requires the wget command - see http://wget.sunsite.dk/\n";
  263. }
  264. }
  265. sub checkunshield {
  266. if (system("which unshield > /dev/null 2>&1")) {
  267. die "This firmware requires the unshield command - see http://sourceforge.net/projects/synce/\n";
  268. }
  269. }
  270. sub wgetfile {
  271. my ($sourcefile, $url) = @_;
  272. if (! -f $sourcefile) {
  273. system("wget -O \"$sourcefile\" \"$url\"") and die "wget failed - unable to download firmware";
  274. }
  275. }
  276. sub unzip {
  277. my ($sourcefile, $todir) = @_;
  278. $status = system("unzip -q -o -d \"$todir\" \"$sourcefile\" 2>/dev/null" );
  279. if ((($status >> 8) > 2) || (($status & 0xff) != 0)) {
  280. die ("unzip failed - unable to extract firmware");
  281. }
  282. }
  283. sub unshield {
  284. my ($sourcefile, $todir) = @_;
  285. system("unshield x -d \"$todir\" \"$sourcefile\" > /dev/null" ) and die ("unshield failed - unable to extract firmware");
  286. }
  287. sub verify {
  288. my ($filename, $hash) = @_;
  289. my ($testhash);
  290. open(CMD, "md5sum \"$filename\"|");
  291. $testhash = <CMD>;
  292. $testhash =~ /([a-zA-Z0-9]*)/;
  293. $testhash = $1;
  294. close CMD;
  295. die "Hash of extracted file does not match!\n" if ($testhash ne $hash);
  296. }
  297. sub copy {
  298. my ($from, $to) = @_;
  299. system("cp -f \"$from\" \"$to\"") and die ("cp failed");
  300. }
  301. sub extract {
  302. my ($infile, $offset, $length, $outfile) = @_;
  303. my ($chunklength, $buf, $rcount);
  304. open INFILE, "<$infile";
  305. open OUTFILE, ">$outfile";
  306. sysseek(INFILE, $offset, SEEK_SET);
  307. while($length > 0) {
  308. # Calc chunk size
  309. $chunklength = 2048;
  310. $chunklength = $length if ($chunklength > $length);
  311. $rcount = sysread(INFILE, $buf, $chunklength);
  312. die "Ran out of data\n" if ($rcount != $chunklength);
  313. syswrite(OUTFILE, $buf);
  314. $length -= $rcount;
  315. }
  316. close INFILE;
  317. close OUTFILE;
  318. }
  319. sub appendfile {
  320. my ($FH, $infile) = @_;
  321. my ($buf);
  322. open INFILE, "<$infile";
  323. while(1) {
  324. $rcount = sysread(INFILE, $buf, 2048);
  325. last if ($rcount == 0);
  326. print $FH $buf;
  327. }
  328. close(INFILE);
  329. }
  330. sub syntax() {
  331. print STDERR "syntax: get_dvb_firmware <component>\n";
  332. print STDERR "Supported components:\n";
  333. for($i=0; $i < scalar(@components); $i++) {
  334. print STDERR "\t" . $components[$i] . "\n";
  335. }
  336. exit(1);
  337. }