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

Revision 864, 7.4 kB (checked in by ppalmers, 15 years ago)

update license to GPLv2 or GPLv3 instead of GPLv2 or any later version. Update copyrights to reflect the new year

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     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 &= 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 = 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     result &= deserializePlugVector( basePath + "m_plugs", deser,
283                                      unit.getPlugManager(), pSubunit->m_plugs );
284     result &= pSubunit->deserializeChild( basePath, deser, unit );
285
286     if ( !result ) {
287         delete pSubunit;
288         return 0;
289     }
290
291     return pSubunit;
292 }
293
294 }
Note: See TracBrowser for help on using the browser.