root/trunk/libffado/src/libavc/musicsubunit/avc_descriptor_music.cpp

Revision 864, 23.4 kB (checked in by ppalmers, 15 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 Pieter Palmers
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 program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23  
24 #include "avc_descriptor_music.h"
25
26 #include "../descriptors/avc_descriptor.h"
27 #include "../descriptors/avc_descriptor_cmd.h"
28
29 #include "libutil/cmd_serialize.h"
30 #include "libieee1394/ieee1394service.h"
31
32 #include "../general/avc_subunit.h"
33 #include "../general/avc_unit.h"
34
35 #include <netinet/in.h>
36
37 // info block implementations
38
39 namespace AVC {
40
41
42 AVCMusicGeneralStatusInfoBlock::AVCMusicGeneralStatusInfoBlock( )
43     : AVCInfoBlock( 0x8100 )
44     , m_current_transmit_capability ( 0 )
45     , m_current_receive_capability  ( 0 )
46     , m_current_latency_capability  ( 0xFFFFFFFF )
47 {}
48
49 bool
50 AVCMusicGeneralStatusInfoBlock::serialize( Util::Cmd::IOSSerialize& se )
51 {
52     bool result=true;
53     result &= AVCInfoBlock::serialize(se);
54    
55     quadlet_t tmp=htonl(m_current_latency_capability);
56    
57     result &= se.write(m_current_transmit_capability, "AVCMusicGeneralStatusInfoBlock m_current_transmit_capability");
58     result &= se.write(m_current_receive_capability, "AVCMusicGeneralStatusInfoBlock m_current_receive_capability");
59     result &= se.write(tmp, "AVCMusicGeneralStatusInfoBlock m_current_latency_capability");
60
61     return result;
62 }
63
64 bool
65 AVCMusicGeneralStatusInfoBlock::deserialize( Util::Cmd::IISDeserialize& de )
66 {
67     bool result=true;
68     result &= AVCInfoBlock::deserialize(de);
69     if (m_primary_field_length != 6) {
70         debugWarning("Incorrect primary field length: %u, should be 6\n", m_primary_field_length);
71         return false;
72     }
73    
74     result &= de.read(&m_current_transmit_capability);
75     result &= de.read(&m_current_receive_capability);
76     result &= de.read(&m_current_latency_capability);
77     m_current_latency_capability=ntohl(m_current_latency_capability);
78    
79     return result;
80 }
81
82 // ---------
83 AVCMusicOutputPlugStatusInfoBlock::AVCMusicOutputPlugStatusInfoBlock( )
84     : AVCInfoBlock( 0x8101 )
85 {}
86
87 bool
88 AVCMusicOutputPlugStatusInfoBlock::serialize( Util::Cmd::IOSSerialize& se )
89 {
90     bool result=true;
91     result &= AVCInfoBlock::serialize(se);
92     debugWarning("%s not supported\n", getInfoBlockName());
93     result=false;
94     return result;
95 }
96
97 bool
98 AVCMusicOutputPlugStatusInfoBlock::deserialize( Util::Cmd::IISDeserialize& de )
99 {
100     bool result=true;
101     result &= AVCInfoBlock::deserialize(de);
102     debugWarning("%s not supported, skipping\n", getInfoBlockName());
103     de.skip(m_compound_length-4);
104     return result;
105 }
106 // ---------
107 AVCMusicClusterInfoBlock::AVCMusicClusterInfoBlock( )
108     : AVCInfoBlock( 0x810A )
109     , m_stream_format ( 0 )
110     , m_port_type ( 0 )
111     , m_nb_signals ( 0 )
112 {}
113
114 AVCMusicClusterInfoBlock::~AVCMusicClusterInfoBlock( )
115 {
116     clear();
117 }
118
119 bool
120 AVCMusicClusterInfoBlock::clear( ) {
121     m_stream_format=0;
122     m_port_type=0;
123     m_nb_signals=0;
124    
125     m_SignalInfos.clear();
126     return true;
127 }
128
129 bool
130 AVCMusicClusterInfoBlock::serialize( Util::Cmd::IOSSerialize& se )
131 {
132     bool result=true;
133     result &= AVCInfoBlock::serialize(se);
134    
135     result &= se.write(m_stream_format, "AVCMusicClusterInfoBlock m_stream_format");
136     result &= se.write(m_port_type, "AVCMusicClusterInfoBlock m_port_type");
137     result &= se.write(m_nb_signals, "AVCMusicClusterInfoBlock m_nb_signals");
138    
139     if (m_SignalInfos.size() != m_nb_signals) {
140         debugError("not enough elements in AVCMusicClusterInfoBlock vector\n");
141         return false;
142     }
143    
144     unsigned int cnt;
145     for (cnt=0;cnt<m_nb_signals;cnt++) {
146 //         debugOutput(DEBUG_LEVEL_VERBOSE, "Adding SignalInfo %2u\n",cnt);
147         struct sSignalInfo s=m_SignalInfos.at(cnt);
148         result &= se.write(s.music_plug_id, "AVCMusicClusterInfoBlock music_plug_id");
149         result &= se.write(s.stream_position, "AVCMusicClusterInfoBlock stream_position");
150         result &= se.write(s.stream_location, "AVCMusicClusterInfoBlock stream_location");
151     }
152    
153     // do the optional text/name info block
154     if(m_RawTextInfoBlock.m_compound_length>0) {
155         result &= m_RawTextInfoBlock.serialize(se);
156     } else if (m_NameInfoBlock.m_compound_length>0) {
157         result &= m_NameInfoBlock.serialize(se);
158     }
159    
160     return result;
161 }
162
163 bool
164 AVCMusicClusterInfoBlock::deserialize( Util::Cmd::IISDeserialize& de )
165 {
166     bool result=true;
167     result &= AVCInfoBlock::deserialize(de);
168    
169     unsigned int consumed_at_start=de.getNrOfConsumedBytes();
170
171     result &= de.read(&m_stream_format);
172     result &= de.read(&m_port_type);
173     result &= de.read(&m_nb_signals);
174    
175     unsigned int cnt;
176     for (cnt=0;cnt<m_nb_signals;cnt++) {
177         debugOutput(DEBUG_LEVEL_VERBOSE, "Adding SignalInfo %2u\n",cnt);
178         struct sSignalInfo s;
179         result &= de.read(&s.music_plug_id);
180         result &= de.read(&s.stream_position);
181         result &= de.read(&s.stream_location);
182         m_SignalInfos.push_back(s);
183     }
184     unsigned int consumed_at_sinfo_end=de.getNrOfConsumedBytes();
185    
186     // do the optional text info block
187     // first find out if the block is present
188     int bytes_done=4+consumed_at_sinfo_end-consumed_at_start;
189     int bytes_left=m_compound_length-bytes_done;
190     debugOutput(DEBUG_LEVEL_VERBOSE,"len=%d, @start=%d @end=%d done=%d, left=%d\n",
191         m_compound_length, consumed_at_start, consumed_at_sinfo_end, bytes_done, bytes_left);
192     if(bytes_left>0) {
193         uint16_t block_type;
194         AVCInfoBlock::peekBlockType(de, &block_type);
195         if(block_type==m_RawTextInfoBlock.m_supported_info_block_type) {
196             result &= m_RawTextInfoBlock.deserialize(de);
197         } else if (block_type==m_NameInfoBlock.m_supported_info_block_type) {
198             result &= m_NameInfoBlock.deserialize(de);
199         } else {
200             debugWarning("Unexpected info block, skipping...\n");
201             de.skip(bytes_left);
202         }
203     }
204
205     return result;
206 }
207
208 std::string
209 AVCMusicClusterInfoBlock::getName() {
210     if(m_RawTextInfoBlock.m_compound_length>0) {
211         return m_RawTextInfoBlock.m_text;
212     } else if (m_NameInfoBlock.m_compound_length>0) {
213         return m_NameInfoBlock.m_text;
214     } else {
215         return std::string("Unknown");
216     }
217 }
218
219
220 // ---------
221 AVCMusicSubunitPlugInfoBlock::AVCMusicSubunitPlugInfoBlock( )
222     : AVCInfoBlock( 0x8109 )
223     , m_subunit_plug_id ( 0 )
224     , m_signal_format ( 0 )
225     , m_plug_type ( 0xFF )
226     , m_nb_clusters ( 0 )
227     , m_nb_channels ( 0 )
228 {}
229
230 AVCMusicSubunitPlugInfoBlock::~AVCMusicSubunitPlugInfoBlock( )
231 {
232     clear();
233 }
234
235 bool
236 AVCMusicSubunitPlugInfoBlock::clear()
237 {
238     m_subunit_plug_id=0;
239     m_signal_format=0;
240     m_plug_type=0xFF;
241     m_nb_clusters=0;
242     m_nb_channels=0;
243    
244     // clean up dynamically allocated stuff
245     for ( AVCMusicClusterInfoBlockVectorIterator it = m_Clusters.begin();
246       it != m_Clusters.end();
247       ++it )
248     {
249         delete *it;
250     }
251     m_Clusters.clear();
252    
253     return true;
254 }
255
256 bool
257 AVCMusicSubunitPlugInfoBlock::serialize( Util::Cmd::IOSSerialize& se )
258 {
259     bool result=true;
260     result &= AVCInfoBlock::serialize(se);
261    
262     result &= se.write(m_subunit_plug_id, "AVCMusicPlugInfoBlock m_subunit_plug_id");
263     result &= se.write(m_signal_format, "AVCMusicPlugInfoBlock m_signal_format");
264     result &= se.write(m_plug_type, "AVCMusicPlugInfoBlock m_plug_type");
265     result &= se.write(m_nb_clusters, "AVCMusicPlugInfoBlock m_nb_clusters");
266     result &= se.write(m_nb_channels, "AVCMusicPlugInfoBlock m_nb_channels");
267    
268     unsigned int cnt;
269     if (m_Clusters.size() != m_nb_clusters) {
270         debugError("not enough elements in AVCMusicClusterInfoBlock vector\n");
271         return false;
272     }
273     for (cnt=0;cnt<m_nb_clusters;cnt++) {
274         AVCMusicClusterInfoBlock *p=m_Clusters.at(cnt);
275         result &= p->serialize(se);
276     }
277
278     // do the optional text/name info block
279     if(m_RawTextInfoBlock.m_compound_length>0) {
280         result &= m_RawTextInfoBlock.serialize(se);
281     } else if (m_NameInfoBlock.m_compound_length>0) {
282         result &= m_NameInfoBlock.serialize(se);
283     }
284     return result;
285 }
286
287 bool
288 AVCMusicSubunitPlugInfoBlock::deserialize( Util::Cmd::IISDeserialize& de )
289 {
290     bool result=true;
291     result &= AVCInfoBlock::deserialize(de);
292    
293     if (m_primary_field_length != 8) {
294         debugWarning("Incorrect primary field length: %u, should be 4\n", m_primary_field_length);
295         return false;
296     }
297    
298     unsigned int consumed_at_start=de.getNrOfConsumedBytes();
299    
300     result &= de.read(&m_subunit_plug_id);
301     result &= de.read(&m_signal_format);
302     result &= de.read(&m_plug_type);
303     result &= de.read(&m_nb_clusters);
304     result &= de.read(&m_nb_channels);
305    
306     unsigned int cnt;
307     for (cnt=0;cnt<m_nb_clusters;cnt++) {
308         debugOutput(DEBUG_LEVEL_VERBOSE, "Adding AVCMusicClusterInfoBlock %2u\n",cnt);
309         AVCMusicClusterInfoBlock *p=new AVCMusicClusterInfoBlock();
310         if (p==NULL) {
311             debugError("Could not allocate memory for dest AVCMusicClusterInfoBlock\n");
312         }
313         m_Clusters.push_back(p);
314         result &= p->deserialize(de);
315     }
316     unsigned int consumed_at_cluster_end=de.getNrOfConsumedBytes();
317    
318     // do the optional text info block
319     // first find out if the block is present
320     int bytes_done=4+consumed_at_cluster_end-consumed_at_start;
321     int bytes_left=m_compound_length-bytes_done;
322     debugOutput(DEBUG_LEVEL_VERBOSE,"len=%d, @start=%d @end=%d done=%d, left=%d\n",
323         m_compound_length, consumed_at_start, consumed_at_cluster_end, bytes_done, bytes_left);
324     if(bytes_left>0) {
325         uint16_t block_type;
326         AVCInfoBlock::peekBlockType(de, &block_type);
327         if(block_type==m_RawTextInfoBlock.m_supported_info_block_type) {
328             result &= m_RawTextInfoBlock.deserialize(de);
329         } else if (block_type==m_NameInfoBlock.m_supported_info_block_type) {
330             result &= m_NameInfoBlock.deserialize(de);
331         } else {
332             debugWarning("Unexpected info block, skipping...\n");
333             de.skip(bytes_left);
334         }
335     }
336    
337     return result;
338 }
339
340 std::string
341 AVCMusicSubunitPlugInfoBlock::getName() {
342     if(m_RawTextInfoBlock.m_compound_length>0) {
343         return m_RawTextInfoBlock.m_text;
344     } else if (m_NameInfoBlock.m_compound_length>0) {
345         return m_NameInfoBlock.m_text;
346     } else {
347         return std::string("Unknown");
348     }
349 }
350
351
352 // ---------
353 AVCMusicPlugInfoBlock::AVCMusicPlugInfoBlock( )
354     : AVCInfoBlock( 0x810B )
355     , m_music_plug_type ( 0 )
356     , m_music_plug_id ( 0 )
357     , m_routing_support ( 0 )
358     , m_source_plug_function_type ( 0 )
359     , m_source_plug_id ( 0 )
360     , m_source_plug_function_block_id ( 0 )
361     , m_source_stream_position ( 0 )
362     , m_source_stream_location ( 0 )
363     , m_dest_plug_function_type ( 0 )
364     , m_dest_plug_id ( 0 )
365     , m_dest_plug_function_block_id ( 0 )
366     , m_dest_stream_position ( 0 )
367     , m_dest_stream_location ( 0 )
368 {}
369
370 bool
371 AVCMusicPlugInfoBlock::clear( ) {
372     m_music_plug_type=0;
373     m_music_plug_id=0;
374     m_routing_support=0;
375     m_source_plug_function_type=0;
376     m_source_plug_id=0;
377     m_source_plug_function_block_id=0;
378     m_source_stream_position=0;
379     m_source_stream_location=0;
380     m_dest_plug_function_type=0;
381     m_dest_plug_id=0;
382     m_dest_plug_function_block_id=0;
383     m_dest_stream_position=0;
384     m_dest_stream_location=0;
385    
386     return true;
387 }
388
389 bool
390 AVCMusicPlugInfoBlock::serialize( Util::Cmd::IOSSerialize& se )
391 {
392     bool result=true;
393     result &= AVCInfoBlock::serialize(se);
394
395     result &= se.write(m_music_plug_type, "AVCMusicPlugInfoBlock m_music_plug_type" );
396     result &= se.write(m_music_plug_id, "AVCMusicPlugInfoBlock m_music_plug_id" );
397     result &= se.write(m_routing_support, "AVCMusicPlugInfoBlock m_routing_support" );
398     result &= se.write(m_source_plug_function_type, "AVCMusicPlugInfoBlock m_source_plug_function_type" );
399     result &= se.write(m_source_plug_id, "AVCMusicPlugInfoBlock m_source_plug_id" );
400     result &= se.write(m_source_plug_function_block_id, "AVCMusicPlugInfoBlock m_source_plug_function_block_id" );
401     result &= se.write(m_source_stream_position, "AVCMusicPlugInfoBlock m_source_stream_position" );
402     result &= se.write(m_source_stream_location, "AVCMusicPlugInfoBlock m_source_stream_location" );
403     result &= se.write(m_dest_plug_function_type, "AVCMusicPlugInfoBlock m_dest_plug_function_type" );
404     result &= se.write(m_dest_plug_id, "AVCMusicPlugInfoBlock m_dest_plug_id" );
405     result &= se.write(m_dest_plug_function_block_id, "AVCMusicPlugInfoBlock m_dest_plug_function_block_id" );
406     result &= se.write(m_dest_stream_position, "AVCMusicPlugInfoBlock m_dest_stream_position" );
407     result &= se.write(m_dest_stream_location, "AVCMusicPlugInfoBlock m_dest_stream_location" );
408    
409     // do the optional text/name info block
410     if(m_RawTextInfoBlock.m_compound_length>0) {
411         result &= m_RawTextInfoBlock.serialize(se);
412     } else if (m_NameInfoBlock.m_compound_length>0) {
413         result &= m_NameInfoBlock.serialize(se);
414     }
415    
416     return result;
417 }
418
419 bool
420 AVCMusicPlugInfoBlock::deserialize( Util::Cmd::IISDeserialize& de )
421 {
422     bool result=true;
423     result &= AVCInfoBlock::deserialize(de);
424    
425     if (m_primary_field_length != 14) {
426         debugWarning("Incorrect primary field length: %u, should be 4\n", m_primary_field_length);
427         return false;
428     }
429
430     result &= de.read(&m_music_plug_type);
431     result &= de.read(&m_music_plug_id);
432     result &= de.read(&m_routing_support);
433     result &= de.read(&m_source_plug_function_type);
434     result &= de.read(&m_source_plug_id);
435     result &= de.read(&m_source_plug_function_block_id);
436     result &= de.read(&m_source_stream_position);
437     result &= de.read(&m_source_stream_location);
438     result &= de.read(&m_dest_plug_function_type);
439     result &= de.read(&m_dest_plug_id);
440     result &= de.read(&m_dest_plug_function_block_id);
441     result &= de.read(&m_dest_stream_position);
442     result &= de.read(&m_dest_stream_location);
443    
444     if(m_compound_length>18) {
445         uint16_t block_type;
446         AVCInfoBlock::peekBlockType(de, &block_type);
447         if(block_type==m_RawTextInfoBlock.m_supported_info_block_type) {
448             result &= m_RawTextInfoBlock.deserialize(de);
449         } else if (block_type==m_NameInfoBlock.m_supported_info_block_type) {
450             result &= m_NameInfoBlock.deserialize(de);
451         } else {
452             debugWarning("Unexpected info block, skipping...\n");
453             de.skip(m_compound_length-18);
454         }
455     }
456    
457     return result;
458 }
459
460 std::string
461 AVCMusicPlugInfoBlock::getName() {
462     if(m_RawTextInfoBlock.m_compound_length>0) {
463         return m_RawTextInfoBlock.m_text;
464     } else if (m_NameInfoBlock.m_compound_length>0) {
465         return m_NameInfoBlock.m_text;
466     } else {
467         return std::string("Unknown");
468     }
469 }
470
471
472 // ---------
473 AVCMusicRoutingStatusInfoBlock::AVCMusicRoutingStatusInfoBlock( )
474     : AVCInfoBlock( 0x8108 )
475     , m_nb_dest_plugs ( 0 )
476     , m_nb_source_plugs ( 0 )
477     , m_nb_music_plugs ( 0 )
478 {}
479
480 AVCMusicRoutingStatusInfoBlock::~AVCMusicRoutingStatusInfoBlock( ) {
481
482     clear();
483 }
484
485 bool
486 AVCMusicRoutingStatusInfoBlock::clear()
487 {
488     m_nb_dest_plugs=0;
489     m_nb_source_plugs=0;
490     m_nb_music_plugs=0;
491    
492     // clean up dynamically allocated stuff
493     for ( AVCMusicSubunitPlugInfoBlockVectorIterator it = mDestPlugInfoBlocks.begin();
494       it != mDestPlugInfoBlocks.end();
495       ++it )
496     {
497         delete *it;
498     }
499     mDestPlugInfoBlocks.clear();
500    
501     for ( AVCMusicSubunitPlugInfoBlockVectorIterator it = mSourcePlugInfoBlocks.begin();
502       it != mSourcePlugInfoBlocks.end();
503       ++it )
504     {
505         delete *it;
506     }
507     mSourcePlugInfoBlocks.clear();
508    
509     for ( AVCMusicPlugInfoBlockVectorIterator it = mMusicPlugInfoBlocks.begin();
510       it != mMusicPlugInfoBlocks.end();
511       ++it )
512     {
513         delete *it;
514     }
515     mMusicPlugInfoBlocks.clear();
516    
517     return true;
518 }
519
520 bool
521 AVCMusicRoutingStatusInfoBlock::serialize( Util::Cmd::IOSSerialize& se )
522 {
523     bool result=true;
524     result &= AVCInfoBlock::serialize(se);
525    
526     result &= se.write(m_nb_dest_plugs, "AVCMusicRoutingStatusInfoBlock m_nb_dest_plugs");
527     result &= se.write(m_nb_source_plugs, "AVCMusicRoutingStatusInfoBlock m_nb_source_plugs");
528     result &= se.write(m_nb_music_plugs, "AVCMusicRoutingStatusInfoBlock m_nb_music_plugs");
529    
530     unsigned int cnt;
531     if (mDestPlugInfoBlocks.size() != m_nb_dest_plugs) {
532         debugError("not enough elements in dest AVCMusicSubunitPlugInfoBlock vector\n");
533         return false;
534     }
535     for (cnt=0;cnt<m_nb_dest_plugs;cnt++) {
536         AVCMusicSubunitPlugInfoBlock *p=mDestPlugInfoBlocks.at(cnt);
537         result &= p->serialize(se);
538     }
539    
540     if (mSourcePlugInfoBlocks.size() != m_nb_source_plugs) {
541         debugError("not enough elements in  src AVCMusicSubunitPlugInfoBlock\n");
542         return false;
543     }
544     for (cnt=0;cnt<m_nb_source_plugs;cnt++) {
545         AVCMusicSubunitPlugInfoBlock *p=mSourcePlugInfoBlocks.at(cnt);
546         result &= p->serialize(se);
547     }
548    
549     if (mMusicPlugInfoBlocks.size() != m_nb_music_plugs) {
550         debugError("not enough elements in AVCMusicPlugInfoBlock\n");
551         return false;
552     }
553     for (cnt=0;cnt<m_nb_music_plugs;cnt++) {
554         AVCMusicPlugInfoBlock *p=mMusicPlugInfoBlocks.at(cnt);
555         result &= p->serialize(se);
556     }
557
558     return result;
559 }
560
561 bool
562 AVCMusicRoutingStatusInfoBlock::deserialize( Util::Cmd::IISDeserialize& de )
563 {
564     bool result=true;
565     result &= AVCInfoBlock::deserialize(de);
566    
567     if (m_primary_field_length != 4) {
568         debugWarning("Incorrect primary field length: %u, should be 4\n", m_primary_field_length);
569         return false;
570     }
571    
572     result &= de.read(&m_nb_dest_plugs);
573     result &= de.read(&m_nb_source_plugs);
574     result &= de.read(&m_nb_music_plugs);
575    
576     unsigned int cnt;
577     for (cnt=0;cnt<m_nb_dest_plugs;cnt++) {
578         debugOutput(DEBUG_LEVEL_VERBOSE, "Adding dest AVCMusicSubunitPlugInfoBlock %2u\n",cnt);
579         AVCMusicSubunitPlugInfoBlock *p=new AVCMusicSubunitPlugInfoBlock();
580         if (p==NULL) {
581             debugError("Could not allocate memory for dest AVCMusicSubunitPlugInfoBlock\n");
582         }
583         mDestPlugInfoBlocks.push_back(p);
584         result &= p->deserialize(de);
585     }
586    
587     for (cnt=0;cnt<m_nb_source_plugs;cnt++) {
588         debugOutput(DEBUG_LEVEL_VERBOSE, "Adding source AVCMusicSubunitPlugInfoBlock %2u\n",cnt);
589         AVCMusicSubunitPlugInfoBlock *p=new AVCMusicSubunitPlugInfoBlock();
590         if (p==NULL) {
591             debugError("Could not allocate memory for src AVCMusicSubunitPlugInfoBlock vector\n");
592         }
593         mSourcePlugInfoBlocks.push_back(p);
594         result &= p->deserialize(de);
595     }
596    
597     for (cnt=0;cnt<m_nb_music_plugs;cnt++) {
598         debugOutput(DEBUG_LEVEL_VERBOSE, "Adding AVCMusicPlugInfoBlock %2u\n",cnt);
599         AVCMusicPlugInfoBlock *p=new AVCMusicPlugInfoBlock();
600         if (p==NULL) {
601             debugError("Could not allocate memory for AVCMusicPlugInfoBlock vector\n");
602         }
603         mMusicPlugInfoBlocks.push_back(p);
604         result &= p->deserialize(de);
605     }
606     return result;
607 }
608
609 AVCMusicSubunitPlugInfoBlock *
610 AVCMusicRoutingStatusInfoBlock::getSubunitPlugInfoBlock(Plug::EPlugDirection direction, plug_id_t id) {
611     if (direction == Plug::eAPD_Input) {
612         for ( AVCMusicSubunitPlugInfoBlockVectorIterator it = mDestPlugInfoBlocks.begin();
613         it != mDestPlugInfoBlocks.end();
614         ++it )
615         {
616             AVCMusicSubunitPlugInfoBlock *b=(*it);
617             if (b->m_subunit_plug_id == id) return b;
618         }
619         debugOutput(DEBUG_LEVEL_VERBOSE, "no plug info found.\n");
620         return NULL;
621     } else if (direction == Plug::eAPD_Output) {
622         for ( AVCMusicSubunitPlugInfoBlockVectorIterator it = mSourcePlugInfoBlocks.begin();
623         it != mSourcePlugInfoBlocks.end();
624         ++it )
625         {
626             AVCMusicSubunitPlugInfoBlock *b=(*it);
627             if (b->m_subunit_plug_id == id) return b;
628         }
629         debugOutput(DEBUG_LEVEL_VERBOSE, "no plug info found.\n");
630         return NULL;
631     } else {
632         debugOutput(DEBUG_LEVEL_VERBOSE, "Invalid direction.\n");
633         return NULL;
634     }
635 }
636
637 AVCMusicPlugInfoBlock *
638 AVCMusicRoutingStatusInfoBlock::getMusicPlugInfoBlock(plug_id_t id) {
639     for ( AVCMusicPlugInfoBlockVectorIterator it = mMusicPlugInfoBlocks.begin();
640     it != mMusicPlugInfoBlocks.end();
641     ++it )
642     {
643         AVCMusicPlugInfoBlock *b=(*it);
644         if (b->m_music_plug_id == id) return b;
645     }
646     debugOutput(DEBUG_LEVEL_VERBOSE, "no music plug info found.\n");
647     return NULL;
648 }
649
650 // ----------------------
651 AVCMusicStatusDescriptor::AVCMusicStatusDescriptor( Unit* unit, Subunit* subunit )
652     : AVCDescriptor(unit, subunit, AVCDescriptorSpecifier::eSubunit0x80)
653 {}
654
655 bool
656 AVCMusicStatusDescriptor::serialize( Util::Cmd::IOSSerialize& se )
657 {
658     bool result=true;
659    
660     result &= AVCDescriptor::serialize(se);
661    
662     result &= m_general_status_infoblock.serialize(se);
663    
664     if (m_output_plug_status_infoblock.m_compound_length>0) {
665         result &= m_output_plug_status_infoblock.serialize(se);
666     }
667    
668     if (m_routing_status_infoblock.m_compound_length>0) {
669         result &= m_routing_status_infoblock.serialize(se);
670     }
671
672     return true;
673 }
674
675 bool
676 AVCMusicStatusDescriptor::deserialize( Util::Cmd::IISDeserialize& de )
677 {
678     bool result=true;
679    
680     unsigned int blocks_done=0;
681     const unsigned int max_blocks=10;
682    
683     result &= AVCDescriptor::deserialize(de);
684    
685     uint16_t block_type;
686     uint16_t block_length;
687    
688     // process all infoblocks until done or until failure
689     while(AVCInfoBlock::peekBlockType(de, &block_type) && result) {
690         AVCInfoBlock::peekBlockLength(de, &block_length);
691        
692         debugOutput(DEBUG_LEVEL_VERBOSE, "type=0x%04X, length=%u\n",block_type, block_length);
693        
694         switch (block_type) {
695             case 0x8100:
696                 m_general_status_infoblock.setVerbose(getVerboseLevel());
697                 result &= m_general_status_infoblock.deserialize(de);
698                 break;
699             case 0x8101:
700                 m_output_plug_status_infoblock.setVerbose(getVerboseLevel());
701                 result &= m_output_plug_status_infoblock.deserialize(de);
702                 break;
703             case 0x8108:
704                 m_routing_status_infoblock.setVerbose(getVerboseLevel());
705                 result &= m_routing_status_infoblock.deserialize(de);
706                 break;
707             default:
708                 debugWarning("Unknown info block type: 0x%04X, length=%u, skipping...\n", block_type, block_length);
709                 de.skip(block_length);
710                 break;
711         }
712
713         if(blocks_done++>max_blocks) {
714             debugError("Too much info blocks in descriptor, probably a runaway parser\n");
715             break;
716         }
717     }
718    
719     return result;
720 }
721
722 AVCMusicSubunitPlugInfoBlock *
723 AVCMusicStatusDescriptor::getSubunitPlugInfoBlock(Plug::EPlugDirection direction, plug_id_t id) {
724     return m_routing_status_infoblock.getSubunitPlugInfoBlock(direction, id);
725 }
726
727 AVCMusicPlugInfoBlock *
728 AVCMusicStatusDescriptor::getMusicPlugInfoBlock(plug_id_t id) {
729     return m_routing_status_infoblock.getMusicPlugInfoBlock(id);
730 }
731
732 }
Note: See TracBrowser for help on using the browser.