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

Revision 630, 29.5 kB (checked in by wagi, 17 years ago)

Some more fixing of the cashing code. The loading is still disabled because it seems not to work right. But at least it doesn't crash anymore. Some further debugging is
needed.

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