root/branches/echoaudio/src/bebob/bebob_avplug.cpp

Revision 507, 30.6 kB (checked in by ppalmers, 17 years ago)

[Temporary commit: compiles but doesn't run]

First pass on AV/C code refactoring. Generic code and data structures
are moved to libavc classes. Implementation/vendor specific stuff remains
in specific classes.

In this case all 'Extended' commands and the discovery procedures remain in
the bebob/ classes, while the remainder goes into the libavc classes.

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_avplug.h"
25 #include "bebob/bebob_avdevice.h"
26 #include "libieee1394/configrom.h"
27
28 #include "libieee1394/ieee1394service.h"
29 #include "libavc/util/avc_serialize.h"
30
31 #include <sstream>
32
33 using namespace AVC;
34
35 namespace BeBoB {
36
37 Plug::Plug( AVC::Unit* unit,
38             AVC::Subunit* subunit,
39             AVC::function_block_type_t functionBlockType,
40             AVC::function_block_type_t functionBlockId,
41             AVC::Plug::EPlugAddressType plugAddressType,
42             AVC::Plug::EPlugDirection plugDirection,
43             AVC::plug_id_t plugId )
44     : AVC::Plug( unit,
45                  subunit,
46                  functionBlockType,
47                  functionBlockId,
48                  plugAddressType,
49                  plugDirection,
50                  plugId )
51 {
52
53 }
54
55 Plug::Plug( const Plug& rhs )
56     : AVC::Plug( rhs )
57 {
58 }
59
60 Plug::Plug()
61     : AVC::Plug()
62 {
63 }
64
65 Plug::~Plug()
66 {
67
68 }
69
70 bool
71 Plug::discover()
72 {
73     if ( !discoverPlugType() ) {
74         debugError( "discover: Could not discover plug type (%d,%d,%d,%d,%d)\n",
75                     m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
76         return false;
77     }
78
79     if ( !discoverName() ) {
80         debugError( "Could not discover name (%d,%d,%d,%d,%d)\n",
81                     m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
82         return false;
83     }
84
85     if ( !discoverNoOfChannels() ) {
86         debugError( "Could not discover number of channels "
87                     "(%d,%d,%d,%d,%d)\n",
88                     m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
89         return false;
90     }
91
92     if ( !discoverChannelPosition() ) {
93         debugError( "Could not discover channel positions "
94                     "(%d,%d,%d,%d,%d)\n",
95                     m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
96         return false;
97     }
98
99     if ( !discoverChannelName() ) {
100         debugError( "Could not discover channel name "
101                     "(%d,%d,%d,%d,%d)\n",
102                     m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
103         return false;
104     }
105
106     if ( !discoverClusterInfo() ) {
107         debugError( "Could not discover channel name "
108                     "(%d,%d,%d,%d,%d)\n",
109                     m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
110         return false;
111     }
112
113     if ( !discoverStreamFormat() ) {
114         debugError( "Could not discover stream format "
115                     "(%d,%d,%d,%d,%d)\n",
116                     m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
117         return false;
118     }
119
120     if ( !discoverSupportedStreamFormats() ) {
121         debugError( "Could not discover supported stream formats "
122                     "(%d,%d,%d,%d,%d)\n",
123                     m_unit->getConfigRom().getNodeId(), getSubunitType(), getSubunitId(), m_direction, m_id );
124         return false;
125     }
126
127     return m_unit->getPlugManager().addPlug( *this );
128 }
129
130 bool
131 Plug::discoverConnections()
132 {
133     return discoverConnectionsInput() && discoverConnectionsOutput();
134 }
135
136 bool
137 Plug::discoverPlugType()
138 {
139     ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
140     ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
141         ExtendedPlugInfoInfoType::eIT_PlugType );
142     extendedPlugInfoInfoType.initialize();
143     extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
144     extPlugInfoCmd.setVerbose( getDebugLevel() );
145
146     if ( !extPlugInfoCmd.fire() ) {
147         debugError( "plug type command failed\n" );
148         return false;
149     }
150
151     m_infoPlugType = eAPT_Unknown;
152
153     if ( extPlugInfoCmd.getResponse() == AVCCommand::eR_Implemented ) {
154
155         ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
156         if ( infoType
157              && infoType->m_plugType )
158         {
159             plug_type_t plugType = infoType->m_plugType->m_plugType;
160
161             debugOutput( DEBUG_LEVEL_VERBOSE,
162                          "plug %d is of type %d (%s)\n",
163                          m_id,
164                          plugType,
165                          extendedPlugInfoPlugTypeToString( plugType ) );
166             switch ( plugType ) {
167             case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_IsoStream:
168                 m_infoPlugType = eAPT_IsoStream;
169                 break;
170             case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_AsyncStream:
171                 m_infoPlugType = eAPT_AsyncStream;
172                 break;
173             case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_Midi:
174                 m_infoPlugType = eAPT_Midi;
175                 break;
176             case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_Sync:
177                 m_infoPlugType = eAPT_Sync;
178                 break;
179             case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_Analog:
180                 m_infoPlugType = eAPT_Analog;
181                 break;
182             case ExtendedPlugInfoPlugTypeSpecificData::eEPIPT_Digital:
183                 m_infoPlugType = eAPT_Digital;
184                 break;
185             default:
186                 m_infoPlugType = eAPT_Unknown;
187
188             }
189         }
190     } else {
191         debugError( "Plug does not implement extended plug info plug "
192                     "type info command\n" );
193         return false;
194     }
195
196    return true;
197 }
198
199 bool
200 Plug::discoverName()
201 {
202     ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
203     ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
204         ExtendedPlugInfoInfoType::eIT_PlugName );
205     extendedPlugInfoInfoType.initialize();
206     extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
207     extPlugInfoCmd.setVerbose( getDebugLevel() );
208
209     if ( !extPlugInfoCmd.fire() ) {
210         debugError( "name command failed\n" );
211         return false;
212     }
213
214     ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
215     if ( infoType
216          && infoType->m_plugName )
217     {
218         std::string name =
219             infoType->m_plugName->m_name;
220
221         debugOutput( DEBUG_LEVEL_VERBOSE,
222                      "plug %d has name '%s'\n",
223                      m_id,
224                      name.c_str() );
225
226         m_name = name;
227     }
228     return true;
229 }
230
231 bool
232 Plug::discoverNoOfChannels()
233 {
234     ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
235     //extPlugInfoCmd.setVerbose( true );
236     ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
237         ExtendedPlugInfoInfoType::eIT_NoOfChannels );
238     extendedPlugInfoInfoType.initialize();
239     extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
240     extPlugInfoCmd.setVerbose( getDebugLevel() );
241
242     if ( !extPlugInfoCmd.fire() ) {
243         debugError( "number of channels command failed\n" );
244         return false;
245     }
246
247     ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
248     if ( infoType
249          && infoType->m_plugNrOfChns )
250     {
251         nr_of_channels_t nrOfChannels
252             = infoType->m_plugNrOfChns->m_nrOfChannels;
253
254         debugOutput( DEBUG_LEVEL_VERBOSE,
255                      "plug %d has %d channels\n",
256                      m_id,
257                      nrOfChannels );
258
259         m_nrOfChannels = nrOfChannels;
260     }
261     return true;
262 }
263
264 bool
265 Plug::discoverChannelPosition()
266 {
267     ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
268     ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
269         ExtendedPlugInfoInfoType::eIT_ChannelPosition );
270     extendedPlugInfoInfoType.initialize();
271     extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
272     extPlugInfoCmd.setVerbose( getDebugLevel() );
273
274     if ( !extPlugInfoCmd.fire() ) {
275         debugError( "channel position command failed\n" );
276         return false;
277     }
278
279     ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
280     if ( infoType
281          && infoType->m_plugChannelPosition )
282     {
283         if ( !copyClusterInfo( *( infoType->m_plugChannelPosition ) ) ) {
284             debugError( "Could not copy channel position "
285                         "information\n" );
286             return false;
287         }
288
289         debugOutput( DEBUG_LEVEL_VERBOSE,
290                      "plug %d: channel position information "
291                      "retrieved\n",
292                      m_id );
293
294         debugOutputClusterInfos( DEBUG_LEVEL_VERBOSE );
295     }
296
297     return true;
298 }
299
300 bool
301 Plug::discoverChannelName()
302 {
303     for ( ClusterInfoVector::iterator clit = m_clusterInfos.begin();
304           clit != m_clusterInfos.end();
305           ++clit )
306     {
307         ClusterInfo* clitInfo = &*clit;
308
309         for ( ChannelInfoVector::iterator pit =  clitInfo->m_channelInfos.begin();
310               pit != clitInfo->m_channelInfos.end();
311               ++pit )
312         {
313             ChannelInfo* channelInfo = &*pit;
314
315             ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
316             ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
317                 ExtendedPlugInfoInfoType::eIT_ChannelName );
318             extendedPlugInfoInfoType.initialize();
319             extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
320             extPlugInfoCmd.setVerbose( getDebugLevel() );
321
322             ExtendedPlugInfoInfoType* infoType =
323                 extPlugInfoCmd.getInfoType();
324             if ( infoType ) {
325                 infoType->m_plugChannelName->m_streamPosition =
326                     channelInfo->m_streamPosition;
327             }
328             if ( !extPlugInfoCmd.fire() ) {
329                 debugError( "channel name command failed\n" );
330                 return false;
331             }
332             infoType = extPlugInfoCmd.getInfoType();
333             if ( infoType
334                  && infoType->m_plugChannelName )
335             {
336                 debugOutput( DEBUG_LEVEL_VERBOSE,
337                              "plug %d stream "
338                              "position %d: channel name = %s\n",
339                              m_id,
340                              channelInfo->m_streamPosition,
341                              infoType->m_plugChannelName->m_plugChannelName.c_str() );
342                 channelInfo->m_name =
343                     infoType->m_plugChannelName->m_plugChannelName;
344             }
345
346         }
347     }
348
349     return true;
350 }
351
352 bool
353 Plug::discoverClusterInfo()
354 {
355     if ( m_infoPlugType == eAPT_Sync )
356     {
357         // If the plug is of type sync it is either a normal 2 channel
358         // stream (not compound stream) or it is a compound stream
359         // with exactly one cluster. This depends on the
360         // extended stream format command version which is used.
361         // We are not interested in this plug so we skip it.
362         debugOutput( DEBUG_LEVEL_VERBOSE,
363                      "%s plug %d is of type sync -> skip\n",
364                      getName(),
365                      m_id );
366         return true;
367     }
368
369     for ( ClusterInfoVector::iterator clit = m_clusterInfos.begin();
370           clit != m_clusterInfos.end();
371           ++clit )
372     {
373         ClusterInfo* clusterInfo = &*clit;
374
375         ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
376         ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
377             ExtendedPlugInfoInfoType::eIT_ClusterInfo );
378         extendedPlugInfoInfoType.initialize();
379         extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
380         extPlugInfoCmd.setVerbose( getDebugLevel() );
381
382         extPlugInfoCmd.getInfoType()->m_plugClusterInfo->m_clusterIndex =
383             clusterInfo->m_index;
384
385         if ( !extPlugInfoCmd.fire() ) {
386             debugError( "cluster info command failed\n" );
387             return false;
388         }
389
390         ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
391         if ( infoType
392              && infoType->m_plugClusterInfo )
393         {
394             debugOutput( DEBUG_LEVEL_VERBOSE,
395                          "%s plug %d: cluster index = %d, "
396                          "portType %s, cluster name = %s\n",
397                          getName(),
398                          m_id,
399                          infoType->m_plugClusterInfo->m_clusterIndex,
400                          extendedPlugInfoClusterInfoPortTypeToString(
401                              infoType->m_plugClusterInfo->m_portType ),
402                          infoType->m_plugClusterInfo->m_clusterName.c_str() );
403
404             clusterInfo->m_portType = infoType->m_plugClusterInfo->m_portType;
405             clusterInfo->m_name = infoType->m_plugClusterInfo->m_clusterName;
406         }
407     }
408
409     return true;
410 }
411
412 bool
413 Plug::discoverStreamFormat()
414 {
415     ExtendedStreamFormatCmd extStreamFormatCmd =
416         setPlugAddrToStreamFormatCmd( ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommand );
417     extStreamFormatCmd.setVerbose( getDebugLevel() );
418
419     if ( !extStreamFormatCmd.fire() ) {
420         debugError( "stream format command failed\n" );
421         return false;
422     }
423
424     if ( ( extStreamFormatCmd.getStatus() ==  ExtendedStreamFormatCmd::eS_NoStreamFormat )
425          || ( extStreamFormatCmd.getStatus() ==  ExtendedStreamFormatCmd::eS_NotUsed ) )
426     {
427         debugOutput( DEBUG_LEVEL_VERBOSE,
428                      "No stream format information available\n" );
429         return true;
430     }
431
432     if ( !extStreamFormatCmd.getFormatInformation() ) {
433         debugWarning( "No stream format information for plug found -> skip\n" );
434         return true;
435     }
436
437     if ( extStreamFormatCmd.getFormatInformation()->m_root
438            != FormatInformation::eFHR_AudioMusic  )
439     {
440         debugWarning( "Format hierarchy root is not Audio&Music -> skip\n" );
441         return true;
442     }
443
444     FormatInformation* formatInfo =
445         extStreamFormatCmd.getFormatInformation();
446     FormatInformationStreamsCompound* compoundStream
447         = dynamic_cast< FormatInformationStreamsCompound* > (
448             formatInfo->m_streams );
449     if ( compoundStream ) {
450         m_samplingFrequency =
451             compoundStream->m_samplingFrequency;
452         debugOutput( DEBUG_LEVEL_VERBOSE,
453                      "%s plug %d uses "
454                      "sampling frequency %d, nr of stream infos = %d\n",
455                      getName(),
456                      m_id,
457                      m_samplingFrequency,
458                      compoundStream->m_numberOfStreamFormatInfos );
459
460         for ( int i = 1;
461               i <= compoundStream->m_numberOfStreamFormatInfos;
462               ++i )
463         {
464             ClusterInfo* clusterInfo =
465                 const_cast<ClusterInfo*>( getClusterInfoByIndex( i ) );
466
467             if ( !clusterInfo ) {
468                 debugError( "No matching cluster "
469                             "info found for index %d\n",  i );
470                     return false;
471             }
472             StreamFormatInfo* streamFormatInfo =
473                 compoundStream->m_streamFormatInfos[ i - 1 ];
474
475             debugOutput( DEBUG_LEVEL_VERBOSE,
476                          "number of channels = %d, stream format = %d\n",
477                          streamFormatInfo->m_numberOfChannels,
478                          streamFormatInfo->m_streamFormat );
479
480             int nrOfChannels = clusterInfo->m_nrOfChannels;
481             if ( streamFormatInfo->m_streamFormat ==
482                  FormatInformation::eFHL2_AM824_MIDI_CONFORMANT )
483             {
484                 // 8 logical midi channels fit into 1 channel
485                 nrOfChannels = ( ( nrOfChannels + 7 ) / 8 );
486             }
487             // sanity check
488             if ( nrOfChannels != streamFormatInfo->m_numberOfChannels )
489             {
490                 debugWarning( "Number of channels "
491                               "mismatch: '%s' plug discovering reported "
492                               "%d channels for cluster '%s', while stream "
493                               "format reported %d\n",
494                               getName(),
495                               nrOfChannels,
496                               clusterInfo->m_name.c_str(),
497                               streamFormatInfo->m_numberOfChannels);
498             }
499             clusterInfo->m_streamFormat = streamFormatInfo->m_streamFormat;
500
501             debugOutput( DEBUG_LEVEL_VERBOSE,
502                          "%s plug %d cluster info %d ('%s'): "
503                          "stream format %d\n",
504                          getName(),
505                          m_id,
506                          i,
507                          clusterInfo->m_name.c_str(),
508                          clusterInfo->m_streamFormat );
509         }
510     }
511
512     FormatInformationStreamsSync* syncStream
513         = dynamic_cast< FormatInformationStreamsSync* > (
514             formatInfo->m_streams );
515     if ( syncStream ) {
516         m_samplingFrequency =
517             syncStream->m_samplingFrequency;
518         debugOutput( DEBUG_LEVEL_VERBOSE,
519                      "%s plug %d is sync stream with sampling frequency %d\n",
520                      getName(),
521                      m_id,
522                      m_samplingFrequency );
523     }
524
525
526     if ( !compoundStream && !syncStream )
527     {
528         debugError( "Unsupported stream format\n" );
529         return false;
530     }
531
532     return true;
533 }
534
535 bool
536 Plug::discoverSupportedStreamFormats()
537 {
538     ExtendedStreamFormatCmd extStreamFormatCmd =
539         setPlugAddrToStreamFormatCmd(
540             ExtendedStreamFormatCmd::eSF_ExtendedStreamFormatInformationCommandList);
541     extStreamFormatCmd.setVerbose( getDebugLevel() );
542
543     int i = 0;
544     bool cmdSuccess = false;
545
546     do {
547         extStreamFormatCmd.setIndexInStreamFormat( i );
548         extStreamFormatCmd.setCommandType( AVCCommand::eCT_Status );
549         cmdSuccess = extStreamFormatCmd.fire();
550         if ( cmdSuccess
551              && ( extStreamFormatCmd.getResponse()
552                   == AVCCommand::eR_Implemented ) )
553         {
554             FormatInfo formatInfo;
555             formatInfo.m_index = i;
556             bool formatInfoIsValid = true;
557
558             FormatInformationStreamsSync* syncStream
559                 = dynamic_cast< FormatInformationStreamsSync* >
560                 ( extStreamFormatCmd.getFormatInformation()->m_streams );
561             if ( syncStream ) {
562                 formatInfo.m_samplingFrequency =
563                     syncStream->m_samplingFrequency;
564                 formatInfo.m_isSyncStream = true ;
565             }
566
567             FormatInformationStreamsCompound* compoundStream
568                 = dynamic_cast< FormatInformationStreamsCompound* >
569                 ( extStreamFormatCmd.getFormatInformation()->m_streams );
570             if ( compoundStream ) {
571                 formatInfo.m_samplingFrequency =
572                     compoundStream->m_samplingFrequency;
573                 formatInfo.m_isSyncStream = false;
574                 for ( int j = 0;
575                       j < compoundStream->m_numberOfStreamFormatInfos;
576                       ++j )
577                 {
578                     switch ( compoundStream->m_streamFormatInfos[j]->m_streamFormat ) {
579                     case AVC1394_STREAM_FORMAT_AM824_IEC60968_3:
580                         formatInfo.m_audioChannels +=
581                             compoundStream->m_streamFormatInfos[j]->m_numberOfChannels;
582                         break;
583                     case AVC1394_STREAM_FORMAT_AM824_MULTI_BIT_LINEAR_AUDIO_RAW:
584                         formatInfo.m_audioChannels +=
585                             compoundStream->m_streamFormatInfos[j]->m_numberOfChannels;
586                         break;
587                     case AVC1394_STREAM_FORMAT_AM824_MIDI_CONFORMANT:
588                         formatInfo.m_midiChannels +=
589                             compoundStream->m_streamFormatInfos[j]->m_numberOfChannels;
590                         break;
591                     default:
592                         formatInfoIsValid = false;
593                         debugWarning("unknown stream format (0x%02x) for channel "
594                                       "(%d)\n",
595                                      compoundStream->m_streamFormatInfos[j]->m_streamFormat,
596                                      j );
597                     }
598                 }
599             }
600
601             if ( formatInfoIsValid ) {
602                 debugOutput( DEBUG_LEVEL_VERBOSE,
603                              "[%s:%d] formatInfo[%d].m_samplingFrequency "
604                              "= %d\n",
605                              getName(), m_id,
606                              i, formatInfo.m_samplingFrequency );
607                 debugOutput( DEBUG_LEVEL_VERBOSE,
608                              "[%s:%d] formatInfo[%d].m_isSyncStream = %d\n",
609                              getName(), m_id,
610                              i, formatInfo.m_isSyncStream );
611                 debugOutput( DEBUG_LEVEL_VERBOSE,
612                              "[%s:%d] formatInfo[%d].m_audioChannels = %d\n",
613                              getName(), m_id,
614                              i, formatInfo.m_audioChannels );
615                 debugOutput( DEBUG_LEVEL_VERBOSE,
616                              "[%s:%d] formatInfo[%d].m_midiChannels = %d\n",
617                              getName(), m_id,
618                              i, formatInfo.m_midiChannels );
619                 m_formatInfos.push_back( formatInfo );
620             }
621         }
622
623         ++i;
624     } while ( cmdSuccess && ( extStreamFormatCmd.getResponse()
625                               == ExtendedStreamFormatCmd::eR_Implemented ) );
626
627     return true;
628 }
629
630
631 bool
632 Plug::discoverConnectionsInput()
633 {
634     ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
635     ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
636         ExtendedPlugInfoInfoType::eIT_PlugInput );
637     extendedPlugInfoInfoType.initialize();
638     extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
639     extPlugInfoCmd.setVerbose( getDebugLevel() );
640
641     if ( !extPlugInfoCmd.fire() ) {
642         debugError( "plug type command failed\n" );
643         return false;
644     }
645
646     if ( extPlugInfoCmd.getResponse() == AVCCommand::eR_Rejected ) {
647         // Plugs does not like to be asked about connections
648         debugOutput( DEBUG_LEVEL_VERBOSE, "Plug '%s' rejects "
649                      "connections command\n",
650                      getName() );
651         return true;
652     }
653
654     ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
655     if ( infoType
656          && infoType->m_plugInput )
657     {
658         PlugAddressSpecificData* plugAddress
659             = infoType->m_plugInput->m_plugAddress;
660
661         if ( plugAddress->m_addressMode ==
662              PlugAddressSpecificData::ePAM_Undefined )
663         {
664             // This plug has no input connection
665             return true;
666         }
667
668         if ( !discoverConnectionsFromSpecificData( eAPD_Input,
669                                                    plugAddress,
670                                                    m_inputConnections ) )
671         {
672             debugWarning( "Could not discover connnections for plug '%s'\n",
673                           getName() );
674         }
675     } else {
676         debugError( "no valid info type for plug '%s'\n", getName() );
677         return false;
678     }
679
680     return true;
681 }
682
683 bool
684 Plug::discoverConnectionsOutput()
685 {
686     ExtendedPlugInfoCmd extPlugInfoCmd = setPlugAddrToPlugInfoCmd();
687     ExtendedPlugInfoInfoType extendedPlugInfoInfoType(
688         ExtendedPlugInfoInfoType::eIT_PlugOutput );
689     extendedPlugInfoInfoType.initialize();
690     extPlugInfoCmd.setInfoType( extendedPlugInfoInfoType );
691     extPlugInfoCmd.setVerbose( getDebugLevel() );
692
693     if ( !extPlugInfoCmd.fire() ) {
694         debugError( "plug type command failed\n" );
695         return false;
696     }
697
698     if ( extPlugInfoCmd.getResponse() == AVCCommand::eR_Rejected ) {
699         // Plugs does not like to be asked about connections
700         debugOutput( DEBUG_LEVEL_VERBOSE, "Plug '%s' rejects "
701                      "connections command\n",
702                      getName() );
703         return true;
704     }
705
706     ExtendedPlugInfoInfoType* infoType = extPlugInfoCmd.getInfoType();
707     if ( infoType
708          && infoType->m_plugOutput )
709     {
710         if ( infoType->m_plugOutput->m_nrOfOutputPlugs
711              != infoType->m_plugOutput->m_outputPlugAddresses.size() )
712         {
713             debugError( "number of output plugs (%d) disagree with "
714                         "number of elements in plug address vector (%d)\n",
715                         infoType->m_plugOutput->m_nrOfOutputPlugs,
716                         infoType->m_plugOutput->m_outputPlugAddresses.size());
717         }
718
719         if ( infoType->m_plugOutput->m_nrOfOutputPlugs == 0 ) {
720             // This plug has no output connections
721             return true;
722         }
723
724         for ( unsigned int i = 0;
725               i < infoType->m_plugOutput->m_outputPlugAddresses.size();
726               ++i )
727         {
728             PlugAddressSpecificData* plugAddress
729                 = infoType->m_plugOutput->m_outputPlugAddresses[i];
730
731             if ( !discoverConnectionsFromSpecificData( eAPD_Output,
732                                                        plugAddress,
733                                                        m_outputConnections ) )
734             {
735                 debugWarning( "Could not discover connnections for "
736                               "plug '%s'\n", getName() );
737             }
738         }
739     } else {
740         debugError( "no valid info type for plug '%s'\n", getName() );
741         return false;
742     }
743
744     return true;
745 }
746
747 ExtendedPlugInfoCmd
748 Plug::setPlugAddrToPlugInfoCmd()
749 {
750     ExtendedPlugInfoCmd extPlugInfoCmd( m_unit->get1394Service() );
751
752     switch( getSubunitType() ) {
753     case eST_Unit:
754         {
755             UnitPlugAddress::EPlugType ePlugType =
756                 UnitPlugAddress::ePT_Unknown;
757             switch ( m_addressType ) {
758                 case eAPA_PCR:
759                     ePlugType = UnitPlugAddress::ePT_PCR;
760                     break;
761                 case eAPA_ExternalPlug:
762                     ePlugType = UnitPlugAddress::ePT_ExternalPlug;
763                     break;
764                 case eAPA_AsynchronousPlug:
765                     ePlugType = UnitPlugAddress::ePT_AsynchronousPlug;
766                     break;
767                 default:
768                     ePlugType = UnitPlugAddress::ePT_Unknown;
769             }
770             UnitPlugAddress unitPlugAddress( ePlugType,
771                                              m_id );
772             extPlugInfoCmd.setPlugAddress(
773                 PlugAddress( convertPlugDirection( getPlugDirection() ),
774                              PlugAddress::ePAM_Unit,
775                              unitPlugAddress ) );
776         }
777         break;
778     case eST_Music:
779     case eST_Audio:
780         {
781             switch( m_addressType ) {
782             case eAPA_SubunitPlug:
783             {
784                 SubunitPlugAddress subunitPlugAddress( m_id );
785                 extPlugInfoCmd.setPlugAddress(
786                     PlugAddress(
787                         convertPlugDirection( getPlugDirection() ),
788                         PlugAddress::ePAM_Subunit,
789                         subunitPlugAddress ) );
790             }
791             break;
792             case eAPA_FunctionBlockPlug:
793             {
794                 FunctionBlockPlugAddress functionBlockPlugAddress(
795                     m_functionBlockType,
796                     m_functionBlockId,
797                     m_id );
798                 extPlugInfoCmd.setPlugAddress(
799                     PlugAddress(
800                         convertPlugDirection( getPlugDirection() ),
801                         PlugAddress::ePAM_FunctionBlock,
802                         functionBlockPlugAddress ) );
803             }
804             break;
805             default:
806                 extPlugInfoCmd.setPlugAddress(PlugAddress());
807             }
808         }
809         break;
810     default:
811         debugError( "Unknown subunit type\n" );
812     }
813
814     extPlugInfoCmd.setNodeId( m_unit->getConfigRom().getNodeId() );
815     extPlugInfoCmd.setCommandType( AVCCommand::eCT_Status );
816     extPlugInfoCmd.setSubunitId( getSubunitId() );
817     extPlugInfoCmd.setSubunitType( getSubunitType() );
818
819     return extPlugInfoCmd;
820 }
821
822 ExtendedStreamFormatCmd
823 Plug::setPlugAddrToStreamFormatCmd(
824     ExtendedStreamFormatCmd::ESubFunction subFunction)
825 {
826     ExtendedStreamFormatCmd extStreamFormatInfoCmd(
827         m_unit->get1394Service(),
828         subFunction );
829     switch( getSubunitType() ) {
830     case eST_Unit:
831     {
832             UnitPlugAddress::EPlugType ePlugType =
833                 UnitPlugAddress::ePT_Unknown;
834             switch ( m_addressType ) {
835                 case eAPA_PCR:
836                     ePlugType = UnitPlugAddress::ePT_PCR;
837                     break;
838                 case eAPA_ExternalPlug:
839                     ePlugType = UnitPlugAddress::ePT_ExternalPlug;
840                     break;
841                 case eAPA_AsynchronousPlug:
842                     ePlugType = UnitPlugAddress::ePT_AsynchronousPlug;
843                     break;
844                 default:
845                     ePlugType = UnitPlugAddress::ePT_Unknown;
846             }
847         UnitPlugAddress unitPlugAddress( ePlugType,
848                                          m_id );
849         extStreamFormatInfoCmd.setPlugAddress(
850             PlugAddress( convertPlugDirection( getPlugDirection() ),
851                          PlugAddress::ePAM_Unit,
852                          unitPlugAddress ) );
853         }
854         break;
855     case eST_Music:
856     case eST_Audio:
857     {
858         switch( m_addressType ) {
859         case eAPA_SubunitPlug:
860         {
861             SubunitPlugAddress subunitPlugAddress( m_id );
862             extStreamFormatInfoCmd.setPlugAddress(
863                 PlugAddress( convertPlugDirection( getPlugDirection() ),
864                              PlugAddress::ePAM_Subunit,
865                              subunitPlugAddress ) );
866         }
867         break;
868         case eAPA_FunctionBlockPlug:
869         {
870             FunctionBlockPlugAddress functionBlockPlugAddress(
871                 m_functionBlockType,
872                 m_functionBlockId,
873                 m_id );
874             extStreamFormatInfoCmd.setPlugAddress(
875                 PlugAddress( convertPlugDirection( getPlugDirection() ),
876                              PlugAddress::ePAM_FunctionBlock,
877                              functionBlockPlugAddress ) );
878         }
879         break;
880         default:
881             extStreamFormatInfoCmd.setPlugAddress(PlugAddress());
882         }
883     }
884     break;
885     default:
886         debugError( "Unknown subunit type\n" );
887     }
888
889     extStreamFormatInfoCmd.setNodeId( m_unit->getConfigRom().getNodeId() );
890     extStreamFormatInfoCmd.setCommandType( AVCCommand::eCT_Status );
891     extStreamFormatInfoCmd.setSubunitId( getSubunitId() );
892     extStreamFormatInfoCmd.setSubunitType( getSubunitType() );
893
894     return extStreamFormatInfoCmd;
895 }
896
897 }
Note: See TracBrowser for help on using the browser.