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

Revision 445, 46.4 kB (checked in by pieterpalmers, 17 years ago)

* name change from FreeBoB to FFADO
* replaced tabs by 4 spaces
* got rid of end-of-line spaces
* made all license and copyrights conform

library becomes LGPL, apps become GPL
explicitly state LGPL v2.1 and GPL v2 (don't like v3 draft)

copyrights are 2005-2007 Daniel & Pieter
except for the MotU stuff (C) Jonathan, Pieter

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