root/trunk/libffado/src/bebob/bebob_avdevice.cpp

Revision 477, 47.4 kB (checked in by ppalmers, 15 years ago)

Add M-Audio NRV10 device ID

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