root/branches/streaming-rework/src/libavc/avc_function_block.cpp

Revision 439, 20.1 kB (checked in by pieterpalmers, 16 years ago)

- some work on the AVC mixer & control stuff

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