get_dvb_firmware 12 KB

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