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

Revision 716, 7.7 kB (checked in by wagi, 13 years ago)

cache bebob avc model. lot's of small bug fixed. it should work now.

Line 
1 /*
2  * Copyright (C)      2007 by Pieter Palmers
3  * Copyright (C) 2005-2007 by Daniel Wagner
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License version 2.1, as published by the Free Software Foundation;
13  *
14  * This library 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 GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22  * MA 02110-1301 USA
23  */
24
25
26 #include "avc_subunit.h"
27 #include "../general/avc_unit.h"
28 #include "../general/avc_plug.h"
29
30 #include "libieee1394/configrom.h"
31
32 #include "../general/avc_plug_info.h"
33 #include "../streamformat/avc_extended_stream_format.h"
34 #include "libutil/cmd_serialize.h"
35
36 #include <sstream>
37
38 namespace AVC {
39
40 IMPL_DEBUG_MODULE( Subunit, Subunit, DEBUG_LEVEL_NORMAL );
41
42 ////////////////////////////////////////////
43
44 Subunit::Subunit( Unit& unit,
45                   ESubunitType type,
46                   subunit_t id )
47     : m_unit( &unit )
48     , m_sbType( type )
49     , m_sbId( id )
50 {
51
52 }
53
54 Subunit::Subunit()
55 {
56 }
57
58 Subunit::~Subunit()
59 {
60     for ( PlugVector::iterator it = m_plugs.begin();
61           it != m_plugs.end();
62           ++it )
63     {
64         delete *it;
65     }
66 }
67
68 void
69 Subunit::setVerboseLevel(int l)
70 {
71     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
72     setDebugLevel(l);
73 }
74
75
76 Plug *
77 Subunit::createPlug( AVC::Unit* unit,
78                      AVC::Subunit* subunit,
79                      AVC::function_block_type_t functionBlockType,
80                      AVC::function_block_type_t functionBlockId,
81                      AVC::Plug::EPlugAddressType plugAddressType,
82                      AVC::Plug::EPlugDirection plugDirection,
83                      AVC::plug_id_t plugId )
84 {
85
86     return new Plug( unit,
87                      subunit,
88                      functionBlockType,
89                      functionBlockId,
90                      plugAddressType,
91                      plugDirection,
92                      plugId );
93 }
94
95 bool
96 Subunit::discover()
97 {
98     if ( !discoverPlugs() ) {
99         debugError( "plug discovery failed\n" );
100         return false;
101     }
102     return true;
103 }
104
105 bool
106 Subunit::discoverPlugs()
107 {
108     debugOutput(DEBUG_LEVEL_NORMAL, "Discovering plugs...\n");
109
110     PlugInfoCmd plugInfoCmd( getUnit().get1394Service(),
111                              PlugInfoCmd::eSF_SerialBusIsochronousAndExternalPlug );
112     plugInfoCmd.setNodeId( getUnit().getConfigRom().getNodeId() );
113     plugInfoCmd.setCommandType( AVCCommand::eCT_Status );
114     plugInfoCmd.setSubunitType( getSubunitType() );
115     plugInfoCmd.setSubunitId( getSubunitId() );
116     plugInfoCmd.setVerbose( getDebugLevel() );
117
118     if ( !plugInfoCmd.fire() ) {
119         debugError( "plug info command failed\n" );
120         return false;
121     }
122
123     debugOutput( DEBUG_LEVEL_VERBOSE, "number of source plugs = %d\n",
124                  plugInfoCmd.m_sourcePlugs );
125     debugOutput( DEBUG_LEVEL_VERBOSE, "number of destination output "
126                  "plugs = %d\n", plugInfoCmd.m_destinationPlugs );
127
128     if ( !discoverPlugs( Plug::eAPD_Input,
129                          plugInfoCmd.m_destinationPlugs ) )
130     {
131         debugError( "destination plug discovering failed\n" );
132         return false;
133     }
134
135     if ( !discoverPlugs(  Plug::eAPD_Output,
136                           plugInfoCmd.m_sourcePlugs ) )
137     {
138         debugError( "source plug discovering failed\n" );
139         return false;
140     }
141
142     return true;
143 }
144
145 bool
146 Subunit::discoverConnections()
147 {
148     debugOutput(DEBUG_LEVEL_NORMAL, "Discovering connections...\n");
149
150     for ( PlugVector::iterator it = getPlugs().begin();
151           it != getPlugs().end();
152           ++it )
153     {
154         Plug* plug = *it;
155         if ( !plug->discoverConnections() ) {
156             debugError( "plug connection discovering failed ('%s')\n",
157                         plug->getName() );
158             return false;
159         }
160     }
161
162     return true;
163 }
164
165 bool
166 Subunit::discoverPlugs(Plug::EPlugDirection plugDirection,
167                                       plug_id_t plugMaxId )
168 {
169     debugOutput(DEBUG_LEVEL_VERBOSE, "Discovering plugs for direction %d...\n", plugDirection);
170     for ( int plugIdx = 0;
171           plugIdx < plugMaxId;
172           ++plugIdx )
173     {
174         Plug* plug = createPlug(  &getUnit(),
175                                 &getSubunit(),
176                                 0xff,
177                                 0xff,
178                                 Plug::eAPA_SubunitPlug,
179                                 plugDirection,
180                                 plugIdx );
181         if ( !plug ) {
182             debugError( "plug creation failed\n" );
183             return false;
184         }
185
186         plug->setVerboseLevel(getDebugLevel());
187
188         if ( !plug->discover() ) {
189             debugError( "plug discover failed\n" );
190             return false;
191         }
192
193         debugOutput( DEBUG_LEVEL_VERBOSE, "plug '%s' found\n",
194                      plug->getName() );
195         getPlugs().push_back( plug );
196     }
197     return true;
198 }
199
200 bool
201 Subunit::addPlug( Plug& plug )
202 {
203     m_plugs.push_back( &plug );
204     return true;
205 }
206
207
208 Plug*
209 Subunit::getPlug(Plug::EPlugDirection direction, plug_id_t plugId)
210 {
211     for ( PlugVector::iterator it = m_plugs.begin();
212           it != m_plugs.end();
213           ++it )
214     {
215         Plug* plug = *it;
216         if ( ( plug->getPlugId() == plugId )
217             && ( plug->getDirection() == direction ) )
218         {
219             return plug;
220         }
221     }
222     return 0;
223 }
224
225 bool
226 Subunit::initPlugFromDescriptor( Plug& plug )
227 {
228     debugError("plug loading from descriptor not implemented\n");
229     return false;
230 }
231
232 bool
233 Subunit::serialize( Glib::ustring basePath,
234                     Util::IOSerialize& ser ) const
235 {
236     bool result;
237
238     result  = ser.write( basePath + "m_sbType", m_sbType );
239     result &= ser.write( basePath + "m_sbId", m_sbId );
240     result &= ser.write( basePath + "m_verboseLevel", getDebugLevel() );
241     result &= serializePlugVector( basePath + "m_plugs", ser, m_plugs );
242     result &= serializeChild( basePath, ser );
243
244     return result;
245 }
246
247 Subunit*
248 Subunit::deserialize( Glib::ustring basePath,
249                       Util::IODeserialize& deser,
250                       Unit& unit )
251 {
252     bool result;
253     ESubunitType sbType;
254
255     if ( !deser.isExisting( basePath + "m_sbType" ) ) {
256         return 0;
257     }
258
259     result  = deser.read( basePath + "m_sbType", sbType );
260
261     Subunit* pSubunit = 0;
262
263     #warning FIXME: The derived class should be creating these
264     // FIXME: The derived class should be creating these, such that discover() can become pure virtual
265     switch( sbType ) {
266     case eST_Audio:
267         pSubunit = new SubunitAudio;
268         break;
269     case eST_Music:
270         pSubunit = new SubunitMusic;
271         break;
272     default:
273         pSubunit = 0;
274     }
275
276     if ( !pSubunit ) {
277         return 0;
278     }
279
280     pSubunit->m_unit = &unit;
281     pSubunit->m_sbType = sbType;
282     result &= deser.read( basePath + "m_sbId", pSubunit->m_sbId );
283     result &= deserializePlugVector( basePath + "m_plugs", deser,
284                                      unit.getPlugManager(), pSubunit->m_plugs );
285     int verboseLevel;
286     result &= deser.read( basePath + "m_verboseLevel", verboseLevel );
287     setDebugLevel(verboseLevel);
288     result &= pSubunit->deserializeChild( basePath, deser, unit );
289
290     if ( !result ) {
291         delete pSubunit;
292         return 0;
293     }
294
295     return pSubunit;
296 }
297
298 }
Note: See TracBrowser for help on using the browser.