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

Revision 479, 47.5 kB (checked in by wagi, 17 years ago)

- added all missing 'virtual' to function declared in avdevice implementation
- added getConfigurationId function (used for av/c model caching)

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 int
816 AvDevice::getConfigurationId()
817 {
818     return 0;
819 }
820
821 bool
822 AvDevice::setSamplingFrequencyPlug( AvPlug& plug,
823                                     AvPlug::EAvPlugDirection direction,
824                                     ESamplingFrequency samplingFrequency )
825 {
826
827     ExtendedStreamFormatCmd extStreamFormatCmd(
828         *m_p1394Service,
829         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList );
830     UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
831                                      plug.getPlugId() );
832
833     extStreamFormatCmd.setPlugAddress(
834         PlugAddress(
835             AvPlug::convertPlugDirection(direction ),
836             PlugAddress::ePAM_Unit,
837             unitPlugAddress ) );
838
839     extStreamFormatCmd.setNodeId( m_pConfigRom->getNodeId() );
840     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
841
842     int i = 0;
843     bool cmdSuccess = false;
844     bool correctFormatFound = false;
845
846     do {
847         extStreamFormatCmd.setIndexInStreamFormat( i );
848         extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
849         extStreamFormatCmd.setVerbose( m_verboseLevel );
850
851         cmdSuccess = extStreamFormatCmd.fire();
852
853         if ( cmdSuccess
854              && ( extStreamFormatCmd.getResponse() ==
855                   AVCCommand::eR_Implemented ) )
856         {
857             ESamplingFrequency foundFreq = eSF_DontCare;
858
859             FormatInformation* formatInfo =
860                 extStreamFormatCmd.getFormatInformation();
861             FormatInformationStreamsCompound* compoundStream
862                 = dynamic_cast< FormatInformationStreamsCompound* > (
863                     formatInfo->m_streams );
864             if ( compoundStream ) {
865                 foundFreq =
866                     static_cast< ESamplingFrequency >(
867                         compoundStream->m_samplingFrequency );
868             }
869
870             FormatInformationStreamsSync* syncStream
871                 = dynamic_cast< FormatInformationStreamsSync* > (
872                     formatInfo->m_streams );
873             if ( syncStream ) {
874                 foundFreq =
875                     static_cast< ESamplingFrequency >(
876                         syncStream->m_samplingFrequency );
877             }
878
879             if ( foundFreq == samplingFrequency )
880             {
881                 correctFormatFound = true;
882                 break;
883             }
884         }
885
886         ++i;
887     } while ( cmdSuccess
888               && ( extStreamFormatCmd.getResponse() ==
889                    ExtendedStreamFormatCmd::eR_Implemented ) );
890
891     if ( !cmdSuccess ) {
892         debugError( "setSampleRatePlug: Failed to retrieve format info\n" );
893         return false;
894     }
895
896     if ( !correctFormatFound ) {
897         debugError( "setSampleRatePlug: %s plug %d does not support "
898                     "sample rate %d\n",
899                     plug.getName(),
900                     plug.getPlugId(),
901                     convertESamplingFrequency( samplingFrequency ) );
902         return false;
903     }
904
905     extStreamFormatCmd.setSubFunction(
906         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand );
907     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Control );
908     extStreamFormatCmd.setVerbose( m_verboseLevel );
909
910     if ( !extStreamFormatCmd.fire() ) {
911         debugError( "setSampleRate: Could not set sample rate %d "
912                     "to %s plug %d\n",
913                     convertESamplingFrequency( samplingFrequency ),
914                     plug.getName(),
915                     plug.getPlugId() );
916         return false;
917     }
918
919     return true;
920 }
921
922 void
923 AvDevice::showDevice()
924 {
925     debugOutput(DEBUG_LEVEL_VERBOSE,
926         "%s %s at node %d\n", m_model->vendor_name, m_model->model_name,
927         m_nodeId);
928
929     m_pPlugManager->showPlugs();
930 }
931
932 void
933 AvDevice::showAvPlugs( AvPlugVector& plugs ) const
934 {
935     int i = 0;
936     for ( AvPlugVector::const_iterator it = plugs.begin();
937           it != plugs.end();
938           ++it, ++i )
939     {
940         AvPlug* plug = *it;
941         debugOutput( DEBUG_LEVEL_VERBOSE, "Plug %d\n", i );
942         plug->showPlug();
943     }
944 }
945
946 bool
947 AvDevice::checkSyncConnectionsAndAddToList( AvPlugVector& plhs,
948                                             AvPlugVector& prhs,
949                                             std::string syncDescription )
950 {
951     for ( AvPlugVector::iterator plIt = plhs.begin();
952           plIt != plhs.end();
953           ++plIt )
954     {
955         AvPlug* pl = *plIt;
956         for ( AvPlugVector::iterator prIt = prhs.begin();
957               prIt != prhs.end();
958               ++prIt )
959         {
960             AvPlug* pr = *prIt;
961             if ( pl->inquireConnnection( *pr ) ) {
962                 m_syncInfos.push_back( SyncInfo( *pl, *pr, syncDescription ) );
963                 debugOutput( DEBUG_LEVEL_NORMAL,
964                              "Sync connection '%s' -> '%s'\n",
965                              pl->getName(),
966                              pr->getName() );
967             }
968         }
969     }
970     return true;
971 }
972
973 bool AvDevice::setActiveSync(const SyncInfo& syncInfo)
974 {
975     return syncInfo.m_source->setConnection( *syncInfo.m_destination );
976 }
977
978 bool
979 AvDevice::lock() {
980     bool snoopMode=false;
981     if(!getOption("snoopMode", snoopMode)) {
982         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
983     }
984
985     if (snoopMode) {
986         // don't lock
987     } else {
988
989     }
990
991     return true;
992 }
993
994 bool
995 AvDevice::unlock() {
996     bool snoopMode=false;
997     if(!getOption("snoopMode", snoopMode)) {
998         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
999     }
1000
1001     if (snoopMode) {
1002         // don't unlock
1003     } else {
1004
1005     }
1006     return true;
1007 }
1008
1009 bool
1010 AvDevice::prepare() {
1011     bool snoopMode=false;
1012     if(!getOption("snoopMode", snoopMode)) {
1013         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1014     }
1015
1016     ///////////
1017     // get plugs
1018
1019     AvPlug* inputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Input, 0 );
1020     if ( !inputPlug ) {
1021         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
1022         return false;
1023     }
1024     AvPlug* outputPlug = getPlugById( m_pcrPlugs, AvPlug::eAPD_Output, 0 );
1025     if ( !outputPlug ) {
1026         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
1027         return false;
1028     }
1029
1030     int samplerate=outputPlug->getSampleRate();
1031
1032     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing receive processor...\n");
1033     // create & add streamprocessors
1034     Streaming::StreamProcessor *p;
1035
1036     p=new Streaming::AmdtpReceiveStreamProcessor(
1037                              m_p1394Service->getPort(),
1038                              samplerate,
1039                              outputPlug->getNrOfChannels());
1040
1041     if(!p->init()) {
1042         debugFatal("Could not initialize receive processor!\n");
1043         delete p;
1044         return false;
1045     }
1046
1047     if (!addPlugToProcessor(*outputPlug,p,
1048         Streaming::Port::E_Capture)) {
1049         debugFatal("Could not add plug to processor!\n");
1050         delete p;
1051         return false;
1052     }
1053
1054     m_receiveProcessors.push_back(p);
1055
1056     // do the transmit processor
1057     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing transmit processor%s...\n",
1058             (snoopMode?" in snoop mode":""));
1059     if (snoopMode) {
1060         // we are snooping, so this is receive too.
1061         p=new Streaming::AmdtpReceiveStreamProcessor(
1062                                   m_p1394Service->getPort(),
1063                                   samplerate,
1064                                   inputPlug->getNrOfChannels());
1065     } else {
1066         p=new Streaming::AmdtpTransmitStreamProcessor(
1067                                 m_p1394Service->getPort(),
1068                                 samplerate,
1069                                 inputPlug->getNrOfChannels());
1070     }
1071
1072     if(!p->init()) {
1073         debugFatal("Could not initialize transmit processor %s!\n",
1074             (snoopMode?" in snoop mode":""));
1075         delete p;
1076         return false;
1077     }
1078
1079     if (snoopMode) {
1080         if (!addPlugToProcessor(*inputPlug,p,
1081             Streaming::Port::E_Capture)) {
1082             debugFatal("Could not add plug to processor!\n");
1083             return false;
1084         }
1085     } else {
1086         if (!addPlugToProcessor(*inputPlug,p,
1087             Streaming::Port::E_Playback)) {
1088             debugFatal("Could not add plug to processor!\n");
1089             return false;
1090         }
1091     }
1092
1093     // we put this SP into the transmit SP vector,
1094     // no matter if we are in snoop mode or not
1095     // this allows us to find out what direction
1096     // a certain stream should have.
1097     m_transmitProcessors.push_back(p);
1098
1099     return true;
1100 }
1101
1102 bool
1103 AvDevice::addPlugToProcessor(
1104     AvPlug& plug,
1105     Streaming::StreamProcessor *processor,
1106     Streaming::AmdtpAudioPort::E_Direction direction) {
1107
1108     std::string id=std::string("dev?");
1109     if(!getOption("id", id)) {
1110         debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n");
1111     }
1112
1113     AvPlug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
1114     for ( AvPlug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
1115           it != clusterInfos.end();
1116           ++it )
1117     {
1118         const AvPlug::ClusterInfo* clusterInfo = &( *it );
1119
1120         AvPlug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
1121         for ( AvPlug::ChannelInfoVector::const_iterator it = channelInfos.begin();
1122               it != channelInfos.end();
1123               ++it )
1124         {
1125             const AvPlug::ChannelInfo* channelInfo = &( *it );
1126             std::ostringstream portname;
1127
1128             portname << id << "_" << channelInfo->m_name;
1129
1130             Streaming::Port *p=NULL;
1131             switch(clusterInfo->m_portType) {
1132             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
1133             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
1134             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
1135             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
1136             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
1137                 p=new Streaming::AmdtpAudioPort(
1138                         portname.str(),
1139                         direction,
1140                         // \todo: streaming backend expects indexing starting from 0
1141                         // but bebob reports it starting from 1. Decide where
1142                         // and how to handle this (pp: here)
1143                         channelInfo->m_streamPosition - 1,
1144                         channelInfo->m_location - 1,
1145                         Streaming::AmdtpPortInfo::E_MBLA
1146                 );
1147                 break;
1148
1149             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
1150                 p=new Streaming::AmdtpMidiPort(
1151                         portname.str(),
1152                         direction,
1153                         // \todo: streaming backend expects indexing starting from 0
1154                         // but bebob reports it starting from 1. Decide where
1155                         // and how to handle this (pp: here)
1156                         channelInfo->m_streamPosition - 1,
1157                         channelInfo->m_location - 1,
1158                         Streaming::AmdtpPortInfo::E_Midi
1159                 );
1160
1161                 break;
1162             case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
1163             case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
1164             case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
1165             case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
1166             case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
1167             case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
1168             default:
1169             // unsupported
1170                 break;
1171             }
1172
1173             if (!p) {
1174                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
1175             } else {
1176
1177                 if (!processor->addPort(p)) {
1178                     debugWarning("Could not register port with stream processor\n");
1179                     return false;
1180                 }
1181             }
1182          }
1183     }
1184     return true;
1185 }
1186
1187 int
1188 AvDevice::getStreamCount() {
1189     return m_receiveProcessors.size() + m_transmitProcessors.size();
1190 }
1191
1192 Streaming::StreamProcessor *
1193 AvDevice::getStreamProcessorByIndex(int i) {
1194
1195     if (i<(int)m_receiveProcessors.size()) {
1196         return m_receiveProcessors.at(i);
1197     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1198         return m_transmitProcessors.at(i-m_receiveProcessors.size());
1199     }
1200
1201     return NULL;
1202 }
1203
1204 bool
1205 AvDevice::startStreamByIndex(int i) {
1206     int iso_channel=-1;
1207     bool snoopMode=false;
1208     if(!getOption("snoopMode", snoopMode)) {
1209         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1210     }
1211
1212     if (i<(int)m_receiveProcessors.size()) {
1213         int n=i;
1214         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
1215
1216         if(snoopMode) { // a stream from the device to another host
1217             // FIXME: put this into a decent framework!
1218             // we should check the oPCR[n] on the device
1219             struct iec61883_oPCR opcr;
1220             if (iec61883_get_oPCRX(
1221                     m_p1394Service->getHandle(),
1222                     m_pConfigRom->getNodeId() | 0xffc0,
1223                     (quadlet_t *)&opcr,
1224                     n)) {
1225
1226                 debugWarning("Error getting the channel for SP %d\n",i);
1227                 return false;
1228             }
1229
1230             iso_channel=opcr.channel;
1231         } else {
1232             iso_channel=m_p1394Service->allocateIsoChannelCMP(
1233                 m_pConfigRom->getNodeId() | 0xffc0, n,
1234                 m_p1394Service->getLocalNodeId()| 0xffc0, -1);
1235         }
1236         if (iso_channel<0) {
1237             debugError("Could not allocate ISO channel for SP %d\n",i);
1238             return false;
1239         }
1240
1241         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
1242
1243         p->setChannel(iso_channel);
1244         return true;
1245
1246     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1247         int n=i-m_receiveProcessors.size();
1248         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
1249
1250         if(snoopMode) { // a stream from another host to the device
1251             // FIXME: put this into a decent framework!
1252             // we should check the iPCR[n] on the device
1253             struct iec61883_iPCR ipcr;
1254             if (iec61883_get_iPCRX(
1255                     m_p1394Service->getHandle(),
1256                     m_pConfigRom->getNodeId() | 0xffc0,
1257                     (quadlet_t *)&ipcr,
1258                     n)) {
1259
1260                 debugWarning("Error getting the channel for SP %d\n",i);
1261                 return false;
1262             }
1263
1264             iso_channel=ipcr.channel;
1265
1266         } else {
1267             iso_channel=m_p1394Service->allocateIsoChannelCMP(
1268                 m_p1394Service->getLocalNodeId()| 0xffc0, -1,
1269                 m_pConfigRom->getNodeId() | 0xffc0, n);
1270         }
1271
1272         if (iso_channel<0) {
1273             debugError("Could not allocate ISO channel for SP %d\n",i);
1274             return false;
1275         }
1276
1277         debugOutput(DEBUG_LEVEL_VERBOSE, "Started SP %d on channel %d\n",i,iso_channel);
1278
1279         p->setChannel(iso_channel);
1280         return true;
1281     }
1282
1283     debugError("SP index %d out of range!\n",i);
1284     return false;
1285 }
1286
1287 bool
1288 AvDevice::stopStreamByIndex(int i) {
1289     bool snoopMode=false;
1290     if(!getOption("snoopMode", snoopMode)) {
1291         debugWarning("Could not retrieve snoopMode parameter, defauling to false\n");
1292     }
1293
1294     if (i<(int)m_receiveProcessors.size()) {
1295         int n=i;
1296         Streaming::StreamProcessor *p=m_receiveProcessors.at(n);
1297
1298         if(snoopMode) {
1299
1300         } else {
1301             // deallocate ISO channel
1302             if(!m_p1394Service->freeIsoChannel(p->getChannel())) {
1303                 debugError("Could not deallocate iso channel for SP %d\n",i);
1304                 return false;
1305             }
1306         }
1307         p->setChannel(-1);
1308
1309         return true;
1310
1311     } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) {
1312         int n=i-m_receiveProcessors.size();
1313         Streaming::StreamProcessor *p=m_transmitProcessors.at(n);
1314
1315         if(snoopMode) {
1316
1317         } else {
1318             // deallocate ISO channel
1319             if(!m_p1394Service->freeIsoChannel(p->getChannel())) {
1320                 debugError("Could not deallocate iso channel for SP %d\n",i);
1321                 return false;
1322             }
1323         }
1324         p->setChannel(-1);
1325
1326         return true;
1327     }
1328
1329     debugError("SP index %d out of range!\n",i);
1330     return false;
1331 }
1332
1333 template <typename T> bool serializeVector( Glib::ustring path,
1334                                             Util::IOSerialize& ser,
1335                                             const T& vec )
1336 {
1337     bool result = true; // if vec.size() == 0
1338     int i = 0;
1339     for ( typename T::const_iterator it = vec.begin(); it != vec.end(); ++it ) {
1340         std::ostringstream strstrm;
1341         strstrm << path << i;
1342         result &= ( *it )->serialize( strstrm.str() + "/", ser );
1343         i++;
1344     }
1345     return result;
1346 }
1347
1348 template <typename T, typename VT> bool deserializeVector( Glib::ustring path,
1349                                                            Util::IODeserialize& deser,
1350                                                            AvDevice& avDevice,
1351                                                            VT& vec )
1352 {
1353     int i = 0;
1354     bool bFinished = false;
1355     do {
1356         std::ostringstream strstrm;
1357         strstrm << path << i << "/";
1358         T* ptr = T::deserialize( strstrm.str(),
1359                                  deser,
1360                                  avDevice );
1361         if ( ptr ) {
1362             vec.push_back( ptr );
1363             i++;
1364         } else {
1365             bFinished = true;
1366         }
1367     } while ( !bFinished );
1368
1369     return true;
1370 }
1371
1372 bool
1373 AvDevice::serializeSyncInfoVector( Glib::ustring basePath,
1374                                    Util::IOSerialize& ser,
1375                                    const SyncInfoVector& vec )
1376 {
1377     bool result = true;
1378     int i = 0;
1379
1380     for ( SyncInfoVector::const_iterator it = vec.begin();
1381           it != vec.end();
1382           ++it )
1383     {
1384         const SyncInfo& info = *it;
1385
1386         std::ostringstream strstrm;
1387         strstrm << basePath << i << "/";
1388
1389         result &= ser.write( strstrm.str() + "m_source", info.m_source->getGlobalId() );
1390         result &= ser.write( strstrm.str() + "m_destination", info.m_destination->getGlobalId() );
1391         result &= ser.write( strstrm.str() + "m_description", Glib::ustring( info.m_description ) );
1392
1393         i++;
1394     }
1395
1396     return result;
1397 }
1398
1399 bool
1400 AvDevice::deserializeSyncInfoVector( Glib::ustring basePath,
1401                                      Util::IODeserialize& deser,
1402                                      AvDevice& avDevice,
1403                                      SyncInfoVector& vec )
1404 {
1405     int i = 0;
1406     bool bFinished = false;
1407     do {
1408         bool result;
1409         std::ostringstream strstrm;
1410         strstrm << basePath << i << "/";
1411
1412         plug_id_t sourceId;
1413         plug_id_t destinationId;
1414         Glib::ustring description;
1415
1416         result  = deser.read( strstrm.str() + "m_source", sourceId );
1417         result &= deser.read( strstrm.str() + "m_destination", destinationId );
1418         result &= deser.read( strstrm.str() + "m_description", description );
1419
1420         if ( result ) {
1421             SyncInfo syncInfo;
1422             syncInfo.m_source = avDevice.getPlugManager().getPlug( sourceId );
1423             syncInfo.m_destination = avDevice.getPlugManager().getPlug( destinationId );
1424             syncInfo.m_description = description;
1425
1426             vec.push_back( syncInfo );
1427             i++;
1428         } else {
1429             bFinished = true;
1430         }
1431     } while ( !bFinished );
1432
1433     return true;
1434 }
1435
1436 static bool
1437 deserializeAvPlugUpdateConnections( Glib::ustring path,
1438                                     Util::IODeserialize& deser,
1439                                     AvPlugVector& vec )
1440 {
1441     bool result = true;
1442     for ( AvPlugVector::iterator it = vec.begin();
1443           it != vec.end();
1444           ++it )
1445     {
1446         AvPlug* pPlug = *it;
1447         result &= pPlug->deserializeUpdate( path, deser );
1448     }
1449     return result;
1450 }
1451
1452 bool
1453 AvDevice::serialize( Glib::ustring basePath,
1454                      Util::IOSerialize& ser ) const
1455 {
1456
1457     bool result;
1458     result  = m_pConfigRom->serialize( basePath + "m_pConfigRom/", ser );
1459     result &= ser.write( basePath + "m_verboseLevel", m_verboseLevel );
1460     result &= m_pPlugManager->serialize( basePath + "AvPlug", ser ); // serialize all av plugs
1461     result &= serializeVector( basePath + "PlugConnection", ser, m_plugConnections );
1462     result &= serializeVector( basePath + "Subunit", ser, m_subunits );
1463     result &= serializeSyncInfoVector( basePath + "SyncInfo", ser, m_syncInfos );
1464
1465     int i = 0;
1466     for ( SyncInfoVector::const_iterator it = m_syncInfos.begin();
1467           it != m_syncInfos.end();
1468           ++it )
1469     {
1470         const SyncInfo& info = *it;
1471         if ( m_activeSyncInfo == &info ) {
1472             result &= ser.write( basePath + "m_activeSyncInfo",  i );
1473             break;
1474         }
1475         i++;
1476     }
1477
1478     result &= serializeOptions( basePath + "Options", ser );
1479
1480 //     result &= ser.write( basePath + "m_id", id );
1481
1482     return result;
1483 }
1484
1485 AvDevice*
1486 AvDevice::deserialize( Glib::ustring basePath,
1487                        Util::IODeserialize& deser,
1488                        Ieee1394Service& ieee1394Service )
1489 {
1490
1491     ConfigRom *configRom =
1492         ConfigRom::deserialize( basePath + "m_pConfigRom/", deser, ieee1394Service );
1493
1494     if ( !configRom ) {
1495         return NULL;
1496     }
1497
1498     AvDevice* pDev = new AvDevice(
1499         std::auto_ptr<ConfigRom>(configRom),
1500         ieee1394Service, configRom->getNodeId());
1501
1502     if ( pDev ) {
1503         bool result;
1504         result  = deser.read( basePath + "m_verboseLevel", pDev->m_verboseLevel );
1505
1506         if (pDev->m_pPlugManager) delete pDev->m_pPlugManager;
1507         pDev->m_pPlugManager = AvPlugManager::deserialize( basePath + "AvPlug", deser, *pDev );
1508         if ( !pDev->m_pPlugManager ) {
1509             delete pDev;
1510             return 0;
1511         }
1512         result &= deserializeAvPlugUpdateConnections( basePath + "AvPlug", deser, pDev->m_pcrPlugs );
1513         result &= deserializeAvPlugUpdateConnections( basePath + "AvPlug", deser, pDev->m_externalPlugs );
1514         result &= deserializeVector<AvPlugConnection>( basePath + "PlugConnnection", deser, *pDev, pDev->m_plugConnections );
1515         result &= deserializeVector<AvDeviceSubunit>( basePath + "Subunit",  deser, *pDev, pDev->m_subunits );
1516         result &= deserializeSyncInfoVector( basePath + "SyncInfo", deser, *pDev, pDev->m_syncInfos );
1517
1518         unsigned int i;
1519         result &= deser.read( basePath + "m_activeSyncInfo", i );
1520
1521         if ( result ) {
1522             if ( i < pDev->m_syncInfos.size() ) {
1523                 pDev->m_activeSyncInfo = &pDev->m_syncInfos[i];
1524             }
1525         }
1526
1527         result &= deserializeOptions( basePath + "Options", deser, *pDev );
1528     }
1529
1530     return pDev;
1531 }
1532
1533 } // end of namespace
Note: See TracBrowser for help on using the browser.