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

Revision 618, 7.5 kB (checked in by ppalmers, 17 years ago)

move serialization routines to libutil such that they can be used for non-AVC stuff too (fireworks EFC)

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 &= serializeChild( basePath, ser );
242
243     return result;
244 }
245
246 Subunit*
247 Subunit::deserialize( Glib::ustring basePath,
248                       Util::IODeserialize& deser,
249                       Unit& unit )
250 {
251     bool result;
252     ESubunitType sbType;
253
254     if ( !deser.isExisting( basePath + "m_sbType" ) ) {
255         return 0;
256     }
257
258     result  = deser.read( basePath + "m_sbType", sbType );
259
260     Subunit* pSubunit = 0;
261    
262     #warning FIXME: The derived class should be creating these
263     // FIXME: The derived class should be creating these, such that discover() can become pure virtual
264     switch( sbType ) {
265     case eST_Audio:
266         pSubunit = new SubunitAudio;
267         break;
268     case eST_Music:
269         pSubunit = new SubunitMusic;
270         break;
271     default:
272         pSubunit = 0;
273     }
274
275     if ( !pSubunit ) {
276         return 0;
277     }
278
279     pSubunit->m_unit = &unit;
280     pSubunit->m_sbType = sbType;
281     result &= deser.read( basePath + "m_sbId", pSubunit->m_sbId );
282     int verboseLevel;
283     result &= deser.read( basePath + "m_verboseLevel", verboseLevel );
284     setDebugLevel(verboseLevel);
285     result &= pSubunit->deserializeChild( basePath, deser, unit );
286
287     if ( !result ) {
288         delete pSubunit;
289         return 0;
290     }
291
292     return pSubunit;
293 }
294
295 }
Note: See TracBrowser for help on using the browser.