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

Revision 472, 47.3 kB (checked in by ppalmers, 17 years ago)

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