root/branches/libfreebob-2.0/src/bebob_light/bebob_light_avdevice.cpp

Revision 242, 66.7 kB (checked in by pieterpalmers, 18 years ago)

- made the bounce device actually work

Line 
1 /* bebob_light_avdevice.cpp
2  * Copyright (C) 2006 by Daniel Wagner
3  *
4  * This file is part of FreeBob.
5  *
6  * FreeBob is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * FreeBob is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with FreeBob; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA.
19  */
20
21 #include "bebob_light/bebob_light_avdevice.h"
22 #include "bebob_light/bebob_light_avdevicesubunit.h"
23
24 #include "configrom.h"
25
26 #include "libfreebobavc/avc_plug_info.h"
27 #include "libfreebobavc/avc_extended_plug_info.h"
28 #include "libfreebobavc/avc_subunit_info.h"
29 #include "libfreebobavc/avc_extended_stream_format.h"
30 #include "libfreebobavc/serialize.h"
31 #include "libfreebobavc/ieee1394service.h"
32 #include "libfreebobavc/avc_definitions.h"
33
34 #include "debugmodule/debugmodule.h"
35
36 #include <iostream>     
37 #include <sstream>
38 #include <stdint.h>
39
40 namespace BeBoB_Light {
41
42 using namespace std;
43
44 IMPL_DEBUG_MODULE( AvDevice, AvDevice, DEBUG_LEVEL_VERBOSE );
45
46 AvDevice::AvDevice( Ieee1394Service& ieee1394service,
47                     int nodeId,
48                     int verboseLevel )
49     : m_1394Service( &ieee1394service )
50     , m_nodeId( nodeId )
51     , m_verboseLevel( verboseLevel )
52     , m_id(0)
53     , m_receiveProcessor ( 0 )
54     , m_receiveProcessorBandwidth ( -1 )
55     , m_transmitProcessor ( 0 )
56     , m_transmitProcessorBandwidth ( -1 )
57 {
58     if ( m_verboseLevel ) {
59         setDebugLevel( DEBUG_LEVEL_VERBOSE );
60     }
61     debugOutput( DEBUG_LEVEL_VERBOSE, "Created BeBoB_Light::AvDevice "
62                  "(NodeID %d)\n", nodeId );
63
64     m_configRom = new ConfigRom( m_1394Service, m_nodeId );
65     m_configRom->initialize();
66 }
67
68 AvDevice::~AvDevice()
69 {
70     delete m_configRom;
71     for ( AvDeviceSubunitVector::iterator it = m_subunits.begin();
72           it != m_subunits.end();
73           ++it )
74     {
75         delete *it;
76     }
77     for ( AvPlugConnectionVector::iterator it = m_plugConnections.begin();
78           it != m_plugConnections.end();
79           ++it )
80     {
81         delete *it;
82     }
83     for ( AvPlugVector::iterator it = m_isoInputPlugs.begin();
84           it != m_isoInputPlugs.end();
85           ++it )
86     {
87         delete *it;
88     }
89     for ( AvPlugVector::iterator it = m_isoOutputPlugs.begin();
90           it != m_isoOutputPlugs.end();
91           ++it )
92     {
93         delete *it;
94     }
95 }
96
97 bool
98 AvDevice::discover()
99 {
100     if ( !enumerateSubUnits() ) {
101         debugError( "Could not enumarate sub units\n" );
102         return false;
103     }
104
105     if ( !discoverStep1() ) {
106         debugError( "Discover step 1 failed\n" );
107         return false;
108     }
109     if ( !discoverStep2() ) {
110         debugError( "Discover step 2 failed\n" );
111         return false;
112     }
113     if ( !discoverStep3() ) {
114         debugError( "Discover step 3 failed\n" );
115         return false;
116     }
117     if ( !discoverStep4() ) {
118         debugError( "Discover step 4 failed\n" );
119         return false;
120     }
121     if ( !discoverStep5() ) {
122         debugError( "Discover step 5 failed\n" );
123         return false;
124     }
125     if ( !discoverStep6() ) {
126         debugError( "Discover step 6 failed\n" );
127         return false;
128     }
129     if ( !discoverStep7() ) {
130         debugError( "Discover step 7 failed\n" );
131         return false;
132     }
133     if ( !discoverStep8() ) {
134         debugError( "Discover step 8 failed\n" );
135         return false;
136     }
137     if ( !discoverStep9() ) {
138         debugError( "Discover step 9 failed\n" );
139         return false;
140     }
141     if ( !discoverStep10() ) {
142         debugError( "Discover step 10 failed\n" );
143         return false;
144     }
145
146     return true;
147 }
148
149 bool
150 AvDevice::discoverStep1()
151 {
152     //////////////////////////////////////////////
153     // Step 1: Get number of available isochronous input
154     // and output plugs of unit
155
156     PlugInfoCmd plugInfoCmd( m_1394Service );
157     plugInfoCmd.setNodeId( m_nodeId );
158     plugInfoCmd.setCommandType( AVCCommand::eCT_Status );
159
160     if ( !plugInfoCmd.fire() ) {
161         debugError( "discover: plug info command failed (step 1)\n" );
162         return false;
163     }
164
165     for ( int plugId = 0; plugId < plugInfoCmd.m_serialBusIsochronousInputPlugs; ++plugId )
166     {
167         AvPlug* plug        = new AvPlug;
168         plug->m_plugId      = plugId;
169         plug->m_subunitType = PlugAddress::ePAM_Unit;
170         plug->m_direction   = PlugAddress::ePD_Input;
171         plug->m_name        = "IsoStreamInput";
172
173         m_isoInputPlugs.push_back( plug );
174     }
175
176     for ( int plugId = 0; plugId < plugInfoCmd.m_serialBusIsochronousOutputPlugs; ++plugId )
177     {
178         AvPlug* plug        = new AvPlug;
179         plug->m_plugId      = plugId;
180         plug->m_subunitType = PlugAddress::ePAM_Unit;
181         plug->m_direction   = PlugAddress::ePD_Output;
182         plug->m_name        = "IsoStreamOutput";
183
184         m_isoOutputPlugs.push_back( plug );
185     }
186
187     debugOutput( DEBUG_LEVEL_VERBOSE,
188                  "number of iso input plugs = %d, "
189                  "number of iso output plugs = %d\n",
190                  plugInfoCmd.m_serialBusIsochronousInputPlugs,
191                  plugInfoCmd.m_serialBusIsochronousOutputPlugs );
192
193     return true;
194 }
195
196 bool
197 AvDevice::discoverStep2()
198 {
199     //////////////////////////////////////////////
200     // Step 2: For each ISO input plug: get internal
201     // output connections (data sink) of the ISO input plug
202
203     for ( AvPlugVector::iterator it = m_isoInputPlugs.begin();
204           it != m_isoInputPlugs.end();
205           ++it )
206     {
207         AvPlug* isoInputPlug = *it;
208
209         ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service );
210         UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
211                                          isoInputPlug->getPlugId() );
212         extPlugInfoCmd.setPlugAddress( PlugAddress( PlugAddress::ePD_Input,
213                                                     PlugAddress::ePAM_Unit,
214                                                     unitPlugAddress ) );
215         extPlugInfoCmd.setNodeId( m_nodeId );
216         extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status );
217         //extPlugInfoCmd.setVerbose( true );
218         ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
219             ExtendedPlugInfoInfoType::eIT_PlugOutput );
220         extendedPlugInfoInfoType.initialize();
221         extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
222
223         if ( !extPlugInfoCmd.fire() ) {
224             debugError( "discoverStep2: plug outputs command failed\n" );
225             return false;
226         }
227
228         ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
229         if ( infoType
230              && infoType->m_plugOutput )
231         {
232             debugOutput( DEBUG_LEVEL_VERBOSE,
233                          "number of output plugs is %d for iso input "
234                          "plug %d\n",
235                          infoType->m_plugOutput->m_nrOfOutputPlugs,
236                          isoInputPlug->getPlugId() );
237
238             if ( infoType->m_plugOutput->m_nrOfOutputPlugs
239                  != infoType->m_plugOutput->m_outputPlugAddresses.size() )
240             {
241                 debugError( "number of output plugs (%d) disagree with "
242                             "number of elements in plug address vector (%d)\n",
243                             infoType->m_plugOutput->m_nrOfOutputPlugs,
244                             infoType->m_plugOutput->m_outputPlugAddresses.size());
245             }
246             for ( unsigned int i = 0;
247                   i < infoType->m_plugOutput->m_outputPlugAddresses.size();
248                   ++i )
249             {
250                 PlugAddressSpecificData* plugAddress
251                     = infoType->m_plugOutput->m_outputPlugAddresses[i];
252
253
254                 UnitPlugSpecificDataPlugAddress* pUnitPlugAddress =
255                     dynamic_cast<UnitPlugSpecificDataPlugAddress*>
256                     ( plugAddress->m_plugAddressData );
257
258                 if ( pUnitPlugAddress ) {
259                     debugOutput( DEBUG_LEVEL_VERBOSE,
260                                  "unit plug address is not handled\n" );
261                 }
262
263                 SubunitPlugSpecificDataPlugAddress* pSubunitPlugAddress =
264                     dynamic_cast<SubunitPlugSpecificDataPlugAddress*>
265                     ( plugAddress->m_plugAddressData );
266
267                 if ( pSubunitPlugAddress ) {
268                     debugOutput( DEBUG_LEVEL_VERBOSE,
269                                  "output plug %d is owned by subunit_type %d, "
270                                  "subunit_id = %d\n",
271                                  pSubunitPlugAddress->m_plugId,
272                                  pSubunitPlugAddress->m_subunitType,
273                                  pSubunitPlugAddress->m_subunitId );
274
275                     if ( !discoverPlugConnection( *isoInputPlug,
276                                                   *pSubunitPlugAddress ) )
277                     {
278                         debugError( "Discovering of plug connection failed\n" );
279                         return false;
280                     }
281                 }
282
283                 FunctionBlockPlugSpecificDataPlugAddress*
284                     pFunctionBlockPlugAddress =
285                     dynamic_cast<FunctionBlockPlugSpecificDataPlugAddress*>
286                     ( plugAddress->m_plugAddressData );
287
288                 if (  pFunctionBlockPlugAddress  ) {
289                     debugOutput( DEBUG_LEVEL_VERBOSE,
290                                  "function block address is not handled\n" );
291                 }
292             }
293         } else {
294             debugError( "discoverStep2: no valid info type, output plug\n" );
295             return false;
296         }
297     }
298
299     return true;
300 }
301
302 bool
303 AvDevice::discoverStep3()
304 {
305     //////////////////////////////////////////////
306     // Step 3: For each ISO output plug: get internal
307     // intput connections (data source) of the ISO output plug
308
309     for ( AvPlugVector::iterator it = m_isoOutputPlugs.begin();
310           it != m_isoOutputPlugs.end();
311           ++it )
312     {
313         AvPlug* isoOutputPlug = *it;
314
315         ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service );
316         UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
317                                          isoOutputPlug->getPlugId() );
318         extPlugInfoCmd.setPlugAddress( PlugAddress( PlugAddress::ePD_Output,
319                                                     PlugAddress::ePAM_Unit,
320                                                     unitPlugAddress ) );
321         extPlugInfoCmd.setNodeId( m_nodeId );
322         extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status );
323         //extPlugInfoCmd.setVerbose( true );
324         ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
325             ExtendedPlugInfoInfoType::eIT_PlugInput );
326         extendedPlugInfoInfoType.initialize();
327         extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
328
329         if ( !extPlugInfoCmd.fire() ) {
330             debugError( "discoverStep3: plug inputs command failed\n" );
331             return false;
332         }
333
334         ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
335         if ( infoType
336              && infoType->m_plugInput )
337         {
338             PlugAddressSpecificData* plugAddress
339                 = infoType->m_plugInput->m_plugAddress;
340
341
342             UnitPlugSpecificDataPlugAddress* pUnitPlugAddress =
343                 dynamic_cast<UnitPlugSpecificDataPlugAddress*>
344                 ( plugAddress->m_plugAddressData );
345
346             if ( pUnitPlugAddress ) {
347                 debugOutput( DEBUG_LEVEL_VERBOSE,
348                              "unit plug address is not handled\n" );
349             }
350
351             SubunitPlugSpecificDataPlugAddress* pSubunitPlugAddress =
352                 dynamic_cast<SubunitPlugSpecificDataPlugAddress*>
353                 ( plugAddress->m_plugAddressData );
354
355             if ( pSubunitPlugAddress ) {
356                 debugOutput( DEBUG_LEVEL_VERBOSE,
357                              "output plug %d is owned by subunit_type %d, "
358                              "subunit_id %d\n",
359                              pSubunitPlugAddress->m_plugId,
360                              pSubunitPlugAddress->m_subunitType,
361                              pSubunitPlugAddress->m_subunitId );
362
363                 if ( !discoverPlugConnection( *isoOutputPlug, *pSubunitPlugAddress ) ) {
364                     debugError( "Discovering of plug connection failed\n" );
365                     return false;
366                 }
367             }
368
369             FunctionBlockPlugSpecificDataPlugAddress*
370                 pFunctionBlockPlugAddress =
371                 dynamic_cast<FunctionBlockPlugSpecificDataPlugAddress*>
372                 ( plugAddress->m_plugAddressData );
373
374             if (  pFunctionBlockPlugAddress  ) {
375                 debugOutput( DEBUG_LEVEL_VERBOSE,
376                              "function block address is not handled\n" );
377             }
378         } else {
379             debugError( "discoverStep3: no valid info type, input plug\n" );
380             return false;
381         }
382     }
383
384     return true;
385 }
386
387 bool
388 AvDevice::discoverStep4Plug( AvPlugVector& isoPlugs )
389 {
390     //////////////////////////////////////////////
391     // Step 4: For all ISO plugs with valid internal connections:
392     // get type of data stream flowing through plug.
393     // Stream type of interest: iso stream & sync stream
394
395     for ( AvPlugVector::iterator it = isoPlugs.begin();
396           it != isoPlugs.end();
397           ++it )
398     {
399         AvPlug* isoPlug = *it;
400
401         AvPlugConnection* plugConnection = getPlugConnection( *isoPlug );
402         if ( !plugConnection ) {
403             debugOutput( DEBUG_LEVEL_VERBOSE,
404                          "plug %d has no valid connecton -> skip\n",
405                          isoPlug->getPlugId() );
406             continue;
407         }
408
409         ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service );
410         UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
411                                          isoPlug->getPlugId() );
412         PlugAddress::EPlugDirection direction =
413             static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() );
414         extPlugInfoCmd.setPlugAddress( PlugAddress( direction,
415                                                     PlugAddress::ePAM_Unit,
416                                                     unitPlugAddress ) );
417         extPlugInfoCmd.setNodeId( m_nodeId );
418         extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status );
419         //extPlugInfoCmd.setVerbose( true );
420         ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
421             ExtendedPlugInfoInfoType::eIT_PlugType );
422         extendedPlugInfoInfoType.initialize();
423         extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
424
425         if ( !extPlugInfoCmd.fire() ) {
426             debugError( "discoverStep4Plug: plug type command failed\n" );
427             return false;
428         }
429
430         ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
431         if ( infoType
432              && infoType->m_plugType )
433         {
434             plug_type_t plugType = infoType->m_plugType->m_plugType;
435
436             debugOutput( DEBUG_LEVEL_VERBOSE,
437                          "plug %d is of type %d (%s)\n",
438                          isoPlug->getPlugId(),
439                          plugType,
440                          extendedPlugInfoPlugTypeToString( plugType ) );
441
442             isoPlug->m_plugType = plugType;
443         }
444     }
445
446    return true;
447 }
448
449 bool
450 AvDevice::discoverStep4()
451 {
452     bool success;
453     success  = discoverStep4Plug( m_isoInputPlugs );
454     success &= discoverStep4Plug( m_isoOutputPlugs );
455
456     return success;
457 }
458
459 bool
460 AvDevice::discoverStep5Plug( AvPlugVector& isoPlugs )
461 {
462     //////////////////////////////////////////////
463     // Step 5: For all ISO plugs with valid internal connections:
464     // get data block size of the stream flowing through the plug
465
466     for ( AvPlugVector::iterator it = isoPlugs.begin();
467           it != isoPlugs.end();
468           ++it )
469     {
470         AvPlug* isoPlug = *it;
471
472         AvPlugConnection* plugConnection = getPlugConnection( *isoPlug );
473         if ( !plugConnection ) {
474             debugOutput( DEBUG_LEVEL_VERBOSE,
475                          "plug %d has no valid connecton -> skip\n",
476                          isoPlug->getPlugId() );
477             continue;
478         }
479
480         ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service );
481         UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
482                                          isoPlug->getPlugId() );
483         PlugAddress::EPlugDirection direction =
484             static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() );
485         extPlugInfoCmd.setPlugAddress( PlugAddress( direction,
486                                                     PlugAddress::ePAM_Unit,
487                                                     unitPlugAddress ) );
488         extPlugInfoCmd.setNodeId( m_nodeId );
489         extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status );
490         //extPlugInfoCmd.setVerbose( true );
491         ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
492             ExtendedPlugInfoInfoType::eIT_NoOfChannels );
493         extendedPlugInfoInfoType.initialize();
494         extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
495
496         if ( !extPlugInfoCmd.fire() ) {
497             debugError( "discoverStep5Plug: number of channels command failed\n" );
498             return false;
499         }
500
501         ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
502         if ( infoType
503              && infoType->m_plugNrOfChns )
504         {
505             nr_of_channels_t nrOfChannels
506                 = infoType->m_plugNrOfChns->m_nrOfChannels;
507
508             debugOutput( DEBUG_LEVEL_VERBOSE,
509                          "plug %d has %d channels\n",
510                          isoPlug->getPlugId(),
511                          nrOfChannels );
512
513             isoPlug->m_nrOfChannels = nrOfChannels;
514         }
515     }
516
517     return true;
518 }
519
520
521 bool
522 AvDevice::discoverStep5()
523 {
524     bool success;
525     success  = discoverStep5Plug( m_isoInputPlugs );
526     success &= discoverStep5Plug( m_isoOutputPlugs );
527
528     return success;
529 }
530
531 bool
532 AvDevice::discoverStep6Plug( AvPlugVector& isoPlugs )
533 {
534     //////////////////////////////////////////////
535     // Step 6: For all ISO plugs with valid internal connections:
536     // get position of channels within data block
537
538     for ( AvPlugVector::iterator it = isoPlugs.begin();
539           it != isoPlugs.end();
540           ++it )
541     {
542         AvPlug* isoPlug = *it;
543
544         AvPlugConnection* plugConnection = getPlugConnection( *isoPlug );
545         if ( !plugConnection ) {
546             debugOutput( DEBUG_LEVEL_VERBOSE,
547                          "plug %d has no valid connecton -> skip\n",
548                          isoPlug->getPlugId() );
549             continue;
550         }
551
552         ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service );
553         UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
554                                          isoPlug->getPlugId() );
555         PlugAddress::EPlugDirection direction =
556             static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() );
557         extPlugInfoCmd.setPlugAddress( PlugAddress( direction,
558                                                     PlugAddress::ePAM_Unit,
559                                                     unitPlugAddress ) );
560         extPlugInfoCmd.setNodeId( m_nodeId );
561         extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status );
562         //extPlugInfoCmd.setVerbose( true );
563         ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
564             ExtendedPlugInfoInfoType::eIT_ChannelPosition );
565         extendedPlugInfoInfoType.initialize();
566         extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
567
568         if ( !extPlugInfoCmd.fire() ) {
569             debugError( "discoverStep6Plug: channels position command failed\n" );
570             return false;
571         }
572
573         ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
574         if ( infoType
575              && infoType->m_plugChannelPosition )
576         {
577             if ( !isoPlug->copyClusterInfo(
578                      *( infoType->m_plugChannelPosition ) ) )
579             {
580                 debugError( "discoverStep6Plug: Could not copy channel position "
581                             "information\n" );
582                 return false;
583             }
584
585             debugOutput( DEBUG_LEVEL_VERBOSE,
586                          "plug %d: channel position information "
587                          "retrieved\n",
588                          isoPlug->getPlugId() );
589
590             isoPlug->debugOutputClusterInfos( DEBUG_LEVEL_VERBOSE );
591         }
592     }
593
594     return true;
595 }
596
597 bool
598 AvDevice::discoverStep6()
599 {
600     bool success;
601     success  = discoverStep6Plug( m_isoInputPlugs );
602     success &= discoverStep6Plug( m_isoOutputPlugs );
603
604     return success;
605 }
606
607 bool
608 AvDevice::discoverStep7Plug( AvPlugVector& isoPlugs )
609 {
610     //////////////////////////////////////////////
611     // Step 7: For all ISO plugs with valid internal connections:
612     // get hardware name of channel
613
614     for ( AvPlugVector::iterator it = isoPlugs.begin();
615           it != isoPlugs.end();
616           ++it )
617     {
618         AvPlug* isoPlug = *it;
619
620         AvPlugConnection* plugConnection = getPlugConnection( *isoPlug );
621         if ( !plugConnection ) {
622             debugOutput( DEBUG_LEVEL_VERBOSE,
623                          "plug %d has no valid connecton -> skip\n",
624                          isoPlug->getPlugId() );
625             continue;
626         }
627
628         for ( AvPlug::ClusterInfoVector::iterator clit =
629                   isoPlug->m_clusterInfos.begin();
630               clit != isoPlug->m_clusterInfos.end();
631               ++clit )
632         {
633             AvPlug::ClusterInfo* clitInfo = &*clit;
634
635             for ( AvPlug::ChannelInfoVector::iterator pit =
636                       clitInfo->m_channelInfos.begin();
637                   pit != clitInfo->m_channelInfos.end();
638                   ++pit )
639             {
640                 AvPlug::ChannelInfo* channelInfo = &*pit;
641
642                 ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service );
643                 UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
644                                                  isoPlug->getPlugId() );
645                 PlugAddress::EPlugDirection direction =
646                     static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() );
647                 extPlugInfoCmd.setPlugAddress( PlugAddress( direction,
648                                                             PlugAddress::ePAM_Unit,
649                                                             unitPlugAddress ) );
650                 extPlugInfoCmd.setNodeId( m_nodeId );
651                 extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status );
652                 //extPlugInfoCmd.setVerbose( true );
653                 ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
654                     ExtendedPlugInfoInfoType::eIT_ChannelName );
655                 extendedPlugInfoInfoType.initialize();
656                 extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
657
658                 ExtendedPlugInfoInfoType* infoType =
659                     extPlugInfoCmd.getInfoType();
660                 if ( infoType ) {
661                     infoType->m_plugChannelName->m_streamPosition =
662                         channelInfo->m_streamPosition;
663                 }
664                 if ( !extPlugInfoCmd.fire() ) {
665                     debugError( "discoverStep7: channel name command failed\n" );
666                     return false;
667                 }
668                 infoType = extPlugInfoCmd.getInfoType();
669                 if ( infoType
670                      && infoType->m_plugChannelName )
671                 {
672                     debugOutput( DEBUG_LEVEL_VERBOSE,
673                                  "plug %d stream "
674                                  "position %d: channel name = %s\n",
675                                  isoPlug->getPlugId(),
676                                  channelInfo->m_streamPosition,
677                                  infoType->m_plugChannelName->m_plugChannelName.c_str() );
678                     channelInfo->m_name =
679                         infoType->m_plugChannelName->m_plugChannelName;
680                 }
681
682             }
683         }
684     }
685
686     return true;
687 }
688 bool
689 AvDevice::discoverStep7()
690 {
691     bool success;
692     success  = discoverStep7Plug( m_isoInputPlugs );
693     success &= discoverStep7Plug( m_isoOutputPlugs );
694
695     return success;
696 }
697
698 bool
699 AvDevice::discoverStep8Plug( AvPlugVector& isoPlugs )
700 {
701     //////////////////////////////////////////////
702     // Step 8: For all ISO plugs with valid internal connections:
703     // get logical input and output streams provided by the device
704
705     for ( AvPlugVector::iterator it = isoPlugs.begin();
706           it != isoPlugs.end();
707           ++it )
708     {
709         AvPlug* isoPlug = *it;
710
711         AvPlugConnection* plugConnection = getPlugConnection( *isoPlug );
712         if ( !plugConnection ) {
713             debugOutput( DEBUG_LEVEL_VERBOSE,
714                          "%s plug %d has no valid connecton -> skip\n",
715                          isoPlug->getName(),
716                          isoPlug->getPlugId() );
717             continue;
718         }
719
720         if ( isoPlug->getPlugType()
721              == ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_Sync )
722         {
723             // If the plug is of type sync it is either a normal 2 channel
724             // stream (not compound stream) or it is a compound stream
725             // with exactly one cluster. This depends on the
726             // extended stream format command version which is used.
727             // We are not interested in this plug so we skip it.
728             debugOutput( DEBUG_LEVEL_VERBOSE,
729                          "%s plug %d is of type sync -> skip\n",
730                          isoPlug->getName(),
731                          isoPlug->getPlugId() );
732             continue;
733         }
734
735         for ( AvPlug::ClusterInfoVector::iterator clit =
736                   isoPlug->m_clusterInfos.begin();
737               clit != isoPlug->m_clusterInfos.end();
738               ++clit )
739         {
740             AvPlug::ClusterInfo* clusterInfo = &*clit;
741
742             ExtendedPlugInfoCmd extPlugInfoCmd( m_1394Service );
743             UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
744                                              isoPlug->getPlugId() );
745             PlugAddress::EPlugDirection direction =
746                 static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() );
747             extPlugInfoCmd.setPlugAddress( PlugAddress( direction,
748                                                         PlugAddress::ePAM_Unit,
749                                                         unitPlugAddress ) );
750             extPlugInfoCmd.setNodeId( m_nodeId );
751             extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status );
752             //extPlugInfoCmd.setVerbose( true );
753             ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
754                 ExtendedPlugInfoInfoType::eIT_ClusterInfo );
755             extendedPlugInfoInfoType.initialize();
756             extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
757
758             extPlugInfoCmd.getInfoType()->m_plugClusterInfo->m_clusterIndex =
759                 clusterInfo->m_index;
760
761             if ( !extPlugInfoCmd.fire() ) {
762                 debugError( "discoverStep8Plug: cluster info command failed\n" );
763                 return false;
764             }
765
766             ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
767             if ( infoType
768                  && infoType->m_plugClusterInfo )
769             {
770                 debugOutput( DEBUG_LEVEL_VERBOSE,
771                              "%s plug %d: cluster index = %d, "
772                              "portType %s, cluster name = %s\n",
773                              isoPlug->getName(),
774                              isoPlug->getPlugId(),
775                              infoType->m_plugClusterInfo->m_clusterIndex,
776                              extendedPlugInfoClusterInfoPortTypeToString(
777                                  infoType->m_plugClusterInfo->m_portType ),
778                              infoType->m_plugClusterInfo->m_clusterName.c_str() );
779
780                 clusterInfo->m_portType = infoType->m_plugClusterInfo->m_portType;
781                 clusterInfo->m_name = infoType->m_plugClusterInfo->m_clusterName;
782             }
783         }
784     }
785
786     return true;
787 }
788
789 bool
790 AvDevice::discoverStep8()
791 {
792     bool success;
793     success  = discoverStep8Plug( m_isoInputPlugs );
794     success &= discoverStep8Plug( m_isoOutputPlugs );
795
796     return success;
797 }
798
799 bool
800 AvDevice::discoverStep9Plug( AvPlugVector& isoPlugs )
801 {
802     //////////////////////////////////////////////
803     // Step 9: For all ISO plugs with valid internal connections:
804     // get current stream format
805
806     for ( AvPlugVector::iterator it = isoPlugs.begin();
807           it != isoPlugs.end();
808           ++it )
809     {
810         AvPlug* isoPlug = *it;
811
812         AvPlugConnection* plugConnection = getPlugConnection( *isoPlug );
813         if ( !plugConnection ) {
814             debugOutput( DEBUG_LEVEL_VERBOSE,
815                          "%s plug %d has no valid connecton -> skip\n",
816                          isoPlug->getName(),
817                          isoPlug->getPlugId() );
818             continue;
819         }
820
821         ExtendedStreamFormatCmd extStreamFormatCmd( m_1394Service );
822         UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
823                                          isoPlug->getPlugId() );
824         PlugAddress::EPlugDirection direction =
825             static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() );
826         extStreamFormatCmd.setPlugAddress( PlugAddress( direction,
827                                                         PlugAddress::ePAM_Unit,
828                                                         unitPlugAddress ) );
829
830         extStreamFormatCmd.setNodeId( m_nodeId );
831         extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
832         //extStreamFormatCmd.setVerbose( true );
833
834         if ( !extStreamFormatCmd.fire() ) {
835             debugError( "discoverStep9Plug: stream format command failed\n" );
836             return false;
837         }
838
839         FormatInformation* formatInfo =
840             extStreamFormatCmd.getFormatInformation();
841         FormatInformationStreamsCompound* compoundStream
842             = dynamic_cast< FormatInformationStreamsCompound* > (
843                 formatInfo->m_streams );
844         if ( compoundStream ) {
845             isoPlug->m_samplingFrequency =
846                 compoundStream->m_samplingFrequency;
847             debugOutput( DEBUG_LEVEL_VERBOSE,
848                          "discoverStep9Plug: %s plug %d uses "
849                          "sampling frequency %d\n",
850                          isoPlug->getName(),
851                          isoPlug->getPlugId(),
852                          isoPlug->m_samplingFrequency );
853
854             for ( int i = 1;
855                   i <= compoundStream->m_numberOfStreamFormatInfos;
856                   ++i )
857             {
858                 AvPlug::ClusterInfo* clusterInfo =
859                     isoPlug->getClusterInfoByIndex( i );
860
861                 if ( !clusterInfo ) {
862                     debugError( "discoverStep9Plug: No matching cluster info found "
863                                 "for index %d\n",  i );
864                     return false;
865                 }
866                 StreamFormatInfo* streamFormatInfo =
867                     compoundStream->m_streamFormatInfos[ i - 1 ];
868
869                 int nrOfChannels = clusterInfo->m_nrOfChannels;
870                 if ( streamFormatInfo->m_streamFormat ==
871                      FormatInformation::eFHL2_AM824_MIDI_CONFORMANT )
872                 {
873                     // 8 logical midi channels fit into 1 channel
874                     nrOfChannels = ( ( nrOfChannels + 7 ) / 8 );
875                 }
876                 // sanity checks
877                 if (  nrOfChannels !=
878                      streamFormatInfo->m_numberOfChannels )
879                 {
880                     debugError( "discoverStep9Plug: Number of channels "
881                                 "mismatch: %s plug %d discovering reported "
882                                 "%d channels for cluster '%s', while stream format "
883                                 "reported %d\n",
884                                 isoPlug->getName(),
885                                 isoPlug->getPlugId(),
886                                 nrOfChannels,
887                                 clusterInfo->m_name.c_str(),
888                                 streamFormatInfo->m_numberOfChannels);
889                     return false;
890                 }
891                 clusterInfo->m_streamFormat = streamFormatInfo->m_streamFormat;
892
893                 debugOutput( DEBUG_LEVEL_VERBOSE,
894                              "%s plug %d cluster info %d ('%s'): stream format %d\n",
895                              isoPlug->getName(),
896                              isoPlug->getPlugId(),
897                              i,
898                              clusterInfo->m_name.c_str(),
899                              clusterInfo->m_streamFormat );
900             }
901         }
902
903         FormatInformationStreamsSync* syncStream
904             = dynamic_cast< FormatInformationStreamsSync* > (
905                 formatInfo->m_streams );
906         if ( syncStream ) {
907             isoPlug->m_samplingFrequency =
908                 syncStream->m_samplingFrequency;
909                 debugOutput( DEBUG_LEVEL_VERBOSE,
910                              "%s plug %d is sync stream with sampling frequency %d\n",
911                              isoPlug->getName(),
912                              isoPlug->getPlugId(),
913                              isoPlug->m_samplingFrequency );
914         }
915
916         if ( !compoundStream && !syncStream ) {
917             debugError( "discoverStep9Plug: Unsupported stream format\n" );
918             return false;
919         }
920     }
921
922     return true;
923 }
924
925 bool
926 AvDevice::discoverStep9()
927 {
928     bool success;
929     success  = discoverStep9Plug( m_isoInputPlugs );
930     success &= discoverStep9Plug( m_isoOutputPlugs );
931
932     return success;
933 }
934
935 bool
936 AvDevice::discoverStep10Plug( AvPlugVector& isoPlugs )
937 {
938    for ( AvPlugVector::iterator it = isoPlugs.begin();
939           it != isoPlugs.end();
940           ++it )
941     {
942         AvPlug* isoPlug = *it;
943         ExtendedStreamFormatCmd extStreamFormatCmd( m_1394Service,
944                                                     ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList);
945         UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
946                                          isoPlug->getPlugId() );
947         PlugAddress::EPlugDirection direction =
948             static_cast<PlugAddress::EPlugDirection>( isoPlug->getPlugDirection() );
949         extStreamFormatCmd.setPlugAddress( PlugAddress( direction,
950                                                         PlugAddress::ePAM_Unit,
951                                                         unitPlugAddress ) );
952
953         extStreamFormatCmd.setNodeId( m_nodeId );
954         //extStreamFormatCmd.setVerbose( true );
955
956         int i = 0;
957         bool cmdSuccess = false;
958
959         do {
960             extStreamFormatCmd.setIndexInStreamFormat( i );
961             extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
962             cmdSuccess = extStreamFormatCmd.fire();
963             if ( cmdSuccess
964                  && ( extStreamFormatCmd.getResponse() == AVCCommand::eR_Implemented ) )
965             {
966                 AvPlug::FormatInfo formatInfo;
967                 formatInfo.m_index = i;
968
969                 FormatInformationStreamsSync* syncStream
970                     = dynamic_cast< FormatInformationStreamsSync* >
971                     ( extStreamFormatCmd.getFormatInformation()->m_streams );
972                 if ( syncStream ) {
973                     formatInfo.m_samplingFrequency =
974                         syncStream->m_samplingFrequency;
975                     formatInfo.m_isSyncStream = true ;
976                 }
977
978                 FormatInformationStreamsCompound* compoundStream
979                     = dynamic_cast< FormatInformationStreamsCompound* >
980                     ( extStreamFormatCmd.getFormatInformation()->m_streams );
981                 if ( compoundStream ) {
982                     formatInfo.m_samplingFrequency =
983                         compoundStream->m_samplingFrequency;
984                     formatInfo.m_isSyncStream = false;
985                     for ( int j = 0;
986                           j < compoundStream->m_numberOfStreamFormatInfos;
987                           ++j )
988                     {
989                         switch ( compoundStream->m_streamFormatInfos[j]->m_streamFormat ) {
990                         case AVC1394_STREAM_FORMAT_AM824_MULTI_BIT_LINEAR_AUDIO_RAW:
991                             formatInfo.m_audioChannels +=
992                                 compoundStream->m_streamFormatInfos[j]->m_numberOfChannels;
993                             break;
994                         case AVC1394_STREAM_FORMAT_AM824_MIDI_CONFORMANT:
995                             formatInfo.m_midiChannels +=
996                                 compoundStream->m_streamFormatInfos[j]->m_numberOfChannels;
997                             break;
998                         default:
999                             debugWarning( "discoverStep10Plug: unknown stream "
1000                                           "format for channel (%d)\n", j );
1001                         }
1002                     }
1003                 }
1004
1005                 debugOutput( DEBUG_LEVEL_VERBOSE,
1006                              "[%s:%d] formatInfo[%d].m_samplingFrequency = %d\n",
1007                              isoPlug->getName(), isoPlug->getPlugId(),
1008                              i, formatInfo.m_samplingFrequency );
1009                 debugOutput( DEBUG_LEVEL_VERBOSE,
1010                              "[%s:%d] formatInfo[%d].m_isSyncStream = %d\n",
1011                              isoPlug->getName(), isoPlug->getPlugId(),
1012                              i, formatInfo.m_isSyncStream );
1013                 debugOutput( DEBUG_LEVEL_VERBOSE,
1014                              "[%s:%d] formatInfo[%d].m_audioChannels = %d\n",
1015                              isoPlug->getName(), isoPlug->getPlugId(),
1016                              i, formatInfo.m_audioChannels );
1017                 debugOutput( DEBUG_LEVEL_VERBOSE,
1018                              "[%s:%d] formatInfo[%d].m_midiChannels = %d\n",
1019                              isoPlug->getName(), isoPlug->getPlugId(),
1020                              i, formatInfo.m_midiChannels );
1021
1022                 isoPlug->m_formatInfos.push_back( formatInfo );
1023             }
1024
1025             ++i;
1026         } while ( cmdSuccess && ( extStreamFormatCmd.getResponse()
1027                                   == ExtendedStreamFormatCmd::eR_Implemented ) );
1028     }
1029
1030    return true;
1031 }
1032
1033
1034 bool
1035 AvDevice::discoverStep10()
1036 {
1037     //////////////////////////////////////////////
1038     // Step 10: For all ISO plugs: get all stream
1039     // supported formats
1040
1041     bool success;
1042
1043     success  = discoverStep10Plug( m_isoInputPlugs );
1044     success &= discoverStep10Plug( m_isoOutputPlugs );
1045
1046     return success;
1047 }
1048
1049 bool
1050 AvDevice::discoverPlugConnection( AvPlug& srcPlug,
1051                                   SubunitPlugSpecificDataPlugAddress& subunitPlugAddress )
1052 {
1053     AvDeviceSubunit* subunit = getSubunit( subunitPlugAddress.m_subunitType,
1054                                            subunitPlugAddress.m_subunitId );
1055
1056     if ( subunit ) {
1057         debugOutput( DEBUG_LEVEL_VERBOSE,
1058                      "%s plug %d has a valid connection to plug %d of "
1059                      "%s subunit %d \n",
1060                      srcPlug.getName(),
1061                      srcPlug.getPlugId(),
1062                      subunitPlugAddress.m_plugId,
1063                      subunit->getName(),
1064                      subunit->getSubunitId() );
1065
1066         AvPlug* destPlug        = new AvPlug;
1067         destPlug->m_plugId      = subunitPlugAddress.m_plugId;
1068         destPlug->m_subunitType = subunitPlugAddress.m_subunitType;
1069         destPlug->m_subunitId   = subunitPlugAddress.m_subunitId;
1070
1071         if ( !subunit->addPlug( *destPlug ) ) {
1072             debugError( "Could not add plug %d to subunit %d\n",
1073                         destPlug->getPlugId(), subunit->getSubunitId() );
1074             return false;
1075         }
1076
1077         AvPlugConnection* plugConnection = new AvPlugConnection;
1078         plugConnection->m_srcPlug = &srcPlug;
1079         plugConnection->m_destPlug = destPlug;
1080         m_plugConnections.push_back( plugConnection );
1081
1082         return true;
1083     } else {
1084         debugOutput( DEBUG_LEVEL_VERBOSE,
1085                      "found plug address points to unhandled  "
1086                      "subunit -> ignored\n" );
1087     }
1088
1089     return true;
1090 }
1091
1092 bool
1093 AvDevice::enumerateSubUnits()
1094 {
1095     bool musicSubunitFound=false;
1096     bool audioSubunitFound=false;
1097
1098     SubUnitInfoCmd subUnitInfoCmd( m_1394Service );
1099     //subUnitInfoCmd.setVerbose( 1 );
1100     subUnitInfoCmd.setCommandType( AVCCommand::eCT_Status );
1101
1102     // BeBob has always exactly one audio and one music subunit. This
1103     // means is fits into the first page of the SubUnitInfo command.
1104     // So there is no need to do more than needed
1105
1106     subUnitInfoCmd.m_page = 0;
1107     subUnitInfoCmd.setNodeId( m_nodeId );
1108     if ( !subUnitInfoCmd.fire() ) {
1109         debugError( "Subunit info command failed\n" );
1110         // shouldn't this be an error situation?
1111         return false;
1112     }
1113
1114     for ( int i = 0; i < subUnitInfoCmd.getNrOfValidEntries(); ++i ) {
1115         subunit_type_t subunit_type
1116             = subUnitInfoCmd.m_table[i].m_subunit_type;
1117
1118         unsigned int subunitId = getNrOfSubunits( subunit_type );
1119
1120         debugOutput( DEBUG_LEVEL_VERBOSE,
1121                      "subunit_id = %2d, subunit_type = %2d (%s)\n",
1122                      subunitId,
1123                      subunit_type,
1124                      subunitTypeToString( subunit_type ) );
1125
1126         AvDeviceSubunit* subunit = 0;
1127         switch( subunit_type ) {
1128         case AVCCommand::eST_Audio:
1129             subunit = new AvDeviceSubunitAudio( this, subunitId );
1130             if ( !subunit ) {
1131                 debugFatal( "Could not allocate AvDeviceSubunitAudio\n" );
1132                 return false;
1133             }
1134             m_subunits.push_back( subunit );
1135             audioSubunitFound=true;
1136             break;
1137         case AVCCommand::eST_Music:
1138             subunit = new AvDeviceSubunitMusic( this, subunitId );
1139             if ( !subunit ) {
1140                 debugFatal( "Could not allocate AvDeviceSubunitMusic\n" );
1141                 return false;
1142             }
1143             m_subunits.push_back( subunit );
1144             musicSubunitFound=true;
1145             break;
1146         default:
1147             debugOutput( DEBUG_LEVEL_NORMAL,
1148                          "Unsupported subunit found, subunit_type = %d (%s)\n",
1149                          subunit_type,
1150                          subunitTypeToString( subunit_type ) );
1151
1152         }
1153
1154     }
1155    
1156     // a BeBoB always has an audio and a music subunit
1157     return (musicSubunitFound && audioSubunitFound);
1158 }
1159
1160
1161 AvDeviceSubunit*
1162 AvDevice::getSubunit( subunit_type_t subunitType,
1163                       subunit_id_t subunitId ) const
1164 {
1165     for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin();
1166           it != m_subunits.end();
1167           ++it )
1168     {
1169         AvDeviceSubunit* subunit = *it;
1170         if ( ( subunitType == subunit->getSubunitType() )
1171              && ( subunitId == subunit->getSubunitId() ) )
1172         {
1173             return subunit;
1174         }
1175     }
1176
1177     return 0;
1178 }
1179
1180
1181 unsigned int
1182 AvDevice::getNrOfSubunits( subunit_type_t subunitType ) const
1183 {
1184     unsigned int nrOfSubunits = 0;
1185
1186     for ( AvDeviceSubunitVector::const_iterator it = m_subunits.begin();
1187           it != m_subunits.end();
1188           ++it )
1189     {
1190         AvDeviceSubunit* subunit = *it;
1191         if ( subunitType == subunit->getSubunitType() ) {
1192             nrOfSubunits++;
1193         }
1194     }
1195
1196     return nrOfSubunits;
1197 }
1198
1199 AvPlugConnection*
1200 AvDevice::getPlugConnection( AvPlug& srcPlug ) const
1201 {
1202     for ( AvPlugConnectionVector::const_iterator it
1203               = m_plugConnections.begin();
1204           it != m_plugConnections.end();
1205           ++it )
1206     {
1207         AvPlugConnection* plugConnection = *it;
1208         if ( plugConnection->m_srcPlug == &srcPlug ) {
1209             return plugConnection;
1210         }
1211     }
1212
1213     return 0;
1214 }
1215
1216 AvPlug*
1217 AvDevice::getPlugById( AvPlugVector& plugs, int id )
1218 {
1219     for ( AvPlugVector::iterator it = plugs.begin();
1220           it != plugs.end();
1221           ++it )
1222     {
1223         AvPlug* plug = *it;
1224         if ( id == plug->getPlugId() ) {
1225             return plug;
1226         }
1227     }
1228
1229     return 0;
1230 }
1231
1232 bool
1233 AvDevice::addXmlDescriptionPlug( AvPlug& plug,
1234                                  xmlNodePtr connectionSet )
1235 {
1236     char* result;
1237
1238     int direction;
1239     switch ( plug.getPlugDirection() ) {
1240         case 0:
1241             direction = FREEBOB_PLAYBACK;
1242             break;
1243         case 1:
1244             direction = FREEBOB_CAPTURE;
1245             break;
1246     default:
1247         debugError( "plug direction invalid (%d)\n",
1248                     plug.getPlugDirection() );
1249         return false;
1250     }
1251
1252     asprintf( &result, "%d",  direction );
1253     if ( !xmlNewChild( connectionSet,
1254                        0,
1255                        BAD_CAST "Direction",
1256                        BAD_CAST result ) )
1257     {
1258         debugError( "Couldn't create 'Direction' node\n" );
1259         return false;
1260     }
1261
1262     xmlNodePtr connection = xmlNewChild( connectionSet, 0,
1263                                          BAD_CAST "Connection", 0 );
1264     if ( !connection ) {
1265         debugError( "Couldn't create 'Connection' node for "
1266                     "direction %d\n", plug.getPlugDirection() );
1267         return false;
1268     }
1269
1270     asprintf( &result, "%08x%08x",
1271               ( quadlet_t )( m_configRom->getGuid() >> 32 ),
1272               ( quadlet_t )( m_configRom->getGuid() & 0xfffffff ) );
1273     if ( !xmlNewChild( connection,  0,
1274                        BAD_CAST "GUID",  BAD_CAST result ) ) {
1275         debugError( "Couldn't create 'GUID' node\n" );
1276         return false;
1277     }
1278    
1279     asprintf( &result, "%d", m_id & 0xFF );
1280     if ( !xmlNewChild( connection,  0,
1281                        BAD_CAST "Id",  BAD_CAST result ) ) {
1282         debugError( "Couldn't create 'Id' node\n" );
1283         return false;
1284     }
1285
1286     asprintf( &result, "%d", m_1394Service->getPort() );
1287     if ( !xmlNewChild( connection,  0,
1288                        BAD_CAST "Port",  BAD_CAST result ) ) {
1289         debugError( "Couldn't create 'Port' node\n" );
1290         return false;
1291     }
1292
1293     asprintf( &result, "%d",  m_nodeId);
1294     if ( !xmlNewChild( connection,  0,
1295                        BAD_CAST "Node",  BAD_CAST result ) ) {
1296         debugError( "Couldn't create 'Node' node\n" );
1297         return false;
1298     }
1299
1300     asprintf( &result, "%d",  plug.getNrOfChannels() );
1301     if ( !xmlNewChild( connection,  0,
1302                        BAD_CAST "Dimension",  BAD_CAST result ) ) {
1303         debugError( "Couldn't create 'Dimension' node\n" );
1304         return false;
1305     }
1306
1307     asprintf( &result, "%d",  plug.getSampleRate() );
1308     if ( !xmlNewChild( connection,  0,
1309                        BAD_CAST "Samplerate",  BAD_CAST result ) ) {
1310         debugError( "Couldn't create 'Samplerate' node\n" );
1311         return false;
1312     }
1313
1314     if ( !xmlNewChild( connection,  0,
1315                        BAD_CAST "IsoChannel", BAD_CAST "-1" ) )
1316     {
1317         debugError( "Couldn't create 'IsoChannel' node\n" );
1318         return false;
1319     }
1320
1321     xmlNodePtr streams = xmlNewChild( connection,  0,
1322                                       BAD_CAST "Streams",  0 );
1323     if ( !streams ) {
1324         debugError( "Couldn't create 'Streams' node for "
1325                     "direction %d\n", plug.getPlugDirection() );
1326         return false;
1327     }
1328
1329     AvPlug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
1330     for ( AvPlug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
1331           it != clusterInfos.end();
1332           ++it )
1333     {
1334         const AvPlug::ClusterInfo* clusterInfo = &( *it );
1335
1336         AvPlug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
1337         for ( AvPlug::ChannelInfoVector::const_iterator it = channelInfos.begin();
1338               it != channelInfos.end();
1339               ++it )
1340         {
1341             const AvPlug::ChannelInfo* channelInfo = &( *it );
1342
1343             xmlNodePtr stream = xmlNewChild( streams,  0,
1344                                              BAD_CAST "Stream",  0 );
1345             if ( !stream ) {
1346                 debugError( "Coulnd't create 'Stream' node" );
1347                 return false;
1348             }
1349
1350             // \todo: iec61883 backend expects indexing starting from 0
1351             // but bebob reports it starting from 1. Decide where
1352             // and how to handle this
1353             asprintf( &result, "%d", channelInfo->m_streamPosition - 1 );
1354             if ( !xmlNewChild( stream,  0,
1355                                BAD_CAST "Position",  BAD_CAST result ) )
1356             {
1357                 debugError( "Couldn't create 'Position' node" );
1358                 return false;
1359             }
1360
1361             asprintf( &result, "%d", channelInfo->m_location );
1362             if ( !xmlNewChild( stream,  0,
1363                                BAD_CAST "Location",  BAD_CAST result ) )
1364             {
1365                 debugError( "Couldn't create 'Location' node" );
1366                 return false;
1367             }
1368
1369             asprintf( &result, "%d", clusterInfo->m_streamFormat );
1370             if ( !xmlNewChild( stream,  0,
1371                                BAD_CAST "Format",  BAD_CAST result ) )
1372             {
1373                 debugError( "Couldn't create 'Format' node" );
1374                 return false;
1375             }
1376
1377             asprintf( &result, "%d", clusterInfo->m_portType );
1378             if ( !xmlNewChild( stream,  0,
1379                                BAD_CAST "Type",  BAD_CAST result ) )
1380             {
1381                 debugError( "Couldn't create 'Type' node" );
1382                 return false;
1383             }
1384
1385             // \todo XXX: What do to do with DestinationPort value??
1386             asprintf( &result, "%d", 0 );
1387             if ( !xmlNewChild( stream,  0,
1388                                BAD_CAST "DestinationPort",  BAD_CAST result ) )
1389             {
1390                 debugError( "Couldn't create 'DestinationPort' node" );
1391                 return false;
1392             }
1393
1394             if ( !xmlNewChild( stream,  0,
1395                                BAD_CAST "Name",
1396                                BAD_CAST channelInfo->m_name.c_str() ) )
1397             {
1398                 debugError( "Couldn't create 'Name' node" );
1399                 return false;
1400             }
1401         }
1402     }
1403
1404     return true;
1405 }
1406
1407 bool
1408 AvDevice::addXmlDescriptionStreamFormats( AvPlug& plug,
1409                                           xmlNodePtr streamFormatNode )
1410 {
1411     int direction;
1412     switch ( plug.getPlugDirection() ) {
1413         case 0:
1414             direction = FREEBOB_PLAYBACK;
1415             break;
1416         case 1:
1417             direction = FREEBOB_CAPTURE;
1418             break;
1419     default:
1420         debugError( "addXmlDescriptionStreamFormats: plug direction invalid (%d)\n",
1421                     plug.getPlugDirection() );
1422         return false;
1423     }
1424
1425     char* result;
1426     asprintf( &result, "%d",  direction );
1427     if ( !xmlNewChild( streamFormatNode,
1428                        0,
1429                        BAD_CAST "Direction",
1430                        BAD_CAST result ) )
1431     {
1432         debugError( "addXmlDescriptionStreamFormats: Could not  create 'Direction' node\n" );
1433         return false;
1434     }
1435
1436     for ( AvPlug::FormatInfoVector::iterator it =
1437               plug.m_formatInfos.begin();
1438           it != plug.m_formatInfos.end();
1439           ++it )
1440     {
1441         AvPlug::FormatInfo formatInfo = *it;
1442         xmlNodePtr formatNode = xmlNewChild( streamFormatNode, 0,
1443                                              BAD_CAST "Format", 0 );
1444         if ( !formatNode ) {
1445             debugError( "addXmlDescriptionStreamFormats: Could not create 'Format' node\n" );
1446             return false;
1447         }
1448
1449         asprintf( &result, "%d",
1450                   convertESamplingFrequency( static_cast<ESamplingFrequency>( formatInfo.m_samplingFrequency ) ) );
1451         if ( !xmlNewChild( formatNode,  0,
1452                            BAD_CAST "Samplerate",  BAD_CAST result ) )
1453         {
1454             debugError( "Couldn't create 'Samplerate' node\n" );
1455             return false;
1456         }
1457
1458         asprintf( &result, "%d",  formatInfo.m_audioChannels );
1459         if ( !xmlNewChild( formatNode,  0,
1460                            BAD_CAST "AudioChannels",  BAD_CAST result ) )
1461         {
1462             debugError( "Couldn't create 'AudioChannels' node\n" );
1463             return false;
1464         }
1465
1466         asprintf( &result, "%d",  formatInfo.m_midiChannels );
1467         if ( !xmlNewChild( formatNode,  0,
1468                            BAD_CAST "MidiChannels",  BAD_CAST result ) )
1469         {
1470             debugError( "Couldn't create 'MidiChannels' node\n" );
1471             return false;
1472         }
1473     }
1474
1475     return true;
1476 }
1477
1478 bool
1479 AvDevice::addXmlDescription( xmlNodePtr deviceNode )
1480 {
1481     // connection set
1482     //  direction
1483     //  connection
1484     //    id
1485     //    port
1486     //    node
1487     //    plug
1488     //    dimension
1489     //    samplerate
1490     //    streams
1491     //      stream
1492
1493
1494     ///////////
1495     // get plugs
1496
1497     AvPlug* inputPlug = getPlugById( m_isoInputPlugs, 0 );
1498     if ( !inputPlug ) {
1499         debugError( "addXmlDescription: No iso input plug found with id %d\n" );
1500         return false;
1501     }
1502     AvPlug* outputPlug = getPlugById( m_isoOutputPlugs, 0 );
1503     if ( !outputPlug ) {
1504         debugError( "addXmlDescription: No iso output plug found with id %d\n" );
1505         return false;
1506     }
1507
1508     ///////////
1509     // add connection set output
1510
1511     xmlNodePtr connectionSet = xmlNewChild( deviceNode, 0,
1512                                             BAD_CAST "ConnectionSet", 0 );
1513     if ( !connectionSet ) {
1514         debugError( "addXmlDescription:: Could not create 'ConnnectionSet' node for "
1515                     "direction 1 (playback)\n" );
1516         return false;
1517     }
1518
1519     if ( !addXmlDescriptionPlug( *inputPlug, connectionSet ) ) {
1520         debugError( "addXmlDescription: Could not add iso input plug 0 to XML description\n" );
1521         return false;
1522     }
1523
1524     // add connection set input
1525
1526     connectionSet = xmlNewChild( deviceNode, 0,
1527                                  BAD_CAST "ConnectionSet", 0 );
1528     if ( !connectionSet ) {
1529         debugError( "addXmlDescription: Couldn't create 'ConnectionSet' node for "
1530                     "direction 0 (recorder)\n" );
1531         return false;
1532     }
1533
1534     if ( !addXmlDescriptionPlug( *outputPlug, connectionSet ) ) {
1535         debugError( "addXmlDescription: Could not add iso output plug 0 to XML description\n" );
1536         return false;
1537     }
1538
1539     ////////////
1540     // add stream format
1541
1542     xmlNodePtr streamFormatNode = xmlNewChild( deviceNode, 0,
1543                                                BAD_CAST "StreamFormats", 0 );
1544     if ( !streamFormatNode ) {
1545         debugError( "addXmlDescription: Could not create 'StreamFormats' node\n" );
1546         return false;
1547     }
1548
1549     if ( !addXmlDescriptionStreamFormats( *inputPlug, streamFormatNode ) ) {
1550         debugError( "addXmlDescription:: Could not add stream format info\n" );
1551         return false;
1552     }
1553
1554     streamFormatNode= xmlNewChild( deviceNode, 0,
1555                                  BAD_CAST "StreamFormats", 0 );
1556     if ( !streamFormatNode ) {
1557         debugError( "addXmlDescription: Could not create 'StreamFormat' node\n" );
1558         return false;
1559     }
1560
1561     if ( !addXmlDescriptionStreamFormats( *outputPlug, streamFormatNode ) ) {
1562         debugError( "addXmlDescription:: Could not add stream format info\n" );
1563         return false;
1564     }
1565
1566     return true;
1567 }
1568
1569 bool
1570 AvDevice::setSamplingFrequencyPlug( AvPlug& plug,
1571                                     PlugAddress::EPlugDirection direction,
1572                                     ESamplingFrequency samplingFrequency )
1573 {
1574     ExtendedStreamFormatCmd extStreamFormatCmd( m_1394Service,
1575                                                 ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList );
1576     UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR,
1577                                      plug.getPlugId() );
1578     extStreamFormatCmd.setPlugAddress( PlugAddress( direction,
1579                                                     PlugAddress::ePAM_Unit,
1580                                                     unitPlugAddress ) );
1581
1582     extStreamFormatCmd.setNodeId( m_nodeId );
1583     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
1584     //extStreamFormatCmd.setVerbose( true );
1585
1586     int i = 0;
1587     bool cmdSuccess = false;
1588     bool correctFormatFound = false;
1589
1590     do {
1591         extStreamFormatCmd.setIndexInStreamFormat( i );
1592         extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
1593
1594         cmdSuccess = extStreamFormatCmd.fire();
1595         if ( cmdSuccess
1596              && ( extStreamFormatCmd.getResponse() == AVCCommand::eR_Implemented ) )
1597         {
1598             ESamplingFrequency foundFreq = eSF_DontCare;
1599
1600             FormatInformation* formatInfo =
1601                 extStreamFormatCmd.getFormatInformation();
1602             FormatInformationStreamsCompound* compoundStream
1603                 = dynamic_cast< FormatInformationStreamsCompound* > (
1604                     formatInfo->m_streams );
1605             if ( compoundStream ) {
1606                 foundFreq = static_cast<ESamplingFrequency>( compoundStream->m_samplingFrequency );
1607             }
1608
1609             FormatInformationStreamsSync* syncStream
1610                 = dynamic_cast< FormatInformationStreamsSync* > (
1611                     formatInfo->m_streams );
1612             if ( syncStream ) {
1613                 foundFreq = static_cast<ESamplingFrequency>( compoundStream->m_samplingFrequency );
1614             }
1615
1616             if (  foundFreq == samplingFrequency )
1617             {
1618                 correctFormatFound = true;
1619                 break;
1620             }
1621         }
1622
1623         ++i;
1624     } while ( cmdSuccess && ( extStreamFormatCmd.getResponse()
1625                               == ExtendedStreamFormatCmd::eR_Implemented ) );
1626
1627     if ( !cmdSuccess ) {
1628         debugError( "setSampleRatePlug: Failed to retrieve format info\n" );
1629         return false;
1630     }
1631
1632     if ( !correctFormatFound ) {
1633         debugError( "setSampleRatePlug: %s plug %d does not support sample rate %d\n",
1634                     plug.getName(),
1635                     plug.getPlugId(),
1636                     convertESamplingFrequency( samplingFrequency ) );
1637         return false;
1638     }
1639
1640     extStreamFormatCmd.setSubFunction(
1641         ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand );
1642     extStreamFormatCmd.setCommandType( AVCCommand::eCT_Control );
1643
1644     if ( !extStreamFormatCmd.fire() ) {
1645         debugError( "setSampleRate: Could not set sample rate %d "
1646                     "to %s plug %d\n",
1647                     convertESamplingFrequency( samplingFrequency ),
1648                     plug.getName(),
1649                     plug.getPlugId() );
1650         return false;
1651     }
1652
1653     return true;
1654 }
1655
1656 bool
1657 AvDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency )
1658 {
1659     AvPlug* plug = getPlugById( m_isoInputPlugs, 0 );
1660     if ( !plug ) {
1661         debugError( "setSampleRate: Could not retrieve iso input plug 0\n" );
1662         return false;
1663     }
1664
1665     if ( !setSamplingFrequencyPlug( *plug, PlugAddress::ePD_Input, samplingFrequency ) ) {
1666         debugError( "setSampleRate: Setting sample rate failed\n" );
1667         return false;
1668     }
1669
1670     plug = getPlugById( m_isoOutputPlugs, 0 );
1671     if ( !plug ) {
1672         debugError( "setSampleRate: Could not retrieve iso output plug 0\n" );
1673         return false;
1674     }
1675
1676     if ( !setSamplingFrequencyPlug( *plug, PlugAddress::ePD_Output, samplingFrequency ) ) {
1677         debugError( "setSampleRate: Setting sample rate failed\n" );
1678         return false;
1679     }
1680
1681     debugOutput( DEBUG_LEVEL_VERBOSE,
1682                  "setSampleRate: Set sample rate to %d\n",  convertESamplingFrequency( samplingFrequency ) );
1683     return true;
1684 }
1685
1686 int
1687 AvDevice::getSamplingFrequency( ) {
1688     AvPlug* inputPlug = getPlugById( m_isoInputPlugs, 0 );
1689     if ( !inputPlug ) {
1690         debugError( "No iso input plug found with id %d\n" );
1691         return false;
1692     }
1693     AvPlug* outputPlug = getPlugById( m_isoOutputPlugs, 0 );
1694     if ( !outputPlug ) {
1695         debugError( "No iso output plug found with id %d\n" );
1696         return false;
1697     }
1698
1699         int samplerate_playback=inputPlug->getSampleRate();
1700         int samplerate_capture=outputPlug->getSampleRate();
1701
1702         if (samplerate_playback != samplerate_capture) {
1703                 debugWarning("Samplerates for capture and playback differ!\n");
1704         }
1705         return samplerate_capture;
1706 }
1707
1708
1709
1710 ConfigRom&
1711 AvDevice::getConfigRom() const
1712 {
1713     return *m_configRom;
1714 }
1715
1716 void
1717 AvDevice::showDevice() const
1718 {
1719     debugWarning( "showDevice: not implemented\n" );
1720 }
1721
1722 bool AvDevice::setId( unsigned int id) {
1723     m_id=id;
1724     return true;
1725 }
1726
1727 bool
1728 AvDevice::prepare() {
1729     ///////////
1730     // get plugs
1731
1732     AvPlug* inputPlug = getPlugById( m_isoInputPlugs, 0 );
1733     if ( !inputPlug ) {
1734         debugError( "No iso input plug found with id %d\n" );
1735         return false;
1736     }
1737     AvPlug* outputPlug = getPlugById( m_isoOutputPlugs, 0 );
1738     if ( !outputPlug ) {
1739         debugError( "No iso output plug found with id %d\n" );
1740         return false;
1741     }
1742
1743         int samplerate=outputPlug->getSampleRate();
1744         m_receiveProcessor=new FreebobStreaming::AmdtpReceiveStreamProcessor(
1745                                  m_1394Service->getPort(),
1746                                  samplerate,
1747                                  outputPlug->getNrOfChannels());
1748
1749         if(!m_receiveProcessor->init()) {
1750                 debugFatal("Could not initialize receive processor!\n");
1751                 return false;
1752        
1753         }
1754
1755         if (!addPlugToProcessor(*outputPlug,m_receiveProcessor,
1756                 FreebobStreaming::AmdtpAudioPort::E_Capture)) {
1757                 debugFatal("Could not add plug to processor!\n");
1758                 return false;
1759         }
1760
1761         // do the transmit processor
1762         // for now we are snooping, so these are receive too.
1763 //      samplerate=inputPlug->getSampleRate();
1764 //      m_receiveProcessor2=new FreebobStreaming::AmdtpReceiveStreamProcessor(
1765 //                               channel,
1766 //                               m_1394Service->getPort(),
1767 //                               samplerate,
1768 //                               inputPlug->getNrOfChannels());
1769 //
1770 //      if (!addPlugToProcessor(*inputPlug,m_receiveProcessor2,
1771 //              FreebobStreaming::AmdtpAudioPort::E_Capture)) {
1772 //              debugFatal("Could not add plug to processor!\n");
1773 //              return false;
1774 //      }
1775
1776         // do the transmit processor
1777         samplerate=inputPlug->getSampleRate();
1778         m_transmitProcessor=new FreebobStreaming::AmdtpTransmitStreamProcessor(
1779                                  m_1394Service->getPort(),
1780                                  samplerate,
1781                                  inputPlug->getNrOfChannels());
1782                                  
1783         if(!m_transmitProcessor->init()) {
1784                 debugFatal("Could not initialize transmit processor!\n");
1785                 return false;
1786        
1787         }
1788
1789         if (!addPlugToProcessor(*inputPlug,m_transmitProcessor,
1790                 FreebobStreaming::AmdtpAudioPort::E_Playback)) {
1791                 debugFatal("Could not add plug to processor!\n");
1792                 return false;
1793         }
1794
1795         return true;
1796 }
1797
1798 bool
1799 AvDevice::addPlugToProcessor(
1800         AvPlug& plug,
1801         FreebobStreaming::StreamProcessor *processor,
1802         FreebobStreaming::AmdtpAudioPort::E_Direction direction) {
1803
1804     AvPlug::ClusterInfoVector& clusterInfos = plug.getClusterInfos();
1805     for ( AvPlug::ClusterInfoVector::const_iterator it = clusterInfos.begin();
1806           it != clusterInfos.end();
1807           ++it )
1808     {
1809         const AvPlug::ClusterInfo* clusterInfo = &( *it );
1810
1811         AvPlug::ChannelInfoVector channelInfos = clusterInfo->m_channelInfos;
1812         for ( AvPlug::ChannelInfoVector::const_iterator it = channelInfos.begin();
1813               it != channelInfos.end();
1814               ++it )
1815         {
1816             const AvPlug::ChannelInfo* channelInfo = &( *it );
1817                 std::ostringstream portname;
1818                
1819                 portname << "dev" << m_id << "_" << channelInfo->m_name;
1820                
1821                         FreebobStreaming::Port *p=NULL;
1822                         switch(clusterInfo->m_portType) {
1823                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_Speaker:
1824                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_Headphone:
1825                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_Microphone:
1826                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_Line:
1827                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_Analog:
1828                                 p=new FreebobStreaming::AmdtpAudioPort(
1829                                                 portname.str(),
1830                                                 direction,
1831                                                 // \todo: streaming backend expects indexing starting from 0
1832                                                 // but bebob reports it starting from 1. Decide where
1833                                                 // and how to handle this (pp: here)
1834                                                 channelInfo->m_streamPosition - 1,
1835                                                 channelInfo->m_location,
1836                                                 FreebobStreaming::AmdtpPortInfo::E_MBLA,
1837                                                 clusterInfo->m_portType
1838                                 );
1839                                 break;
1840
1841                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_MIDI:
1842                                 p=new FreebobStreaming::AmdtpMidiPort(
1843                                                 portname.str(),
1844                                                 direction,
1845                                                 // \todo: streaming backend expects indexing starting from 0
1846                                                 // but bebob reports it starting from 1. Decide where
1847                                                 // and how to handle this (pp: here)
1848                                                 channelInfo->m_streamPosition - 1,
1849                                                 channelInfo->m_location,
1850                                                 FreebobStreaming::AmdtpPortInfo::E_Midi,
1851                                                 clusterInfo->m_portType
1852                                 );
1853
1854                                 break;
1855                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_SPDIF:
1856                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_ADAT:
1857                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_TDIF:
1858                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_MADI:
1859                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_Digital:
1860                         case ExtendedPlugInfoClusterInfoSpecificData::ePT_NoType:
1861                         default:
1862                         // unsupported
1863                                 break;
1864                         }
1865
1866                         if (!p) {
1867                                 debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->m_name.c_str());
1868                         } else {
1869                
1870                                 if (!processor->addPort(p)) {
1871                                         debugWarning("Could not register port with stream processor\n");
1872                                         return false;
1873                                 }
1874                         }
1875          }
1876     }
1877         return true;
1878 }
1879
1880 int
1881 AvDevice::getStreamCount() {
1882         return 2; // one receive, one transmit
1883 }
1884
1885 FreebobStreaming::StreamProcessor *
1886 AvDevice::getStreamProcessorByIndex(int i) {
1887         switch (i) {
1888         case 0:
1889                 return m_receiveProcessor;
1890         case 1:
1891 //              return m_receiveProcessor2;
1892                 return m_transmitProcessor;
1893         default:
1894                 return NULL;
1895         }
1896         return 0;
1897 }
1898
1899 int
1900 AvDevice::startStreamByIndex(int i) {
1901         int iso_channel=0;
1902         int plug=0;
1903         int hostplug=-1;
1904        
1905         switch (i) {
1906         case 0:
1907                 // do connection management: make connection
1908                 iso_channel = iec61883_cmp_connect(
1909                         m_1394Service->getHandle(),
1910                         m_nodeId | 0xffc0,
1911                         &plug,
1912                         raw1394_get_local_id (m_1394Service->getHandle()),
1913                         &hostplug,
1914                         &m_receiveProcessorBandwidth);
1915                
1916                 // set the channel obtained by the connection management
1917                 m_receiveProcessor->setChannel(iso_channel);
1918                 break;
1919         case 1:
1920                 // do connection management: make connection
1921                 iso_channel = iec61883_cmp_connect(
1922                         m_1394Service->getHandle(),
1923                         raw1394_get_local_id (m_1394Service->getHandle()),
1924                         &hostplug,
1925                         m_nodeId | 0xffc0,
1926                         &plug,
1927                         &m_transmitProcessorBandwidth);
1928                
1929                 // set the channel obtained by the connection management
1930 //              m_receiveProcessor2->setChannel(iso_channel);
1931                 m_transmitProcessor->setChannel(iso_channel);
1932                 break;
1933         default:
1934                 return 0;
1935         }
1936
1937         return 0;
1938
1939 }
1940
1941 int
1942 AvDevice::stopStreamByIndex(int i) {
1943         // do connection management: break connection
1944
1945         int plug=0;
1946         int hostplug=-1;
1947
1948         switch (i) {
1949         case 0:
1950                 // do connection management: break connection
1951                 iec61883_cmp_disconnect(
1952                         m_1394Service->getHandle(),
1953                         m_nodeId | 0xffc0,
1954                         plug,
1955                         raw1394_get_local_id (m_1394Service->getHandle()),
1956                         hostplug,
1957                         m_receiveProcessor->getChannel(),
1958                         m_receiveProcessorBandwidth);
1959
1960                 break;
1961         case 1:
1962                 // do connection management: break connection
1963                 iec61883_cmp_disconnect(
1964                         m_1394Service->getHandle(),
1965                         raw1394_get_local_id (m_1394Service->getHandle()),
1966                         hostplug,
1967                         m_nodeId | 0xffc0,
1968                         plug,
1969                         m_transmitProcessor->getChannel(),
1970                         m_transmitProcessorBandwidth);
1971
1972                 // set the channel obtained by the connection management
1973 //              m_receiveProcessor2->setChannel(iso_channel);
1974                 break;
1975         default:
1976                 return 0;
1977         }
1978
1979         return 0;
1980 }
1981
1982 } // end of namespace
1983
Note: See TracBrowser for help on using the browser.