root/branches/libfreebob-downloader/src/bebob/bebob_dl_bcd.cpp

Revision 276, 9.5 kB (checked in by wagi, 16 years ago)

2006-06-27 Daniel Wagner <wagi@monom.org>

  • configure.ac: Version bump to 1.1.0
  • remove bebob_light code
  • downloader various improvements
  • ConfigRom::isAvcDevice() removed. Device probe code added.
    Each device driver class can check if it supports a device.
Line 
1 /* bebob_dl_bcd.cpp
2  * Copyright (C) 2006 by Daniel Wagner
3  *
4  * This file is part of FreeBoB.
5  *
6  * FreeBoB 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  * FreeBoB is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with FreeBoB; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA.
19  */
20
21 #include "bebob_dl_bcd.h"
22
23 #include <cstdio>
24
25 namespace BeBoB {
26     enum {
27         BCDMagic = 0x446f4362,
28     };
29
30     // XXX not very nice tool box function?
31     std::string makeString( fb_octlet_t v )
32     {
33         std::string s;
34
35         for ( unsigned int i=0; i<sizeof( v ); ++i ) {
36             s += reinterpret_cast<char*> ( &v )[i];
37         }
38
39         return s;
40     }
41
42     std::string makeDate( fb_octlet_t v )
43     {
44         std::string s;
45         char* vc = reinterpret_cast<char*> ( &v );
46
47         s += vc[6];
48         s += vc[7];
49         s += '.';
50         s += vc[4];
51         s += vc[5];
52         s += '.';
53         s += vc[0];
54         s += vc[1];
55         s += vc[2];
56         s += vc[3];
57
58         return s;
59     }
60
61     std::string makeTime( fb_octlet_t v )
62     {
63         std::string s;
64         char* vc = reinterpret_cast<char*>( &v );
65
66         s += vc[0];
67         s += vc[1];
68         s += ':';
69         s += vc[2];
70         s += vc[3];
71         s += ':';
72         s += vc[4];
73         s += vc[5];
74         s += vc[6];
75         s += vc[7];
76
77         return s;
78     }
79
80     enum {
81         BCDFileVersionOffset = 0x28,
82
83         V0HeaderCRCOffset    = 0x2c,
84         V0HeaderSize         = 0x60,
85
86         V1HeaderCRC0ffset    = 0x2c,
87         V1HeaderSize         = 0x70,
88     };
89
90     IMPL_DEBUG_MODULE( BCD, BCD, DEBUG_LEVEL_NORMAL );
91 };
92
93 BeBoB::BCD::BCD( std::string filename )
94     : m_file( 0 )
95     , m_filename( filename )
96     , m_bcd_version( -1 )
97     , m_softwareDate( 0 )
98     , m_softwareTime( 0 )
99     , m_softwareId( 0 )
100     , m_softwareVersion( 0 )
101     , m_hardwareId( 0 )
102     , m_vendorOUI( 0 )
103     , m_imageBaseAddress( 0 )
104     , m_imageLength( 0 )
105     , m_imageOffset( 0 )
106     , m_imageCRC( 0 )
107     , m_cneLength( 0 )
108     , m_cneOffset( 0 )
109     , m_cneCRC( 0 )
110 {
111     initCRC32Table();
112 }
113
114 BeBoB::BCD::~BCD()
115 {
116     if ( m_file ) {
117         fclose( m_file );
118     }
119 }
120
121 bool
122 BeBoB::BCD::parse()
123 {
124     using namespace std;
125
126     m_file = fopen( m_filename.c_str(), "r" );
127     if ( !m_file ) {
128         debugError( "parse: Could not open file '%s'\n",
129                     m_filename.c_str() );
130         return false;
131     }
132
133     fb_quadlet_t identifier;
134     size_t bytes_read = fread( &identifier, 1, sizeof( identifier ), m_file );
135     if ( bytes_read  != sizeof( identifier ) ) {
136         debugError( "parse: 4 bytes read failed at position 0\n" );
137         return false;
138     }
139
140     if ( identifier != BCDMagic ) {
141         debugError( "parse: File has not BCD header magic, 0x%08x expected, "
142                     "0x%08x found\n", BCDMagic, identifier );
143         return false;
144     }
145
146     if ( fseek( m_file, BCDFileVersionOffset, SEEK_SET ) == -1 ) {
147         debugError( "parse: fseek failed\n" );
148         return false;
149     }
150
151     bytes_read = fread( &m_bcd_version, 1, sizeof( fb_quadlet_t ), m_file );
152     if ( bytes_read != sizeof( fb_quadlet_t ) ) {
153         debugError( "parse: %d bytes read at position %d failed\n",
154                     sizeof( fb_quadlet_t ),
155                     BCDFileVersionOffset );
156         return false;
157     }
158
159     unsigned int headerSize = 0;
160     unsigned int crcOffset = 0;
161     switch( m_bcd_version ) {
162     case 0:
163         headerSize = V0HeaderSize;
164         crcOffset = V0HeaderCRCOffset;
165         break;
166     case 1:
167         headerSize = V1HeaderSize;
168         crcOffset = V1HeaderCRC0ffset;
169         break;
170     default:
171         debugError( "parse: Unknown BCD file version %d found\n",
172                     m_bcd_version );
173         return false;
174     }
175
176     if ( !checkHeaderCRC( crcOffset, headerSize ) ) {
177         debugError( "parse: Header CRC check failed\n" );
178         return false;
179     }
180
181     if ( !readHeaderInfo() ) {
182         debugError( "parse: Could not read all header info\n" );
183         return false;
184     }
185
186     return true;
187 }
188
189 bool
190 BeBoB::BCD::readHeaderInfo()
191 {
192     if ( !read( 0x08, &m_softwareDate ) ) {
193         return false;
194     }
195     if ( !read( 0x10, &m_softwareTime ) ) {
196         return false;
197     }
198     if ( !read( 0x18, &m_softwareId ) ) {
199         return false;
200     }
201     if ( !read( 0x1c, &m_softwareVersion ) ) {
202         return false;
203     }
204     if ( !read( 0x20, &m_hardwareId ) ) {
205         return false;
206     }
207     if ( !read( 0x24, &m_vendorOUI ) ) {
208         return false;
209     }
210     if ( !read( 0x30, &m_imageOffset ) ) {
211         return false;
212     }
213     if ( !read( 0x34, &m_imageBaseAddress ) ) {
214         return false;
215     }
216     if ( !read( 0x38, &m_imageLength ) ) {
217         return false;
218     }
219     if ( !read( 0x3c, &m_imageCRC ) ) {
220         return false;
221     }
222     if ( !read( 0x50, &m_cneOffset ) ) {
223         return false;
224     }
225     if ( !read( 0x58, &m_cneLength ) ) {
226         return false;
227     }
228     if ( !read( 0x5c, &m_cneCRC ) ) {
229         return false;
230     }
231     return true;
232 }
233
234 bool
235 BeBoB::BCD::read( int addr, fb_quadlet_t* q )
236 {
237     if ( std::fseek( m_file, addr, SEEK_SET ) == -1 ) {
238         debugError( "read: seek to position 0x%08x failed\n", addr );
239         return false;
240     }
241
242     size_t bytes_read = std::fread( q, 1, sizeof( *q ), m_file );
243     if ( bytes_read  != sizeof( *q ) ) {
244         debugError( "read: %d byte read failed at position 0x%08x\n",
245                     sizeof( *q ),  addr );
246         return false;
247     }
248
249     return true;
250 }
251
252 bool
253 BeBoB::BCD::read( int addr, fb_octlet_t* o )
254 {
255     if ( std::fseek( m_file, addr, SEEK_SET ) == -1 ) {
256         debugError( "read: seek to position 0x%08x failed\n", addr );
257         return false;
258     }
259
260     size_t bytes_read = std::fread( o, 1, sizeof( *o ), m_file );
261     if ( bytes_read  != sizeof( *o ) ) {
262         debugError( "read: %d byte read failed at position 0x%08x\n",
263                     sizeof( *o ), addr );
264         return false;
265     }
266
267     return true;
268 }
269
270 bool
271 BeBoB::BCD::read( int addr, unsigned char* b, size_t len )
272 {
273     if ( std::fseek( m_file, addr, SEEK_SET ) == -1 ) {
274         debugError( "read: seek to position 0x%08x failed\n", addr );
275         return false;
276     }
277
278     size_t bytes_read = std::fread( b, 1, len, m_file );
279     if ( bytes_read  != len ) {
280         debugError( "read: %d byte read failed at position 0x%08x\n",
281                     len, addr );
282         return false;
283     }
284
285     return true;
286 }
287
288 void
289 BeBoB::BCD::initCRC32Table()
290 {
291     unsigned long polynomial = 0x04c11db7;
292
293     for ( int i = 0; i <= 0xff; ++i ) {
294         crc32_table[i] = reflect( i, 8 ) << 24;
295         for ( int j = 0; j < 8; ++j ) {
296             crc32_table[i] =
297                 (crc32_table[i] << 1)
298                 ^ (crc32_table[i] & (1 << 31) ? polynomial : 0);
299         }
300         crc32_table[i] = reflect( crc32_table[i], 32 );
301     }
302 }
303
304 unsigned long
305 BeBoB::BCD::reflect( unsigned long ref, char ch )
306 {
307     unsigned long value = 0;
308
309     for ( int i = 1; i < (ch + 1); ++i ) {
310         if(ref & 1) {
311             value |= 1 << (ch - i);
312         }
313         ref >>= 1;
314     }
315     return value;
316 }
317
318 unsigned int
319 BeBoB::BCD::getCRC( unsigned char* text, size_t len )
320 {
321     unsigned long crc = 0xffffffff;
322     unsigned char* buffer;
323
324     buffer = text;
325     while ( len-- ) {
326         crc = (crc >> 8) ^ crc32_table[(crc & 0xff) ^ *buffer++];
327     }
328
329     return crc ^ 0xffffffff;
330 }
331
332 bool
333 BeBoB::BCD::checkHeaderCRC( unsigned int crcOffset, unsigned int headerSize )
334 {
335     fb_quadlet_t headerCRC;
336     if ( !read( crcOffset, &headerCRC ) ) {
337         debugError( "checkHeaderCRC: Could not read header CRC\n" );
338         return false;
339     }
340
341     const int headerLength = headerSize;
342     unsigned char buf[headerLength];
343     if ( !read( 0x00, buf, headerLength ) ) {
344         debugError( "checkHeaderCRC: Could not read complete header from file\n" );
345         return false;
346     }
347     buf[crcOffset+0] = 0x00;
348     buf[crcOffset+1] = 0x00;
349     buf[crcOffset+2] = 0x00;
350     buf[crcOffset+3] = 0x00;
351
352     fb_quadlet_t calcCRC = getCRC( buf, headerLength );
353     if ( headerCRC != calcCRC ) {
354         debugError( "checkHeaderCRC: CRC check failed, 0x%08x expected, "
355                     "0x%08x calculated\n", headerCRC, calcCRC );
356         return false;
357     }
358
359     return true;
360 }
361
362 void
363 BeBoB::BCD::displayInfo()
364 {
365     using namespace std;
366
367     printf( "BCD Info\n" );
368     printf( "\tBCD File Version\t%d\n", m_bcd_version );
369     printf( "\tSoftware Date:\t\t%s, %s\n",
370             makeDate( m_softwareDate ).c_str(),
371             makeTime( m_softwareTime ).c_str() );
372     printf( "\tSoftware Version:\t0x%08x\n", m_softwareVersion );
373     printf( "\tSoftware Id:\t\t0x%08x\n", m_softwareId );
374     printf( "\tHardware ID:\t\t0x%08x\n", m_hardwareId );
375     printf( "\tVendor OUI:\t\t0x%08x\n", m_vendorOUI );
376     printf( "\tImage Offset:\t\t0x%08x\n", m_imageOffset );
377     printf( "\tImage Base Address:\t0x%08x\n", m_imageBaseAddress );
378     printf( "\tImage Length:\t\t0x%08x\n", m_imageLength );
379     printf( "\tImage CRC:\t\t0x%08x\n", m_imageCRC );
380     printf( "\tCNE Length:\t\t0x%08x\n", m_cneLength );
381     printf( "\tCNE Offset:\t\t0x%08x\n", m_cneOffset );
382     printf( "\tCNE CRC:\t\t0x%08x\n", m_cneCRC );
383 }
384
Note: See TracBrowser for help on using the browser.