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

Revision 2732, 31.6 kB (checked in by jwoithe, 3 years ago)

Fix typos throughout the source tree.

Rectify some long-lived typos in strings throughout the source code. in the
FFADO desktop file. This benefits Debian and possibly others. Patch by
Nicolas Boulenguez for Debian and provided to FFADO by Benoit Delcour via
the ffado-user mailing list.

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 #include "avc_unit.h"
26 #include "avc_subunit.h"
27 #include "avc_plug.h"
28
29 #include "libieee1394/configrom.h"
30 #include "libieee1394/ieee1394service.h"
31
32 #include "../general/avc_plug_info.h"
33 #include "../general/avc_extended_plug_info.h"
34 #include "../general/avc_subunit_info.h"
35 #include "../streamformat/avc_extended_stream_format.h"
36 #include "libutil/cmd_serialize.h"
37 #include "../avc_definitions.h"
38
39 #include "debugmodule/debugmodule.h"
40
41 #include <iostream>
42 #include <sstream>
43
44 namespace AVC {
45
46 IMPL_DEBUG_MODULE( Unit, Unit, DEBUG_LEVEL_NORMAL );
47
48 Unit::Unit( )
49     : m_pPlugManager( new PlugManager( ) )
50 {
51     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Unit\n" );
52     m_pPlugManager->setVerboseLevel( getDebugLevel() );
53 }
54
55 Unit::~Unit()
56 {
57     clean();
58 }
59
60 Plug *
61 Unit::createPlug( Unit* unit,
62                   Subunit* subunit,
63                   function_block_type_t functionBlockType,
64                   function_block_type_t functionBlockId,
65                   Plug::EPlugAddressType plugAddressType,
66                   Plug::EPlugDirection plugDirection,
67                   plug_id_t plugId,
68                   int globalId )
69 {
70
71     Plug *p= new Plug( unit,
72                        subunit,
73                        functionBlockType,
74                        functionBlockId,
75                        plugAddressType,
76                        plugDirection,
77                        plugId,
78                        globalId );
79     if (p) p->setVerboseLevel(getDebugLevel());
80     return p;
81 }
82
83 Subunit*
84 Unit::createSubunit(Unit& unit,
85                     ESubunitType type,
86                     subunit_t id )
87 {
88     Subunit* s=NULL;
89     switch (type) {
90         case eST_Audio:
91             s=new SubunitAudio(unit, id );
92             break;
93         case eST_Music:
94             s=new SubunitMusic(unit, id );
95             break;
96         default:
97             s=NULL;
98             break;
99     }
100     if(s) s->setVerboseLevel(getDebugLevel());
101     return s;
102 }
103
104 void
105 Unit::setVerboseLevel(int l)
106 {
107     setDebugLevel(l);
108     for ( SubunitVector::const_iterator it = m_subunits.begin();
109           it != m_subunits.end();
110           ++it )
111     {
112         (*it)->setVerboseLevel(l);
113     }
114     m_pPlugManager->setVerboseLevel(l);
115     debugOutput( DEBUG_LEVEL_VERBOSE, "Setting verbose level to %d...\n", l );
116 }
117
118 // prepare the device for a rediscovery
119 bool
120 Unit::clean()
121 {
122     for ( SubunitVector::iterator it = m_subunits.begin();
123           it != m_subunits.end();
124           ++it )
125     {
126         delete *it;
127     }
128     m_subunits.clear();
129
130     for ( PlugVector::iterator it = m_pcrPlugs.begin();
131           it != m_pcrPlugs.end();
132           ++it )
133     {
134         delete *it;
135     }
136     m_pcrPlugs.clear();
137
138     for ( PlugVector::iterator it = m_externalPlugs.begin();
139           it != m_externalPlugs.end();
140           ++it )
141     {
142         delete *it;
143     }
144     m_externalPlugs.clear();
145
146     for ( PlugConnectionVector::iterator it = m_plugConnections.begin();
147           it != m_plugConnections.end();
148           ++it )
149     {
150         delete *it;
151     }
152     m_plugConnections.clear();
153
154     delete m_pPlugManager;
155     m_pPlugManager = new PlugManager();
156
157     if (m_pPlugManager == NULL) {
158         debugError("Could not create new plugmanager\n");
159         return false;
160     }
161
162     m_syncInfos.clear();
163
164     return true;
165 }
166
167 bool
168 Unit::discover()
169 {
170     debugOutput( DEBUG_LEVEL_VERBOSE, "Discovering AVC::Unit...\n");
171     if( !clean() ) {
172         debugError( "Could not clean unit data structures\n" );
173         return false;
174     }
175
176     if ( !enumerateSubUnits() ) {
177         debugError( "Could not enumerate sub units\n" );
178         return false;
179     }
180
181     if ( !discoverPlugs() ) {
182         debugError( "Detecting plugs failed\n" );
183         return false;
184     }
185
186     if ( !rediscoverConnections() ) {
187         debugError( "Detecting connections failed\n" );
188         return false;
189     }
190
191     if ( !discoverSyncModes() ) {
192         debugError( "Detecting sync modes failed\n" );
193         return false;
194     }
195
196     if ( !propagatePlugInfo() ) {
197         debugError( "Failed to propagate plug info\n" );
198         return false;
199     }
200
201     return true;
202 }
203
204 bool
205 Unit::rediscoverConnections() {
206     debugOutput( DEBUG_LEVEL_VERBOSE, "Re-discovering plug connections...\n");
207
208     // clear the previous connections
209     for ( PlugConnectionVector::iterator it = m_plugConnections.begin();
210           it != m_plugConnections.end();
211           ++it )
212     {
213         delete *it;
214     }
215     m_plugConnections.clear();
216
217     if ( !discoverPlugConnections() ) {
218         debugError( "Detecting plug connections failed\n" );
219         return false;
220     }
221
222     if ( !discoverSubUnitsPlugConnections() ) {
223         debugError( "Detecting subunit plug connections failed\n" );
224         return false;
225     }
226
227     if ( !m_pPlugManager->tidyPlugConnections(m_plugConnections) ) {
228         debugError( "Tidying of plug connections failed\n" );
229         return false;
230     }
231     return true;
232 }
233
234 bool
235 Unit::enumerateSubUnits()
236 {
237     SubUnitInfoCmd subUnitInfoCmd( get1394Service() );
238     subUnitInfoCmd.setCommandType( AVCCommand::eCT_Status );
239
240     // NOTE: BeBoB has always exactly one audio and one music subunit. This
241     // means is fits into the first page of the SubUnitInfo command.
242     // So there is no need to do more than needed
243     // FIXME: to be fully spec compliant this needs to be fixed, but let's not
244     //        do that for now
245
246     subUnitInfoCmd.m_page = 0;
247     subUnitInfoCmd.setNodeId( getConfigRom().getNodeId() );
248     subUnitInfoCmd.setVerbose( getDebugLevel() );
249     if ( !subUnitInfoCmd.fire() ) {
250         debugError( "Subunit info command failed\n" );
251         // shouldn't this be an error situation?
252         return false;
253     }
254
255     for ( int i = 0; i < subUnitInfoCmd.getNrOfValidEntries(); ++i ) {
256         subunit_type_t subunit_type
257             = subUnitInfoCmd.m_table[i].m_subunit_type;
258
259         unsigned int subunitId = getNrOfSubunits( subunit_type );
260
261         debugOutput( DEBUG_LEVEL_VERBOSE,
262                      "subunit_id = %2d, subunit_type = %2d (%s)\n",
263                      subunitId,
264                      subunit_type,
265                      subunitTypeToString( subunit_type ) );
266
267         Subunit* subunit = 0;
268         switch( subunit_type ) {
269         case eST_Audio:
270             subunit = createSubunit( *this, eST_Audio, subunitId );
271             if ( !subunit ) {
272                 debugFatal( "Could not allocate SubunitAudio\n" );
273                 return false;
274             }
275
276             subunit->setVerboseLevel(getDebugLevel());
277
278             if ( !subunit->discover() ) {
279                 debugError( "enumerateSubUnits: Could not discover "
280                             "subunit_id = %2d, subunit_type = %2d (%s)\n",
281                             subunitId,
282                             subunit_type,
283                             subunitTypeToString( subunit_type ) );
284                 delete subunit;
285                 return false;
286             } else {
287                 m_subunits.push_back( subunit );
288             }
289
290             break;
291         case eST_Music:
292             subunit = createSubunit( *this, eST_Music, subunitId );
293             if ( !subunit ) {
294                 debugFatal( "Could not allocate SubunitMusic\n" );
295                 return false;
296             }
297
298             subunit->setVerboseLevel(getDebugLevel());
299
300             if ( !subunit->discover() ) {
301                 debugError( "enumerateSubUnits: Could not discover "
302                             "subunit_id = %2d, subunit_type = %2d (%s)\n",
303                             subunitId,
304                             subunit_type,
305                             subunitTypeToString( subunit_type ) );
306                 delete subunit;
307                 return false;
308             } else {
309                 m_subunits.push_back( subunit );
310             }
311
312             break;
313         default:
314             debugOutput( DEBUG_LEVEL_NORMAL,
315                          "Unsupported subunit found, subunit_type = %d (%s)\n",
316                          subunit_type,
317                          subunitTypeToString( subunit_type ) );
318             continue;
319
320         }
321     }
322
323     return true;
324 }
325
326 Subunit*
327 Unit::getSubunit( subunit_type_t subunitType,
328                       subunit_id_t subunitId ) const
329 {
330     for ( SubunitVector::const_iterator it = m_subunits.begin();
331           it != m_subunits.end();
332           ++it )
333     {
334         Subunit* subunit = *it;
335         if ( ( subunitType == subunit->getSubunitType() )
336              && ( subunitId == subunit->getSubunitId() ) )
337         {
338             return subunit;
339         }
340     }
341
342     return 0;
343 }
344
345 unsigned int
346 Unit::getNrOfSubunits( subunit_type_t subunitType ) const
347 {
348     unsigned int nrOfSubunits = 0;
349
350     for ( SubunitVector::const_iterator it = m_subunits.begin();
351           it != m_subunits.end();
352           ++it )
353     {
354         Subunit* subunit = *it;
355         if ( subunitType == subunit->getSubunitType() ) {
356             nrOfSubunits++;
357         }
358     }
359
360     return nrOfSubunits;
361 }
362
363 bool
364 Unit::discoverPlugs()
365 {
366     debugOutput( DEBUG_LEVEL_NORMAL, "Discovering plugs...\n");
367
368     //////////////////////////////////////////////
369     // Get number of available isochronous input
370     // and output plugs of unit
371
372     PlugInfoCmd plugInfoCmd( get1394Service() );
373     plugInfoCmd.setNodeId( getConfigRom().getNodeId() );
374     plugInfoCmd.setCommandType( AVCCommand::eCT_Status );
375     plugInfoCmd.setVerbose( getDebugLevel() );
376
377     if ( !plugInfoCmd.fire() ) {
378         debugError( "plug info command failed\n" );
379         return false;
380     }
381
382     debugOutput( DEBUG_LEVEL_NORMAL, "number of iso input plugs = %d\n",
383                  plugInfoCmd.m_serialBusIsochronousInputPlugs );
384     debugOutput( DEBUG_LEVEL_NORMAL, "number of iso output plugs = %d\n",
385                  plugInfoCmd.m_serialBusIsochronousOutputPlugs );
386     debugOutput( DEBUG_LEVEL_NORMAL, "number of external input plugs = %d\n",
387                  plugInfoCmd.m_externalInputPlugs );
388     debugOutput( DEBUG_LEVEL_NORMAL, "number of external output plugs = %d\n",
389                  plugInfoCmd.m_externalOutputPlugs );
390
391     if ( !discoverPlugsPCR( Plug::eAPD_Input,
392                             plugInfoCmd.m_serialBusIsochronousInputPlugs ) )
393     {
394         debugError( "pcr input plug discovering failed\n" );
395         return false;
396     }
397
398     if ( !discoverPlugsPCR( Plug::eAPD_Output,
399                             plugInfoCmd.m_serialBusIsochronousOutputPlugs ) )
400     {
401         debugError( "pcr output plug discovering failed\n" );
402         return false;
403     }
404
405     if ( !discoverPlugsExternal( Plug::eAPD_Input,
406                                  plugInfoCmd.m_externalInputPlugs ) )
407     {
408         debugError( "external input plug discovering failed\n" );
409         return false;
410     }
411
412     if ( !discoverPlugsExternal( Plug::eAPD_Output,
413                                  plugInfoCmd.m_externalOutputPlugs ) )
414     {
415         debugError( "external output plug discovering failed\n" );
416         return false;
417     }
418
419     return true;
420 }
421
422 bool
423 Unit::discoverPlugsPCR( Plug::EPlugDirection plugDirection,
424                         plug_id_t plugMaxId )
425 {
426     debugOutput( DEBUG_LEVEL_NORMAL, "Discovering PCR plugs, direction %d...\n",plugDirection);
427     for ( int plugId = 0;
428           plugId < plugMaxId;
429           ++plugId )
430     {
431         Plug* plug  = createPlug( this,
432                                   NULL,
433                                   0xff,
434                                   0xff,
435                                   Plug::eAPA_PCR,
436                                   plugDirection,
437                                   plugId );
438
439         if( plug ) plug->setVerboseLevel(getDebugLevel());
440
441         if ( !plug || !plug->discover() ) {
442             debugError( "plug discovering failed\n" );
443             delete plug;
444             return false;
445         }
446
447         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
448                      plug->getName() );
449         m_pcrPlugs.push_back( plug );
450     }
451
452     return true;
453 }
454
455 bool
456 Unit::discoverPlugsExternal( Plug::EPlugDirection plugDirection,
457                              plug_id_t plugMaxId )
458 {
459     debugOutput( DEBUG_LEVEL_NORMAL, "Discovering External plugs, direction %d...\n",plugDirection);
460     for ( int plugId = 0;
461           plugId < plugMaxId;
462           ++plugId )
463     {
464         Plug* plug  = createPlug( this, NULL,
465                                 0xff,
466                                 0xff,
467                                 Plug::eAPA_ExternalPlug,
468                                 plugDirection,
469                                 plugId );
470
471         if( plug ) plug->setVerboseLevel(getDebugLevel());
472
473         if ( !plug || !plug->discover() ) {
474             debugError( "plug discovering failed\n" );
475             return false;
476         }
477
478         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
479                      plug->getName() );
480         m_externalPlugs.push_back( plug );
481     }
482
483     return true;
484 }
485
486 bool
487 Unit::discoverPlugConnections()
488 {
489     debugOutput( DEBUG_LEVEL_NORMAL, "Discovering PCR plug connections...\n");
490     for ( PlugVector::iterator it = m_pcrPlugs.begin();
491           it != m_pcrPlugs.end();
492           ++it )
493     {
494         Plug* plug = *it;
495         if ( !plug->discoverConnections() ) {
496             debugError( "Could not discover PCR plug connections\n" );
497             return false;
498         }
499     }
500     debugOutput( DEBUG_LEVEL_NORMAL, "Discovering External plug connections...\n");
501     for ( PlugVector::iterator it = m_externalPlugs.begin();
502           it != m_externalPlugs.end();
503           ++it )
504     {
505         Plug* plug = *it;
506         if ( !plug->discoverConnections() ) {
507             debugError( "Could not discover External plug connections\n" );
508             return false;
509         }
510     }
511
512     return true;
513 }
514
515 bool
516 Unit::discoverSubUnitsPlugConnections()
517 {
518     for ( SubunitVector::iterator it = m_subunits.begin();
519           it != m_subunits.end();
520           ++it )
521     {
522         Subunit* subunit = *it;
523
524         if ( !subunit->discoverConnections() ) {
525             debugError( "Subunit '%s'  plug connections failed\n",
526                         subunit->getName() );
527             return false;
528         }
529     }
530     return true;
531 }
532
533 bool
534 Unit::propagatePlugInfo()
535 {
536     debugOutput( DEBUG_LEVEL_NORMAL, "Propagating info to PCR plugs...\n");
537     for ( PlugVector::iterator it = m_pcrPlugs.begin();
538           it != m_pcrPlugs.end();
539           ++it )
540     {
541         Plug* plug = *it;
542         debugOutput( DEBUG_LEVEL_NORMAL, "plug: %s\n", plug->getName());
543         if (!plug->propagateFromConnectedPlug()) {
544             debugWarning( "Could not propagate info for plug '%s'\n", plug->getName());
545         }
546     }
547     debugOutput( DEBUG_LEVEL_NORMAL, "Propagating info to External plugs...\n");
548     for ( PlugVector::iterator it = m_externalPlugs.begin();
549           it != m_externalPlugs.end();
550           ++it )
551     {
552         Plug* plug = *it;
553         debugOutput( DEBUG_LEVEL_NORMAL, "plug: %s\n", plug->getName());
554         if (!plug->propagateFromConnectedPlug()) {
555             debugWarning( "Could not propagate info for plug '%s'\n", plug->getName());
556         }
557     }
558
559     return true;
560
561 }
562
563
564 PlugConnection*
565 Unit::getPlugConnection( Plug& srcPlug ) const
566 {
567     for ( PlugConnectionVector::const_iterator it
568               = m_plugConnections.begin();
569           it != m_plugConnections.end();
570           ++it )
571     {
572         PlugConnection* plugConnection = *it;
573         if ( &( plugConnection->getSrcPlug() ) == &srcPlug ) {
574             return plugConnection;
575         }
576     }
577
578     return 0;
579 }
580
581 Plug*
582 Unit::getPlugById( PlugVector& plugs,
583                    Plug::EPlugDirection plugDirection,
584                    int id )
585 {
586     for ( PlugVector::iterator it = plugs.begin();
587           it != plugs.end();
588           ++it )
589     {
590         Plug* plug = *it;
591         if ( ( id == plug->getPlugId() )
592              && ( plugDirection == plug->getPlugDirection() ) )
593         {
594             return plug;
595         }
596     }
597
598     return 0;
599 }
600
601 PlugVector
602 Unit::getPlugsByType( PlugVector& plugs,
603                       Plug::EPlugDirection plugDirection,
604                       Plug::EPlugType type)
605 {
606     PlugVector plugVector;
607     for ( PlugVector::iterator it = plugs.begin();
608           it != plugs.end();
609           ++it )
610     {
611         Plug* plug = *it;
612         if ( ( type == plug->getPlugType() )
613              && ( plugDirection == plug->getPlugDirection() ) )
614         {
615             plugVector.push_back( plug );
616         }
617     }
618
619     return plugVector;
620 }
621
622 Plug*
623 Unit::getSyncPlug( int maxPlugId, Plug::EPlugDirection )
624 {
625     return 0;
626 }
627
628 bool
629 Unit::discoverSyncModes()
630 {
631     // Following possible sync plugs exists:
632     // - Music subunit sync output plug = internal sync (CSP)
633     // - Unit input plug 0 = SYT match
634     // - Unit input plut 1 = Sync stream
635     //
636     // If last sync mode is reported it is mostelikely not
637     // implemented *sic*
638     //
639     // Following sync sources are device specific:
640     // - All unit external input plugs which have a
641     //   sync information (WS, SPDIF, ...)
642
643     // First we have to find the sync input and output plug
644     // in the music subunit.
645
646     // Note PCR input means 1394bus-to-device where as
647     // MSU input means subunit-to-device
648
649     PlugVector syncPCRInputPlugs = getPlugsByType( m_pcrPlugs,
650                                                    Plug::eAPD_Input,
651                                                    Plug::eAPT_Sync );
652     if ( !syncPCRInputPlugs.size() ) {
653         debugOutput(DEBUG_LEVEL_NORMAL, "No PCR sync input plug found\n" );
654     }
655
656     PlugVector syncPCROutputPlugs = getPlugsByType( m_pcrPlugs,
657                                                     Plug::eAPD_Output,
658                                                     Plug::eAPT_Sync );
659     if ( !syncPCROutputPlugs.size() ) {
660         debugOutput(DEBUG_LEVEL_NORMAL, "No PCR sync output plug found\n" );
661     }
662
663     PlugVector isoPCRInputPlugs = getPlugsByType( m_pcrPlugs,
664                                                   Plug::eAPD_Input,
665                                                   Plug::eAPT_IsoStream );
666     if ( !isoPCRInputPlugs.size() ) {
667         debugOutput(DEBUG_LEVEL_NORMAL, "No PCR iso input plug found\n" );
668
669     }
670
671     PlugVector isoPCROutputPlugs = getPlugsByType( m_pcrPlugs,
672                                                    Plug::eAPD_Output,
673                                                    Plug::eAPT_IsoStream );
674     if ( !isoPCROutputPlugs.size() ) {
675         debugOutput(DEBUG_LEVEL_NORMAL, "No PCR iso output plug found\n" );
676
677     }
678
679     PlugVector digitalExternalInputPlugs = getPlugsByType( m_externalPlugs,
680                                                            Plug::eAPD_Input,
681                                                            Plug::eAPT_Digital );
682     if ( !digitalExternalInputPlugs.size() ) {
683         debugOutput( DEBUG_LEVEL_VERBOSE, "No external digital input plugs found\n" );
684
685     }
686
687     PlugVector syncExternalInputPlugs = getPlugsByType( m_externalPlugs,
688                                                         Plug::eAPD_Input,
689                                                         Plug::eAPT_Sync );
690     if ( !syncExternalInputPlugs.size() ) {
691         debugOutput( DEBUG_LEVEL_VERBOSE, "No external sync input plugs found\n" );
692
693     }
694
695     PlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType(
696         eST_Music,
697         0,
698         0xff,
699         0xff,
700         Plug::eAPA_SubunitPlug,
701         Plug::eAPD_Input,
702         Plug::eAPT_Sync );
703     if ( !syncMSUInputPlugs.size() ) {
704         debugWarning( "No sync input plug for MSU subunit found\n" );
705     }
706
707     PlugVector syncMSUOutputPlugs = m_pPlugManager->getPlugsByType(
708         eST_Music,
709         0,
710         0xff,
711         0xff,
712         Plug::eAPA_SubunitPlug,
713         Plug::eAPD_Output,
714         Plug::eAPT_Sync );
715     if ( !syncMSUOutputPlugs.size() ) {
716         debugWarning( "No sync output plug for MSU subunit found\n" );
717     }
718
719     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Input Plugs:\n" );
720     showPlugs( syncPCRInputPlugs );
721     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Output Plugs:\n" );
722     showPlugs( syncPCROutputPlugs );
723     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Input Plugs:\n" );
724     showPlugs( isoPCRInputPlugs );
725     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Output Plugs:\n" );
726     showPlugs( isoPCROutputPlugs );
727     debugOutput( DEBUG_LEVEL_VERBOSE, "External digital Input Plugs:\n" );
728     showPlugs( digitalExternalInputPlugs );
729     debugOutput( DEBUG_LEVEL_VERBOSE, "External sync Input Plugs:\n" );
730     showPlugs( syncExternalInputPlugs );
731     debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Input Plugs:\n" );
732     showPlugs( syncMSUInputPlugs );
733     debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Output Plugs:\n" );
734     showPlugs( syncMSUOutputPlugs );
735
736     m_syncInfos.clear();
737     // Currently there is no usable setup for sync streams.
738     // There is no point in wasting time here. Let's skip
739     // 'sync stream input' and 'sync stream output'.
740
741     // Check all PCR iso input to MSU input connections
742     // -> SYT match
743     checkSyncConnectionsAndAddToList( isoPCRInputPlugs,
744                                       syncMSUInputPlugs,
745                                       "Syt Match" );
746
747     // Check all MSU sync output to MSU input connections
748     // -> CSP
749     checkSyncConnectionsAndAddToList( syncMSUOutputPlugs,
750                                       syncMSUInputPlugs,
751                                       "Internal (CSP)" );
752
753     // Check all external digital input to MSU input connections
754     // -> SPDIF/ADAT sync
755     checkSyncConnectionsAndAddToList( digitalExternalInputPlugs,
756                                       syncMSUInputPlugs,
757                                       "Digital Input Sync" );
758
759     // Check all external sync input to MSU input connections
760     // -> SPDIF/ADAT sync
761     checkSyncConnectionsAndAddToList( syncExternalInputPlugs,
762                                       syncMSUInputPlugs,
763                                       "Digital Input Sync" );
764
765     return true;
766 }
767
768 const Unit::SyncInfo*
769 Unit::getActiveSyncInfo()
770 {
771     SyncInfo* activeSyncInfo = NULL;
772     PlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType(
773         eST_Music,
774         0,
775         0xff,
776         0xff,
777         Plug::eAPA_SubunitPlug,
778         Plug::eAPD_Input,
779         Plug::eAPT_Sync );
780     if ( !syncMSUInputPlugs.size() ) {
781         debugWarning( "No sync input plug for MSU subunit found\n" );
782     }
783
784     // Currently active connection signal source cmd, command type
785     // status, source unknown, destination MSU sync input plug
786     for ( PlugVector::const_iterator it = syncMSUInputPlugs.begin();
787           it != syncMSUInputPlugs.end();
788           ++it )
789     {
790         AVC::Plug* msuPlug = *it;
791         for ( PlugVector::const_iterator jt =
792                   msuPlug->getInputConnections().begin();
793               jt != msuPlug->getInputConnections().end();
794               ++jt )
795         {
796             AVC::Plug* plug = *jt;
797
798             for ( SyncInfoVector::iterator it = m_syncInfos.begin();
799                   it != m_syncInfos.end();
800                   ++it )
801             {
802                 SyncInfo* pSyncInfo = &*it;
803                 if ( ( pSyncInfo->m_source == plug )
804                      && ( pSyncInfo->m_destination == msuPlug ) )
805                 {
806                     activeSyncInfo = pSyncInfo;
807                     break;
808                 }
809             }
810             if(activeSyncInfo) {
811                 debugOutput( DEBUG_LEVEL_NORMAL,
812                             "Active Sync Connection: %s, '%s' -> '%s'\n",
813                             activeSyncInfo->m_description.c_str(),
814                             plug->getName(),
815                             msuPlug->getName() );
816             }
817         }
818     }
819     return activeSyncInfo;
820 }
821
822 bool
823 Unit::checkSyncConnectionsAndAddToList( PlugVector& plhs,
824                                         PlugVector& prhs,
825                                         std::string syncDescription )
826 {
827     for ( PlugVector::iterator plIt = plhs.begin();
828           plIt != plhs.end();
829           ++plIt )
830     {
831         AVC::Plug* pl = *plIt;
832         for ( PlugVector::iterator prIt = prhs.begin();
833               prIt != prhs.end();
834               ++prIt )
835         {
836             AVC::Plug* pr = *prIt;
837             if ( pl->inquireConnnection( *pr ) ) {
838                 m_syncInfos.push_back( SyncInfo( *pl, *pr, syncDescription ) );
839                 debugOutput( DEBUG_LEVEL_NORMAL,
840                              "%s, sync connection '%s' -> '%s'\n",
841                              syncDescription.c_str(),
842                              pl->getName(),
843                              pr->getName() );
844             }
845         }
846     }
847     return true;
848 }
849
850 bool Unit::setActiveSync(const SyncInfo& syncInfo)
851 {
852     bool retval = true;
853
854     if ( ! syncInfo.m_source->inquireConnnection( *syncInfo.m_destination ) ) {
855         // this should not happen
856         debugError("Sync connection '%s' -> '%s' not possible. This might be a bug.\n",
857                    syncInfo.m_source->getName(), syncInfo.m_destination->getName());
858     }
859
860     if(!syncInfo.m_source->setConnection( *syncInfo.m_destination )) {
861         debugError("Could not set sync source connection while device reported it as possible.\n");
862         retval = false; // proceed to rediscovery anyway
863     }
864
865     // we now have to rediscover the connections
866     if ( !rediscoverConnections() ) {
867         debugError( "Re-discovery of plug connections failed\n" );
868         return false;
869     }
870     return retval;
871 }
872
873 void
874 Unit::show()
875 {
876     if (getDebugLevel() >= DEBUG_LEVEL_VERY_VERBOSE) {
877         m_pPlugManager->showPlugs();
878     }
879     //SubunitMusic* s=getMusicSubunit(0);
880     //if(s) s->showMusicPlugs();
881 }
882
883 void
884 Unit::showPlugs( PlugVector& plugs ) const
885 {
886     int i = 0;
887     for ( PlugVector::const_iterator it = plugs.begin();
888           it != plugs.end();
889           ++it, ++i )
890     {
891         Plug* plug = *it;
892         debugOutput( DEBUG_LEVEL_VERBOSE, "Plug %d\n", i );
893         plug->showPlug();
894     }
895 }
896
897 template <typename T>
898 bool
899 serializeVector( std::string path,
900                  Util::IOSerialize& ser,
901                  const T& vec )
902 {
903     bool result = true; // if vec.size() == 0
904     int i = 0;
905     for ( typename T::const_iterator it = vec.begin(); it != vec.end(); ++it ) {
906         std::ostringstream strstrm;
907         strstrm << path << i;
908         result &= ( *it )->serialize( strstrm.str() + "/", ser );
909         i++;
910     }
911     return result;
912 }
913
914 template <typename T, typename VT>
915 bool
916 deserializeVector( std::string path,
917                    Util::IODeserialize& deser,
918                    Unit& unit,
919                    VT& vec )
920 {
921     int i = 0;
922     T* ptr = 0;
923     do {
924         std::ostringstream strstrm;
925         strstrm << path << i << "/";
926         ptr = T::deserialize( strstrm.str(),
927                               deser,
928                               unit );
929         if ( ptr ) {
930             vec.push_back( ptr );
931         }
932         i++;
933     } while ( ptr );
934
935     return true;
936 }
937
938 bool
939 Unit::serializeSyncInfoVector( std::string basePath,
940                                Util::IOSerialize& ser,
941                                const SyncInfoVector& vec ) const
942 {
943     bool result = true;
944     int i = 0;
945
946     for ( SyncInfoVector::const_iterator it = vec.begin();
947           it != vec.end();
948           ++it )
949     {
950         const SyncInfo& info = *it;
951
952         std::ostringstream strstrm;
953         strstrm << basePath << i << "/";
954
955         result &= ser.write( strstrm.str() + "m_source", info.m_source->getGlobalId() );
956         result &= ser.write( strstrm.str() + "m_destination", info.m_destination->getGlobalId() );
957         result &= ser.write( strstrm.str() + "m_description", std::string( info.m_description ) );
958
959         i++;
960     }
961
962     return result;
963 }
964
965 bool
966 Unit::deserializeSyncInfoVector( std::string basePath,
967                                  Util::IODeserialize& deser,
968                                  SyncInfoVector& vec )
969 {
970     int i = 0;
971     bool bFinished = false;
972     do {
973         bool result;
974         std::ostringstream strstrm;
975         strstrm << basePath << i << "/";
976
977         plug_id_t sourceId;
978         plug_id_t destinationId;
979         std::string description;
980
981         if ( deser.isExisting( strstrm.str() + "m_source" ) ) {
982             result  = deser.read( strstrm.str() + "m_source", sourceId );
983             result &= deser.read( strstrm.str() + "m_destination", destinationId );
984             result &= deser.read( strstrm.str() + "m_description", description );
985         } else {
986             result = false;
987         }
988
989         if ( result ) {
990             SyncInfo syncInfo;
991             syncInfo.m_source = m_pPlugManager->getPlug( sourceId );
992             syncInfo.m_destination = m_pPlugManager->getPlug( destinationId );
993             syncInfo.m_description = description;
994
995             vec.push_back( syncInfo );
996             i++;
997         } else {
998             bFinished = true;
999         }
1000     } while ( !bFinished );
1001
1002     return true;
1003 }
1004
1005 bool
1006 Unit::serialize( std::string basePath,
1007                  Util::IOSerialize& ser ) const
1008 {
1009     bool result;
1010     result =  serializeVector( basePath + "Subunit", ser, m_subunits );
1011     result &= serializePlugVector( basePath + "PcrPlug", ser, m_pcrPlugs );
1012     result &= serializePlugVector( basePath + "ExternalPlug",  ser, m_externalPlugs );
1013     result &= serializeVector( basePath + "PlugConnection", ser, m_plugConnections );
1014     result &= m_pPlugManager->serialize( basePath + "Plug", ser ); // serialize all av plugs
1015     result &= serializeSyncInfoVector( basePath + "SyncInfo", ser, m_syncInfos );
1016
1017     return result;
1018 }
1019
1020 bool
1021 Unit::deserialize( std::string basePath,
1022                    Util::IODeserialize& deser )
1023 {
1024     bool result = true;
1025
1026     result &= deserializeVector<Subunit>( basePath + "Subunit", deser, *this, m_subunits );
1027
1028     if (m_pPlugManager)
1029         delete m_pPlugManager;
1030
1031     // load all plugs
1032     m_pPlugManager = PlugManager::deserialize( basePath + "Plug", deser, *this );
1033
1034     if ( !m_pPlugManager )
1035         return false;
1036
1037     // update the plug related stuff in the subunits. we have to
1038     // do that in 2 steps because we have a circular dependency.
1039     for ( SubunitVector::iterator it = m_subunits.begin();
1040           it != m_subunits.end();
1041           ++it )
1042     {
1043         result &= (*it)->deserializeUpdate( basePath + "Subunit", deser );
1044     }
1045
1046     // load path /PcrPlug0/global_id
1047     result &= deserializePlugVector( basePath + "PcrPlug", deser,
1048                                      getPlugManager(), m_pcrPlugs );
1049     // load path /ExternalPlug0/global_id
1050     result &= deserializePlugVector( basePath + "ExternalPlug", deser,
1051                                      getPlugManager(), m_externalPlugs );
1052     result &= deserializeVector<PlugConnection>( basePath + "PlugConnection", deser,
1053                                                  *this, m_plugConnections );
1054     result &= deserializeVector<Subunit>( basePath + "Subunit",  deser, *this, m_subunits );
1055     result &= deserializeSyncInfoVector( basePath + "SyncInfo", deser, m_syncInfos );
1056
1057     // update connectsion between plugs (plug.m_inputConnections
1058     // and plug.m_outputConnnections list)
1059     m_pPlugManager->deserializeUpdate( basePath, deser );
1060
1061     // this might have changed since the cache was saved
1062     // if the config ID doesn't account for the clock source
1063     if(!rediscoverConnections()) {
1064         debugError("Could not rediscover plug connections\n");
1065     }
1066
1067     return result;
1068 }
1069
1070 } // end of namespace
Note: See TracBrowser for help on using the browser.