root/trunk/libffado/src/libavc/general/avc_generic.cpp

Revision 1234, 8.8 kB (checked in by holin, 15 years ago)

fix gcc 4.3 compile errors and some warnings (largely from Adrian Knoth)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2  * Copyright (C) 2005-2008 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 2 of the License, or
12  * (at your option) version 3 of the License.
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 "avc_generic.h"
25 #include "libutil/cmd_serialize.h"
26 #include "libieee1394/ieee1394service.h"
27
28 #include "debugmodule/debugmodule.h"
29
30 #include "libutil/Time.h"
31
32 #include "libutil/ByteSwap.h"
33
34 #include <cstring>
35 #include <cstdlib>
36
37 #define DEBUG_EXTRA_VERBOSE 5
38
39
40 namespace AVC {
41
42 IMPL_DEBUG_MODULE( AVCCommand, AVCCommand, DEBUG_LEVEL_NORMAL );
43 IMPL_DEBUG_MODULE( IBusData, IBusData, DEBUG_LEVEL_VERBOSE );
44
45 int AVCCommand::m_time = 0;
46
47 AVCCommand::AVCCommand( Ieee1394Service& ieee1394service,
48                         opcode_t opcode )
49     : m_p1394Service( &ieee1394service )
50     , m_nodeId( 0 )
51     , m_ctype( eCT_Unknown )
52     , m_subunit( 0xff )
53     , m_opcode( opcode )
54     , m_eResponse( eR_Unknown )
55 {
56
57 }
58
59 bool
60 AVCCommand::serialize( Util::Cmd::IOSSerialize& se )
61 {
62     // XXX \todo improve Util::Cmd::IOSSerialize::write interface
63     char* buf;
64     asprintf( &buf, "AVCCommand ctype ('%s')",
65               responseToString( static_cast<AVCCommand::EResponse>( m_ctype ) ) );
66     se.write( m_ctype, buf );
67     free( buf );
68
69     asprintf( &buf, "AVCCommand subunit (subunit_type = %d, subunit_id = %d)",
70               getSubunitType(), getSubunitId() );
71     se.write( m_subunit, buf );
72     free( buf );
73
74     se.write( m_opcode, "AVCCommand opcode" );
75     return true;
76 }
77
78 bool
79 AVCCommand::deserialize( Util::Cmd::IISDeserialize& de )
80 {
81     de.read( &m_ctype );
82     de.read( &m_subunit );
83     de.read( &m_opcode );
84     return true;
85 }
86
87 bool
88 AVCCommand::setCommandType( ECommandType commandType )
89 {
90     m_ctype = commandType;
91     m_commandType = commandType;
92     return true;
93 }
94
95 AVCCommand::ECommandType
96 AVCCommand::getCommandType()
97 {
98     return m_commandType;
99 }
100
101 AVCCommand::EResponse
102 AVCCommand::getResponse()
103 {
104     return m_eResponse;
105 }
106
107 bool
108 AVCCommand::setSubunitType(ESubunitType subunitType)
109 {
110     byte_t subT = subunitType;
111
112     m_subunit = ( subT << 3 ) | ( m_subunit & 0x7 );
113     return true;
114 }
115
116 bool
117 AVCCommand::setNodeId( fb_nodeid_t nodeId )
118 {
119     m_nodeId = nodeId;
120     return true;
121 }
122
123 bool
124 AVCCommand::setSubunitId(subunit_id_t subunitId)
125 {
126     m_subunit = ( subunitId & 0x7 ) | ( m_subunit & 0xf8 );
127     return true;
128 }
129
130 ESubunitType
131 AVCCommand::getSubunitType()
132 {
133     return static_cast<ESubunitType>( ( m_subunit >> 3 ) );
134 }
135
136 subunit_id_t
137 AVCCommand::getSubunitId()
138 {
139     return m_subunit & 0x7;
140 }
141
142 bool
143 AVCCommand::setVerbose( int verboseLevel )
144 {
145     setDebugLevel(verboseLevel);
146     return true;
147 }
148
149 int
150 AVCCommand::getVerboseLevel()
151 {
152     return getDebugLevel();
153 }
154
155
156 void
157 AVCCommand::showFcpFrame( const unsigned char* buf,
158                           unsigned short frameSize ) const
159 {
160     // use an intermediate buffer to avoid a load of very small print's that cause the
161     // message ringbuffer to overflow
162     char msg[DEBUG_MAX_MESSAGE_LENGTH];
163     int chars_written=0;
164     for ( int i = 0; i < frameSize; ++i ) {
165         if ( ( i % 16 ) == 0 ) {
166             if ( i > 0 ) {
167                 debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%s\n", msg);
168                 chars_written=0;
169             }
170             chars_written+=snprintf(msg+chars_written,DEBUG_MAX_MESSAGE_LENGTH-chars_written,"  %3d:\t", i );;
171         } else if ( ( i % 4 ) == 0 ) {
172             chars_written+=snprintf(msg+chars_written,DEBUG_MAX_MESSAGE_LENGTH-chars_written," ");
173         }
174         chars_written+=snprintf(msg+chars_written,DEBUG_MAX_MESSAGE_LENGTH-chars_written, "%02x ", buf[i] );
175     }
176     if (chars_written != 0) {
177         debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%s\n", msg );
178     } else {
179         debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "\n" );
180     }
181 }
182
183 bool
184 AVCCommand::fire()
185 {
186     memset( &m_fcpFrame,  0x0,  sizeof( m_fcpFrame ) );
187
188     Util::Cmd::BufferSerialize se( m_fcpFrame, sizeof( m_fcpFrame ) );
189     if ( !serialize( se ) ) {
190         debugFatal(  "fire: Could not serialize\n" );
191         return false;
192     }
193
194     unsigned short fcpFrameSize = se.getNrOfProducesBytes();
195
196     if (getDebugLevel() >= DEBUG_LEVEL_VERY_VERBOSE) {
197         debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE, "%s:\n", getCmdName() );
198         debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE,  "  Request:\n");
199         showFcpFrame( m_fcpFrame, fcpFrameSize );
200
201         Util::Cmd::StringSerializer se_dbg;
202         serialize( se_dbg );
203        
204         // output the debug message in smaller chunks to avoid problems
205         // with a max message size
206         unsigned int chars_to_write=se_dbg.getString().size();
207         unsigned int chars_written=0;
208         while (chars_written<chars_to_write) {
209             debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%s\n",
210                          se_dbg.getString().substr(chars_written, DEBUG_MAX_MESSAGE_LENGTH).c_str());
211             chars_written += DEBUG_MAX_MESSAGE_LENGTH-1;
212         }
213     }
214
215     unsigned int resp_len;
216     quadlet_t* resp = m_p1394Service->transactionBlock( m_nodeId,
217                                                         (quadlet_t*)m_fcpFrame,
218                                                         ( fcpFrameSize+3 ) / 4,
219                                                         &resp_len );
220     bool result = false;
221     if ( resp ) {
222         resp_len *= 4;
223         unsigned char* buf = ( unsigned char* ) resp;
224
225         m_eResponse = ( EResponse )( *buf );
226         switch ( m_eResponse )
227         {
228         case eR_Accepted:
229         case eR_Implemented:
230         case eR_Rejected:
231         case eR_NotImplemented:
232         {
233             Util::Cmd::BufferDeserialize de( buf, resp_len );
234             result = deserialize( de );
235
236             debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE,"  Response:\n");
237             showFcpFrame( buf, de.getNrOfConsumedBytes() );
238
239             Util::Cmd::StringSerializer se_dbg;
240             serialize( se_dbg );
241
242             // output the debug message in smaller chunks to avoid problems
243             // with a max message size
244             unsigned int chars_to_write=se_dbg.getString().size();
245             unsigned int chars_written=0;
246             while (chars_written<chars_to_write) {
247                 debugOutputShort(DEBUG_LEVEL_VERY_VERBOSE, "%s\n",
248                             se_dbg.getString().substr(chars_written, DEBUG_MAX_MESSAGE_LENGTH).c_str());
249                 chars_written += DEBUG_MAX_MESSAGE_LENGTH-1;
250             }
251
252         }
253         break;
254         default:
255             debugWarning( "unexpected response received (0x%x)\n", m_eResponse );
256             debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE,"  Response:\n");
257
258             Util::Cmd::BufferDeserialize de( buf, resp_len );
259             deserialize( de );
260
261             showFcpFrame( buf, de.getNrOfConsumedBytes() );
262
263         }
264     } else {
265        debugWarning( "no response\n" );
266     }
267
268     debugOutputShort( DEBUG_LEVEL_VERY_VERBOSE, "\n" );
269
270     m_p1394Service->transactionBlockClose();
271
272     SleepRelativeUsec( m_time );
273
274     return result;
275 }
276
277 void
278 AVCCommand::setSleepAfterAVCCommand( int time )
279 {
280     m_time = time;
281 }
282
283 const char* subunitTypeStrings[] =
284 {
285     "Monitor",
286     "Audio",
287     "Printer",
288     "Disc recorder",
289     "Tape recorder/VCR",
290     "Tuner",
291     "CA",
292     "Video camera",
293     "unknown",
294     "Panel",
295     "Bulletin board",
296     "Camera storage",
297     "Music",
298 };
299
300 const char*
301 subunitTypeToString( subunit_type_t subunitType )
302 {
303     if ( subunitType == eST_Unit ) {
304         return "Unit";
305     }
306     if ( subunitType > ( int ) ( sizeof( subunitTypeStrings )
307              / sizeof( subunitTypeStrings[0] ) ) ) {
308         return "unknown";
309     } else {
310         return subunitTypeStrings[subunitType];
311     }
312 }
313
314 const char* responseToStrings[] =
315 {
316     "control",
317     "status",
318     "specific inquiry",
319     "notify",
320     "general inquiry",
321     "reserved for future specification",
322     "reserved for future specification",
323     "reserved for future specification",
324     "not implemented",
325     "accepted",
326     "rejected",
327     "in transition",
328     "implemented/stable",
329     "changed"
330     "reserved for future specification",
331     "interim",
332 };
333
334 const char*
335 responseToString( AVCCommand::EResponse eResponse )
336 {
337     if ( eResponse > ( int )( sizeof( responseToStrings ) / sizeof( responseToStrings[0] ) ) ) {
338         return "unknown";
339     }
340     return responseToStrings[eResponse];
341 }
342
343 }
Note: See TracBrowser for help on using the browser.