root/branches/streaming-rework/src/bebob/bebob_avdevice.cpp

Revision 426, 46.6 kB (checked in by pieterpalmers, 15 years ago)

- changed the IAvDevice from an interface to a base class,

since there is some code duplication starting to
appear.

Line 
1 /* bebob_avdevice.cpp
2  * Copyright (C) 2005,06,07 by Daniel Wagner
3  *
4  * This file is part of FreeBoB.
5  *
6  * FreeBoB is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * FreeBoB is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with FreeBoB; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA.
19  */
20
21 #include "bebob/bebob_avdevice.h"
22 #include "bebob/bebob_avdevice_subunit.h"
23
24 #include "libieee1394/configrom.h"
25 #include "libieee1394/ieee1394service.h"
26
27 #include "libavc/avc_plug_info.h"
28 #include "libavc/avc_extended_plug_info.h"
29 #include "libavc/avc_subunit_info.h"
30 #include "libavc/avc_extended_stream_format.h"
31 #include "libavc/avc_serialize.h"
32 #include "libavc/avc_definitions.h"
33
34 #include "debugmodule/debugmodule.h"
35
36 #include <iostream>
37 #include <sstream>
38
39 namespace BeBoB {
40
41 static VendorModelEntry supportedDeviceList[] =
42 {
43     {0x00000f, 0x00010065, "Mackie", "Onyx Firewire"},
44    
45     {0x0003db, 0x00010048, "Apogee Electronics", "Rosetta 200"},
46
47     {0x0007f5, 0x00010048, "BridgeCo", "RD Audio1"},
48
49     {0x000a92, 0x00010000, "PreSonus", "FIREBOX"},
50     {0x000a92, 0x00010066, "PreSonus", "FirePOD"},
51
52     {0x000aac, 0x00000003, "TerraTec Electronic GmbH", "Phase 88 FW"},
53     {0x000aac, 0x00000004, "TerraTec Electronic GmbH", "Phase X24 FW (model version 4)"},
54     {0x000aac, 0x00000007, "TerraTec Electronic GmbH", "Phase X24 FW (model version 7)"},
55
56     {0x000f1b, 0x00010064, "ESI", "Quatafire 610"},
57
58     {0x00130e, 0x00000003, "Focusrite", "Saffire Pro26IO"},
59
60     {0x0040ab, 0x00010048, "EDIROL", "FA-101"},
61     {0x0040ab, 0x00010049, "EDIROL", "FA-66"},
62 };
63
64 AvDevice::AvDevice( std::auto_ptr< ConfigRom >( configRom ),
65                     Ieee1394Service& ieee1394service,
66                     int nodeId )
67     : IAvDevice( configRom, ieee1394service, nodeId )
68     , m_pPlugManager( new AvPlugManager( DEBUG_LEVEL_NORMAL ) )
69     , m_activeSyncInfo( 0 )
70     , m_model ( NULL )
71 {
72     debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB::AvDevice (NodeID %d)\n",
73                  nodeId );
74     addOption(Util::OptionContainer::Option("snoopMode",false));
75 }
76
77 AvDevice::~AvDevice()
78 {
79
80     for ( AvDeviceSubunitVector::iterator it = m_subunits.begin();
81           it != m_subunits.end();
82           ++it )
83     {
84         delete *it;
85     }
86     for ( AvPlugConnectionVector::iterator it = m_plugConnections.begin();
87           it != m_plugConnections.end();
88           ++it )
89     {
90         delete *it;
91     }
92     for ( AvPlugVector::iterator it = m_pcrPlugs.begin();
93           it != m_pcrPlugs.end();
94           ++it )
95     {
96         delete *it;
97     }
98     for ( AvPlugVector::iterator it = m_externalPlugs.begin();
99           it != m_externalPlugs.end();
100           ++it )
101     {
102         delete *it;
103     }
104 }
105
106 void
107 AvDevice::setVerboseLevel(int l)
108 {
109 //     m_pPlugManager->setVerboseLevel(l);
110    
111     IAvDevice::setVerboseLevel(l);
112 }
113
114 bool
115 AvDevice::probe( ConfigRom& configRom )
116 {
117     unsigned int vendorId = configRom.getNodeVendorId();
118     unsigned int modelId = configRom.getModelId();
119
120     for ( unsigned int i = 0;
121           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
122           ++i )
123     {
124         if ( ( supportedDeviceList[i].vendor_id == vendorId )
125              && ( supportedDeviceList[i].model_id == modelId ) )
126         {
127             return true;
128         }
129     }
130
131     return false;
132 }
133
134 bool
135 AvDevice::discover()
136 {
137     unsigned int vendorId = m_pConfigRom->getNodeVendorId();
138     unsigned int modelId = m_pConfigRom->getModelId();
139
140     for ( unsigned int i = 0;
141           i < ( sizeof( supportedDeviceList )/sizeof( VendorModelEntry ) );
142           ++i )
143     {
144         if ( ( supportedDeviceList[i].vendor_id == vendorId )
145              && ( supportedDeviceList[i].model_id == modelId )
146            )
147         {
148             m_model = &(supportedDeviceList[i]);
149             break;
150         }
151     }
152
153     if (m_model != NULL) {
154         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
155                 m_model->vendor_name, m_model->model_name);
156     } else return false;
157    
158     if ( !enumerateSubUnits() ) {
159         debugError( "Could not enumarate sub units\n" );
160         return false;
161     }
162
163     if ( !discoverPlugs() ) {
164         debugError( "Detecting plugs failed\n" );
165         return false;
166     }
167
168     if ( !discoverPlugConnections() ) {
169         debugError( "Detecting plug connections failed\n" );
170         return false;
171     }
172
173     if ( !discoverSubUnitsPlugConnections() ) {
174         debugError( "Detecting plug connnection failed\n" );
175         return false;
176     }
177
178     if ( !discoverSyncModes() ) {
179         debugError( "Detecting sync modes failed\n" );
180         return false;
181     }
182
183     return true;
184 }
185
186 bool
187 AvDevice::discoverPlugs()
188 {
189     //////////////////////////////////////////////
190     // Get number of available isochronous input
191     // and output plugs of unit
192
193     PlugInfoCmd plugInfoCmd( *m_p1394Service );
194     plugInfoCmd.setNodeId( m_pConfigRom->getNodeId() );
195     plugInfoCmd.setCommandType( AVCCommand::eCT_Status );
196     plugInfoCmd.setVerbose( m_verboseLevel );
197
198     if ( !plugInfoCmd.fire() ) {
199         debugError( "plug info command failed\n" );
200         return false;
201     }
202
203     debugOutput( DEBUG_LEVEL_NORMAL, "number of iso input plugs = %d\n",
204                  plugInfoCmd.m_serialBusIsochronousInputPlugs );
205     debugOutput( DEBUG_LEVEL_NORMAL, "number of iso output plugs = %d\n",
206                  plugInfoCmd.m_serialBusIsochronousOutputPlugs );
207     debugOutput( DEBUG_LEVEL_NORMAL, "number of external input plugs = %d\n",
208                  plugInfoCmd.m_externalInputPlugs );
209     debugOutput( DEBUG_LEVEL_NORMAL, "number of external output plugs = %d\n",
210                  plugInfoCmd.m_externalOutputPlugs );
211
212     if ( !discoverPlugsPCR( AvPlug::eAPD_Input,
213                             plugInfoCmd.m_serialBusIsochronousInputPlugs ) )
214     {
215         debugError( "pcr input plug discovering failed\n" );
216         return false;
217     }
218
219     if ( !discoverPlugsPCR( AvPlug::eAPD_Output,
220                             plugInfoCmd.m_serialBusIsochronousOutputPlugs ) )
221     {
222         debugError( "pcr output plug discovering failed\n" );
223         return false;
224     }
225
226     if ( !discoverPlugsExternal( AvPlug::eAPD_Input,
227                                  plugInfoCmd.m_externalInputPlugs ) )
228     {
229         debugError( "external input plug discovering failed\n" );
230         return false;
231     }
232
233     if ( !discoverPlugsExternal( AvPlug::eAPD_Output,
234                                  plugInfoCmd.m_externalOutputPlugs ) )
235     {
236         debugError( "external output plug discovering failed\n" );
237         return false;
238     }
239
240     return true;
241 }
242
243 bool
244 AvDevice::discoverPlugsPCR( AvPlug::EAvPlugDirection plugDirection,
245                             plug_id_t plugMaxId )
246 {
247     for ( int plugId = 0;
248           plugId < plugMaxId;
249           ++plugId )
250     {
251         AvPlug* plug  = new AvPlug( *m_p1394Service,
252                                     *m_pConfigRom,
253                                     *m_pPlugManager,
254                                     AVCCommand::eST_Unit,
255                                     0xff,
256                                     0xff,
257                                     0xff,
258                                     AvPlug::eAPA_PCR,
259                                     plugDirection,
260                                     plugId,
261                                     m_verboseLevel );
262         if ( !plug || !plug->discover() ) {
263             debugError( "plug discovering failed\n" );
264             delete plug;
265             return false;
266         }
267
268         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
269                      plug->getName() );
270         m_pcrPlugs.push_back( plug );
271     }
272
273     return true;
274 }
275
276 bool
277 AvDevice::discoverPlugsExternal( AvPlug::EAvPlugDirection plugDirection,
278                                  plug_id_t plugMaxId )
279 {
280     for ( int plugId = 0;
281           plugId < plugMaxId;
282           ++plugId )
283     {
284         AvPlug* plug  = new AvPlug( *m_p1394Service,
285                                     *m_pConfigRom,
286                                     *m_pPlugManager,
287                                     AVCCommand::eST_Unit,
288                                     0xff,
289                                     0xff,
290                                     0xff,
291                                     AvPlug::eAPA_ExternalPlug,
292                                     plugDirection,
293                                     plugId,
294                                     m_verboseLevel );
295         if ( !plug || !plug->discover() ) {
296             debugError( "plug discovering failed\n" );
297             return false;
298         }
299
300         debugOutput( DEBUG_LEVEL_NORMAL, "plug '%s' found\n",
301                      plug->getName() );
302         m_externalPlugs.push_back( plug );
303     }
304
305     return true;
306 }
307
308 bool
309 AvDevice::discoverPlugConnections()
310 {
311     for ( AvPlugVector::iterator it = m_pcrPlugs.begin();
312           it != m_pcrPlugs.end();
313           ++it )
314     {
315         AvPlug* plug = *it;
316         if ( !plug->discoverConnections() ) {
317             debugError( "Could not discover plug connections\n" );
318             return false;
319         }
320     }
321     for ( AvPlugVector::iterator it = m_externalPlugs.begin();
322           it != m_externalPlugs.end();
323           ++it )
324     {
325         AvPlug* plug = *it;
326         if ( !plug->discoverConnections() ) {
327             debugError( "Could not discover plug connections\n" );
328             return false;
329         }
330     }
331
332     return true;
333 }
334
335 bool
336 AvDevice::discoverSubUnitsPlugConnections()
337 {
338     for ( AvDeviceSubunitVector::iterator it = m_subunits.begin();
339           it != m_subunits.end();
340           ++it )
341     {
342         AvDeviceSubunit* subunit = *it;
343         if ( !subunit->discoverConnections() ) {
344             debugError( "Subunit '%s'  plug connections failed\n",
345                         subunit->getName() );
346             return false;
347         }
348     }
349     return true;
350 }
351
352 bool
353 AvDevice::discoverSyncModes()
354 {
355     // Following possible sync plugs exists:
356     // - Music subunit sync output plug = internal sync (CSP)
357     // - Unit input plug 0 = SYT match
358     // - Unit input plut 1 = Sync stream
359     //
360     // If last sync mode is reported it is mostelikely not
361     // implemented *sic*
362     //
363     // Following sync sources are device specific:
364     // - All unit external input plugs which have a
365     //   sync information (WS, SPDIF, ...)
366
367     // First we have to find the sync input and output plug
368     // in the music subunit.
369
370     // Note PCR input means 1394bus-to-device where as
371     // MSU input means subunit-to-device
372
373     AvPlugVector syncPCRInputPlugs = getPlugsByType( m_pcrPlugs,
374                                                      AvPlug::eAPD_Input,
375                                                      AvPlug::eAPT_Sync );
376     if ( !syncPCRInputPlugs.size() ) {
377         debugWarning( "No PCR sync input plug found\n" );
378     }
379
380     AvPlugVector syncPCROutputPlugs = getPlugsByType( m_pcrPlugs,
381                                                       AvPlug::eAPD_Output,
382                                                       AvPlug::eAPT_Sync );
383     if ( !syncPCROutputPlugs.size() ) {
384         debugWarning( "No PCR sync output plug found\n" );
385     }
386
387     AvPlugVector isoPCRInputPlugs = getPlugsByType( m_pcrPlugs,
388                                                     AvPlug::eAPD_Input,
389                                                     AvPlug::eAPT_IsoStream );
390     if ( !isoPCRInputPlugs.size() ) {
391         debugWarning( "No PCR iso input plug found\n" );
392
393     }
394
395     AvPlugVector isoPCROutputPlugs = getPlugsByType( m_pcrPlugs,
396                                                     AvPlug::eAPD_Output,
397                                                     AvPlug::eAPT_IsoStream );
398     if ( !isoPCROutputPlugs.size() ) {
399         debugWarning( "No PCR iso output plug found\n" );
400
401     }
402
403     AvPlugVector digitalPCRInputPlugs = getPlugsByType( m_externalPlugs,
404                                                     AvPlug::eAPD_Input,
405                                                     AvPlug::eAPT_Digital );
406
407     AvPlugVector syncMSUInputPlugs = m_pPlugManager->getPlugsByType(
408         AVCCommand::eST_Music,
409         0,
410         0xff,
411         0xff,
412         AvPlug::eAPA_SubunitPlug,
413         AvPlug::eAPD_Input,
414         AvPlug::eAPT_Sync );
415     if ( !syncMSUInputPlugs.size() ) {
416         debugWarning( "No sync input plug for MSU subunit found\n" );
417     }
418
419     AvPlugVector syncMSUOutputPlugs = m_pPlugManager->getPlugsByType(
420         AVCCommand::eST_Music,
421         0,
422         0xff,
423         0xff,
424         AvPlug::eAPA_SubunitPlug,
425         AvPlug::eAPD_Output,
426         AvPlug::eAPT_Sync );
427     if ( !syncMSUOutputPlugs.size() ) {
428         debugWarning( "No sync output plug for MSU subunit found\n" );
429     }
430
431     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Input Plugs:\n" );
432     showAvPlugs( syncPCRInputPlugs );
433     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Sync Output Plugs:\n" );
434     showAvPlugs( syncPCROutputPlugs );
435     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Input Plugs:\n" );
436     showAvPlugs( isoPCRInputPlugs );
437     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR Iso Output Plugs:\n" );
438     showAvPlugs( isoPCROutputPlugs );
439     debugOutput( DEBUG_LEVEL_VERBOSE, "PCR digital Input Plugs:\n" );
440     showAvPlugs( digitalPCRInputPlugs );
441     debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Input Plugs:\n" );
442     showAvPlugs( syncMSUInputPlugs );
443     debugOutput( DEBUG_LEVEL_VERBOSE, "MSU Sync Output Plugs:\n" );
444     showAvPlugs( syncMSUOutputPlugs );
445
446     // Check all possible PCR input to MSU input connections
447     // -> sync stream input
448     checkSyncConnectionsAndAddToList( syncPCRInputPlugs,
449                                       syncMSUInputPlugs,
450                                       "Sync Stream Input" );
451
452     // Check all possible MSU output to PCR output connections
453     // -> sync stream output
454     checkSyncConnectionsAndAddToList( syncMSUOutputPlugs,
455                                       syncPCROutputPlugs,
456                                       "Sync Stream Output" );
457
458     // Check all PCR iso input to MSU input connections
459     // -> SYT match
460     checkSyncConnectionsAndAddToList( isoPCRInputPlugs,
461                                       syncMSUInputPlugs,
462                                       "Syt Match" );
463
464     // Check all MSU sync output to MSU input connections
465     // -> CSP
466     checkSyncConnectionsAndAddToList( syncMSUOutputPlugs,
467                                       syncMSUInputPlugs,
468                                       "Internal (CSP)" );
469
470     // Check all external PCR digital input to MSU input connections
471     // -> SPDIF/ADAT sync
472     checkSyncConnectionsAndAddToList( digitalPCRInputPlugs,
473                                       syncMSUInputPlugs,
474                                       "Digital Input Sync" );
475
476     // Currently active connection signal source cmd, command type
477     // status, source unknown, destination MSU sync input plug
478
479     for ( AvPlugVector::const_iterator it = syncMSUInputPlugs.begin();
480           it != syncMSUInputPlugs.end();
481           ++it )
482     {
483         AvPlug* msuPlug = *it;
484         for ( AvPlugVector::const_iterator jt =
485                   msuPlug->getInputConnections().begin();
486               jt != msuPlug->getInputConnections().end();
487               ++jt )
488         {
489             AvPlug* plug = *jt;
490
491             for ( SyncInfoVector::iterator it = m_syncInfos.begin();
492                   it != m_syncInfos.end();
493                   ++it )
494             {
495                 SyncInfo* pSyncInfo = &*it;
496                 if ( ( pSyncInfo->m_source == plug )
497                      && ( pSyncInfo->m_destination == msuPlug ) )
498                 {
499                     m_activeSyncInfo = pSyncInfo;
500                     break;
501                 }
502             }
503             debugOutput( DEBUG_LEVEL_NORMAL,
504                          "Active Sync Connection: '%s' -> '%s'\n",
505                          plug->getName(),
506                          msuPlug->getName() );
507         }
508     }
509
510     return true;
511 }
512
513 bool
514 AvDevice::enumerateSubUnits()
515 {
516     bool musicSubunitFound=false;
517     bool audioSubunitFound=false;
518
519     SubUnitInfoCmd subUnitInfoCmd( *m_p1394Service );
520     //subUnitInfoCmd.setVerbose( 1 );
521     subUnitInfoCmd.setCommandType( AVCCommand::eCT_Status );
522
523     // BeBoB has always exactly one audio and one music subunit. This
524     // means is fits into the first page of the SubUnitInfo command.
525     // So there is no need to do more than needed
526
527     subUnitInfoCmd.m_page = 0;
528     subUnitInfoCmd.setNodeId( m_pConfigRom->getNodeId() );
529     subUnitInfoCmd.setVerbose( m_verboseLevel );
530     if ( !subUnitInfoCmd.fire() ) {
531         debugError( "Subunit info command failed\n" );
532         // shouldn't this be an error situation?
533         return false;
534     }
535
536     for ( int i = 0; i < subUnitInfoCmd.getNrOfValidEntries(); ++i ) {
537         subunit_type_t subunit_type
538             = subUnitInfoCmd.m_table[i].m_subunit_type;
539
540         unsigned int subunitId = getNrOfSubunits( subunit_type );
541
542         debugOutput( DEBUG_LEVEL_VERBOSE,
543                      "subunit_id = %2d, subunit_type = %2d (%s)\n",
544                      subunitId,
545                      subunit_type,
546                      subunitTypeToString( subunit_type ) );
547
548         AvDeviceSubunit* subunit = 0;
549         switch( subunit_type ) {
550         case AVCCommand::eST_Audio:
551             subunit = new AvDeviceSubunitAudio( *this,
552                                                 subunitId,
553                                                 m_verboseLevel );
554             if ( !subunit ) {
555                 debugFatal( "Could not allocate AvDeviceSubunitAudio\n" );
556                 return false;
557             }
558
559             m_subunits.push_back( subunit );
560             audioSubunitFound=true;
561
562             break;
563         case AVCCommand::eST_Music:
564             subunit = new AvDeviceSubunitMusic( *this,
565                                                 subunitId,
566                                                 m_verboseLevel );
567             if ( !subunit ) {
568                 debugFatal( "Could not allocate AvDeviceSubunitMusic\n" );
569                 return false;
570             }
571
572             m_subunits.push_back( subunit );
573             musicSubunitFound=true;
574
575             break;
576         default:
577             debugOutput( DEBUG_LEVEL_NORMAL,
578                          "Unsupported subunit found, subunit_type = %d (%s)\n",
579                          subunit_type,
580                          subunitTypeToString( subunit_type ) );
581             continue;
582
583         }
584
585         if ( !subunit->discover() ) {
586             debugError( "enumerateSubUnits: Could not discover "
587                         "subunit_id = %2d, subunit_type = %2d (%s)\n",
588                         subunitId,
589                         subunit_type,
590                         subunitTypeToString( subunit_type ) );
591             delete subunit;
592             return false;
593         }
594
595     }
596
597     // a BeBoB always has an audio and a music subunit
598     return (musicSubunitFound && audioSubunitFound);
599 }
600
601
602 AvDeviceSubunit*
603 AvDevice::getSubunit( subunit_type_t subunitType,
604                       subunit_id_t subunitId ) const
605 {
606     for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin();
607           it != m_subunits.end();
608           ++it )
609     {
610         AvDeviceSubunit* subunit = *it;
611         if ( ( subunitType == subunit->getSubunitType() )
612              && ( subunitId == subunit->getSubunitId() ) )
613         {
614             return subunit;
615         }
616     }
617
618     return 0;
619 }
620
621
622 unsigned int
623 AvDevice::getNrOfSubunits( subunit_type_t subunitType ) const
624 {
625     unsigned int nrOfSubunits = 0;
626
627     for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin();
628           it != m_subunits.end();
629           ++it )
630     {
631         AvDeviceSubunit* subunit = *it;
632         if ( subunitType == subunit->getSubunitType() ) {
633             nrOfSubunits++;
634         }
635     }
636
637     return nrOfSubunits;
638 }
639
640 AvPlugConnection*
641 AvDevice::getPlugConnection( AvPlug& srcPlug ) const
642 {
643     for ( AvPlugConnectionVector::const_iterator it
644               = m_plugConnections.begin();
645           it != m_plugConnections.end();
646           ++it )
647     {
648         AvPlugConnection* plugConnection = *it;
649         if ( &( plugConnection->getSrcPlug() ) == &srcPlug ) {
650             return plugConnection;
651         }
652     }
653
654     return 0;
655 }
656
657 AvPlug*
658 AvDevice::getPlugById( AvPlugVector& plugs,
659                        AvPlug::EAvPlugDirection plugDirection,
660                        int id )
661 {
662     for ( AvPlugVector::iterator it = plugs.begin();
663           it != plugs.end();
664           ++it )
665     {
666         AvPlug* plug = *it;
667         if ( ( id == plug->getPlugId() )
668              && ( plugDirection == plug->getPlugDirection() ) )
669         {
670             return plug;
671         }
672     }
673
674     return 0;
675 }
676
677 AvPlugVector
678 AvDevice::getPlugsByType( AvPlugVector& plugs,
679                           AvPlug::EAvPlugDirection plugDirection,
680                           AvPlug::EAvPlugType type)
681 {
682     AvPlugVector plugVector;
683     for ( AvPlugVector::iterator it = plugs.begin();
684           it != plugs.end();
685           ++it )
686     {
687         AvPlug* plug = *it;
688         if ( ( type == plug->getPlugType() )
689              && ( plugDirection == plug->getPlugDirection() ) )
690         {
691             plugVector.push_back( plug );
692         }
693     }
694
695     return plugVector;
696 }
697
698 AvPlug*
699 AvDevice::getSyncPlug( int maxPlugId, AvPlug::EAvPlugDirection )
700 {
701     return 0;
702 }
703
704 bool
705 AvDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency )
706 {
707     bool snoopMode=false;
708     if(!getOption("snoopMode", snoopMode)) {
709         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
710     }
711    
712     if(snoopMode) {
713         int current_sr=getSamplingFrequency();
714         if (current_sr != convertESamplingFrequency( samplingFrequency ) ) {
715             debugError("In snoop mode it is impossible to set the sample rate.\n");
716             debugError("Please start the client with the correct setting.\n");
717             return false;
718         }
719         return true;
720     } else {
721         AvPlug* plug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 );
722         if ( !plug ) {
723             debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
724             return false;
725         }
726    
727         if ( !setSamplingFrequencyPlug( *plug,
728                                         AvPlug::eAPD_Input,
729                                         samplingFrequency ) )
730         {
731             debugError( "setSampleRate: Setting sample rate failed\n" );
732             return false;
733         }
734    
735         plug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output,  0 );
736         if ( !plug ) {
737             debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
738             return false;
739         }
740    
741         if ( !setSamplingFrequencyPlug( *plug,
742                                         AvPlug::eAPD_Output,
743                                         samplingFrequency ) )
744         {
745             debugError( "setSampleRate: Setting sample rate failed\n" );
746             return false;
747         }
748    
749         debugOutput( DEBUG_LEVEL_VERBOSE,
750                      "setSampleRate: Set sample rate to %d\n",
751                      convertESamplingFrequency( samplingFrequency ) );
752         return true;
753     }
754     // not executable
755     return false;
756 }
757
758 int
759 AvDevice::getSamplingFrequency( ) {
760     AvPlug* inputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 );
761     if ( !inputPlug ) {
762         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
763         return false;
764     }
765     AvPlug* outputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output, 0 );
766     if ( !outputPlug ) {
767         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
768         return false;
769     }
770
771     int samplerate_playback=inputPlug->getSampleRate();
772     int samplerate_capture=outputPlug->getSampleRate();
773
774     if (samplerate_playback != samplerate_capture) {
775         debugWarning("Samplerates for capture and playback differ!\n");
776     }
777     return samplerate_capture;
778 }
779
780
781 bool
782 AvDevice::setSamplingFrequencyPlug( AvPlug& plug,
783                                     AvPlug::EAvPlugDirection direction,
784                                     ESamplingFrequency samplingFrequency )
785 {
786
787     ExtendedStreamFormatCmd extStreamFormatCmd(
788         *m_p1394Service,
789         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList );
790     UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
791                                      plug.getPlugId() );
792
793     extStreamFormatCmd.setPlugAddress(
794         PlugAddress(
795             AvPlug::convertPlugDirection(direction ),
796             PlugAddress::ePAM_Unit,
797             unitPlugAddress ) );
798
799     extStreamFormatCmd.setNodeId( m_pConfigRom->getNodeId() );
800     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
801
802     int i = 0;
803     bool cmdSuccess = false;
804     bool correctFormatFound = false;
805
806     do {
807         extStreamFormatCmd.setIndexInStreamFormat( i );
808         extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
809         extStreamFormatCmd.setVerbose( m_verboseLevel );
810
811         cmdSuccess = extStreamFormatCmd.fire();
812
813         if ( cmdSuccess
814              && ( extStreamFormatCmd.getResponse() ==
815                   AVCCommand::eR_Implemented ) )
816         {
817             ESamplingFrequency foundFreq = eSF_DontCare;
818
819             FormatInformation* formatInfo =
820                 extStreamFormatCmd.getFormatInformation();
821             FormatInformationStreamsCompound* compoundStream
822                 = dynamic_cast< FormatInformationStreamsCompound* > (
823                     formatInfo->m_streams );
824             if ( compoundStream ) {
825                 foundFreq =
826                     static_cast< ESamplingFrequency >(
827                         compoundStream->m_samplingFrequency );
828             }
829
830             FormatInformationStreamsSync* syncStream
831                 = dynamic_cast< FormatInformationStreamsSync* > (
832                     formatInfo->m_streams );
833             if ( syncStream ) {
834                 foundFreq =
835                     static_cast< ESamplingFrequency >(
836                         syncStream->m_samplingFrequency );
837             }
838
839             if ( foundFreq == samplingFrequency )
840             {
841                 correctFormatFound = true;
842                 break;
843             }
844         }
845
846         ++i;
847     } while ( cmdSuccess
848               && ( extStreamFormatCmd.getResponse() ==
849                    ExtendedStreamFormatCmd::eR_Implemented ) );
850
851     if ( !cmdSuccess ) {
852         debugError( "setSampleRatePlug: Failed to retrieve format info\n" );
853         return false;
854     }
855
856     if ( !correctFormatFound ) {
857         debugError( "setSampleRatePlug: %s plug %d does not support "
858                     "sample rate %d\n",
859                     plug.getName(),
860                     plug.getPlugId(),
861                     convertESamplingFrequency( samplingFrequency ) );
862         return false;
863     }
864
865     extStreamFormatCmd.setSubFunction(
866         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand );
867     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Control );
868     extStreamFormatCmd.setVerbose( m_verboseLevel );
869
870     if ( !extStreamFormatCmd.fire() ) {
871         debugError( "setSampleRate: Could not set sample rate %d "
872                     "to %s plug %d\n",
873                     convertESamplingFrequency( samplingFrequency ),
874                     plug.getName(),
875                     plug.getPlugId() );
876         return false;
877     }
878
879     return true;
880 }
881
882 void
883 AvDevice::showDevice() const
884 {
885     debugOutput(DEBUG_LEVEL_VERBOSE,
886         "%s %s at node %d\n", m_model->vendor_name, m_model->model_name,
887         m_nodeId);
888        
889     m_pPlugManager->showPlugs();
890 }
891
892 void
893 AvDevice::showAvPlugs( AvPlugVector& plugs ) const
894 {
895     int i = 0;
896     for ( AvPlugVector::const_iterator it = plugs.begin();
897           it != plugs.end();
898           ++it, ++i )
899     {
900         AvPlug* plug = *it;
901         debugOutput( DEBUG_LEVEL_VERBOSE, "Plug %d\n", i );
902         plug->showPlug();
903     }
904 }
905
906 bool
907 AvDevice::checkSyncConnectionsAndAddToList( AvPlugVector& plhs,
908                                             AvPlugVector& prhs,
909                                             std::string syncDescription )
910 {
911     for ( AvPlugVector::iterator plIt = plhs.begin();
912           plIt != plhs.end();
913           ++plIt )
914     {
915         AvPlug* pl = *plIt;
916         for ( AvPlugVector::iterator prIt = prhs.begin();
917               prIt != prhs.end();
918               ++prIt )
919         {
920             AvPlug* pr = *prIt;
921             if ( pl->inquireConnnection( *pr ) ) {
922                 m_syncInfos.push_back( SyncInfo( *pl, *pr, syncDescription ) );
923                 debugOutput( DEBUG_LEVEL_NORMAL,
924                              "Sync connection '%s' -> '%s'\n",
925                              pl->getName(),
926                              pr->getName() );
927             }
928         }
929     }
930     return true;
931 }
932
933 bool AvDevice::setActiveSync(const SyncInfo& syncInfo)
934 {
935     return syncInfo.m_source->setConnection( *syncInfo.m_destination );
936 }
937
938 bool
939 AvDevice::lock() {
940     bool snoopMode=false;
941     if(!getOption("snoopMode", snoopMode)) {
942         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
943     }
944
945     if (snoopMode) {
946         // don't lock
947     } else {
948    
949     }
950
951     return true;
952 }
953
954 bool
955 AvDevice::unlock() {
956     bool snoopMode=false;
957     if(!getOption("snoopMode", snoopMode)) {
958         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
959     }
960
961     if (snoopMode) {
962         // don't unlock
963     } else {
964    
965     }
966     return true;
967 }
968
969 bool
970 AvDevice::prepare() {
971     bool snoopMode=false;
972     if(!getOption("snoopMode", snoopMode)) {
973         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
974     }
975    
976     ///////////
977     // get plugs
978
979     AvPlug* inputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 );
980     if ( !inputPlug ) {
981         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
982         return false;
983     }
984     AvPlug* outputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output, 0 );
985     if ( !outputPlug ) {
986         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
987         return false;
988     }
989
990     int samplerate=outputPlug->getSampleRate();
991    
992     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n");
993     // create & add streamprocessors
994     Streaming::StreamProcessor *p;
995    
996     p=new Streaming::AmdtpReceiveStreamProcessor(
997                              m_p1394Service->getPort(),
998                              samplerate,
999                              outputPlug->getNrOfChannels());
1000
1001     if(!p->init()) {
1002         debugFatal("Could not initialize receive processor!\n");
1003         delete p;
1004         return false;
1005     }
1006
1007     if (!addPlugToProcessor(*outputPlug,p,
1008         Streaming::Port::E_Capture)) {
1009         debugFatal("Could not add plug to processor!\n");
1010         delete p;
1011         return false;
1012     }
1013    
1014     m_receiveProcessors.push_back(p);
1015
1016     // do the transmit processor
1017     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n",
1018             (snoopMode?" in snoop mode":""));
1019     if (snoopMode) {
1020         // we are snooping, so this is receive too.
1021         p=new Streaming::AmdtpReceiveStreamProcessor(
1022                                   m_p1394Service->getPort(),
1023                                   samplerate,
1024                                   inputPlug->getNrOfChannels());
1025     } else {
1026         p=new Streaming::AmdtpTransmitStreamProcessor(
1027                                 m_p1394Service->getPort(),
1028                                 samplerate,
1029                                 inputPlug->getNrOfChannels());
1030     }
1031    
1032     if(!p->init()) {
1033         debugFatal("Could not initialize transmit processor %s!\n",
1034             (snoopMode?" in snoop mode":""));
1035         delete p;
1036         return false;
1037     }
1038
1039     if (snoopMode) {
1040         if (!addPlugToProcessor(*inputPlug,p,
1041             Streaming::Port::E_Capture)) {
1042             debugFatal("Could not add plug to processor!\n");
1043             return false;
1044         }
1045     } else {
1046         if (!addPlugToProcessor(*inputPlug,p,
1047             Streaming::Port::E_Playback)) {
1048             debugFatal("Could not add plug to processor!\n");
1049             return false;
1050         }
1051     }
1052    
1053     // we put this SP into the transmit SP vector,
1054     // no matter if we are in snoop mode or not
1055     // this allows us to find out what direction
1056     // a certain stream should have.
1057     m_transmitProcessors.push_back(p);
1058
1059     return true;
1060 }
1061
1062 bool
1063 AvDevice::addPlugToProcessor(
1064     AvPlug& plug,
1065     Streaming::StreamProcessor *processor,
1066     Streaming::AmdtpAudioPort::E_Direction direction) {
1067    
1068     std::string id=std::string("dev?");
1069     if(!getOption("id", id)) {
1070         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
1071     }
1072    
1073     AvPlug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
1074     for ( AvPlug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
1075           it != clusterInfos.end();
1076           ++it )
1077     {
1078         const AvPlug::ClusterInfo* clusterInfo = &( *it );
1079
1080         AvPlug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
1081         for ( AvPlug::ChannelInfoVector::const_iterator it = channelInfos.begin();
1082               it != channelInfos.end();
1083               ++it )
1084         {
1085             const AvPlug::ChannelInfo* channelInfo = &( *it );
1086             std::ostringstream portname;
1087
1088             portname << id << "_" << channelInfo->m_name;
1089
1090             Streaming::Port *p=NULL;
1091             switch(clusterInfo->m_portType) {
1092             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
1093             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
1094             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
1095             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
1096             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
1097                 p=new Streaming::AmdtpAudioPort(
1098                         portname.str(),
1099                         direction,
1100                         // \todo: streaming backend expects indexing starting from 0
1101                         // but bebob reports it starting from 1. Decide where
1102                         // and how to handle this (pp: here)
1103                         channelInfo->m_streamPosition - 1,
1104                         channelInfo->m_location,
1105                         Streaming::AmdtpPortInfo::E_MBLA
1106                 );
1107                 break;
1108
1109             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
1110                 p=new Streaming::AmdtpMidiPort(
1111                         portname.str(),
1112                         direction,
1113                         // \todo: streaming backend expects indexing starting from 0
1114                         // but bebob reports it starting from 1. Decide where
1115                         // and how to handle this (pp: here)
1116                         channelInfo->m_streamPosition - 1,
1117                         channelInfo->m_location,
1118                         Streaming::AmdtpPortInfo::E_Midi
1119                 );
1120
1121                 break;
1122             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
1123             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
1124             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
1125             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
1126             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
1127             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
1128             default:
1129             // unsupported
1130                 break;
1131             }
1132
1133             if (!p) {
1134                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
1135             } else {
1136
1137                 if (!processor->addPort(p)) {
1138                     debugWarning("Could not register port with stream processor\n");
1139                     return false;
1140                 }
1141             }
1142          }
1143     }
1144     return true;
1145 }
1146
1147 int
1148 AvDevice::getStreamCount() {
1149     return m_receiveProcessors.size() + m_transmitProcessors.size();
1150 }
1151
1152 Streaming::StreamProcessor *
1153 AvDevice::getStreamProcessorByIndex(int i) {
1154
1155     if (i<(int)m_receiveProcessors.size()) {
1156         return m_receiveProcessors.at(i);
1157     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1158         return m_transmitProcessors.at(i-m_receiveProcessors.size());
1159     }
1160
1161     return NULL;
1162 }
1163
1164 bool
1165 AvDevice::startStreamByIndex(int i) {
1166     int iso_channel=-1;
1167     bool snoopMode=false;
1168     if(!getOption("snoopMode", snoopMode)) {
1169         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1170     }
1171
1172     if (i<(int)m_receiveProcessors.size()) {
1173         int n=i;
1174         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
1175        
1176         if(snoopMode) { // a stream from the device to another host
1177             // FIXME: put this into a decent framework!
1178             // we should check the oPCR[n] on the device
1179             struct iec61883_oPCR opcr;
1180             if (iec61883_get_oPCRX(
1181                     m_p1394Service->getHandle(),
1182                     m_pConfigRom->getNodeId() | 0xffc0,
1183                     (quadlet_t *)&opcr,
1184                     n)) {
1185                    
1186                 debugWarning("Error getting the channel for SP %d\n",i);
1187                 return false;
1188             }
1189            
1190             iso_channel=opcr.channel;
1191         } else {
1192             iso_channel=m_p1394Service->allocateIsoChannelCMP(
1193                 m_pConfigRom->getNodeId() | 0xffc0, n,
1194                 m_p1394Service->getLocalNodeId()| 0xffc0, -1);
1195         }
1196         if (iso_channel<0) {
1197             debugError("Could not allocate ISO channel for SP %d\n",i);
1198             return false;
1199         }
1200        
1201         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
1202        
1203         p->setChannel(iso_channel);
1204         return true;
1205        
1206     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1207         int n=i-m_receiveProcessors.size();
1208         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
1209        
1210         if(snoopMode) { // a stream from another host to the device
1211             // FIXME: put this into a decent framework!
1212             // we should check the iPCR[n] on the device
1213             struct iec61883_iPCR ipcr;
1214             if (iec61883_get_iPCRX(
1215                     m_p1394Service->getHandle(),
1216                     m_pConfigRom->getNodeId() | 0xffc0,
1217                     (quadlet_t *)&ipcr,
1218                     n)) {
1219                    
1220                 debugWarning("Error getting the channel for SP %d\n",i);
1221                 return false;
1222             }
1223            
1224             iso_channel=ipcr.channel;
1225            
1226         } else {
1227             iso_channel=m_p1394Service->allocateIsoChannelCMP(
1228                 m_p1394Service->getLocalNodeId()| 0xffc0, -1,
1229                 m_pConfigRom->getNodeId() | 0xffc0, n);
1230         }
1231        
1232         if (iso_channel<0) {
1233             debugError("Could not allocate ISO channel for SP %d\n",i);
1234             return false;
1235         }
1236        
1237         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
1238        
1239         p->setChannel(iso_channel);
1240         return true;
1241     }
1242    
1243     debugError("SP index %d out of range!\n",i);
1244     return false;
1245 }
1246
1247 bool
1248 AvDevice::stopStreamByIndex(int i) {
1249     bool snoopMode=false;
1250     if(!getOption("snoopMode", snoopMode)) {
1251         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1252     }
1253
1254     if (i<(int)m_receiveProcessors.size()) {
1255         int n=i;
1256         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
1257
1258         if(snoopMode) {
1259
1260         } else {
1261             // deallocate ISO channel
1262             if(!m_p1394Service->freeIsoChannel(p->getChannel())) {
1263                 debugError("Could not deallocate iso channel for SP %d\n",i);
1264                 return false;
1265             }
1266         }
1267         p->setChannel(-1);
1268        
1269         return true;
1270        
1271     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1272         int n=i-m_receiveProcessors.size();
1273         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
1274        
1275         if(snoopMode) {
1276
1277         } else {
1278             // deallocate ISO channel
1279             if(!m_p1394Service->freeIsoChannel(p->getChannel())) {
1280                 debugError("Could not deallocate iso channel for SP %d\n",i);
1281                 return false;
1282             }
1283         }
1284         p->setChannel(-1);
1285        
1286         return true;
1287     }
1288    
1289     debugError("SP index %d out of range!\n",i);
1290     return false;
1291 }
1292
1293 template <typename T> bool serializeVector( Glib::ustring path,
1294                                             Util::IOSerialize& ser,
1295                                             const T& vec )
1296 {
1297     bool result = true; // if vec.size() == 0
1298     int i = 0;
1299     for ( typename T::const_iterator it = vec.begin(); it != vec.end(); ++it ) {
1300         std::ostringstream strstrm;
1301         strstrm << path << i;
1302         result &= ( *it )->serialize( strstrm.str() + "/", ser );
1303         i++;
1304     }
1305     return result;
1306 }
1307
1308 template <typename T, typename VT> bool deserializeVector( Glib::ustring path,
1309                                                            Util::IODeserialize& deser,
1310                                                            AvDevice& avDevice,
1311                                                            VT& vec )
1312 {
1313     int i = 0;
1314     bool bFinished = false;
1315     do {
1316         std::ostringstream strstrm;
1317         strstrm << path << i << "/";
1318         T* ptr = T::deserialize( strstrm.str(),
1319                                  deser,
1320                                  avDevice );
1321         if ( ptr ) {
1322             vec.push_back( ptr );
1323             i++;
1324         } else {
1325             bFinished = true;
1326         }
1327     } while ( !bFinished );
1328
1329     return true;
1330 }
1331
1332 bool
1333 AvDevice::serializeSyncInfoVector( Glib::ustring basePath,
1334                                    Util::IOSerialize& ser,
1335                                    const SyncInfoVector& vec )
1336 {
1337     bool result = true;
1338     int i = 0;
1339
1340     for ( SyncInfoVector::const_iterator it = vec.begin();
1341           it != vec.end();
1342           ++it )
1343     {
1344         const SyncInfo& info = *it;
1345
1346         std::ostringstream strstrm;
1347         strstrm << basePath << i << "/";
1348
1349         result &= ser.write( strstrm.str() + "m_source", info.m_source->getGlobalId() );
1350         result &= ser.write( strstrm.str() + "m_destination", info.m_destination->getGlobalId() );
1351         result &= ser.write( strstrm.str() + "m_description", Glib::ustring( info.m_description ) );
1352
1353         i++;
1354     }
1355
1356     return result;
1357 }
1358
1359 bool
1360 AvDevice::deserializeSyncInfoVector( Glib::ustring basePath,
1361                                      Util::IODeserialize& deser,
1362                                      AvDevice& avDevice,
1363                                      SyncInfoVector& vec )
1364 {
1365     int i = 0;
1366     bool bFinished = false;
1367     do {
1368         bool result;
1369         std::ostringstream strstrm;
1370         strstrm << basePath << i << "/";
1371
1372         plug_id_t sourceId;
1373         plug_id_t destinationId;
1374         Glib::ustring description;
1375
1376         result  = deser.read( strstrm.str() + "m_source", sourceId );
1377         result &= deser.read( strstrm.str() + "m_destination", destinationId );
1378         result &= deser.read( strstrm.str() + "m_description", description );
1379
1380         if ( result ) {
1381             SyncInfo syncInfo;
1382             syncInfo.m_source = avDevice.getPlugManager().getPlug( sourceId );
1383             syncInfo.m_destination = avDevice.getPlugManager().getPlug( destinationId );
1384             syncInfo.m_description = description;
1385
1386             vec.push_back( syncInfo );
1387             i++;
1388         } else {
1389             bFinished = true;
1390         }
1391     } while ( !bFinished );
1392
1393     return true;
1394 }
1395
1396 static bool
1397 deserializeAvPlugUpdateConnections( Glib::ustring path,
1398                                     Util::IODeserialize& deser,
1399                                     AvPlugVector& vec )
1400 {
1401     bool result = true;
1402     for ( AvPlugVector::iterator it = vec.begin();
1403           it != vec.end();
1404           ++it )
1405     {
1406         AvPlug* pPlug = *it;
1407         result &= pPlug->deserializeUpdate( path, deser );
1408     }
1409     return result;
1410 }
1411
1412 bool
1413 AvDevice::serialize( Glib::ustring basePath,
1414                      Util::IOSerialize& ser ) const
1415 {
1416    
1417     bool result;
1418     result  = m_pConfigRom->serialize( basePath + "m_pConfigRom/", ser );
1419     result &= ser.write( basePath + "m_verboseLevel", m_verboseLevel );
1420     result &= m_pPlugManager->serialize( basePath + "AvPlug", ser ); // serialize all av plugs
1421     result &= serializeVector( basePath + "PlugConnection", ser, m_plugConnections );
1422     result &= serializeVector( basePath + "Subunit", ser, m_subunits );
1423     result &= serializeSyncInfoVector( basePath + "SyncInfo", ser, m_syncInfos );
1424
1425     int i = 0;
1426     for ( SyncInfoVector::const_iterator it = m_syncInfos.begin();
1427           it != m_syncInfos.end();
1428           ++it )
1429     {
1430         const SyncInfo& info = *it;
1431         if ( m_activeSyncInfo == &info ) {
1432             result &= ser.write( basePath + "m_activeSyncInfo",  i );
1433             break;
1434         }
1435         i++;
1436     }
1437    
1438     result &= serializeOptions( basePath + "Options", ser );
1439
1440 //     result &= ser.write( basePath + "m_id", id );
1441
1442     return result;
1443 }
1444
1445 AvDevice*
1446 AvDevice::deserialize( Glib::ustring basePath,
1447                        Util::IODeserialize& deser,
1448                        Ieee1394Service& ieee1394Service )
1449 {
1450
1451     ConfigRom *configRom =
1452         ConfigRom::deserialize( basePath + "m_pConfigRom/", deser, ieee1394Service );
1453        
1454     if ( !configRom ) {
1455         return NULL;
1456     }
1457
1458     AvDevice* pDev = new AvDevice(
1459         std::auto_ptr<ConfigRom>(configRom),
1460         ieee1394Service, configRom->getNodeId());
1461
1462     if ( pDev ) {
1463         bool result;
1464         result  = deser.read( basePath + "m_verboseLevel", pDev->m_verboseLevel );
1465        
1466         if (pDev->m_pPlugManager) delete pDev->m_pPlugManager;
1467         pDev->m_pPlugManager = AvPlugManager::deserialize( basePath + "AvPlug", deser, *pDev );
1468         if ( !pDev->m_pPlugManager ) {
1469             delete pDev;
1470             return 0;
1471         }
1472         result &= deserializeAvPlugUpdateConnections( basePath + "AvPlug", deser, pDev->m_pcrPlugs );
1473         result &= deserializeAvPlugUpdateConnections( basePath + "AvPlug", deser, pDev->m_externalPlugs );
1474         result &= deserializeVector<AvPlugConnection>( basePath + "PlugConnnection", deser, *pDev, pDev->m_plugConnections );
1475         result &= deserializeVector<AvDeviceSubunit>( basePath + "Subunit",  deser, *pDev, pDev->m_subunits );
1476         result &= deserializeSyncInfoVector( basePath + "SyncInfo", deser, *pDev, pDev->m_syncInfos );
1477
1478         unsigned int i;
1479         result &= deser.read( basePath + "m_activeSyncInfo", i );
1480
1481         if ( result ) {
1482             if ( i < pDev->m_syncInfos.size() ) {
1483                 pDev->m_activeSyncInfo = &pDev->m_syncInfos[i];
1484             }
1485         }
1486        
1487         result &= deserializeOptions( basePath + "Options", deser, *pDev );
1488     }
1489
1490     return pDev;
1491 }
1492
1493 } // end of namespace
Note: See TracBrowser for help on using the browser.