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

Revision 742, 8.7 kB (checked in by ppalmers, 16 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

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