root/trunk/libffado/src/libavc/audiosubunit/avc_function_block.cpp

Revision 864, 20.4 kB (checked in by ppalmers, 13 years ago)

update license to GPLv2 or GPLv3 instead of GPLv2 or any later version. Update copyrights to reflect the new year

Line 
1 /*
2  * Copyright (C) 2005-2008 by Daniel Wagner
3  * Copyright (C) 2005-2008 by Pieter Palmers
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include "avc_function_block.h"
26 #include "libutil/cmd_serialize.h"
27 #include "libieee1394/ieee1394service.h"
28
29
30 namespace AVC {
31
32
33 /////////////////////////////////
34
35 FunctionBlockFeatureVolume::FunctionBlockFeatureVolume()
36     : IBusData()
37     , m_controlDataLength( 2 )
38     , m_volume( 0 )
39 {
40 }
41
42 FunctionBlockFeatureVolume::FunctionBlockFeatureVolume( const FunctionBlockFeatureVolume& rhs )
43     : m_controlDataLength( rhs.m_controlDataLength )
44     , m_volume( rhs.m_volume )
45 {
46 }
47
48 FunctionBlockFeatureVolume::~FunctionBlockFeatureVolume()
49 {
50 }
51
52 bool
53 FunctionBlockFeatureVolume::serialize( Util::Cmd::IOSSerialize& se )
54 {
55     bool bStatus;
56     byte_t val;
57     bStatus = se.write( m_controlDataLength,  "FunctionBlockFeatureVolume controlDataLength" );
58     val = (byte_t)(m_volume >> 8);
59     bStatus &= se.write( val,                  "FunctionBlockFeatureVolume volume high" );
60     val = m_volume & 0xff;
61     bStatus &= se.write( val,                  "FunctionBlockFeatureVolume volume low" );
62
63     return bStatus;
64 }
65
66 bool
67 FunctionBlockFeatureVolume::deserialize( Util::Cmd::IISDeserialize& de )
68 {
69     bool bStatus;
70     byte_t val;
71     bStatus = de.read( &m_controlDataLength );
72     bStatus &= de.read( &val );
73     m_volume = val << 8;
74     bStatus &= de.read( &val );
75     m_volume |= val;
76
77     return bStatus;
78 }
79
80 FunctionBlockFeatureVolume*
81 FunctionBlockFeatureVolume::clone() const
82 {
83     return new FunctionBlockFeatureVolume( *this );
84 }
85
86 /////////////////////////////////
87
88 FunctionBlockProcessingMixer::FunctionBlockProcessingMixer()
89     : IBusData()
90     , m_controlSelector( FunctionBlockProcessing::eCSE_Processing_Mixer )
91 {
92 }
93
94 FunctionBlockProcessingMixer::FunctionBlockProcessingMixer( const FunctionBlockProcessingMixer& rhs )
95     : m_controlSelector( rhs.m_controlSelector )
96 {
97 }
98
99 FunctionBlockProcessingMixer::~FunctionBlockProcessingMixer()
100 {
101 }
102
103 bool
104 FunctionBlockProcessingMixer::serialize( Util::Cmd::IOSSerialize& se )
105 {
106     bool bStatus;
107     bStatus = se.write( m_controlSelector,    "FunctionBlockProcessingMixer controlSelector" );
108
109     return bStatus;
110 }
111
112 bool
113 FunctionBlockProcessingMixer::deserialize( Util::Cmd::IISDeserialize& de )
114 {
115     bool bStatus;
116     bStatus = de.read( &m_controlSelector );
117
118     return bStatus;
119 }
120
121 FunctionBlockProcessingMixer*
122 FunctionBlockProcessingMixer::clone() const
123 {
124     return new FunctionBlockProcessingMixer( *this );
125 }
126
127 /////////////////////////////////
128
129 FunctionBlockProcessingEnhancedMixer::FunctionBlockProcessingEnhancedMixer()
130     : IBusData()
131     , m_controlSelector( FunctionBlockProcessing::eCSE_Processing_EnhancedMixer )
132     , m_statusSelector( eSS_ProgramableState )
133     , m_controlDataLength( 0 )
134 {
135 }
136
137 FunctionBlockProcessingEnhancedMixer::FunctionBlockProcessingEnhancedMixer(
138     const FunctionBlockProcessingEnhancedMixer& rhs )
139     : m_controlSelector( rhs.m_controlSelector )
140     , m_statusSelector( rhs.m_statusSelector )
141 {
142 }
143
144 FunctionBlockProcessingEnhancedMixer::~FunctionBlockProcessingEnhancedMixer()
145 {
146 }
147
148 bool
149 FunctionBlockProcessingEnhancedMixer::serialize( Util::Cmd::IOSSerialize& se )
150 {
151     int todo,done;
152     bool bStatus;
153     byte_t data_length_hi, data_length_lo;
154    
155     bStatus  = se.write( m_controlSelector, "FunctionBlockProcessingEnhancedMixer controlSelector" );
156     bStatus &= se.write( m_statusSelector,  "FunctionBlockProcessingEnhancedMixer statusSelector" );
157    
158     switch (m_statusSelector) {
159         case eSS_ProgramableState:
160             m_controlDataLength=m_LevelData.size();
161             data_length_hi=(m_controlDataLength >> 8);
162             data_length_lo=(m_controlDataLength & 0xFF);
163             bStatus &= se.write( data_length_hi,  "FunctionBlockProcessingEnhancedMixer controlDataLengthHi" );
164             bStatus &= se.write( data_length_lo,  "FunctionBlockProcessingEnhancedMixer controlDataLengthLo" );
165
166             for (int i=0;i<m_controlDataLength/8;i++) {
167                 byte_t value=0;
168                
169                 for (int j=0;j<8;j++) {
170                     control_data_ext_length_t bit_value=m_ProgramableStateData.at(i*8+j);
171                     value |= bit_value << (7-j);
172                 }
173                
174                 bStatus &= se.write( value,  "FunctionBlockProcessingEnhancedMixer data" );
175             }
176            
177             todo=m_controlDataLength%8;
178             done=m_controlDataLength-todo;
179             if (todo) {
180                 byte_t value=0;
181                 for (int j=0;j<todo;j++) {
182                     control_data_ext_length_t bit_value=m_ProgramableStateData.at(done*8+j);
183                     value |= bit_value << (7-j);
184                 }
185                 bStatus &= se.write( value,  "FunctionBlockProcessingEnhancedMixer data" );
186             }
187             break;
188         case eSS_Level:
189             m_controlDataLength=m_LevelData.size()/2;
190             data_length_hi=(m_controlDataLength >> 8);
191             data_length_lo=(m_controlDataLength & 0xFF);
192             bStatus &= se.write( data_length_hi,  "FunctionBlockProcessingEnhancedMixer controlDataLengthHi" );
193             bStatus &= se.write( data_length_lo,  "FunctionBlockProcessingEnhancedMixer controlDataLengthLo" );
194
195             for (int i=0;i<m_controlDataLength/2;i++) {
196                 mixer_level_t value=m_LevelData.at(i);
197                 byte_t value_hi=value >> 8;
198                 byte_t value_lo=value & 0xFF;
199                
200                 bStatus &= se.write( value_hi,  "FunctionBlockProcessingEnhancedMixer data" );
201                 bStatus &= se.write( value_lo,  "FunctionBlockProcessingEnhancedMixer data" );
202             }
203             break;
204     }
205     return bStatus;
206 }
207
208 bool
209 FunctionBlockProcessingEnhancedMixer::deserialize( Util::Cmd::IISDeserialize& de )
210 {
211     int todo;
212     bool bStatus=true;
213     bStatus  = de.read( &m_controlSelector );
214
215     // NOTE: the returned value is currently bogus, so overwrite it
216     m_controlSelector=FunctionBlockProcessing::eCSE_Processing_EnhancedMixer;
217
218     bStatus &= de.read( &m_statusSelector );
219
220     // same here
221     //m_statusSelector = eSS_Level;
222     m_statusSelector = eSS_ProgramableState;
223
224     byte_t data_length_hi;
225     byte_t data_length_lo;
226     bStatus &= de.read( &data_length_hi );
227     bStatus &= de.read( &data_length_lo );
228
229     m_controlDataLength = (data_length_hi << 8) + data_length_lo;
230     switch (m_statusSelector) {
231         case eSS_ProgramableState:
232             m_ProgramableStateData.clear();
233             for (int i=0;i<m_controlDataLength/8;i++) {
234                 byte_t value;
235                 bStatus &= de.read( &value);
236
237                 for (int j=7;j>=0;j--) {
238                     byte_t bit_value;
239                     bit_value=(((1<<j) & value) ? 1 : 0);
240                     m_ProgramableStateData.push_back(bit_value);
241                 }
242             }
243
244             todo=m_controlDataLength%8;
245             if (todo) {
246                 byte_t value;
247                 bStatus &= de.read( &value);
248
249                 for (int j=7;j>7-todo;j--) {
250                     byte_t bit_value;
251                     bit_value=(((1<<j) & value) ? 1 : 0);
252                     m_ProgramableStateData.push_back(bit_value);
253                 }
254             }
255             break;
256         case eSS_Level:
257             m_LevelData.clear();
258             for (int i=0;i<m_controlDataLength/2;i++) {
259                 byte_t mixer_value_hi=0, mixer_value_lo=0;
260                 bStatus &= de.read( &mixer_value_hi);
261                 bStatus &= de.read( &mixer_value_lo);
262                 mixer_level_t value = (mixer_value_hi << 8) + mixer_value_lo;
263                 m_LevelData.push_back(value);
264             }
265             break;
266     }
267
268     return bStatus;
269 }
270
271 FunctionBlockProcessingEnhancedMixer*
272 FunctionBlockProcessingEnhancedMixer::clone() const
273 {
274     return new FunctionBlockProcessingEnhancedMixer( *this );
275 }
276
277
278 /////////////////////////////////
279 /////////////////////////////////
280
281 FunctionBlockSelector::FunctionBlockSelector()
282     : IBusData()
283     , m_selectorLength( 0x02 )
284     , m_inputFbPlugNumber( 0x00 )
285     , m_controlSelector( eCSE_Selector_Selector )
286 {
287 }
288
289 FunctionBlockSelector::FunctionBlockSelector( const FunctionBlockSelector& rhs )
290     : IBusData()
291     , m_selectorLength( rhs.m_selectorLength )
292     , m_inputFbPlugNumber( rhs.m_inputFbPlugNumber )
293     , m_controlSelector( rhs.m_controlSelector )
294 {
295 }
296
297 FunctionBlockSelector::~FunctionBlockSelector()
298 {
299 }
300
301 bool
302 FunctionBlockSelector::serialize( Util::Cmd::IOSSerialize& se )
303 {
304     bool bStatus;
305     bStatus  = se.write( m_selectorLength,    "FunctionBlockSelector selectorLength" );
306     bStatus &= se.write( m_inputFbPlugNumber, "FunctionBlockSelector inputFbPlugNumber" );
307     bStatus &= se.write( m_controlSelector,   "FunctionBlockSelector controlSelector" );
308
309     return bStatus;
310 }
311
312 bool
313 FunctionBlockSelector::deserialize( Util::Cmd::IISDeserialize& de )
314 {
315     bool bStatus;
316     bStatus  = de.read( &m_selectorLength );
317     bStatus &= de.read( &m_inputFbPlugNumber );
318     bStatus &= de.read( &m_controlSelector );
319
320     return bStatus;
321 }
322
323 FunctionBlockSelector*
324 FunctionBlockSelector::clone() const
325 {
326     return new FunctionBlockSelector( *this );
327 }
328
329 /////////////////////////////////
330
331 FunctionBlockFeature::FunctionBlockFeature()
332     : IBusData()
333     , m_selectorLength( 0x02 )
334     , m_audioChannelNumber( 0x00 )
335     , m_controlSelector( eCSE_Feature_Unknown )
336     , m_pVolume( new FunctionBlockFeatureVolume )
337 {
338 }
339
340 FunctionBlockFeature::FunctionBlockFeature( const FunctionBlockFeature& rhs )
341     : IBusData()
342     , m_selectorLength( rhs.m_selectorLength )
343     , m_audioChannelNumber( rhs.m_audioChannelNumber )
344     , m_controlSelector( rhs.m_controlSelector )
345 {
346     if ( rhs.m_pVolume ) {
347         m_pVolume = new FunctionBlockFeatureVolume( *rhs.m_pVolume );
348     }
349 }
350
351 FunctionBlockFeature::~FunctionBlockFeature()
352 {
353     delete m_pVolume;
354     m_pVolume = NULL;
355 }
356
357 bool
358 FunctionBlockFeature::serialize( Util::Cmd::IOSSerialize& se )
359 {
360     bool bStatus;
361     bStatus  = se.write( m_selectorLength,     "FunctionBlockFeature selectorLength" );
362     bStatus &= se.write( m_audioChannelNumber, "FunctionBlockFeature audioChannelNumber" );
363     bStatus &= se.write( m_controlSelector,    "FunctionBlockFeature controlSelector" );
364
365     if ( m_controlSelector == eCSE_Feature_Volume ) {
366         bStatus &= m_pVolume->serialize( se );
367     } else {
368         bStatus = false;
369     }
370
371     return bStatus;
372 }
373
374 bool
375 FunctionBlockFeature::deserialize( Util::Cmd::IISDeserialize& de )
376 {
377     bool bStatus;
378     bStatus  = de.read( &m_selectorLength );
379     bStatus &= de.read( &m_audioChannelNumber );
380     bStatus &= de.read( &m_controlSelector );
381
382     switch( m_controlSelector ) {
383     case eCSE_Feature_Volume:
384         bStatus &= m_pVolume->deserialize( de );
385         break;
386     case eCSE_Feature_Mute:
387     case eCSE_Feature_LRBalance:
388     case eCSE_Feature_FRBalance:
389     case eCSE_Feature_Bass:
390     case eCSE_Feature_Mid:
391     case eCSE_Feature_Treble:
392     case eCSE_Feature_GEQ:
393     case eCSE_Feature_AGC:
394     case eCSE_Feature_Delay:
395     case eCSE_Feature_BassBoost:
396     case eCSE_Feature_Loudness:
397     default:
398         bStatus = false;
399     }
400
401     return bStatus;
402 }
403
404 FunctionBlockFeature*
405 FunctionBlockFeature::clone() const
406 {
407     return new FunctionBlockFeature( *this );
408 }
409
410 /////////////////////////////////
411
412 FunctionBlockProcessing::FunctionBlockProcessing()
413     : IBusData()
414     , m_selectorLength( 0x04 )
415     , m_fbInputPlugNumber( 0x00 )
416     , m_inputAudioChannelNumber( 0x00 )
417     , m_outputAudioChannelNumber( 0x00 )
418     , m_pMixer( 0 )
419     , m_pEnhancedMixer( 0 )
420 {
421 }
422
423 FunctionBlockProcessing::FunctionBlockProcessing( const FunctionBlockProcessing& rhs )
424     : m_selectorLength( rhs.m_selectorLength )
425     , m_fbInputPlugNumber( rhs.m_fbInputPlugNumber )
426     , m_inputAudioChannelNumber( rhs.m_inputAudioChannelNumber )
427     , m_outputAudioChannelNumber( rhs.m_outputAudioChannelNumber )
428 {
429     if ( rhs.m_pMixer ) {
430         m_pMixer = new FunctionBlockProcessingMixer( *rhs.m_pMixer );
431     } else if ( rhs.m_pEnhancedMixer ) {
432         m_pEnhancedMixer = new FunctionBlockProcessingEnhancedMixer( *rhs.m_pEnhancedMixer );
433     }
434 }
435
436 FunctionBlockProcessing::~FunctionBlockProcessing()
437 {
438     delete m_pMixer;
439     m_pMixer = 0;
440     delete m_pEnhancedMixer;
441     m_pEnhancedMixer = 0;
442 }
443
444 bool
445 FunctionBlockProcessing::serialize( Util::Cmd::IOSSerialize& se )
446 {
447     bool bStatus;
448     bStatus  = se.write( m_selectorLength,     "FunctionBlockProcessing selectorLength" );
449     bStatus &= se.write( m_fbInputPlugNumber,  "FunctionBlockProcessing fbInputPlugNumber" );
450     bStatus &= se.write( m_inputAudioChannelNumber,  "FunctionBlockProcessing inputAudioChannelNumber" );
451     bStatus &= se.write( m_outputAudioChannelNumber, "FunctionBlockProcessing outputAudioChannelNumber" );
452
453     if ( m_pMixer ) {
454         bStatus &= m_pMixer->serialize( se );
455     } else if ( m_pEnhancedMixer ) {
456         bStatus &= m_pEnhancedMixer->serialize( se );
457     } else {
458         bStatus = false;
459     }
460
461     return bStatus;
462 }
463
464 bool
465 FunctionBlockProcessing::deserialize( Util::Cmd::IISDeserialize& de )
466 {
467     // NOTE: apparently the fbCmd of the STATUS type,
468     // with EnhancedMixer controlSelector returns with this
469     // controlSelector type changed to Mixer, making it
470     // impossible to choose the correct response handler
471     // based upon the response only.
472    
473     // HACK: we assume that it is the same as the sent one
474     // we also look at our data structure to figure out what we sent
475     byte_t controlSelector=eCSE_Processing_Unknown;
476     if(m_pMixer) {
477         controlSelector=eCSE_Processing_Mixer;
478     } else if(m_pEnhancedMixer) {
479         controlSelector=eCSE_Processing_EnhancedMixer;
480     }
481    
482     bool bStatus;
483     bStatus  = de.read( &m_selectorLength );
484     bStatus &= de.read( &m_fbInputPlugNumber );
485     bStatus &= de.read( &m_inputAudioChannelNumber );
486     bStatus &= de.read( &m_outputAudioChannelNumber );
487
488     byte_t controlSelector_response;
489     bStatus &= de.peek( &controlSelector_response );
490 /*    debugOutput(DEBUG_LEVEL_VERBOSE,"ctrlsel: orig = %02X, resp = %02X\n",
491         controlSelector, controlSelector_response);*/
492    
493     switch( controlSelector ) {
494     case eCSE_Processing_Mixer:
495         if ( !m_pMixer ) {
496             m_pMixer = new FunctionBlockProcessingMixer;
497         }
498         bStatus &= m_pMixer->deserialize( de );
499         break;
500     case eCSE_Processing_EnhancedMixer:
501         if ( !m_pEnhancedMixer ) {
502             m_pEnhancedMixer = new FunctionBlockProcessingEnhancedMixer;
503         }
504         bStatus &= m_pEnhancedMixer->deserialize( de );
505         break;
506     case eCSE_Processing_Enable:
507     case eCSE_Processing_Mode:
508     default:
509         bStatus = false;
510     }
511
512     byte_t tmp;
513     if (de.peek(&tmp)) {
514         debugOutput(DEBUG_LEVEL_VERBOSE,"Unprocessed bytes:\n");
515         while (de.read(&tmp)) {
516             debugOutput(DEBUG_LEVEL_VERBOSE," %02X\n",tmp);
517         }
518     }
519
520     return bStatus;
521 }
522
523 FunctionBlockProcessing*
524 FunctionBlockProcessing::clone() const
525 {
526     return new FunctionBlockProcessing( *this );
527 }
528
529 /////////////////////////////////
530
531 FunctionBlockCodec::FunctionBlockCodec()
532     : IBusData()
533 {
534 }
535
536 FunctionBlockCodec::FunctionBlockCodec( const FunctionBlockCodec& rhs )
537     : IBusData()
538 {
539 }
540
541 FunctionBlockCodec::~FunctionBlockCodec()
542 {
543 }
544
545 bool
546 FunctionBlockCodec::serialize( Util::Cmd::IOSSerialize& se )
547 {
548     return false;
549 }
550
551 bool
552 FunctionBlockCodec::deserialize( Util::Cmd::IISDeserialize& de )
553 {
554     return false;
555 }
556
557 FunctionBlockCodec*
558 FunctionBlockCodec::clone() const
559 {
560     return new FunctionBlockCodec( *this );
561 }
562
563 /////////////////////////////////
564 /////////////////////////////////
565
566 FunctionBlockCmd::FunctionBlockCmd( Ieee1394Service& ieee1394service,
567                                     EFunctionBlockType eType,
568                                     function_block_id_t id,
569                                     EControlAttribute eCtrlAttrib )
570     : AVCCommand( ieee1394service, AVC1394_FUNCTION_BLOCK_CMD )
571     , m_functionBlockType( eType )
572     , m_functionBlockId( id )
573     , m_controlAttribute( eCtrlAttrib )
574     , m_pFBSelector( 0 )
575     , m_pFBFeature( 0 )
576     , m_pFBProcessing( 0 )
577     , m_pFBCodec( 0 )
578 {
579     setSubunitType( eST_Audio );
580
581     switch( m_functionBlockType ) {
582         case eFBT_Selector:
583             m_pFBSelector = new FunctionBlockSelector;
584             break;
585         case eFBT_Feature:
586             m_pFBFeature = new FunctionBlockFeature;
587             break;
588         case eFBT_Processing:
589             m_pFBProcessing = new FunctionBlockProcessing;
590             break;
591         case eFBT_Codec:
592             m_pFBCodec = new FunctionBlockCodec;
593             break;
594     }
595 }
596
597 FunctionBlockCmd::FunctionBlockCmd( const FunctionBlockCmd& rhs )
598     : AVCCommand( rhs )
599     , m_functionBlockType( rhs.m_functionBlockType )
600     , m_functionBlockId( rhs.m_functionBlockId )
601     , m_controlAttribute( rhs.m_controlAttribute )
602     , m_pFBSelector( new FunctionBlockSelector( *rhs.m_pFBSelector ) )
603     , m_pFBFeature( new FunctionBlockFeature( *rhs.m_pFBFeature ) )
604     , m_pFBProcessing( new FunctionBlockProcessing( *rhs.m_pFBProcessing ) )
605     , m_pFBCodec( new FunctionBlockCodec( *rhs.m_pFBCodec ) )
606 {
607 }
608
609 FunctionBlockCmd::~FunctionBlockCmd()
610 {
611     delete m_pFBSelector;
612     m_pFBSelector = 0;
613     delete m_pFBFeature;
614     m_pFBFeature = 0;
615     delete m_pFBProcessing;
616     m_pFBProcessing = 0;
617     delete m_pFBCodec;
618     m_pFBCodec = 0;
619 }
620
621 bool
622 FunctionBlockCmd::serialize( Util::Cmd::IOSSerialize& se )
623 {
624     bool bStatus;
625     bStatus  = AVCCommand::serialize( se );
626     bStatus &= se.write( m_functionBlockType, "FunctionBlockCmd functionBlockType" );
627     bStatus &= se.write( m_functionBlockId,   "FunctionBlockCmd functionBlockId" );
628     bStatus &= se.write( m_controlAttribute,  "FunctionBlockCmd controlAttribute" );
629
630     switch( m_functionBlockType ) {
631         case eFBT_Selector:
632             if ( m_pFBSelector ) {
633                 bStatus &= m_pFBSelector->serialize( se );
634             } else {
635                 bStatus = false;
636             }
637             break;
638         case eFBT_Feature:
639             if ( m_pFBFeature ) {
640                 bStatus &= m_pFBFeature->serialize( se );
641             } else {
642                 bStatus = false;
643             }
644             break;
645         case eFBT_Processing:
646             if ( m_pFBProcessing ) {
647                 bStatus &= m_pFBProcessing->serialize( se );
648             } else {
649                 bStatus = false;
650             }
651             break;
652         case eFBT_Codec:
653             if ( m_pFBCodec ) {
654                 bStatus &= m_pFBCodec->serialize( se );
655             } else {
656                 bStatus = false;
657             }
658             break;
659         default:
660             bStatus = false;
661     }
662
663     return bStatus;
664 }
665
666 bool
667 FunctionBlockCmd::deserialize( Util::Cmd::IISDeserialize& de )
668 {
669     bool bStatus;
670     bStatus  = AVCCommand::deserialize( de );
671
672     bStatus &= de.read( &m_functionBlockType );
673     bStatus &= de.read( &m_functionBlockId );
674     bStatus &= de.read( &m_controlAttribute );
675
676     switch( m_functionBlockType ) {
677         case eFBT_Selector:
678             if ( !m_pFBSelector ) {
679                 m_pFBSelector = new FunctionBlockSelector;
680             }
681             bStatus &= m_pFBSelector->deserialize( de );
682             break;
683         case eFBT_Feature:
684             if ( !m_pFBFeature ) {
685                 m_pFBFeature = new FunctionBlockFeature;
686             }
687             bStatus &= m_pFBFeature->deserialize( de );
688             break;
689         case eFBT_Processing:
690             if ( !m_pFBProcessing ) {
691                 m_pFBProcessing = new FunctionBlockProcessing;
692             }
693             bStatus &= m_pFBProcessing->deserialize( de );
694             break;
695         case eFBT_Codec:
696             if ( !m_pFBCodec ) {
697                 m_pFBCodec = new FunctionBlockCodec;
698             }
699             bStatus &= m_pFBCodec->deserialize( de );
700             break;
701         default:
702             bStatus = false;
703     }
704
705     return bStatus;
706 }
707
708 FunctionBlockCmd*
709 FunctionBlockCmd::clone() const
710 {
711     return new FunctionBlockCmd( *this );
712 }
713
714 }
Note: See TracBrowser for help on using the browser.