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

Revision 1110, 7.4 kB (checked in by wagi, 14 years ago)

Lot's of small and big bug fixes allong the caching path.
There were several parts not correctly deserialized.

This should fix ticket #65

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  * Copyright (C) 2005-2008 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 program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
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     setDebugLevel(l);
72     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", 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     debugOutput(DEBUG_LEVEL_NORMAL, "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 &= serializePlugVector( basePath + "m_plugs", ser, m_plugs );
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 = unit.createSubunit(unit, sbType, 0);
261
262     if ( !pSubunit ) {
263         return 0;
264     }
265
266     pSubunit->m_unit = &unit;
267     pSubunit->m_sbType = sbType;
268     result &= deser.read( basePath + "m_sbId", pSubunit->m_sbId );
269     result &= pSubunit->deserializeChild( basePath, deser, unit );
270
271     if ( !result ) {
272         delete pSubunit;
273         return 0;
274     }
275
276     return pSubunit;
277 }
278
279 bool
280 Subunit::deserializeUpdate( Glib::ustring basePath,
281                             Util::IODeserialize& deser )
282 {
283     bool result;
284     std::ostringstream strstrm;
285     strstrm << basePath << m_sbId << "/";
286
287     result  = deserializePlugVector( strstrm.str() + "m_plugs", deser,
288                                      m_unit->getPlugManager(), m_plugs );   
289     result &= deserializeUpdateChild( strstrm.str(), deser );
290    
291     return result;
292 }
293
294 }
Note: See TracBrowser for help on using the browser.