DSMCC  22.11.0
getModuleInfo_include_src.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2004 Ocean Blue Software Ltd
4  * Copyright © 2001 Koninklijke Philips Electronics N.V
5  *
6  * This file is part of a DTVKit Software Component
7  * You are permitted to copy, modify or distribute this file subject to the terms
8  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
9  *
10  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
11  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
12  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * If you or your organisation is not a member of DTVKit then you have access
15  * to this source code outside of the terms of the licence agreement
16  * and you are expected to delete this and any associated files immediately.
17  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
18  *******************************************************************************/
29 /*
30 -- getpModuleInfo_source - Common Code
31 --
32 -- Get module info from module info descriptor in DII message (compatible with
33 -- contiguous or managed/MemSeq memory)
34 --
35 -- Uses/assumes the following vars:
36 -- valid, mpModuleInfoDescStart, *pModuleInfo
37 --
38 -- mpModuleInfoDescStart references ('points' to) first byte of module info
39 -- descriptor, valid (BOOLEAN) indicates whether module info was valid
40 --
41 -- mpModuleInfoDescStart = const pUInt8/MemSeqRef,
42 -- pModuleInfo = P_ModuleInfo
43 -- valid = BOOLEAN
44 --
45 -- NB. Only DVB (UK Profile 1) spec. currently implemented
46 */
47 
48 {
49  MemPtr mpModuleInfoDesc;
50  U8BIT tapsCount;
51  U8BIT infoLength;
52  MemPos currPos, endPos;
53  U8BIT descriptorTag;
54  U8BIT descriptorLength;
55  U8BIT ui8 = 0;
56  U16BIT ui16 = 0;
57 
58  dsmAssert((mpModuleInfoDescStart != NULL));
59  dsmAssert((pModuleInfo != NULL));
60 
61  /* -- Open MemPtr for accessing module descriptor info */
62  MEMPTR_OPEN( mpModuleInfoDescStart, mpModuleInfoDesc );
63 
64  /* -- Read moduleId */
65  READ_UINT16( mpModuleInfoDesc, pModuleInfo->moduleId );
66 
67  /* -- Read moduleSize */
68  READ_UINT32( mpModuleInfoDesc, pModuleInfo->moduleSize );
69  if ( pModuleInfo->moduleSize == 0 )
70  {
71  /* 0 length modules are not useful! */
72  dsmDP2(("DATA ERROR: Zero module size; moduleId=%u\n", pModuleInfo->moduleId));
73  valid = FALSE;
74  }
75  else
76  {
77  #ifndef NDEBUG
78  /* Initialise debug monitor flag */
79  pModuleInfo->blkRcvd = 0;
80  #endif
81 
82  /* -- Read moduleVersion */
83  READ_UINT8( mpModuleInfoDesc, pModuleInfo->version );
84 
85  /* -- Initialise module compression info */
86  pModuleInfo->zipped = FALSE;
87  pModuleInfo->compressed = FALSE;
88  pModuleInfo->originalSize = pModuleInfo->moduleSize;
89 
90  if ( pModuleInfo->crslMagic == OC_MAGIC )
91  {
92  /* -- Skip pModuleInfoLength */
93  SET_POS_REL( mpModuleInfoDesc, 1 );
94 
95  /* -- mpModuleInfoDesc -> BIOP::pModuleInfo */
96  /* -- Read moduleTimeOut */
97  READ_UINT32( mpModuleInfoDesc, pModuleInfo->u.mhgp.moduleTimeout );
98 
99  /* -- Read blockTimeOut */
100  READ_UINT32( mpModuleInfoDesc, pModuleInfo->u.mhgp.blockTimeout );
101 
102  /* -- Read minBlockTime */
103  READ_UINT32( mpModuleInfoDesc, pModuleInfo->u.mhgp.minBlockTime );
104 
105  /* -- Read/check tapsCount >= 1 (DVB) */
106  /* -- L1 check because this should be correct */
107  READ_UINT8( mpModuleInfoDesc, tapsCount );
108  if ( !tapsCount )
109  {
110  dsmDP2(("DATA ERROR: Module info tapsCount zero\n"));
111  valid = FALSE;
112  }
113  else
114  {
115  /* -- mpModuleInfoDesc -> start of first BIOP::Tap */
116  /* -- Read info from first Tap */
117  /* -- Read tapId - TODO: Not required ? */
118  READ_UINT16( mpModuleInfoDesc, pModuleInfo->u.mhgp.tapBiopId );
119 
120  /* -- tapUse = BIOP_OBJECT_USE (in BIOP::pModuleInfoMessage - DVB/UK DTT) */
121  /* -- L0 check because this must be correct */
122  READ_UINT16( mpModuleInfoDesc, ui16 );
123  if (ui16 != BIOP_OBJECT_USE)
124  {
125  dsmDP2(("DATA ERROR: Module info 1st tapUse (!= BIOP_OBJECT_USE) = %u\n", ui16));
126  valid = FALSE;
127  }
128  else
129  {
130  /* -- Read associationTag */
131  READ_UINT16( mpModuleInfoDesc, pModuleInfo->associationTag );
132 
133  /* -- selectorLength = 0 (DVB/UK DTT) */
134  READ_UINT8( mpModuleInfoDesc, ui8 );
135  /* Although, TS 101 102 specifically states that for BIOP_OBJECT_USE, selector is empty,
136  * someone (in HbbTV test case org.hbbtv_DSMCC108) decided that selector length can be
137  * non-zero anyway! The justification of this anomoly is given by quoting TS 102 809:
138  * "selector fields are not used and the receiver may ignore them." But what is even
139  * more crazy is that table B.7 does not account for a selector on the first tap
140  * and simply states length is zero - uh!
141  */
142  if (ui8 != 0x00)
143  {
144  dsmDP2(("DATA ERROR: Module info tap selectorLength (!= 0) = %u\n", ui8));
145  /* now we cater for a data stream that does not comply with the specifications */
146  SET_POS_REL( mpModuleInfoDesc, (S32BIT)ui8 );
147  }
148  valid = TRUE;
149 
150  /* -- Skip any remaining Taps */
151  while (--tapsCount > 0)
152  {
153  /* -- Skip tapId, tapUse, associationTag */
154  SET_POS_REL( mpModuleInfoDesc, 6 );
155  /* -- Read selectorLength */
156  READ_UINT8( mpModuleInfoDesc, ui8 );
157  /* -- Skip selector field */
158  SET_POS_REL( mpModuleInfoDesc, (S32BIT)ui8 );
159  }
160 
161  /* -- mpModuleInfoDesc -> infoLength */
162  /* -- Read infoLength */
163  READ_UINT8( mpModuleInfoDesc, infoLength );
164 
165  if (infoLength != 0)
166  {
167  /* -- Search module descriptor loop for compressed module descriptor */
168  /* -- Determine end position of search data */
169  GET_POS( mpModuleInfoDesc, currPos );
170  endPos = currPos + infoLength;
171  while (currPos < endPos)
172  {
173  /* -- mpModuleInfoDesc -> current module descriptor */
174 
175  /* -- Read descriptorTag */
176  READ_UINT8( mpModuleInfoDesc, descriptorTag );
177 
178  /* -- Read descriptorLength */
179  READ_UINT8( mpModuleInfoDesc, descriptorLength );
180 
181  switch (descriptorTag)
182  {
183  case DESCRIPTOR_COMP_MODULE_TAG:
184  /* -- compressionMethod LSNibble == 0x8 (DVB/RFC1950)*/
185  /* -- L1 check because this should be correct (subsequently
186  -- zlib inflate should also check compression method of
187  -- module data/stream before attempting to decompress) */
188  READ_UINT8( mpModuleInfoDesc, ui8 );
189  if ( (ui8 & 0x0f) != 0x08 )
190  {
191  ERRPRINT("DATA: Module info compressionMethod (!= 0x08) = %u\n", ui8)
192  SET_POS_REL( mpModuleInfoDesc, 4 );
193  }
194  else
195  {
196  /* -- Indicate module is compressed */
197  pModuleInfo->compressed = TRUE;
198  /* -- Read originalSize */
199  READ_UINT32( mpModuleInfoDesc, pModuleInfo->originalSize );
200  dsmDP3(("Compressed Module; original size = %u\n", pModuleInfo->originalSize));
201  }
202  /* -- Found the required info so quit the loop */
203  break;
204 
205  case DESCRIPTOR_MHP_CACHING_PRIORITY:
206  /* TS 101 812, section B.2.2.4.2 Caching priority descriptor */
207  READ_UINT8( mpModuleInfoDesc, pModuleInfo->u.mhgp.priority );
208  READ_UINT8( mpModuleInfoDesc, pModuleInfo->u.mhgp.transparency );
209  dsmDP3(("DESC MHP CACHE %u, %u", pModuleInfo->u.mhgp.priority, pModuleInfo->u.mhgp.transparency));
210  break;
211 
212  default:
213  ERRPRINT(" Module - Unknown descriptor tag: %x\n", descriptorTag)
214  /* -- Skip this module descriptor */
215  SET_POS_REL( mpModuleInfoDesc, (S32BIT)descriptorLength );
216  }
217  /* -- Find next (potential) descriptor start position */
218  GET_POS( mpModuleInfoDesc, currPos );
219  }
220  }
221 
222  }
223  }
224  }
225 
226  else if ( pModuleInfo->crslMagic == UC_MAGIC )
227  {
228  valid = TRUE;
229  READ_UINT8( mpModuleInfoDesc, infoLength );
230  if (infoLength != 0)
231  {
232  GET_POS( mpModuleInfoDesc, currPos );
233  endPos = currPos + infoLength;
234  while (currPos < endPos)
235  {
236  READ_UINT8( mpModuleInfoDesc, descriptorTag );
237  READ_UINT8( mpModuleInfoDesc, descriptorLength );
238  switch (descriptorTag)
239  {
240  case DESCRIPTOR_TYPE_TAG:
241  {
242  pModuleInfo->u.ssup.typeLen = descriptorLength;
243  pModuleInfo->u.ssup.mpType = mpModuleInfoDesc;
244  break;
245  }
246  case DESCRIPTOR_NAME_TAG:
247  {
248  pModuleInfo->u.ssup.nameLen = descriptorLength;
249  pModuleInfo->u.ssup.mpName = mpModuleInfoDesc;
250  break;
251  }
252  case DESCRIPTOR_INFO_TAG:
253  {
254  if (descriptorLength > 3)
255  {
256  READ_UINT24( mpModuleInfoDesc, pModuleInfo->u.ssup.infoLang );
257  pModuleInfo->u.ssup.infoLen = descriptorLength - 3;
258  pModuleInfo->u.ssup.mpInfo = mpModuleInfoDesc;
259  }
260  break;
261  }
262  case DESCRIPTOR_MODULE_LINK_TAG:
263  {
264  READ_UINT8( mpModuleInfoDesc, ui8 );
265  READ_UINT16( mpModuleInfoDesc, pModuleInfo->u.ssup.nextModuleId );
266  pModuleInfo->u.ssup.positionType = ui8 + 1; /* increment so know received desc */
267  DBG3(DD_DC,"mod=%x module_link pos=%d, nxt=%x",
268  pModuleInfo->moduleId, ui8, pModuleInfo->u.ssup.nextModuleId )
269  break;
270  }
271  case DESCRIPTOR_CRC32_TAG:
272  {
273  READ_UINT32( mpModuleInfoDesc, pModuleInfo->u.ssup.moduleCrc );
274  break;
275  }
276  case DESCRIPTOR_LOCATION_TAG:
277  {
278  READ_UINT8( mpModuleInfoDesc, ui8 );
279  pModuleInfo->associationTag = ui8;
280  break;
281  }
282  case DESCRIPTOR_EST_DOWNLOAD_TIME_TAG:
283  {
284  break;
285  }
286  case DESCRIPTOR_COMP_MODULE_TAG:
287  {
288  READ_UINT8( mpModuleInfoDesc, ui8 );
289  if ( (ui8 & 0x0f) != 0x08 )
290  {
291  dsmDP2(("DATA ERROR: Module info compressionMethod (!= 0x08) = %u\n", ui8));
292  }
293  else
294  {
295  /* -- Indicate module is compressed */
296  pModuleInfo->compressed = TRUE;
297  /* -- Read originalSize */
298  READ_UINT32( mpModuleInfoDesc, pModuleInfo->originalSize );
299  }
300  break;
301  }
302  case DESCRIPTOR_SSU_MODULE_TYPE_TAG:
303  {
304  READ_UINT8( mpModuleInfoDesc, pModuleInfo->u.ssup.moduleType );
305  break;
306  }
307  default:
308  {
309  DBG2(DD_DC,"Module - Unknown descriptor tag: %x", descriptorTag);
310  break;
311  }
312  }
313  SET_POS_ABS( mpModuleInfoDesc, currPos + 2 + descriptorLength );
314  GET_POS( mpModuleInfoDesc, currPos );
315  }
316  }
317  }
318 
319  else
320  {
321  ERRPRINT("Module Info magic unknown =%x\n",pModuleInfo->crslMagic)
322  valid = FALSE;
323  }
324  }
325  MEMPTR_CLOSE( mpModuleInfoDesc );
326  DEBUG_CHK( valid == TRUE,
327  dsmDP1(("ERROR: getpModuleInfo failure (invalid)\n")));
328 }
329 
330 
331 /*----------------------------------------------------------------------------*/
332 
333 
334