root/trunk/libfreebob/src/libfreebobavc/avc_extended_plug_info.cpp

Revision 142, 23.2 kB (checked in by wagi, 17 years ago)

2006-01-04 Daniel Wagner <wagi@monom.org>

  • tests/test-extplugcmd.cpp: Changed test application
    to use PlugType? and PlugName? command for testing.
  • src/libfreebobavc/avc_extended_plug_info.cpp (serialize):
    The string.length() thing did not work as expected. A workaround
    added which converts the C++ string into a C string before strlen
    is used.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /* avc_extended_plug_info.cpp
2  * Copyright (C) 2005 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 "avc_extended_plug_info.h"
22 #include "serialize.h"
23 #include "ieee1394service.h"
24
25 #include <netinet/in.h>
26 #include <iostream>
27
28 using namespace std;
29
30 /////////////////////////////////////////
31 /////////////////////////////////////////
32
33 ExtendedPlugInfoPlugTypeSpecificData::ExtendedPlugInfoPlugTypeSpecificData( EExtendedPlugInfoPlugType ePlugType )
34     : IBusData()
35     , m_plugType( ePlugType )
36 {
37 }
38
39 ExtendedPlugInfoPlugTypeSpecificData::~ExtendedPlugInfoPlugTypeSpecificData()
40 {
41 }
42
43 bool
44 ExtendedPlugInfoPlugTypeSpecificData::serialize( IOSSerialize& se )
45 {
46     se.write( m_plugType, "ExtendedPlugInfoPlugTypeSpecificData plugType" );
47     return true;
48 }
49
50
51 bool
52 ExtendedPlugInfoPlugTypeSpecificData::deserialize( IISDeserialize& de )
53 {
54     de.read( &m_plugType );
55     return true;
56 }
57
58 ExtendedPlugInfoPlugTypeSpecificData* ExtendedPlugInfoPlugTypeSpecificData::clone() const
59 {
60     return new ExtendedPlugInfoPlugTypeSpecificData( *this );
61 }
62
63 const char* extendedPlugInfoPlugTypeStrings[] =
64 {
65     "IsoStream",
66     "AsyncStream",
67     "Midi",
68     "Sync",
69     "Analog",
70     "Digital",
71     "Unknown",
72 };
73
74 const char* extendedPlugInfoPlugTypeToString( plug_type_t plugType )
75 {
76     if ( plugType > sizeof( extendedPlugInfoPlugTypeStrings ) ) {
77         return "Unknown";
78     } else {
79         return extendedPlugInfoPlugTypeStrings[plugType];
80     }
81 }
82
83 /////////////////////////////////////////
84 /////////////////////////////////////////
85
86 ExtendedPlugInfoPlugNameSpecificData::ExtendedPlugInfoPlugNameSpecificData()
87     : IBusData()
88 {
89 }
90
91 ExtendedPlugInfoPlugNameSpecificData::~ExtendedPlugInfoPlugNameSpecificData()
92 {
93 }
94
95 bool
96 ExtendedPlugInfoPlugNameSpecificData::serialize( IOSSerialize& se )
97 {
98     byte_t length = strlen( m_name.c_str() );
99     se.write( length,
100               "ExtendedPlugInfoPlugNameSpecificData: string length" );
101     for ( unsigned int i = 0; i < length; ++i ) {
102         se.write( static_cast<byte_t>( m_name[i] ),
103                   "ExtendedPlugInfoPlugNameSpecificData: char" );
104     }
105
106     return true;
107 }
108
109 bool
110 ExtendedPlugInfoPlugNameSpecificData::deserialize( IISDeserialize& de )
111 {
112     byte_t length;
113     de.read( &length );
114     m_name.clear();
115     for ( int i = 0; i < length; ++length ) {
116         byte_t c;
117         de.read( &c );
118         // \todo do correct encoding
119         if ( c == '&' ) {
120             c = '+';
121         }
122         m_name += c;
123     }
124     return true;
125 }
126
127 ExtendedPlugInfoPlugNameSpecificData::ExtendedPlugInfoPlugNameSpecificData*
128 ExtendedPlugInfoPlugNameSpecificData::clone() const
129 {
130     return new ExtendedPlugInfoPlugNameSpecificData( *this );
131 }
132
133
134 /////////////////////////////////////////
135 /////////////////////////////////////////
136
137 ExtendedPlugInfoPlugNumberOfChannelsSpecificData::ExtendedPlugInfoPlugNumberOfChannelsSpecificData()
138     : IBusData()
139     , m_nrOfChannels( 0 )
140 {
141 }
142
143 ExtendedPlugInfoPlugNumberOfChannelsSpecificData::~ExtendedPlugInfoPlugNumberOfChannelsSpecificData()
144 {
145 }
146
147 bool
148 ExtendedPlugInfoPlugNumberOfChannelsSpecificData::serialize( IOSSerialize& se )
149 {
150     se.write( m_nrOfChannels,
151               "ExtendedPlugInfoPlugNumberOfChannelsSpecificData: "
152               "number of channels" );
153     return true;
154 }
155
156 bool
157 ExtendedPlugInfoPlugNumberOfChannelsSpecificData::deserialize( IISDeserialize& de )
158 {
159     de.read( &m_nrOfChannels );
160     return true;
161 }
162
163 ExtendedPlugInfoPlugNumberOfChannelsSpecificData::ExtendedPlugInfoPlugNumberOfChannelsSpecificData*
164 ExtendedPlugInfoPlugNumberOfChannelsSpecificData::clone() const
165 {
166     return new ExtendedPlugInfoPlugNumberOfChannelsSpecificData( *this );
167 }
168
169 /////////////////////////////////////////
170 /////////////////////////////////////////
171
172 ExtendedPlugInfoPlugChannelPositionSpecificData::ExtendedPlugInfoPlugChannelPositionSpecificData()
173     : IBusData()
174     , m_nrOfClusters( 0 )
175 {
176 }
177
178 ExtendedPlugInfoPlugChannelPositionSpecificData::~ExtendedPlugInfoPlugChannelPositionSpecificData()
179 {
180 }
181
182 bool
183 ExtendedPlugInfoPlugChannelPositionSpecificData::serialize( IOSSerialize& se )
184 {
185     se.write( m_nrOfClusters,
186               "ExtendedPlugInfoPlugChannelPositionSpecificData: "
187               "number of clusters" );
188
189     for ( ClusterInfoVector::const_iterator it = m_clusterInfos.begin();
190           it != m_clusterInfos.end();
191           ++it )
192     {
193         const ClusterInfo* clusterInfo = &( *it );
194
195         se.write( clusterInfo->m_nrOfChannels,
196                   "ExtendedPlugInfoPlugChannelPositionSpecificData: "
197                   "number of channels" );
198         for ( ChannelInfoVector::const_iterator cit
199                   = clusterInfo->m_channelInfos.begin();
200               cit != clusterInfo->m_channelInfos.end();
201               ++cit )
202         {
203             const ChannelInfo* channelInfo = &( *cit );
204             se.write( channelInfo->m_streamPosition,
205                       "ExtendedPlugInfoPlugChannelPositionSpecificData: "
206                       "stream position" );
207             se.write( channelInfo->m_location,
208                       "ExtendedPlugInfoPlugChannelPositionSpecificData: "
209                       "location" );
210         }
211     }
212
213     return true;
214 }
215
216 bool
217 ExtendedPlugInfoPlugChannelPositionSpecificData::deserialize( IISDeserialize& de )
218 {
219     m_clusterInfos.clear();
220
221     de.read( &m_nrOfClusters );
222     for ( int i = 0; i < m_nrOfClusters; ++i ) {
223         ClusterInfo clusterInfo;
224         de.read ( &clusterInfo.m_nrOfChannels );
225         for ( int j = 0; j < clusterInfo.m_nrOfChannels; ++j ) {
226             ChannelInfo channelInfo;
227             de.read( &channelInfo.m_streamPosition );
228             de.read( &channelInfo.m_location );
229             clusterInfo.m_channelInfos.push_back( channelInfo );
230         }
231         m_clusterInfos.push_back( clusterInfo );
232     }
233     return true;
234 }
235
236 ExtendedPlugInfoPlugChannelPositionSpecificData::ExtendedPlugInfoPlugChannelPositionSpecificData*
237 ExtendedPlugInfoPlugChannelPositionSpecificData::clone() const
238 {
239     return new ExtendedPlugInfoPlugChannelPositionSpecificData( *this );
240 }
241
242 /////////////////////////////////////////
243 /////////////////////////////////////////
244
245 ExtendedPlugInfoPlugChannelNameSpecificData::ExtendedPlugInfoPlugChannelNameSpecificData()
246     : IBusData()
247     , m_streamPosition( 0 )
248     , m_stringLength( 0xff )
249 {
250 }
251
252 ExtendedPlugInfoPlugChannelNameSpecificData::~ExtendedPlugInfoPlugChannelNameSpecificData()
253 {
254 }
255
256 bool
257 ExtendedPlugInfoPlugChannelNameSpecificData::serialize( IOSSerialize& se )
258 {
259     se.write( m_streamPosition,
260               "ExtendedPlugInfoPlugChannelNameSpecificData: stream position" );
261     se.write( m_stringLength,
262               "ExtendedPlugInfoPlugChannelNameSpecificData: string length" );
263     for ( unsigned int i = 0; i < m_plugChannelName.size(); ++i ) {
264         se.write( static_cast<byte_t>( m_plugChannelName[i] ),
265                   "ExtendedPlugInfoPlugChannelNameSpecificData: char" );
266     }
267
268     return true;
269 }
270
271 bool
272 ExtendedPlugInfoPlugChannelNameSpecificData::deserialize( IISDeserialize& de )
273 {
274     de.read( &m_streamPosition );
275     de.read( &m_stringLength );
276
277     char* name = new char[m_stringLength+1];
278     for ( int i = 0; i < m_stringLength; ++i ) {
279         byte_t c;
280         de.read( &c );
281         // \todo do correct encoding
282         if ( c == '&' ) {
283             c = '+';
284         }
285         name[i] = c;
286     }
287     name[m_stringLength] = '\0';
288     m_plugChannelName = name;
289     delete[] name;
290
291     return true;
292 }
293
294 ExtendedPlugInfoPlugChannelNameSpecificData::ExtendedPlugInfoPlugChannelNameSpecificData*
295 ExtendedPlugInfoPlugChannelNameSpecificData::clone() const
296 {
297     return new ExtendedPlugInfoPlugChannelNameSpecificData( *this );
298 }
299
300 /////////////////////////////////////////
301 /////////////////////////////////////////
302 ExtendedPlugInfoPlugInputSpecificData::ExtendedPlugInfoPlugInputSpecificData()
303     : IBusData()
304 {
305     UnitPlugSpecificDataPlugAddress
306         unitPlug( UnitPlugSpecificDataPlugAddress::ePT_PCR,  0x00 );
307     m_plugAddress
308         = new PlugAddressSpecificData( PlugAddressSpecificData::ePD_Output,
309                                        PlugAddressSpecificData::ePAM_Unit,
310                                        unitPlug );
311 }
312
313 ExtendedPlugInfoPlugInputSpecificData::ExtendedPlugInfoPlugInputSpecificData(const ExtendedPlugInfoPlugInputSpecificData& rhs )
314 {
315     m_plugAddress = rhs.m_plugAddress->clone();
316 }
317
318
319 ExtendedPlugInfoPlugInputSpecificData::~ExtendedPlugInfoPlugInputSpecificData()
320 {
321     delete m_plugAddress;
322 }
323
324 bool
325 ExtendedPlugInfoPlugInputSpecificData::serialize( IOSSerialize& se )
326 {
327     if ( m_plugAddress ) {
328         return m_plugAddress->serialize( se );
329     } else {
330         return false;
331     }
332 }
333
334 bool
335 ExtendedPlugInfoPlugInputSpecificData::deserialize( IISDeserialize& de )
336 {
337     return m_plugAddress->deserialize( de );
338 }
339
340 ExtendedPlugInfoPlugInputSpecificData::ExtendedPlugInfoPlugInputSpecificData*
341 ExtendedPlugInfoPlugInputSpecificData::clone() const
342 {
343     return new ExtendedPlugInfoPlugInputSpecificData( *this );
344 }
345
346 /////////////////////////////////////////
347 /////////////////////////////////////////
348
349 ExtendedPlugInfoPlugOutputSpecificData::ExtendedPlugInfoPlugOutputSpecificData()
350     : IBusData()
351     , m_nrOfOutputPlugs( 0 )
352 {
353 }
354
355 ExtendedPlugInfoPlugOutputSpecificData::ExtendedPlugInfoPlugOutputSpecificData( const ExtendedPlugInfoPlugOutputSpecificData& rhs)
356     : IBusData()
357     , m_nrOfOutputPlugs( rhs.m_nrOfOutputPlugs )
358 {
359     for ( PlugAddressVector::const_iterator it = rhs.m_outputPlugAddresses.begin();
360           it != rhs.m_outputPlugAddresses.end();
361           ++it )
362     {
363         m_outputPlugAddresses.push_back( ( *it )->clone() );
364     }
365
366 }
367
368
369 ExtendedPlugInfoPlugOutputSpecificData::~ExtendedPlugInfoPlugOutputSpecificData()
370 {
371     for ( PlugAddressVector::iterator it = m_outputPlugAddresses.begin();
372           it != m_outputPlugAddresses.end();
373           ++it )
374     {
375         delete *it;
376     }
377 }
378
379 bool
380 ExtendedPlugInfoPlugOutputSpecificData::serialize( IOSSerialize& se )
381 {
382     se.write( m_nrOfOutputPlugs, "ExtendedPlugInfoPlugOutputSpecificData: number of output plugs" );
383     for ( PlugAddressVector::const_iterator it = m_outputPlugAddresses.begin();
384           it != m_outputPlugAddresses.end();
385           ++it )
386     {
387         ( *it )->serialize( se );
388     }
389
390     return true;
391 }
392
393 bool
394 ExtendedPlugInfoPlugOutputSpecificData::deserialize( IISDeserialize& de )
395 {
396     de.read( &m_nrOfOutputPlugs );
397
398     for ( int i = 0; i < m_nrOfOutputPlugs; ++i )
399     {
400         UnitPlugSpecificDataPlugAddress
401             unitPlug( UnitPlugSpecificDataPlugAddress::ePT_PCR,  0x00 );
402         PlugAddressSpecificData* plugAddress
403             = new PlugAddressSpecificData( PlugAddressSpecificData::ePD_Output,
404                                            PlugAddressSpecificData::ePAM_Unit,
405                                            unitPlug );
406         if ( !plugAddress->deserialize( de ) ) {
407             return false;
408         }
409
410         m_outputPlugAddresses.push_back( plugAddress );
411     }
412
413     return true;
414 }
415
416 ExtendedPlugInfoPlugOutputSpecificData::ExtendedPlugInfoPlugOutputSpecificData*
417 ExtendedPlugInfoPlugOutputSpecificData::clone() const
418 {
419     return new ExtendedPlugInfoPlugOutputSpecificData( *this );
420 }
421
422 /////////////////////////////////////////
423 /////////////////////////////////////////
424 ExtendedPlugInfoClusterInfoSpecificData::ExtendedPlugInfoClusterInfoSpecificData()
425     : IBusData()
426     , m_clusterIndex( 0 )
427     , m_portType( ePT_NoType )
428     , m_stringLength( 0xff )
429 {
430 }
431
432 ExtendedPlugInfoClusterInfoSpecificData::~ExtendedPlugInfoClusterInfoSpecificData()
433 {
434 }
435
436 bool
437 ExtendedPlugInfoClusterInfoSpecificData::serialize( IOSSerialize& se )
438 {
439     se.write( m_clusterIndex,
440               "ExtendedPlugInfoClusterInfoSpecificData: cluster index" );
441     se.write( m_portType,
442               "ExtendedPlugInfoClusterInfoSpecificData: port type" );
443     se.write( m_stringLength,
444               "ExtendedPlugInfoClusterInfoSpecificData: string length" );
445     for ( unsigned int i = 0; i < m_clusterName.length(); ++i ) {
446         se.write( static_cast<byte_t>( m_clusterName[i] ),
447                   "ExtendedPlugInfoClusterInfoSpecificData: char" );
448     }
449
450     return true;
451 }
452
453 bool
454 ExtendedPlugInfoClusterInfoSpecificData::deserialize( IISDeserialize& de )
455 {
456
457     de.read( &m_clusterIndex );
458     de.read( &m_portType );
459     de.read( &m_stringLength );
460
461     char* name = new char[m_stringLength+1];
462     for ( int i = 0; i < m_stringLength; ++i ) {
463         byte_t c;
464         de.read( &c );
465         // \todo do correct encoding
466         if ( c == '&' ) {
467             c = '+';
468         }
469         name[i] = c;
470     }
471     name[m_stringLength] = '\0';
472     m_clusterName = name;
473     delete[] name;
474
475     return true;
476 }
477
478 ExtendedPlugInfoClusterInfoSpecificData::ExtendedPlugInfoClusterInfoSpecificData*
479 ExtendedPlugInfoClusterInfoSpecificData::clone() const
480 {
481     return new ExtendedPlugInfoClusterInfoSpecificData( *this );
482 }
483
484 const char* extendedPlugInfoPortTypeStrings[] =
485 {
486     "Speaker",
487     "Headphone",
488     "Microphone",
489     "Line",
490     "SPDIF",
491     "ADAT",
492     "TDIF",
493     "MADI",
494     "Analog",
495     "Digital",
496     "MIDI",
497 };
498
499 const char* extendedPlugInfoClusterInfoPortTypeToString( port_type_t portType )
500 {
501     if ( portType > sizeof( extendedPlugInfoPortTypeStrings ) ) {
502         return "Unknown";
503     } else {
504         return extendedPlugInfoPortTypeStrings[portType];
505     }
506 }
507
508 /////////////////////////////////////////
509 /////////////////////////////////////////
510 /////////////////////////////////////////
511 /////////////////////////////////////////
512
513 ExtendedPlugInfoInfoType::ExtendedPlugInfoInfoType(EInfoType eInfoType)
514     : IBusData()
515     , m_infoType( eInfoType )
516     , m_plugType( 0 )
517     , m_plugName( 0 )
518     , m_plugNrOfChns( 0 )
519     , m_plugChannelPosition( 0 )
520     , m_plugChannelName( 0 )
521     , m_plugInput( 0 )
522     , m_plugOutput( 0 )
523     , m_plugClusterInfo( 0 )
524 {
525 }
526
527 ExtendedPlugInfoInfoType::~ExtendedPlugInfoInfoType()
528 {
529     delete( m_plugType );
530     delete( m_plugName );
531     delete( m_plugNrOfChns );
532     delete( m_plugChannelPosition );
533     delete( m_plugChannelName );
534     delete( m_plugInput );
535     delete( m_plugOutput );
536     delete( m_plugClusterInfo );
537  }
538
539 bool
540 ExtendedPlugInfoInfoType::initialize()
541 {
542     switch ( m_infoType ) {
543     case eIT_PlugType:
544         m_plugType = new ExtendedPlugInfoPlugTypeSpecificData;
545         break;
546     case eIT_PlugName:
547         m_plugName = new ExtendedPlugInfoPlugNameSpecificData;
548         break;
549     case eIT_NoOfChannels:
550         m_plugNrOfChns = new ExtendedPlugInfoPlugNumberOfChannelsSpecificData;
551         break;
552     case eIT_ChannelPosition:
553         m_plugChannelPosition = new ExtendedPlugInfoPlugChannelPositionSpecificData;
554         break;
555     case eIT_ChannelName:
556         m_plugChannelName = new ExtendedPlugInfoPlugChannelNameSpecificData;
557         break;
558     case eIT_PlugInput:
559         m_plugInput = new ExtendedPlugInfoPlugInputSpecificData;
560         break;
561     case eIT_PlugOutput:
562         m_plugOutput = new ExtendedPlugInfoPlugOutputSpecificData;
563         break;
564     case eIT_ClusterInfo:
565         m_plugClusterInfo = new ExtendedPlugInfoClusterInfoSpecificData;
566         break;
567     default:
568         return false;
569     }
570
571     return true;
572 }
573
574 bool
575 ExtendedPlugInfoInfoType::serialize( IOSSerialize& se )
576 {
577     se.write( m_infoType, "ExtendedPlugInfoInfoType infoType" );
578
579     switch ( m_infoType ) {
580     case eIT_PlugType:
581         if ( m_plugType ) {
582             m_plugType->serialize( se );
583         }
584         break;
585     case eIT_PlugName:
586         if ( m_plugName ) {
587             m_plugName->serialize( se );
588         }
589         break;
590     case eIT_NoOfChannels:
591         if ( m_plugNrOfChns ) {
592             m_plugNrOfChns->serialize( se );
593         }
594         break;
595     case eIT_ChannelPosition:
596         if ( m_plugChannelPosition ) {
597             m_plugChannelPosition->serialize( se );
598         }
599         break;
600     case eIT_ChannelName:
601         if ( m_plugChannelName ) {
602             m_plugChannelName->serialize( se );
603         }
604         break;
605     case eIT_PlugInput:
606         if ( m_plugInput ) {
607             m_plugInput->serialize( se );
608         }
609         break;
610     case eIT_PlugOutput:
611         if ( m_plugOutput ) {
612             m_plugOutput->serialize( se );
613         }
614         break;
615     case eIT_ClusterInfo:
616         if ( m_plugClusterInfo ) {
617             m_plugClusterInfo->serialize( se );
618         }
619         break;
620     default:
621         return false;
622     }
623
624     return true;
625 }
626
627 bool
628 ExtendedPlugInfoInfoType::deserialize( IISDeserialize& de )
629 {
630     de.read( &m_infoType );
631
632     switch ( m_infoType ) {
633     case eIT_PlugType:
634         if ( !m_plugType ) {
635             m_plugType = new ExtendedPlugInfoPlugTypeSpecificData;
636         }
637         m_plugType->deserialize( de );
638         break;
639     case eIT_PlugName:
640         if ( !m_plugName ) {
641             m_plugName = new ExtendedPlugInfoPlugNameSpecificData;
642         }
643         m_plugName->deserialize( de );
644         break;
645     case eIT_NoOfChannels:
646         if ( !m_plugNrOfChns ) {
647             m_plugNrOfChns =
648                 new ExtendedPlugInfoPlugNumberOfChannelsSpecificData;
649         }
650         m_plugNrOfChns->deserialize( de );
651         break;
652     case eIT_ChannelPosition:
653         if ( !m_plugChannelPosition ) {
654             m_plugChannelPosition =
655                 new ExtendedPlugInfoPlugChannelPositionSpecificData;
656         }
657         m_plugChannelPosition->deserialize( de );
658
659         break;
660     case eIT_ChannelName:
661         if ( !m_plugChannelName ) {
662             m_plugChannelName =
663                 new ExtendedPlugInfoPlugChannelNameSpecificData;
664         }
665         m_plugChannelName->deserialize( de );
666         break;
667     case eIT_PlugInput:
668         if ( !m_plugInput ) {
669             m_plugInput = new ExtendedPlugInfoPlugInputSpecificData;
670         }
671         m_plugInput->deserialize( de );
672         break;
673     case eIT_PlugOutput:
674         if ( !m_plugOutput ) {
675             m_plugOutput = new ExtendedPlugInfoPlugOutputSpecificData;
676         }
677         m_plugOutput->deserialize( de );
678         break;
679     case eIT_ClusterInfo:
680         if ( !m_plugClusterInfo ) {
681             m_plugClusterInfo = new ExtendedPlugInfoClusterInfoSpecificData;
682         }
683         m_plugClusterInfo->deserialize( de );
684         break;
685     default:
686         return false;
687     }
688
689     return true;
690 }
691
692 ExtendedPlugInfoInfoType*
693 ExtendedPlugInfoInfoType::clone() const
694 {
695    ExtendedPlugInfoInfoType* extPlugInfoInfoType
696        = new ExtendedPlugInfoInfoType( *this );
697    extPlugInfoInfoType->initialize();
698    return extPlugInfoInfoType;
699 }
700
701 //////////////////////////////////////////////
702
703 ExtendedPlugInfoCmd::ExtendedPlugInfoCmd( Ieee1394Service* ieee1394service,
704                                           ESubFunction eSubFunction )
705     : AVCCommand( ieee1394service, AVC1394_CMD_PLUG_INFO )
706 {
707     setSubFunction( eSubFunction );
708     UnitPlugAddress unitPlugAddress( UnitPlugAddress::ePT_PCR, 0x00 );
709     m_plugAddress = new PlugAddress( PlugAddress::ePD_Output,
710                                       PlugAddress::ePAM_Unit,
711                                       unitPlugAddress );
712     m_infoType =
713         new ExtendedPlugInfoInfoType( ExtendedPlugInfoInfoType::eIT_PlugType );
714     m_infoType->initialize();
715 }
716
717 ExtendedPlugInfoCmd::~ExtendedPlugInfoCmd()
718 {
719     delete m_plugAddress;
720     m_plugAddress = 0;
721     delete m_infoType;
722     m_infoType = 0;
723 }
724
725 bool
726 ExtendedPlugInfoCmd::serialize( IOSSerialize& se )
727 {
728     AVCCommand::serialize( se );
729     se.write( m_subFunction, "ExtendedPlugInfoCmd subFunction" );
730     m_plugAddress->serialize( se );
731     m_infoType->serialize( se );
732
733     return true;
734 }
735
736 bool
737 ExtendedPlugInfoCmd::deserialize( IISDeserialize& de )
738 {
739     AVCCommand::deserialize( de );
740     de.read( &m_subFunction );
741     m_plugAddress->deserialize( de );
742     m_infoType->deserialize( de );
743
744     return true;
745 }
746
747 bool
748 ExtendedPlugInfoCmd::fire()
749 {
750     bool result = false;
751
752     #define STREAM_FORMAT_REQUEST_SIZE 20 // XXX random length
753     union UPacket {
754         quadlet_t     quadlet[STREAM_FORMAT_REQUEST_SIZE];
755         unsigned char byte[STREAM_FORMAT_REQUEST_SIZE*4];
756     };
757     typedef union UPacket packet_t;
758
759     packet_t  req;
760     packet_t* resp;
761
762     // initialize complete packet
763     memset( &req,  0xff,  sizeof( req ) );
764
765     BufferSerialize se( req.byte, sizeof( req ) );
766     if ( !serialize( se ) ) {
767         printf(  "ExtendedPlugInfoCmd::fire: Could not serialize\n" );
768         return false;
769     }
770
771     // reorder the bytes to the correct layout
772     for (int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i) {
773         req.quadlet[i] = ntohl( req.quadlet[i] );
774     }
775
776     if ( isVerbose() ) {
777         // debug output
778         puts("request:");
779         for (int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i) {
780             printf("  %2d: 0x%08x\n", i, req.quadlet[i]);
781         }
782     }
783
784     resp = reinterpret_cast<packet_t*>(
785         m_1394Service->transactionBlock( m_nodeId,
786                                          req.quadlet,
787                                          STREAM_FORMAT_REQUEST_SIZE ) );
788     if ( resp ) {
789         if ( isVerbose() ) {
790             // debug output
791             puts("response:");
792             for ( int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i ) {
793                 printf( "  %2d: 0x%08x\n", i, resp->quadlet[i] );
794             }
795         }
796
797         // reorder the bytes to the correct layout
798         for ( int i = 0; i < STREAM_FORMAT_REQUEST_SIZE; ++i ) {
799             resp->quadlet[i] = htonl( resp->quadlet[i] );
800         }
801
802         if ( isVerbose() ) {
803             // a more detailed debug output
804             printf( "\n" );
805             printf( " idx type                       value\n" );
806             printf( "-------------------------------------\n" );
807             printf( "  %02d                     ctype: 0x%02x\n", 0, resp->byte[0] );
808             printf( "  %02d subunit_type + subunit_id: 0x%02x\n", 1, resp->byte[1] );
809             printf( "  %02d                    opcode: 0x%02x\n", 2, resp->byte[2] );
810
811             for ( int i = 3; i < STREAM_FORMAT_REQUEST_SIZE * 4; ++i ) {
812                 printf( "  %02d                operand %2d: 0x%02x\n", i, i-3, resp->byte[i] );
813             }
814         }
815
816         // parse output
817         parseResponse( resp->byte[0] );
818         switch ( getResponse() )
819         {
820             case eR_Implemented:
821             {
822                 BufferDeserialize de( resp->byte, sizeof( req ) );
823                 deserialize( de );
824                 result = true;
825             }
826             break;
827             default:
828                 printf( "unexpected response received (0x%x)\n", getResponse() );
829         }
830     } else {
831         printf( "no response\n" );
832     }
833
834     return result;
835 }
836
837 bool
838 ExtendedPlugInfoCmd::setPlugAddress( const PlugAddress& plugAddress )
839 {
840     delete m_plugAddress;
841     m_plugAddress = plugAddress.clone();
842     return true;
843 }
844
845 bool
846 ExtendedPlugInfoCmd::setSubFunction( ESubFunction subFunction )
847 {
848     m_subFunction = subFunction;
849     return true;
850 }
851
852 bool
853 ExtendedPlugInfoCmd::setInfoType( const ExtendedPlugInfoInfoType& infoType )
854 {
855     delete m_infoType;
856     m_infoType = infoType.clone();
857     return true;
858 }
Note: See TracBrowser for help on using the browser.