root/trunk/libffado/src/bebob/bebob_dl_bcd.cpp

Revision 742, 9.5 kB (checked in by ppalmers, 13 years ago)

- Remove some obsolete support files and dirs

- Clean up the license statements in the source files. Everything is

GPL version 3 now.

- Add license and copyright notices to scons scripts

- Clean up some other text files

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