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

Revision 445, 20.2 kB (checked in by pieterpalmers, 15 years ago)

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

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

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

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