DVBCore  20.3.0
DVBCore Documentation
stbsitab.c
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  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 // gives direct COM port access
26 /* #define STB_DEBUG */
27 
28 // prints table requests
29 /* #define DEBUG_SI_PAT_REQUEST */
30 /* #define DEBUG_SI_PMT_REQUEST */
31 /* #define DEBUG_SI_NIT_REQUEST */
32 /* #define DEBUG_SI_SDT_REQUEST */
33 /* #define DEBUG_SI_BAT_REQUEST */
34 /* #define DEBUG_SI_EIT_REQUEST */
35 /* #define DEBUG_SI_TDT_REQUEST */
36 /* #define DEBUG_SI_TOT_REQUEST */
37 /* #define DEBUG_SI_CAT_REQUEST */
38 
39 // prints table parsing
40 /* #define DEBUG_SI_PAT_SUMMARY*/
41 /* #define DEBUG_SI_PMT_SUMMARY */
42 /* #define DEBUG_SI_NIT_SUMMARY */
43 /* #define DEBUG_SI_SDT_SUMMARY */
44 /* #define DEBUG_SI_BAT_SUMMARY */
45 /* #define DEBUG_SI_EIT_SUMMARY */
46 /* #define DEBUG_SI_TDT_TOT_SUMMARY */
47 /* #define DEBUG_SI_RCT_SUMMARY */
48 
49 /* #define DEBUG_SI_PAT_CONTENT */
50 /* #define DEBUG_SI_PMT_CONTENT */
51 /* #define DEBUG_SI_NIT_CONTENT */
52 /* #define DEBUG_SI_SDT_CONTENT */
53 /* #define DEBUG_SI_BAT_CONTENT */
54 /* #define DEBUG_SI_EIT_CONTENT */
55 /* #define DEBUG_SI_TDT_TOT_CONTENT */
56 /* #define DEBUG_SI_RCT_CONTENT */
57 
58 // prints descriptor parsing
59 /* #define DEBUG_AC3_DESC */
60 /* #define DEBUG_AAC_DESC */
61 /* #define DEBUG_APP_SIG_DESC*/
62 /* #define DEBUG_CA_DESC */
63 /* #define DEBUG_CA_ID_DESC */
64 /* #define DEBUG_CAROUSEL_ID_DESC */
65 /* #define DEBUG_CID_DESC */
66 /* #define DEBUG_COMPONENT_DESC */
67 /* #define DEBUG_CONTENT_DESC */
68 /* #define DEBUG_DEF_AUTH_DESC */
69 /* #define DEBUG_EXTENDED_EVENT_DESC */
70 /* #define DEBUG_FREQ_LIST_DESC */
71 /* #define DEBUG_FTA_CONTENT_DESC */
72 /* #define DEBUG_GUIDANCE_DESC */
73 /* #define DEBUG_IMAGE_ICON_DESC */
74 /* #define DEBUG_ISO_LANG_DESC */
75 /* #define DEBUG_LCN_DESC */
76 /* #define DEBUG_LINKAGE_DESC */
77 /* #define DEBUG_LOCAL_TIME_OFFSET_DESC */
78 /* #define DEBUG_MULTILING_COMPONENT_DESC */
79 /* #define DEBUG_MULTILING_NET_NAME_DESC */
80 /* #define DEBUG_MULTILING_SERV_NAME_DESC */
81 /* #define DEBUG_NET_NAME_DESC */
82 /* #define DEBUG_PARENTAL_RATING_DESC */
83 /* #define DEBUG_PREF_NAME_ID_DESC */
84 /* #define DEBUG_PREF_NAME_LIST_DESC */
85 /* #define DEBUG_PRIV_DATA_SPEC_DESC */
86 /* #define DEBUG_RCT_LINK_INFO */
87 /* #define DEBUG_SAT_DEL_SYS_DESC */
88 /* #define DEBUG_SERVICE_DESC */
89 /* #define DEBUG_SERVICE_MOVE_DESC*/
90 /* #define DEBUG_SERV_LIST_DESC */
91 /* #define DEBUG_SHORT_SERVICE_NAME */
92 /* #define DEBUG_SHORT_EVENT_DESC */
93 /* #define DEBUG_STREAM_ID_DESC */
94 /* #define DEBUG_SUBTITLE_DESC */
95 /* #define DEBUG_TELETEXT_DESC*/
96 /* #define DEBUG_TERR_DEL_SYS_DESC */
97 /* #define DEBUG_CABLE_DEL_SYS_DESC */
98 /* #define DEBUG_TARGET_REGION_DESC */
99 /* #define DEBUG_FREESAT_LCN_DESC */
100 /* #define DEBUG_FREESAT_LINKAGE_DESC */
101 /* #define DEBUG_FREESAT_TUNNELLED_DATA_DESC */
102 /* #define DEBUG_FREESAT_INFO_LOCATION_DESC */
103 /* #define DEBUG_FREESAT_GROUP_NAME_DESC */
104 /* #define DEBUG_FREESAT_PREFIX_DESC */
105 /* #define DEBUG_SUPP_AUDIO_DESC */
106 /* #define DEBUG_URI_LINKAGE_DESC */
107 /* #define DEBUG_NORDIG_CONTENT_PROTECTION_DESC */
108 
109 // includes dump of skipped descriptors if debug messages are turned on for the table
110 /* #define DEBUG_SKIPPED_DESC */
111 
112 
113 //---includes for this file----------------------------------------------------
114 // compiler library header files
115 
116 #include <stdio.h>
117 #include <string.h>
118 
119 // third party header files
120 
121 // Ocean Blue Software header files
122 
123 #include <techtype.h>
124 #include <dbgfuncs.h>
125 
126 #include "stbhwc.h"
127 #include "stbheap.h"
128 #include "stbuni.h"
129 
130 #include "stbsiflt.h"
131 #include "stbdpc.h"
132 #include "stbsitab.h"
133 
134 //---constant definitions for this file----------------------------------------
135 #ifdef STB_SI_PRINT_REQUIRED
136  #define STB_SI_PRINT(x) DEBUG_PRINTX_CONDITIONAL(DEBUG_STB_SI) x
137 #else
138  #ifdef STB_DEBUG
139  #define STB_SI_PRINT(x) STB_SPDebugWrite x
140  #else
141  #define STB_SI_PRINT(x)
142  #endif
143 #endif
144 
145 #ifdef DEBUG_SI_EIT_CONTENT
146  #define DEBUG_SI_EIT_CONTENT_VALUE TRUE
147 #else
148  #define DEBUG_SI_EIT_CONTENT_VALUE FALSE
149 #endif
150 
151 #ifdef DEBUG_SI_SDT_CONTENT
152  #define DEBUG_SI_SDT_CONTENT_VALUE TRUE
153 #else
154  #define DEBUG_SI_SDT_CONTENT_VALUE FALSE
155 #endif
156 
157 #ifdef DEBUG_SI_PMT_CONTENT
158  #define DEBUG_SI_PMT_CONTENT_VALUE TRUE
159 #else
160  #define DEBUG_SI_PMT_CONTENT_VALUE FALSE
161 #endif
162 
163 #ifdef DEBUG_SI_NIT_CONTENT
164  #define DEBUG_SI_NIT_CONTENT_VALUE TRUE
165 #else
166  #define DEBUG_SI_NIT_CONTENT_VALUE FALSE
167 #endif
168 
169 #ifdef DEBUG_SI_BAT_CONTENT
170  #define DEBUG_SI_BAT_CONTENT_VALUE TRUE
171 #else
172  #define DEBUG_SI_BAT_CONTENT_VALUE FALSE
173 #endif
174 
175 #ifdef DEBUG_RCT_LINK_INFO
176  #define DEBUG_RCT_LINK_INFO_VALUE TRUE
177 #else
178  #define DEBUG_RCT_LINK_INFO_VALUE FALSE
179 #endif
180 
181 #ifdef DEBUG_SI_RCT_CONTENT
182  #define DEBUG_SI_RCT_CONTENT_VALUE TRUE
183 #else
184  #define DEBUG_SI_RCT_CONTENT_VALUE FALSE
185 #endif
186 
187 #ifdef DEBUG_SI_TDT_TOT_CONTENT
188  #define DEBUG_SI_TDT_TOT_CONTENT_VALUE TRUE
189 #else
190  #define DEBUG_SI_TDT_TOT_CONTENT_VALUE FALSE
191 #endif
192 
193 #ifdef DEBUG_SERVICE_DESC
194  #define DEBUG_SERVICE_DESC_VALUE TRUE
195 #else
196  #define DEBUG_SERVICE_DESC_VALUE FALSE
197 #endif
198 
199 #ifdef DEBUG_SHORT_EVENT_DESC
200  #define DEBUG_SHORT_EVENT_DESC_VALUE TRUE
201 #else
202  #define DEBUG_SHORT_EVENT_DESC_VALUE FALSE
203 #endif
204 
205 #ifdef DEBUG_TERR_DEL_SYS_DESC
206  #define DEBUG_TERR_DEL_SYS_DESC_VALUE TRUE
207 #else
208  #define DEBUG_TERR_DEL_SYS_DESC_VALUE FALSE
209 #endif
210 
211 #ifdef DEBUG_SAT_DEL_SYS_DESC
212  #define DEBUG_SAT_DEL_SYS_DESC_VALUE TRUE
213 #else
214  #define DEBUG_SAT_DEL_SYS_DESC_VALUE FALSE
215 #endif
216 
217 #ifdef DEBUG_CABLE_DEL_SYS_DESC
218  #define DEBUG_CABLE_DEL_SYS_DESC_VALUE TRUE
219 #else
220  #define DEBUG_CABLE_DEL_SYS_DESC_VALUE FALSE
221 #endif
222 
223 // si table PIDs
224 #define SI_PAT_PID 0x0000
225 #define SI_CAT_PID 0x0001
226 #define SI_NIT_PID 0x0010
227 #define SI_SDT_PID 0x0011
228 #define SI_BAT_PID 0x0011
229 #define SI_EIT_PID 0x0012
230 #define SI_TDT_PID 0x0014
231 #define SI_TOT_PID 0x0014
232 
233 // si table IDs
234 #define SI_PAT_TID 0x00
235 #define SI_CAT_TID 0x01
236 #define SI_PMT_TID 0x02
237 #define SI_NIT_ACTUAL_TID 0x40
238 #define SI_NIT_OTHER_TID 0x41
239 #define SI_SDT_ACTUAL_TID 0x42
240 #define SI_SDT_OTHER_TID 0x46
241 #define SI_BAT_TID 0x4A
242 #define SI_EITPF_ACTUAL_TID 0x4E
243 #define SI_EITPF_OTHER_TID 0x4F
244 #define SI_EITSC_ACTUAL_TID 0x50 // range 0x50 to 0x5f
245 #define SI_EITSC_OTHER_TID 0x60 // range 0x60 to 0x6f
246 #define SI_TDT_TID 0x70
247 #define SI_TOT_TID 0x73
248 #define SI_AIT_TID 0x74
249 #define SI_RCT_TID 0x76
250 #define SI_EIT_PLUS_TID 0xD1
251 
252 
253 // si table descriptor tags...
254 // MPEG descriptors
255 #define CA_DTAG 0x09
256 #define ISO_LANG_DTAG 0x0a
257 #define CAROUSEL_ID_DTAG 0x13
258 
259 // DVB descriptors
260 #define PRIV_DATA_INDICATOR_DTAG 0x0f
261 #define NET_NAME_DTAG 0x40
262 #define SERV_LIST_DTAG 0x41
263 #define SAT_DEL_SYS_DTAG 0x43
264 #define CABLE_DEL_SYS_DTAG 0x44
265 #define SERVICE_DTAG 0x48
266 #define LINKAGE_DTAG 0x4a
267 #define SHORT_EVENT_DTAG 0x4d
268 #define EXTENDED_EVENT_DTAG 0x4e
269 #define COMPONENT_DTAG 0x50
270 #define STREAM_ID_DTAG 0x52
271 #define CA_ID_DTAG 0x53
272 #define CONTENT_DTAG 0x54
273 #define PARENTAL_RATING_DTAG 0x55
274 #define TELETEXT_DTAG 0x56
275 #define LOCAL_TIME_OFFSET_DTAG 0x58
276 #define SUBTITLE_DTAG 0x59
277 #define TERR_DEL_SYS_DTAG 0x5a
278 #define MULTILING_NET_NAME_DTAG 0x5b
279 #define MULTILING_SERV_NAME_DTAG 0x5d
280 #define MULTILING_COMPONENT_DTAG 0x5e
281 #define PRIV_DATA_SPEC_DTAG 0x5f
282 #define SERVICE_MOVE_DTAG 0x60
283 #define FREQ_LIST_DTAG 0x62
284 #define AC3_DTAG 0x6a
285 #define APP_SIG_DTAG 0x6f /* Application signalling descriptor tag value */
286 #define SERV_AVAIL_DESC_DTAG 0x72 /* Service Availability Descriptor */
287 #define DEF_AUTH_DTAG 0x73 /* Default authority descriptor tag value */
288 #define RELATED_CONTENT_DTAG 0x74 /* Related content descriptor tag value */
289 #define CONT_ID_DTAG 0x76 /* Content identifier descriptor tag value */
290 #define EAC3_DTAG 0x7a
291 #define AAC_DTAG 0x7c
292 #define FTA_CONTENT_DTAG 0x7e
293 #define EXT_DTAG 0x7f /* Extension descriptor */
294 
295 // User defined descriptors
296 #define USER_DEFINED_DTAG_0x83 0x83
297 #define USER_DEFINED_DTAG_0x84 0x84
298 #define USER_DEFINED_DTAG_0x85 0x85
299 #define USER_DEFINED_DTAG_0x86 0x86
300 #define USER_DEFINED_DTAG_0x87 0x87
301 #define USER_DEFINED_DTAG_0x88 0x88
302 #define USER_DEFINED_DTAG_0x89 0x89
303 #define USER_DEFINED_DTAG_0xA0 0xa0
304 
305 /* Satellite descriptor tag values */
306 #define BOUQUET_NAME_DTAG 0x47
307 #define LOGICAL_CHANNEL_DTAG 0x83
308 
309 /* CI+ descriptor tag values */
310 #define CIPLUS_SERVICE_DTAG 0xcc /* NIT 2nd*/
311 #define CIPLUS_PROTECTION_DTAG 0xce /* SDT */
312 #define CIPLUS_VIRTUAL_CHAN_DTAG 0xd2 /* NIT 1st */
313 
314 
315 /* Freesat specific descriptor tag values */
316 #define FREESAT_TUNNELLED_DTAG 0xd0 /* PMT 1st */
317 #define FREESAT_ALT_TUNNELLED_DTAG 0xd1 /* PMT 2nd */
318 #define FREESAT_LINK_DTAG 0xd2 /* NIT 1st */
319 #define FREESAT_REGION_LCN_DTAG 0xd3 /* BAT 2nd */
320 #define FREESAT_REGION_NAME_DTAG 0xd4 /* BAT 1st */
321 #define FREESAT_SERV_GROUP_DTAG 0xd5 /* BAT 1st */
322 #define FREESAT_IACTIVE_STORAGE_DTAG 0xd6 /* BAT 1st */
323 #define FREESAT_INFO_LOCATION_DTAG 0xd7 /* BAT 1st */
324 #define FREESAT_SERV_GROUP_NAME_DTAG 0xd8 /* BAT 1st */
325 #define FREESAT_SERV_NAME_DTAG 0xd9 /* SDT */
326 #define FREESAT_GUIDANCE_DTAG 0xda /* SDT, EIT */
327 #define FREESAT_IACTIVE_RESTRICT_DTAG 0xdb /* BAT 2nd */
328 #define FREESAT_CONTENT_MANAGE_DTAG 0xdc /* BAT 1st+2nd, SDT, EIT */
329 #define FREESAT_PREFIX_DTAG 0xdf /* NIT 1st, BAT 1st, SDT */
330 #define FREESAT_MEDIA_LOCATOR_DTAG 0xe0 /* BAT 1st, SDT, EIT */
331 
332 
333 /* Extension descriptor tag values */
334 #define IMAGE_ICON_DTAG 0x00
335 #define T2_DELIVERY_SYS_DTAG 0x04
336 #define SUPPLEMENTARY_AUDIO_DTAG 0x06
337 #define NETWORK_CHANGE_NOTIFY_DTAG 0x07
338 #define MESSAGE_DTAG 0x08
339 #define TARGET_REGION_DTAG 0x09
340 #define TARGET_REGION_NAME_DTAG 0x0a
341 #define URI_LINKAGE_DTAG 0x13
342 
343 
344 /* Private data specifier values - somewhat duplicated in country_data in ap_cfdat.h */
345 #define UK_DTT_PRIVATE_DATA_SPECIFIER 0x0000233a
346 #define CIPLUS_PRIVATE_DATA_SPECIFIER 0x00000040
347 #define FREESAT_PRIVATE_DATA_SPECIFIER 0x46534154
348 #define NORDIG_PRIVATE_DATA_SPECIFIER 0x00000029
349 #define EACEM_PRIVATE_DATA_SPECIFIER 0x00000028 /* E-Book */
350 #define NZ_DTT_PRIVATE_DATA_SPECIFIER 0x00000037 /* New Zealand Freeview DTT */
351 #define NZ_SAT_PRIVATE_DATA_SPECIFIER 0x00000029 /* New Zealand Freeview Satellite */
352 #define ZAF_DTT_PRIVATE_DATA_SPECIFIER 0x000022c6 /* South Africa (SABC) */
353 
354 /* Audio desc lang code */
355 #define LANG_CODE_NAR 0x6e6172
356 
357 
358 //---local typedef structs for this file---------------------------------------
359 
360 
361 //---local (static) variable declarations for this file------------------------
362 // (internal variables declared static to make them local)
363 
364 
365 static const U8BIT eit_tid_match[] =
366 {
367  SI_EITPF_ACTUAL_TID, // EIT_NOW_NEXT_ACT = 0,
368  SI_EITPF_OTHER_TID, // EIT_NOW_NEXT_OTHER = 1,
369  SI_EITPF_OTHER_TID, // EIT_NOW_NEXT_ALL = 2,
370  SI_EIT_PLUS_TID // EIT_PF_PLUS = 3
371 };
372 
373 static const U8BIT eit_tid_mask[] =
374 {
375  0xff, // EIT_NOW_NEXT_ACT = 0,
376  0xff, // EIT_NOW_NEXT_OTHER = 1,
377  (~(SI_EITPF_ACTUAL_TID ^ SI_EITPF_OTHER_TID) & 0xff), // EIT_NOW_NEXT_ALL = 2,
378  0Xff // SI_EITPF_PLUS_TID = 3
379 };
380 
381 static const U8BIT sched_tid_match[] =
382 {
383  SI_EITSC_ACTUAL_TID, // EIT_SCHED_ACT = 0,
384  SI_EITSC_OTHER_TID, // EIT_SCHED_OTHER = 1,
385  SI_EITSC_ACTUAL_TID, // EIT_SCHED_ACT_4DAY = 2,
386  SI_EITSC_OTHER_TID, // EIT_SCHED_OTHER_4DAY = 3,
387  (SI_EITSC_ACTUAL_TID | SI_EITSC_OTHER_TID), // EIT_SCHED_ALL_4DAY = 4,
388  (SI_EITSC_ACTUAL_TID | SI_EITSC_OTHER_TID), // EIT_SCHED_ALL_8DAY = 5,
389  (SI_EITSC_ACTUAL_TID | SI_EITSC_OTHER_TID) // EIT_SCHED_ALL = 6
390 };
391 
392 static const U8BIT sched_tid_mask[] =
393 {
394  0xf0, // EIT_SCHED_ACT = 0,
395  0xf0, // EIT_SCHED_OTHER = 1,
396  0xff, // EIT_SCHED_ACT_4DAY = 2,
397  0xff, // EIT_SCHED_OTHER_4DAY = 3,
398  (~(SI_EITSC_ACTUAL_TID ^ SI_EITSC_OTHER_TID) & 0xff), // EIT_SCHED_ALL_4DAY = 4,
399  (~(SI_EITSC_ACTUAL_TID ^ SI_EITSC_OTHER_TID) & 0xfe), // EIT_SCHED_ALL_8DAY = 5,
400  (~(SI_EITSC_ACTUAL_TID ^ SI_EITSC_OTHER_TID) & 0xf0) // EIT_SCHED_ALL = 6
401 };
402 
403 
404 //---local function prototypes for this file-----------------------------------
405 // (internal functions declared static to make them local)
406 
407 static STB_SI_USER_DEF_DESCRIP_FUNCTION GetUserDefinedDescriptorFunction(U8BIT dtag);
408 
409 static U8BIT* ReadLanguageCode(U8BIT *dptr, U32BIT *code_ptr);
410 static U8BIT* SkipDescriptor(U8BIT *dptr, U8BIT dtag, BOOLEAN db_print);
411 
412 static U8BIT* ParseAACDescriptor(U8BIT *dptr, SI_AAC_DESC **desc_ptr, BOOLEAN db_print);
413 static U8BIT* ParseAC3Descriptor(U8BIT *dptr, U8BIT dtag, SI_AC3_DESC **desc_ptr, BOOLEAN db_print);
414 static U8BIT* ParseAppSignallingDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_APP_SIG_DESC **array_ptr,
415  BOOLEAN db_print);
416 static U8BIT* ParseCaDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_CA_DESC **array_ptr, BOOLEAN db_print);
417 static U8BIT* ParseCaIdentifierDescriptor(U8BIT *dptr, U8BIT *num_ptr, U16BIT **array_ptr, BOOLEAN db_print);
418 static U8BIT* ParseCarouselIdDescriptor(U8BIT *dptr, U32BIT *carousel_id, BOOLEAN db_print);
419 static U8BIT* ParseComponentDescriptor(U8BIT *dptr, U8BIT *num_ptr, SI_COMPONENT_DESC **array_ptr,
420  BOOLEAN db_print);
421 static U8BIT* ParseContentDescriptor(U8BIT *dptr, U8BIT *num_ptr, SI_CONTENT_DESC **array_ptr, BOOLEAN db_print);
422 static U8BIT* ParseFrequencyListDescriptor(U8BIT *dptr, SI_NIT_FREQUENCY_LIST_DESC **freq_list, BOOLEAN db_print);
423 static U8BIT* ParseFTAContentDescriptor(U8BIT *dptr, SI_FTA_CONTENT_DESC **desc_ptr, BOOLEAN db_print);
424 static U8BIT* ParseGuidanceDescriptor(U8BIT *dptr, SI_GUIDANCE_DESC **desc_ptr, BOOLEAN db_print);
425 static U8BIT* ParseIsoLangDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_ISO_LANG_DESC **array_ptr, BOOLEAN db_print);
426 static U8BIT* ParseLocalTimeOffsetDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_LTO_DESC **array_ptr,
427  BOOLEAN db_print);
428 static U8BIT* ParseMultilingComponentDescriptor(U8BIT *dptr, U8BIT *num_ptr,
429  SI_MULTILING_COMPONENT_DESC **array_ptr, BOOLEAN db_print);
430 static U8BIT* ParseMultilingNetNameDescriptor(U8BIT *dptr, U16BIT *num_ptr,
431  SI_MULTILING_NET_NAME_DESC **array_ptr, BOOLEAN db_print);
432 static U8BIT* ParseMultilingServNameDescriptor(U8BIT *dptr, U16BIT *num_ptr,
433  SI_MULTILING_SERV_NAME_DESC **array_ptr, BOOLEAN db_print);
434 static U8BIT* ParseParentalRatingDescriptor(U8BIT *dptr, U8BIT *num_ptr,
435  SI_PARENTAL_RATING_DESC **array_ptr, BOOLEAN db_print);
436 static U8BIT* ParseServiceListDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_SERV_LIST_DESC **array_ptr,
437  BOOLEAN db_print);
438 static U8BIT* ParseShortServiceNameDescriptor(U8BIT *dptr, SI_STRING_DESC **name_ptr, BOOLEAN db_print);
439 static U8BIT* ParseShortEventDescriptor(U8BIT *dptr, U8BIT *num_ptr, SI_SHORT_EVENT_DESC **array_ptr,
440  BOOLEAN db_print);
441 static U8BIT* ParseExtendedEventDescriptor(U8BIT *dptr, U8BIT *num_ptr,
442  SI_EXTENDED_EVENT_DESC **array_ptr, BOOLEAN db_print);
443 static U8BIT* ParseSubtitleDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_SUBTITLE_DESC **array_ptr,
444  BOOLEAN db_print);
445 static U8BIT* ParseTeletextDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_TELETEXT_DESC **array_ptr,
446  BOOLEAN db_print);
447 static U8BIT* ParseLogicalChannelDescriptor(U8BIT *dptr, U8BIT dtag, U16BIT *num_ptr,
448  SI_LCN_DESC **array_ptr, BOOLEAN db_print);
449 static U8BIT* ParseServiceAttributeDescriptor(U8BIT *dptr, U16BIT *num_ptr,
450  SI_SERV_ATTRIBUTE_DESC **array_ptr, BOOLEAN db_print);
451 static U8BIT* ParseNordigLCN2Descriptor(U8BIT *dptr, U16BIT *num_ptr, SI_NORDIG_LCN_DESC **array_ptr,
452  BOOLEAN db_print);
453 static U8BIT* ParsePreferredNameListDescriptor(U8BIT *dptr, U16BIT *num_ptr,
454  SI_PREFERRED_NAME_DESC **array_ptr, BOOLEAN db_print);
455 
456 static U8BIT* ParseLinkageDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_LINKAGE_DESC_ENTRY **list_ptr,
457  SI_LINKAGE_DESC_ENTRY **last_entry_ptr, U32BIT private_data_code, BOOLEAN db_print);
458 
459 static U8BIT* ParseNetNameDescriptor(U8BIT *dptr, SI_STRING_DESC **name_ptr, BOOLEAN db_print);
460 static U8BIT* ParsePrivateDataSpecifierDescriptor(U8BIT *dptr, U32BIT *code_ptr, BOOLEAN db_print);
461 static U8BIT* ParseServiceDescriptor(U8BIT *dptr, U8BIT *type_ptr, SI_STRING_DESC **provider_ptr,
462  SI_STRING_DESC **name_ptr, BOOLEAN db_print);
463 static U8BIT* ParseStreamIdDescriptor(U8BIT *dptr, U8BIT **tag_array_ptr, U8BIT *num_entries_ptr, BOOLEAN db_print);
464 static U8BIT* ParseTerrestrialDeliverySysDescriptor(U8BIT *dptr, SI_DELIVERY_SYS_DESC **desc_ptr,
465  BOOLEAN db_print);
466 static U8BIT* ParseT2DeliverySysDescriptor(U8BIT *dptr, SI_DELIVERY_SYS_DESC **desc_ptr, BOOLEAN db_print);
467 static U8BIT* ParseSatelliteDeliverySysDescriptor(U8BIT *dptr, SI_DELIVERY_SYS_DESC **desc_ptr, BOOLEAN db_print);
468 static U8BIT* ParseFreesatLinkageDescriptor(U8BIT *dptr, SI_FREESAT_LINKAGE_DESC **desc, BOOLEAN db_print);
469 static U8BIT* ParseFreesatPrefixDescriptor(U8BIT *dptr, SI_FREESAT_PREFIX_DESC **list, BOOLEAN db_print);
470 static U8BIT* ParsePreferredNameIdDescriptor(U8BIT *dptr, U8BIT *id_ptr, BOOLEAN db_print);
471 
472 static U8BIT* ParseDefaultAuthorityDescriptor(U8BIT *dptr, SI_STRING_DESC **authority_ptr, BOOLEAN db_print);
473 static U8BIT* ParseContentIdentifierDescriptor(U8BIT *dptr, U8BIT *num_ptr, SI_CRID_DESC **list_ptr,
474  SI_CRID_DESC **last_entry_ptr, BOOLEAN db_print);
475 static U8BIT* ParseNetworkChangeNotifyDescriptor(U8BIT *dptr, U16BIT *num_change_notifies,
476  SI_NIT_CHANGE_NOTIFY_DESC **desc_ptr,
477  BOOLEAN db_print);
478 static U8BIT* ParseMessageDescriptor(U8BIT *dptr, U16BIT *num_messages,
479  SI_NIT_MESSAGE_ENTRY **message_array, BOOLEAN db_print);
480 static U8BIT* ParseTargetRegionNameDescriptor(U8BIT *dptr, SI_NIT_TARGET_REGION_NAME_DESC **desc_list,
481  BOOLEAN db_print);
482 static U8BIT* ParseTargetRegionDescriptor(U8BIT *dptr, SI_TARGET_REGION_DESC **desc_list,
483  BOOLEAN db_print);
484 static U8BIT* ParseSupplementaryAudioDescriptor(U8BIT *dptr, SI_AD_DESC **audio_desc, BOOLEAN db_print);
485 static U8BIT* ParseRctLinkInfo(U8BIT *dptr, SI_RCT_LINK_INFO *link_info, BOOLEAN db_print);
486 static U8BIT* ParseImageIconDesc(U8BIT *dptr, U8BIT *num_icons, SI_IMAGE_ICON_DESC **icon_array, BOOLEAN db_print);
487 static U8BIT* ParseURILinkageDesc(U8BIT *dptr, SI_URI_LINKAGE_DESC **desc_list, U32BIT private_data_code,
488  BOOLEAN db_print);
489 static U8BIT* ParseNordigContentProtectionDesc(U8BIT *dptr, U8BIT *protection_level, BOOLEAN db_print);
490 #if 0
491 static U8BIT* ParseServiceMoveDescriptor(U8BIT *dptr, SI_SERVICE_MOVE_DESC **desc_ptr, BOOLEAN db_print);
492 #endif
493 
494 static U8BIT* ParseFreesatTunnelledDataDescriptor(U8BIT *dptr, U8BIT *num_entries,
495  SI_FREESAT_TUNNELLED_DATA_DESC **desc_array, BOOLEAN alt_descriptor, BOOLEAN db_print);
496 static U8BIT* ParseFreesatServiceGroupNameDescriptor(U8BIT *dptr,
497  SI_BAT_FREESAT_GROUP_NAME_ENTRY **name_list, BOOLEAN db_print);
498 static U8BIT* ParseFreesatServiceGroupDescriptor(U8BIT *dptr, SI_BAT_FREESAT_SERV_GROUP_ENTRY **serv_array,
499  U16BIT *num_entries, BOOLEAN db_print);
500 
501 static U8BIT* ParseFreesatInteractiveRestrictionDescriptor(U8BIT *dptr, U16BIT **int_res_array, U8BIT *num_entries, BOOLEAN db_print);
502 
503 static U8BIT* ParseFreesatShortServiceNameDescriptor(U8BIT *dptr, U16BIT *num_ptr,
504  SI_MULTILING_SHORT_NAME_DESC **array_ptr, BOOLEAN db_print);
505 
506 static U8BIT* ParseRegionNameDescriptor(U8BIT *dptr, SI_BAT_FREESAT_REGION **region_list, BOOLEAN db_print);
507 static U8BIT* ParseIActiveStorageDescriptor(U8BIT *dptr,
508  SI_BAT_FREESAT_IACTIVE_STORAGE_DESC **desc_list, BOOLEAN db_print);
509 static U8BIT* ParseFreesatInfoLocationDescriptor(U8BIT *dptr,
510  SI_BAT_FREESAT_INFO_LOCATION **location_list, BOOLEAN db_print);
511 
512 static U8BIT* SaveCIProtectionDescriptor(U8BIT *dptr, U8BIT **desc, BOOLEAN db_print);
513 static U8BIT* ParseCIPlusServiceDescriptor(U8BIT *dptr, U16BIT *num_services,
514  SI_CIPLUS_SERVICE **service_list, SI_CIPLUS_SERVICE **last_service, BOOLEAN db_print);
515 
516 static float BCDToFloat(U8BIT *data_ptr, U8BIT len, U8BIT point);
517 
518 
519 //--- structures, variables etc associated with the control of private data-------------------------
520 static U32BIT country_private_data_specifier_code = 0;
521 static BOOLEAN freesat_private_data_specifier = FALSE;
522 static BOOLEAN ciplus_private_data_specifier = FALSE;
523 static BOOLEAN eacem_private_data_specifier = FALSE;
524 static BOOLEAN nzsat_private_data_specifier = FALSE;
525 static BOOLEAN nordig_private_data_specifier = FALSE;
526 
527 
528 // not everybody uses private data specifiers - some want the user defined descriptors but don't
529 // send private data specifiers. So individual user-defined descriptors can be enabled by the
530 // application using STB_SISetUserDefinedDescriptor().
531 #define FIRST_USER_DEFINED_DTAG 0x80
532 #define LAST_USER_DEFINED_DTAG 0xfe
533 #define NUM_USER_DEFINED_DTAGS (LAST_USER_DEFINED_DTAG - FIRST_USER_DEFINED_DTAG + 1)
534 static STB_SI_USER_DEF_DESCRIP_FUNCTION user_defined_dtag_function[NUM_USER_DEFINED_DTAGS];
535 
536 
537 //---local function definitions------------------------------------------------
538 
539 
540 
541 //--------------------------------------------------------------------------------------------------
542 // Descriptor handling functions
543 //--------------------------------------------------------------------------------------------------
544 
557 static STB_SI_USER_DEF_DESCRIP_FUNCTION GetUserDefinedDescriptorFunction(U8BIT dtag)
558 {
559  STB_SI_USER_DEF_DESCRIP_FUNCTION retval;
560 
561  FUNCTION_START(GetUserDefinedDescriptorFunction);
562  retval = FALSE;
563  if ((FIRST_USER_DEFINED_DTAG <= dtag) && (dtag <= LAST_USER_DEFINED_DTAG))
564  {
565  retval = user_defined_dtag_function[dtag - FIRST_USER_DEFINED_DTAG];
566  }
567  FUNCTION_FINISH(GetUserDefinedDescriptorFunction);
568  return(retval);
569 }
570 
583 static U8BIT* ReadLanguageCode(U8BIT *dptr, U32BIT *code_ptr)
584 {
585  U32BIT lcode;
586  U8BIT i;
587  U8BIT code_char;
588 
589  FUNCTION_START(ReadLanguageCode);
590 
591  lcode = 0;
592  for (i = 0; i < 3; i++)
593  {
594  code_char = *dptr;
595  dptr++;
596  if ((code_char >= 'A') && (code_char <= 'Z'))
597  {
598  code_char += 0x20; // convert to lower case
599  }
600  lcode = (lcode << 8) | code_char;
601  }
602  *code_ptr = lcode;
603  FUNCTION_FINISH(ReadLanguageCode);
604  return(dptr);
605 }
606 
620 static U8BIT* SkipDescriptor(U8BIT *dptr, U8BIT dtag, BOOLEAN db_print)
621 {
622  U8BIT dlen;
623  U8BIT *end_ptr;
624 
625  FUNCTION_START(SkipDescriptor);
626 
627 #ifndef DEBUG_SKIPPED_DESC
628  USE_UNWANTED_PARAM(dtag);
629  USE_UNWANTED_PARAM(db_print);
630 #endif
631 
632  dlen = *dptr;
633  dptr++;
634  end_ptr = dptr + dlen;
635 
636  #ifdef DEBUG_SKIPPED_DESC
637  {
638  U16BIT i;
639  U8BIT j;
640  U8BIT msg_buff[54];
641  U8BIT *msg_ptr;
642 
643  if (db_print == TRUE)
644  {
645  STB_SI_PRINT((" dtag=0x%02x, len=%d", dtag, dlen));
646  msg_buff[0] = ' ';
647  msg_buff[1] = ' ';
648  msg_buff[2] = ' ';
649  msg_ptr = &msg_buff[3];
650  i = 0;
651  while (i < dlen)
652  {
653  j = 0;
654  while ((j < 16) && (i < dlen))
655  {
656  sprintf((char *)msg_ptr, " %02x", *dptr);
657  dptr++;
658  i++;
659  j++;
660  msg_ptr += 3;
661  }
662  *msg_ptr = '\0';
663  STB_SI_PRINT(("%s", msg_buff));
664  msg_ptr = &msg_buff[3];
665  }
666  }
667  }
668  #endif
669 
670  FUNCTION_FINISH(SkipDescriptor);
671  return(end_ptr);
672 }
673 
674 /*!**************************************************************************
675  * @brief Reads the AAC descriptor, of which only one can be present in an AAC/HE-AAC stream
676  * @param dptr - pointer to length byte of descriptor
677  * @param desc_ptr - pointer for returned descriptor
678  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
679  * @return Updated value of current data byte address i.e. at end of descriptor
680  ****************************************************************************/
681 static U8BIT* ParseAACDescriptor(U8BIT *dptr, SI_AAC_DESC **desc_ptr, BOOLEAN db_print)
682 {
683  U8BIT dlen;
684  U8BIT *end_ptr;
685 
686  FUNCTION_START(ParseAACDescriptor);
687 
688  dlen = *dptr;
689  dptr++;
690  end_ptr = dptr + dlen;
691 
692 #ifdef DEBUG_AAC_DESC
693  if (db_print == TRUE)
694  {
695  STB_SI_PRINT((" AAC desc: (%d bytes)", dlen));
696  }
697 #else
698  USE_UNWANTED_PARAM(db_print);
699 #endif
700 
701  /* There should be only one AAC descriptor in a PMT
702  * so skip this one if it already exists */
703  if (*desc_ptr == NULL)
704  {
705  *desc_ptr = (SI_AAC_DESC *)STB_GetMemory(sizeof(SI_AAC_DESC));
706  if (*desc_ptr != NULL)
707  {
708  /* Profile and level */
709  (*desc_ptr)->profile_level = *dptr;
710  dptr++;
711 
712  if ((dlen > 1) && ((*dptr & 0x80) != 0))
713  {
714  /* Component type */
715  (*desc_ptr)->type_present = TRUE;
716  dptr++;
717  (*desc_ptr)->aac_type = *dptr;
718 #ifdef DEBUG_AAC_DESC
719  if (db_print == TRUE)
720  {
721  STB_SI_PRINT((" profile=0x%02x, type=0x%02x", (*desc_ptr)->profile_level,
722  (*desc_ptr)->aac_type));
723  }
724 #endif
725  }
726  else
727  {
728  (*desc_ptr)->type_present = FALSE;
729 #ifdef DEBUG_AAC_DESC
730  if (db_print == TRUE)
731  {
732  STB_SI_PRINT((" profile=0x%02x", (*desc_ptr)->profile_level));
733  }
734 #endif
735  }
736  }
737  }
738 
739  FUNCTION_FINISH(ParseAACDescriptor);
740  return(end_ptr);
741 }
742 
758 static U8BIT* ParseAC3Descriptor(U8BIT *dptr, U8BIT dtag, SI_AC3_DESC **desc_ptr, BOOLEAN db_print)
759 {
760  U8BIT dlen;
761  U8BIT *end_ptr;
762 
763  FUNCTION_START(ParseAC3Descriptor);
764 
765  dlen = *dptr;
766  dptr++;
767  end_ptr = dptr + dlen;
768 
769 #ifdef DEBUG_AC3_DESC
770  if (db_print)
771  {
772  if (dtag == AC3_DTAG)
773  {
774  STB_SI_PRINT((" AC-3 desc: (%u bytes)", dlen));
775  }
776  else if (dtag == EAC3_DTAG)
777  {
778  STB_SI_PRINT((" E-AC-3 desc: (%u bytes)", dlen));
779  }
780  else
781  {
782  STB_SI_PRINT((" AC-3 desc: (%u bytes) descriptor_tag=0x%02x", dlen, dtag));
783  }
784  }
785 #else
786  USE_UNWANTED_PARAM(db_print);
787 #endif
788 
789  /* There should be only one AC-3 or E-AC3 descriptor in a PMT
790  * so skip this one if it already exists */
791  if ((*desc_ptr == NULL) && (dlen >= 1))
792  {
793  dptr++;
794 
795  *desc_ptr = (SI_AC3_DESC *)STB_GetMemory(sizeof(SI_AC3_DESC));
796  if (*desc_ptr != NULL)
797  {
798  memset(*desc_ptr, 0, sizeof(SI_AC3_DESC));
799 
800  /* Store the descriptor_tag as a means of differentiating between AC-3 and E-AC3 */
801  (*desc_ptr)->dtag = dtag;
802 
803  if ((*dptr & 0x80) != 0)
804  {
805  (*desc_ptr)->component_type_flag = TRUE;
806  }
807 
808  if ((*dptr & 0x40) != 0)
809  {
810  (*desc_ptr)->bsid_flag = TRUE;
811  }
812 
813  if ((*dptr & 0x20) != 0)
814  {
815  (*desc_ptr)->mainid_flag = TRUE;
816  }
817 
818  if ((*dptr & 0x10) != 0)
819  {
820  (*desc_ptr)->asvc_flag = TRUE;
821  }
822 
823  if (dtag == EAC3_DTAG)
824  {
825  if ((*dptr & 0x08) != 0)
826  {
827  (*desc_ptr)->mixinfoexists = TRUE;
828  }
829 
830  if ((*dptr & 0x04) != 0)
831  {
832  (*desc_ptr)->substream1_flag = TRUE;
833  }
834 
835  if ((*dptr & 0x02) != 0)
836  {
837  (*desc_ptr)->substream2_flag = TRUE;
838  }
839 
840  if ((*dptr & 0x01) != 0)
841  {
842  (*desc_ptr)->substream3_flag = TRUE;
843  }
844  }
845 
846  dptr++;
847 
848  if ((*desc_ptr)->component_type_flag)
849  {
850  (*desc_ptr)->component_type = *dptr;
851 #ifdef DEBUG_AC3_DESC
852  if (db_print)
853  {
854  STB_SI_PRINT((" component_type=0x%02x", (*desc_ptr)->component_type));
855  }
856 #endif
857  dptr++;
858  }
859 
860  if ((*desc_ptr)->bsid_flag)
861  {
862  (*desc_ptr)->bsid = *dptr;
863 #ifdef DEBUG_AC3_DESC
864  if (db_print)
865  {
866  STB_SI_PRINT((" bsid=0x%02x", (*desc_ptr)->bsid));
867  }
868 #endif
869  dptr++;
870  }
871 
872  if ((*desc_ptr)->mainid_flag)
873  {
874  (*desc_ptr)->mainid = *dptr;
875 #ifdef DEBUG_AC3_DESC
876  if (db_print)
877  {
878  STB_SI_PRINT((" mainid=0x%02x", (*desc_ptr)->mainid));
879  }
880 #endif
881  dptr++;
882  }
883 
884  if ((*desc_ptr)->asvc_flag)
885  {
886  (*desc_ptr)->asvc = *dptr;
887 #ifdef DEBUG_AC3_DESC
888  if (db_print)
889  {
890  STB_SI_PRINT((" asvc=0x%02x", (*desc_ptr)->asvc));
891  }
892 #endif
893  dptr++;
894  }
895 
896  if ((*desc_ptr)->substream1_flag)
897  {
898  (*desc_ptr)->substream1 = *dptr;
899 #ifdef DEBUG_AC3_DESC
900  if (db_print)
901  {
902  STB_SI_PRINT((" substream1=0x%02x", (*desc_ptr)->substream1));
903  }
904 #endif
905  dptr++;
906  }
907 
908  if ((*desc_ptr)->substream2_flag)
909  {
910  (*desc_ptr)->substream2 = *dptr;
911 #ifdef DEBUG_AC3_DESC
912  if (db_print)
913  {
914  STB_SI_PRINT((" substream2=0x%02x", (*desc_ptr)->substream2));
915  }
916 #endif
917  dptr++;
918  }
919 
920  if ((*desc_ptr)->substream3_flag)
921  {
922  (*desc_ptr)->substream3 = *dptr;
923 #ifdef DEBUG_AC3_DESC
924  if (db_print)
925  {
926  STB_SI_PRINT((" substream3=0x%02x", (*desc_ptr)->substream3));
927  }
928 #endif
929  }
930  }
931  }
932 
933  FUNCTION_FINISH(ParseAC3Descriptor);
934  return(end_ptr);
935 }
936 
951 static U8BIT* ParseAppSignallingDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_APP_SIG_DESC **array_ptr, BOOLEAN db_print)
952 {
953  U8BIT dlen;
954  U8BIT *end_ptr;
955  U16BIT num_entries;
956  SI_APP_SIG_DESC *array;
957  U16BIT app_type;
958  U8BIT ait_version;
959 
960  FUNCTION_START(ParseAppSignallingDescriptor);
961 
962  ASSERT(dptr != NULL);
963  ASSERT(num_ptr != NULL);
964  ASSERT(array_ptr != NULL);
965 
966  dlen = *dptr;
967  dptr++;
968  end_ptr = dptr + dlen;
969 
970 #ifdef DEBUG_APP_SIG_DESC
971  if (db_print)
972  {
973  STB_SI_PRINT((" App sig desc: (%d bytes)", dlen));
974  }
975 #else
976  USE_UNWANTED_PARAM(db_print);
977 #endif
978 
979  while (dlen >= 3)
980  {
981  app_type = ((dptr[0] & 0x7f) << 8) + dptr[1];
982  ait_version = dptr[2] & 0x1f;
983 
984 #ifdef DEBUG_APP_SIG_DESC
985  if (db_print)
986  {
987  STB_SI_PRINT((" app_type=0x%02x, ait_version=%u", app_type, ait_version));
988  }
989 #endif
990 
991  if (*array_ptr == NULL)
992  {
993  /* No entries already - create new array */
994  num_entries = 1;
995  array = (SI_APP_SIG_DESC *)STB_GetMemory(sizeof(SI_APP_SIG_DESC));
996  }
997  else
998  {
999  /* Already got entries - make array bigger */
1000  num_entries = *num_ptr + 1;
1001  array = (SI_APP_SIG_DESC *)STB_GetMemory(num_entries * sizeof(SI_APP_SIG_DESC));
1002  if (array != NULL)
1003  {
1004  /* Copy over previous entries and free old array */
1005  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_APP_SIG_DESC)));
1006  STB_FreeMemory(*array_ptr);
1007  }
1008  }
1009 
1010  /* Add new entry to array */
1011  if (array != NULL)
1012  {
1013  array[num_entries - 1].app_type = app_type;
1014  array[num_entries - 1].ait_version = ait_version;
1015  *array_ptr = array;
1016  *num_ptr = num_entries;
1017  }
1018  else
1019  {
1020 #ifdef DEBUG_APP_SIG_DESC
1021  if (db_print == TRUE)
1022  {
1023  STB_SI_PRINT(("CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
1024  }
1025 #endif
1026  }
1027 
1028  dlen -= 3;
1029  dptr += 3;
1030  }
1031 
1032  FUNCTION_FINISH(ParseAppSignallingDescriptor);
1033 
1034  return(end_ptr);
1035 }
1036 
1052 static U8BIT* ParseCaDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_CA_DESC **array_ptr,
1053  BOOLEAN db_print)
1054 {
1055  U8BIT dlen;
1056  U8BIT *end_ptr;
1057  U16BIT num_entries;
1058  SI_CA_DESC *array;
1059  U16BIT ca_id;
1060  U16BIT ca_pid;
1061 
1062  FUNCTION_START(ParseCaDescriptor);
1063 
1064  ASSERT(dptr != NULL);
1065  ASSERT(num_ptr != NULL);
1066  ASSERT(array_ptr != NULL);
1067 
1068  dlen = *dptr;
1069  dptr++;
1070  end_ptr = dptr + dlen;
1071 
1072  if (dlen >= 4)
1073  {
1074  ca_id = (dptr[0] << 8) | dptr[1];
1075  ca_pid = ((dptr[2] & 0x1f) << 8) | dptr[3];
1076  #ifdef DEBUG_CA_DESC
1077  if (db_print == TRUE)
1078  {
1079  STB_SI_PRINT((" CA desc: (%d bytes) id=0x%04x, pid=0x%04x", dlen, ca_id, ca_pid));
1080  }
1081  #else
1082  USE_UNWANTED_PARAM(db_print);
1083  #endif
1084 
1085  // check if there are already entries in the array (i.e. already received a descriptor)
1086  // if so add to the existing array, otherwise create new array
1087  if (*array_ptr == NULL)
1088  {
1089  // no entries already - create new array
1090  num_entries = 1;
1091  array = (SI_CA_DESC *)STB_GetMemory(sizeof(SI_CA_DESC));
1092  }
1093  else
1094  {
1095  // already got entries - make array bigger
1096  num_entries = *num_ptr + 1;
1097  array = (SI_CA_DESC *)STB_GetMemory(num_entries * sizeof(SI_CA_DESC));
1098  if (array != NULL)
1099  {
1100  // copy over previous entries and free old array
1101  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_CA_DESC)));
1102  STB_FreeMemory(*array_ptr);
1103  }
1104  }
1105 
1106  // add new entry to array
1107  if (array != NULL)
1108  {
1109  array[num_entries - 1].ca_id = ca_id;
1110  array[num_entries - 1].ca_pid = ca_pid;
1111  *array_ptr = array;
1112  *num_ptr = num_entries;
1113  }
1114  else
1115  {
1116  #ifdef DEBUG_CA_DESC
1117  if (db_print == TRUE)
1118  {
1119  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
1120  }
1121  #endif
1122  }
1123  }
1124  else
1125  {
1126  #ifdef DEBUG_CA_DESC
1127  if (db_print == TRUE)
1128  {
1129  STB_SI_PRINT((" Invalid CA desc: (%d bytes)", dlen));
1130  }
1131  #endif
1132  }
1133 
1134  FUNCTION_FINISH(ParseCaDescriptor);
1135  return(end_ptr);
1136 }
1137 
1152 static U8BIT* ParseCaIdentifierDescriptor(U8BIT *dptr, U8BIT *num_ptr, U16BIT **array_ptr, BOOLEAN db_print)
1153 {
1154  U8BIT dlen;
1155  U8BIT *end_ptr;
1156  U8BIT num_entries;
1157  U16BIT *array;
1158  U16BIT i;
1159 
1160  FUNCTION_START(ParseCaIdentifierDescriptor);
1161 
1162  ASSERT(dptr != NULL);
1163  ASSERT(num_ptr != NULL);
1164  ASSERT(array_ptr != NULL);
1165 
1166  dlen = *dptr;
1167  dptr++;
1168  end_ptr = dptr + dlen;
1169 
1170  if (dlen >= 2)
1171  {
1172  num_entries = dlen / 2; // each entry in the descriptor is 2 bytes long
1173  #ifdef DEBUG_CA_ID_DESC
1174  if (db_print == TRUE)
1175  {
1176  STB_SI_PRINT((" CA identifier desc: %d entries", num_entries));
1177  }
1178  #else
1179  USE_UNWANTED_PARAM(db_print);
1180  #endif
1181 
1182  // check if there are already entries in the array (i.e. already received a descriptor)
1183  // if so add to the existing array, otherwise create new array
1184  if (*array_ptr == NULL)
1185  {
1186  // no entries already - create new array
1187  array = (U16BIT *)STB_GetMemory(num_entries * sizeof(U16BIT));
1188  }
1189  else
1190  {
1191  // already got entries - make array bigger
1192  num_entries += *num_ptr;
1193  array = (U16BIT *)STB_GetMemory(num_entries * sizeof(U16BIT));
1194  if (array != NULL)
1195  {
1196  // copy over previous entries and free old array
1197  memcpy(array, *array_ptr, (*num_ptr * sizeof(U16BIT)));
1198  STB_FreeMemory(*array_ptr);
1199  }
1200  }
1201 
1202  // add new entries to array
1203  if (array != NULL)
1204  {
1205  for (i = *num_ptr; i < num_entries; i++)
1206  {
1207  array[i] = (dptr[0] << 8) | dptr[1];
1208  dptr += 2;
1209  #ifdef DEBUG_CA_ID_DESC
1210  if (db_print == TRUE)
1211  {
1212  STB_SI_PRINT((" id=0x%04x", array[i]));
1213  }
1214  #endif
1215  }
1216  *array_ptr = array;
1217  *num_ptr = num_entries;
1218  }
1219  else
1220  {
1221  #ifdef DEBUG_CA_ID_DESC
1222  if (db_print == TRUE)
1223  {
1224  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
1225  }
1226  #endif
1227  }
1228  }
1229  else
1230  {
1231  #ifdef DEBUG_CA_ID_DESC
1232  if (db_print == TRUE)
1233  {
1234  STB_SI_PRINT((" Invalid CA identifier desc: (%d bytes)", dlen));
1235  }
1236  #endif
1237  }
1238 
1239  FUNCTION_FINISH(ParseCaIdentifierDescriptor);
1240  return(end_ptr);
1241 }
1242 
1243 static U8BIT* ParseCarouselIdDescriptor(U8BIT *dptr, U32BIT *carousel_id, BOOLEAN db_print)
1244 {
1245  U8BIT dlen;
1246  U8BIT *end_ptr;
1247 
1248  FUNCTION_START(ParseCarouselIdDescriptor);
1249 
1250  ASSERT(dptr != NULL);
1251 
1252  dlen = *dptr;
1253  dptr++;
1254  end_ptr = dptr + dlen;
1255 
1256  if (dlen == 5)
1257  {
1258  *carousel_id = (dptr[0] << 24) | (dptr[1] << 16) | (dptr[2] << 8) | dptr[3];
1259 
1260 #ifdef DEBUG_CAROUSEL_ID_DESC
1261  if (db_print)
1262  {
1263  STB_SI_PRINT((" Carousel ID: 0x%08x", *carousel_id));
1264  }
1265 #else
1266  USE_UNWANTED_PARAM(db_print);
1267 #endif
1268  }
1269 #ifdef DEBUG_CAROUSEL_ID_DESC
1270  else if (db_print)
1271  {
1272  STB_SI_PRINT((" Invalid carousel ID desc: %u bytes", dlen));
1273  }
1274 #endif
1275 
1276  FUNCTION_FINISH(ParseCarouselIdDescriptor);
1277 
1278  return(end_ptr);
1279 }
1280 
1295 static U8BIT* ParseComponentDescriptor(U8BIT *dptr, U8BIT *num_ptr, SI_COMPONENT_DESC **array_ptr,
1296  BOOLEAN db_print)
1297 {
1298  U8BIT dlen;
1299  U8BIT *end_ptr;
1300  SI_COMPONENT_DESC *array;
1301  U8BIT num_entries;
1302  U8BIT tag;
1303  U8BIT content;
1304  U8BIT type;
1305  U32BIT lang_code;
1306  SI_STRING_DESC *str_desc;
1307 
1308  FUNCTION_START(ParseComponentDescriptor);
1309 
1310  ASSERT(dptr != NULL);
1311  ASSERT(num_ptr != NULL);
1312  ASSERT(array_ptr != NULL);
1313 
1314  dlen = *dptr;
1315  dptr++;
1316  end_ptr = dptr + dlen;
1317 
1318  if (dlen >= 6)
1319  {
1320  content = dptr[0] & 0x0f;
1321  type = dptr[1];
1322  tag = dptr[2];
1323  dptr += 3;
1324  dptr = ReadLanguageCode(dptr, &lang_code);
1325  dptr = STB_SIReadString(dlen - 6, dptr, &str_desc);
1326 
1327  #ifdef DEBUG_COMPONENT_DESC
1328  {
1329  char *tmp_str = "NULL";
1330  if (db_print == TRUE)
1331  {
1332  if (str_desc != NULL)
1333  {
1334  if (str_desc->str_ptr != NULL)
1335  {
1336  tmp_str = (char *)str_desc->str_ptr;
1337  }
1338  }
1339  STB_SI_PRINT((" Component desc: tag=%d, cont=%d, type=0x%02x, lang=%c%c%c, str=%s",
1340  tag, content, type, (lang_code >> 16), (lang_code >> 8), lang_code, tmp_str));
1341  }
1342  }
1343  #else
1344  USE_UNWANTED_PARAM(db_print);
1345  #endif
1346 
1347  // check if there are already entries in the array (i.e. already received a descriptor)
1348  // if so add to the existing array, otherwise create new array
1349  if (*array_ptr == NULL)
1350  {
1351  // no entries already - create new array
1352  num_entries = 1;
1354  }
1355  else
1356  {
1357  // already got entries - make array bigger
1358  num_entries = *num_ptr + 1;
1359  array = (SI_COMPONENT_DESC *)STB_GetMemory(num_entries * sizeof(SI_COMPONENT_DESC));
1360  if (array != NULL)
1361  {
1362  // copy over previous entries and free old array
1363  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_COMPONENT_DESC)));
1364  STB_FreeMemory(*array_ptr);
1365  }
1366  }
1367 
1368  // add new entry to array
1369  if (array != NULL)
1370  {
1371  array[num_entries - 1].tag = tag;
1372  array[num_entries - 1].content = content;
1373  array[num_entries - 1].type = type;
1374  array[num_entries - 1].lang_code = lang_code;
1375  array[num_entries - 1].desc_str = str_desc;
1376  *array_ptr = array;
1377  *num_ptr = num_entries;
1378  }
1379  else
1380  {
1381  #ifdef DEBUG_COMPONENT_DESC
1382  if (db_print == TRUE)
1383  {
1384  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
1385  }
1386  #endif
1387  }
1388  }
1389  else
1390  {
1391  #ifdef DEBUG_COMPONENT_DESC
1392  if (db_print == TRUE)
1393  {
1394  STB_SI_PRINT((" Invalid Component desc: (%d bytes)", dlen));
1395  }
1396  #endif
1397  }
1398 
1399  USE_UNWANTED_PARAM(dptr);
1400  FUNCTION_FINISH(ParseComponentDescriptor);
1401  return(end_ptr);
1402 }
1403 
1418 static U8BIT* ParseContentDescriptor(U8BIT *dptr, U8BIT *num_ptr, SI_CONTENT_DESC **array_ptr, BOOLEAN db_print)
1419 {
1420  U8BIT dlen;
1421  U8BIT *end_ptr;
1422  U8BIT num_entries;
1423  SI_CONTENT_DESC *array;
1424  U16BIT i;
1425 
1426  FUNCTION_START(ParseContentDescriptor);
1427 
1428  ASSERT(dptr != NULL);
1429  ASSERT(num_ptr != NULL);
1430  ASSERT(array_ptr != NULL);
1431 
1432  dlen = *dptr;
1433  dptr++;
1434  end_ptr = dptr + dlen;
1435 
1436  if (dlen >= 2)
1437  {
1438  num_entries = dlen / 2; // each entry in the descriptor is 2 bytes long
1439  #ifdef DEBUG_CONTENT_DESC
1440  if (db_print == TRUE)
1441  {
1442  STB_SI_PRINT((" Content desc: %d entries", num_entries));
1443  }
1444  #else
1445  USE_UNWANTED_PARAM(db_print);
1446  #endif
1447 
1448  // check if there are already entries in the array (i.e. already received a descriptor)
1449  // if so add to the existing array, otherwise create new array
1450  if (*array_ptr == NULL)
1451  {
1452  // no entries already - create new array
1453  array = (SI_CONTENT_DESC *)STB_GetMemory(num_entries * sizeof(SI_CONTENT_DESC));
1454  }
1455  else
1456  {
1457  // already got entries - make array bigger
1458  num_entries += *num_ptr;
1459  array = (SI_CONTENT_DESC *)STB_GetMemory(num_entries * sizeof(SI_CONTENT_DESC));
1460  if (array != NULL)
1461  {
1462  // copy over previous entries and free old array
1463  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_CONTENT_DESC)));
1464  STB_FreeMemory(*array_ptr);
1465  }
1466  }
1467 
1468  // add new entry to array
1469  if (array != NULL)
1470  {
1471  for (i = *num_ptr; i < num_entries; i++)
1472  {
1473  array[i].level_1 = dptr[0] >> 4;
1474  array[i].level_2 = dptr[0] & 0x0f;
1475  array[i].user_1 = dptr[1] >> 4;
1476  array[i].user_2 = dptr[1] & 0x0f;
1477  dptr += 2;
1478  #ifdef DEBUG_CONTENT_DESC
1479  if (db_print == TRUE)
1480  {
1481  STB_SI_PRINT((" L1=0x%02x, L2=0x%02x, U1=0x%02x, U2=0x%02x",
1482  array[i].level_1, array[i].level_2, array[i].user_1, array[i].user_2));
1483  }
1484  #endif
1485  }
1486  *array_ptr = array;
1487  *num_ptr = num_entries;
1488  }
1489  else
1490  {
1491  #ifdef DEBUG_CONTENT_DESC
1492  if (db_print == TRUE)
1493  {
1494  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
1495  }
1496  #endif
1497  }
1498  }
1499  else
1500  {
1501  #ifdef DEBUG_CONTENT_DESC
1502  if (db_print == TRUE)
1503  {
1504  STB_SI_PRINT((" Invalid Content desc: (%d bytes)", dlen));
1505  }
1506  #endif
1507  }
1508 
1509  FUNCTION_FINISH(ParseContentDescriptor);
1510  return(end_ptr);
1511 }
1512 
1526 static U8BIT* ParseFrequencyListDescriptor(U8BIT *dptr, SI_NIT_FREQUENCY_LIST_DESC **freq_list, BOOLEAN db_print)
1527 {
1528  U8BIT dlen;
1529  U8BIT *end_ptr;
1530  U8BIT coding_type;
1531  U8BIT i, num_freqs;
1532  SI_NIT_FREQUENCY_LIST_DESC *list_entry;
1533 
1534  FUNCTION_START(ParseFrequencyListDescriptor);
1535 
1536  ASSERT(dptr != NULL);
1537  ASSERT(freq_list != NULL);
1538 
1539  dlen = *dptr;
1540  dptr++;
1541  end_ptr = dptr + dlen;
1542 
1543  if (dlen >= 5)
1544  {
1545  coding_type = *dptr & 0x03;
1546  dptr++;
1547  dlen--;
1548 
1549  if (coding_type != 0)
1550  {
1551  /* Each frequency is 4 bytes in length */
1552  num_freqs = dlen / 4;
1553 
1554  list_entry = STB_GetMemory(sizeof(SI_NIT_FREQUENCY_LIST_DESC));
1555  if (list_entry != NULL)
1556  {
1557  memset(list_entry, 0, sizeof(SI_NIT_FREQUENCY_LIST_DESC));
1558 
1559  list_entry->frequency_array = STB_GetMemory(num_freqs * sizeof(U32BIT));
1560  if (list_entry->frequency_array != NULL)
1561  {
1562  list_entry->coding_type = coding_type;
1563  list_entry->num_frequencies = num_freqs;
1564 
1565  #ifdef DEBUG_FREQ_LIST_DESC
1566  if (db_print)
1567  {
1568  STB_SI_PRINT((" Frequency list desc: coding_type %u with %u frequencies", coding_type, num_freqs));
1569  }
1570  #endif
1571 
1572  for (i = 0; i < num_freqs; dptr += 4, i++)
1573  {
1574  switch (coding_type)
1575  {
1576  case 1: /* satellite */
1577  list_entry->frequency_array[i] = (U32BIT)BCDToFloat(dptr, 8, 6);
1578  break;
1579  case 2: /* cable */
1580  list_entry->frequency_array[i] = (U32BIT)(BCDToFloat(dptr, 8, 4) * 1000000);
1581  break;
1582  case 3: /* terrestrial */
1583  list_entry->frequency_array[i] = ((dptr[0] << 24) | (dptr[1] << 16) | (dptr[2] << 8) | dptr[3]) * 10;
1584  break;
1585  }
1586 
1587  #ifdef DEBUG_FREQ_LIST_DESC
1588  if (db_print)
1589  {
1590  STB_SI_PRINT((" %u=%lu Hz", i, list_entry->frequency_array[i]));
1591  }
1592  #endif
1593  }
1594 
1595  /* Add the new frequency list entry to the start of the lists */
1596  list_entry->next = *freq_list;
1597  *freq_list = list_entry;
1598  }
1599  else
1600  {
1601  STB_FreeMemory(list_entry);
1602  }
1603  }
1604  }
1605  else
1606  {
1607  #ifdef DEBUG_FREQ_LIST_DESC
1608  if (db_print)
1609  {
1610  STB_SI_PRINT((" Frequency list desc: coding_type 0 is not defined"));
1611  }
1612  #endif
1613  }
1614  }
1615  else
1616  {
1617  #ifdef DEBUG_FREQ_LIST_DESC
1618  if (db_print)
1619  {
1620  STB_SI_PRINT((" Frequency list desc: invalid length, %u bytes", dlen));
1621  }
1622  #else
1623  USE_UNWANTED_PARAM(db_print);
1624  #endif
1625  }
1626 
1627  FUNCTION_FINISH(ParseFrequencyListDescriptor);
1628  return(end_ptr);
1629 }
1630 
1644 static U8BIT* ParseFTAContentDescriptor(U8BIT *dptr, SI_FTA_CONTENT_DESC **desc_ptr, BOOLEAN db_print)
1645 {
1646  U8BIT dlen;
1647  U8BIT *end_ptr;
1648 
1649  FUNCTION_START(ParseFTAContentDescriptor);
1650 
1651  dlen = *dptr;
1652  dptr++;
1653  end_ptr = dptr + dlen;
1654 
1655  /* There should be only one descriptor in whichever table it's being parsed from,
1656  * so skip this one if it already exists */
1657  if (*desc_ptr == NULL)
1658  {
1659  *desc_ptr = (SI_FTA_CONTENT_DESC *)STB_GetMemory(sizeof(SI_FTA_CONTENT_DESC));
1660  if (*desc_ptr != NULL)
1661  {
1662  (*desc_ptr)->do_not_scramble = ((dptr[0] & 0x08) == 0x08) ? TRUE : FALSE;
1663  (*desc_ptr)->access_over_internet = (dptr[0] & 0x06) >> 1;
1664  (*desc_ptr)->do_not_apply_revocation = ((dptr[0] & 0x01) == 1) ? TRUE : FALSE;
1665 
1666 #ifdef DEBUG_FTA_CONTENT_DESC
1667  if (db_print)
1668  {
1669  STB_SI_PRINT((" FTA content desc: do_not_scramble=%s",
1670  ((*desc_ptr)->do_not_scramble ? "TRUE" : "FALSE")));
1671  STB_SI_PRINT((" : do_not_apply_revocation=%s",
1672  ((*desc_ptr)->do_not_apply_revocation ? "TRUE" : "FALSE")));
1673  }
1674 #else
1675  USE_UNWANTED_PARAM(db_print);
1676 #endif
1677  }
1678  }
1679 
1680  FUNCTION_FINISH(ParseFTAContentDescriptor);
1681 
1682  return(end_ptr);
1683 }
1684 
1698 static U8BIT* ParseGuidanceDescriptor(U8BIT *dptr, SI_GUIDANCE_DESC **desc_ptr, BOOLEAN db_print)
1699 {
1700  U8BIT dlen;
1701  U8BIT *end_ptr;
1702  U8BIT index;
1703  U32BIT *lang_codes;
1704  SI_STRING_DESC **strings;
1705 
1706  FUNCTION_START(ParseGuidanceDescriptor);
1707 
1708  ASSERT(dptr != NULL);
1709  ASSERT(desc_ptr != NULL);
1710 
1711  dlen = *dptr;
1712  dptr++;
1713  end_ptr = dptr + dlen;
1714 
1715  /* This descriptor should only be received once in per service or event */
1716  if ((*desc_ptr == NULL) && (dlen >= 4))
1717  {
1718  *desc_ptr = (SI_GUIDANCE_DESC *)STB_GetMemory(sizeof(SI_GUIDANCE_DESC));
1719  memset(*desc_ptr, 0, sizeof(SI_GUIDANCE_DESC));
1720  (*desc_ptr)->guidance_type = 0xff;
1721  }
1722 
1723  if ((*desc_ptr != NULL) && (dlen >= 4))
1724  {
1725  /* The guidance type should be the same for all descriptors because
1726  * it's only the lang and text that should be changing, but type and
1727  * mode are read each time so if they are different it will take the
1728  * values of the last descriptor read */
1729  (*desc_ptr)->guidance_type = *dptr & 0x03;
1730  dptr++;
1731  dlen--;
1732 
1733  if ((*desc_ptr)->guidance_type < 0x02)
1734  {
1735  (*desc_ptr)->guidance_mode = FALSE;
1736 
1737  /* guidance type 0x1 has extra byte for 'mode' */
1738  if ((*desc_ptr)->guidance_type == 0x01)
1739  {
1740  if ((*dptr & 0x01) != 0)
1741  {
1742  (*desc_ptr)->guidance_mode = TRUE;
1743  }
1744  dptr++;
1745  dlen--;
1746  }
1747 
1748  if ((*desc_ptr)->num_langs == 0)
1749  {
1750  index = 0;
1751  lang_codes = (U32BIT *)STB_GetMemory(sizeof(U32BIT));
1752  strings = (SI_STRING_DESC **)STB_GetMemory(sizeof(SI_STRING_DESC *));
1753  }
1754  else
1755  {
1756  index = (*desc_ptr)->num_langs;
1757  lang_codes = (U32BIT *)STB_ResizeMemory((*desc_ptr)->lang_codes,
1758  (index + 1) * sizeof(U32BIT));
1759  strings = (SI_STRING_DESC **)STB_ResizeMemory((*desc_ptr)->strings,
1760  (index + 1) * sizeof(SI_STRING_DESC *));
1761  }
1762 
1763  if ((lang_codes != NULL) && (strings != NULL))
1764  {
1765  dptr = ReadLanguageCode(dptr, &lang_codes[index]);
1766  dlen -= 3;
1767  dptr = STB_SIReadString(dlen, dptr, &strings[index]);
1768 
1769  (*desc_ptr)->lang_codes = lang_codes;
1770  (*desc_ptr)->strings = strings;
1771  (*desc_ptr)->num_langs++;
1772  }
1773  else
1774  {
1775  if (lang_codes != NULL)
1776  {
1777  STB_FreeMemory(lang_codes);
1778  }
1779  if (strings != NULL)
1780  {
1781  STB_FreeMemory(strings);
1782  }
1783 
1784  (*desc_ptr)->num_langs = 0;
1785 
1786  if (db_print)
1787  {
1788  STB_SI_PRINT((" Guidance desc: Out of memory!"));
1789  }
1790  }
1791  }
1792 
1793 #ifdef DEBUG_GUIDANCE_DESC
1794  {
1795  if ((*desc_ptr)->guidance_type < 0x02)
1796  {
1797  char *tmp_str = "NULL";
1798  U8BIT index = (*desc_ptr)->num_langs - 1;
1799  U32BIT lang_code;
1800 
1801  if (((*desc_ptr)->strings != NULL) && ((*desc_ptr)->strings[index] != NULL))
1802  {
1803  if ((*desc_ptr)->strings[index]->str_ptr != NULL)
1804  {
1805  tmp_str = (char *)(*desc_ptr)->strings[index]->str_ptr;
1806  }
1807  }
1808 
1809  lang_code = (*desc_ptr)->lang_codes[index];
1810 
1811  STB_SI_PRINT((" Guidance desc: type=%u, mode=%u, lang=0x%02x%02x%02x, text=\"%s\"",
1812  (*desc_ptr)->guidance_type, (*desc_ptr)->guidance_mode, ((lang_code >> 16) & 0xff),
1813  ((lang_code >> 8) & 0xff), (lang_code & 0xff), tmp_str));
1814  }
1815  else
1816  {
1817  STB_SI_PRINT((" Guidance desc: unsupported type=%u", (*desc_ptr)->guidance_type));
1818  }
1819  }
1820 #endif
1821  }
1822  else
1823  {
1824 #ifdef DEBUG_GUIDANCE_DESC
1825  if (db_print == TRUE)
1826  {
1827  STB_SI_PRINT((" Guidance desc: invalid length, %u", dlen));
1828  }
1829 #endif
1830  }
1831 
1832  USE_UNWANTED_PARAM(dptr);
1833  FUNCTION_FINISH(ParseGuidanceDescriptor);
1834 
1835  return(end_ptr);
1836 }
1837 
1852 static U8BIT* ParseIsoLangDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_ISO_LANG_DESC **array_ptr, BOOLEAN db_print)
1853 {
1854  U8BIT dlen;
1855  U8BIT *end_ptr;
1856  U16BIT num_entries;
1857  SI_ISO_LANG_DESC *array;
1858  U16BIT i;
1859 
1860  FUNCTION_START(ParseIsoLangDescriptor);
1861 
1862  ASSERT(dptr != NULL);
1863  ASSERT(num_ptr != NULL);
1864  ASSERT(array_ptr != NULL);
1865 
1866  dlen = *dptr;
1867  dptr++;
1868  end_ptr = dptr + dlen;
1869 
1870  if (dlen >= 4)
1871  {
1872  num_entries = dlen / 4; // each entry in the descriptor is 4 bytes long
1873  #ifdef DEBUG_ISO_LANG_DESC
1874  if (db_print == TRUE)
1875  {
1876  STB_SI_PRINT((" ISO lang desc: %d entries", num_entries));
1877  }
1878  #else
1879  USE_UNWANTED_PARAM(db_print);
1880  #endif
1881 
1882  // check if there are already entries in the array (i.e. already received a descriptor)
1883  // if so add to the existing array, otherwise create new array
1884  if (*array_ptr == NULL)
1885  {
1886  // no entries already - create new array
1887  array = (SI_ISO_LANG_DESC *)STB_GetMemory(num_entries * sizeof(SI_ISO_LANG_DESC));
1888  }
1889  else
1890  {
1891  // already got entries - make array bigger
1892  num_entries += *num_ptr;
1893  array = (SI_ISO_LANG_DESC *)STB_GetMemory(num_entries * sizeof(SI_ISO_LANG_DESC));
1894  if (array != NULL)
1895  {
1896  // copy over previous entries and free old array
1897  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_ISO_LANG_DESC)));
1898  STB_FreeMemory(*array_ptr);
1899  }
1900  }
1901 
1902  // add new entries to array
1903  if (array != NULL)
1904  {
1905  for (i = *num_ptr; i < num_entries; i++)
1906  {
1907  dptr = ReadLanguageCode(dptr, &array[i].lang_code);
1908  array[i].audio_type = dptr[0];
1909  dptr += 1;
1910  #ifdef DEBUG_ISO_LANG_DESC
1911  if (db_print == TRUE)
1912  {
1913  STB_SI_PRINT((" lang=%c%c%c, type=%d", (array[i].lang_code >> 16),
1914  (array[i].lang_code >> 8), array[i].lang_code, array[i].audio_type));
1915  }
1916  #endif
1917  }
1918  *array_ptr = array;
1919  *num_ptr = num_entries;
1920  }
1921  else
1922  {
1923  #ifdef DEBUG_ISO_LANG_DESC
1924  if (db_print == TRUE)
1925  {
1926  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
1927  }
1928  #endif
1929  }
1930  }
1931  else
1932  {
1933  #ifdef DEBUG_ISO_LANG_DESC
1934  if (db_print == TRUE)
1935  {
1936  STB_SI_PRINT((" Invalid ISO lang desc: (%d bytes)", dlen));
1937  }
1938  #endif
1939  }
1940 
1941  FUNCTION_FINISH(ParseIsoLangDescriptor);
1942  return(end_ptr);
1943 }
1944 
1961 static U8BIT* ParseLinkageDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_LINKAGE_DESC_ENTRY **list_ptr,
1962  SI_LINKAGE_DESC_ENTRY **last_entry_ptr, U32BIT private_data_code, BOOLEAN db_print)
1963 {
1964  U8BIT dlen;
1965  U8BIT *end_ptr;
1966  SI_LINKAGE_DESC_ENTRY *desc_ptr;
1967  U8BIT dsize;
1968 
1969  FUNCTION_START(ParseLinkageDescriptor);
1970 
1971  ASSERT(dptr != NULL);
1972  ASSERT(num_ptr != NULL);
1973  ASSERT(list_ptr != NULL);
1974 
1975  #ifndef DEBUG_LINKAGE_DESC
1976  USE_UNWANTED_PARAM(db_print);
1977  #endif
1978 
1979  dlen = *dptr;
1980  dptr++;
1981  end_ptr = dptr + dlen;
1982 
1983  if (dlen >= 7)
1984  {
1985  dsize = dlen - 7;
1986  desc_ptr = (SI_LINKAGE_DESC_ENTRY *)STB_GetMemory(sizeof(SI_LINKAGE_DESC_ENTRY) + dsize);
1987  if (desc_ptr != NULL)
1988  {
1989  desc_ptr->next = NULL;
1990  desc_ptr->private_data_code = private_data_code;
1991  desc_ptr->tran_id = (dptr[0] << 8) | dptr[1];
1992  desc_ptr->orig_net_id = (dptr[2] << 8) | dptr[3];
1993  desc_ptr->serv_id = (dptr[4] << 8) | dptr[5];
1994  desc_ptr->link_type = dptr[6];
1995  desc_ptr->data_length = dsize;
1996 
1997  if (dsize != 0)
1998  {
1999  memcpy(&(desc_ptr->data), &dptr[7], dsize);
2000  }
2001 
2002  // now add descriptor to linked list
2003  if (*last_entry_ptr == NULL)
2004  {
2005  // first entry in the list
2006  *list_ptr = desc_ptr;
2007  }
2008  else
2009  {
2010  // not the first entry
2011  (*last_entry_ptr)->next = desc_ptr;
2012  }
2013  *last_entry_ptr = desc_ptr;
2014  (*num_ptr)++;
2015 
2016 
2017  #ifdef DEBUG_LINKAGE_DESC
2018  if (db_print == TRUE)
2019  {
2020  STB_SI_PRINT((" Linkage desc: tid=0x%04x, onid=0x%04x, sid=0x%04x, type=0x%02x (private_data_code=0x%02x), dlen=%d",
2021  desc_ptr->tran_id, desc_ptr->orig_net_id, desc_ptr->serv_id,
2022  desc_ptr->link_type, private_data_code, dsize));
2023 
2024  {
2025  U8BIT i;
2026 
2027  for (i = 0; i < dsize; i++)
2028  {
2029  if ((i & 0x07) == 0)
2030  {
2031  STB_SPDebugNoCnWrite(" : 0x%02x", dptr[7 + i]);
2032  }
2033  else if (((i & 0x07) == 7) || (i == (dsize - 1)))
2034  {
2035  STB_SPDebugWrite(" 0x%02x", dptr[7 + i]); // includes cr
2036  }
2037  else
2038  {
2039  STB_SPDebugNoCnWrite(" 0x%02x", dptr[7 + i]);
2040  }
2041  }
2042  }
2043  }
2044  #endif
2045  }
2046  else
2047  {
2048  #ifdef DEBUG_LINKAGE_DESC
2049  if (db_print == TRUE)
2050  {
2051  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
2052  }
2053  #endif
2054  }
2055  }
2056  else
2057  {
2058  #ifdef DEBUG_LINKAGE_DESC
2059  if (db_print == TRUE)
2060  {
2061  STB_SI_PRINT((" Invalid linkage desc: (%d bytes)", dlen));
2062  }
2063  #endif
2064  }
2065 
2066  FUNCTION_FINISH(ParseLinkageDescriptor);
2067  return(end_ptr);
2068 }
2069 
2084 static U8BIT* ParseLocalTimeOffsetDescriptor(U8BIT *dptr, U16BIT *num_ptr, SI_LTO_DESC **array_ptr,
2085  BOOLEAN db_print)
2086 {
2087  U8BIT dlen;
2088  U8BIT *end_ptr;
2089  U16BIT num_entries;
2090  SI_LTO_DESC *array;
2091  U16BIT i;
2092 
2093  FUNCTION_START(ParseLocalTimeOffsetDescriptor);
2094 
2095  ASSERT(dptr != NULL);
2096  ASSERT(num_ptr != NULL);
2097  ASSERT(array_ptr != NULL);
2098 
2099  dlen = *dptr;
2100  dptr++;
2101  end_ptr = dptr + dlen;
2102 
2103  if (dlen >= 13)
2104  {
2105  num_entries = dlen / 13; // each entry in the descriptor is 13 bytes long
2106  #ifdef DEBUG_LOCAL_TIME_OFFSET_DESC
2107  if (db_print == TRUE)
2108  {
2109  STB_SI_PRINT((" Local time offset desc: %d entries", num_entries));
2110  }
2111  #else
2112  USE_UNWANTED_PARAM(db_print);
2113  #endif
2114 
2115  // check if there are already entries in the array (i.e. already received a descriptor)
2116  // if so add to the existing array, otherwise create new array
2117  if (*array_ptr == NULL)
2118  {
2119  // no entries already - create new array
2120  array = (SI_LTO_DESC *)STB_GetMemory(num_entries * sizeof(SI_LTO_DESC));
2121  }
2122  else
2123  {
2124  // already got entries - make array bigger
2125  num_entries += *num_ptr;
2126  array = (SI_LTO_DESC *)STB_GetMemory(num_entries * sizeof(SI_LTO_DESC));
2127  if (array != NULL)
2128  {
2129  // copy over previous entries and free old array
2130  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_LTO_DESC)));
2131  STB_FreeMemory(*array_ptr);
2132  }
2133  }
2134 
2135  // add new entries to array
2136  if (array != NULL)
2137  {
2138  for (i = *num_ptr; i < num_entries; i++)
2139  {
2140  dptr = ReadLanguageCode(dptr, &(array[i].country_code));
2141  array[i].region = (dptr[0] >> 2);
2142  array[i].offset_negative = ((dptr[0] & 0x01) == 1);
2143  array[i].offset_hrs = ((dptr[1] >> 4) * 10) + (dptr[1] & 0x0f);
2144  array[i].offset_mins = ((dptr[2] >> 4) * 10) + (dptr[2] & 0x0f);
2145  array[i].change_date = (dptr[3] << 8) | dptr[4];
2146  array[i].change_hrs = ((dptr[5] >> 4) * 10) + (dptr[5] & 0x0f);
2147  array[i].change_mins = ((dptr[6] >> 4) * 10) + (dptr[6] & 0x0f);
2148  array[i].change_secs = ((dptr[7] >> 4) * 10) + (dptr[7] & 0x0f);
2149  array[i].next_offset_hrs = ((dptr[8] >> 4) * 10) + (dptr[8] & 0x0f);
2150  array[i].next_offset_mins = ((dptr[9] >> 4) * 10) + (dptr[9] & 0x0f);
2151  dptr += 10;
2152 
2153  #ifdef DEBUG_LOCAL_TIME_OFFSET_DESC
2154  {
2155  U8BIT pol_char;
2156 
2157  if (db_print == TRUE)
2158  {
2159  if (array[i].offset_negative == FALSE)
2160  {
2161  pol_char = '+';
2162  }
2163  else
2164  {
2165  pol_char = '-';
2166  }
2167  STB_SI_PRINT((" %c%c%c: %c%d:%02d until %d %02d:%02d:%02d then %c%d:%02d",
2168  (array[i].country_code >> 16), (array[i].country_code >> 8), array[i].country_code,
2169  pol_char, array[i].offset_hrs, array[i].offset_mins,
2170  array[i].change_date, array[i].change_hrs, array[i].change_mins, array[i].change_secs,
2171  pol_char, array[i].next_offset_hrs, array[i].next_offset_mins));
2172  }
2173  }
2174  #endif
2175  }
2176  *array_ptr = array;
2177  *num_ptr = num_entries;
2178  }
2179  else
2180  {
2181  #ifdef DEBUG_LOCAL_TIME_OFFSET_DESC
2182  if (db_print == TRUE)
2183  {
2184  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
2185  }
2186  #endif
2187  }
2188  }
2189  else
2190  {
2191  #ifdef DEBUG_LOCAL_TIME_OFFSET_DESC
2192  if (db_print == TRUE)
2193  {
2194  STB_SI_PRINT((" Invalid local time offset desc: (%d bytes)", dlen));
2195  }
2196  #endif
2197  }
2198 
2199  FUNCTION_FINISH(ParseLocalTimeOffsetDescriptor);
2200  return(end_ptr);
2201 }
2202 
2218 static U8BIT* ParseMultilingComponentDescriptor(U8BIT *dptr, U8BIT *num_ptr,
2219  SI_MULTILING_COMPONENT_DESC **array_ptr, BOOLEAN db_print)
2220 {
2221  U8BIT dlen;
2222  U8BIT *end_ptr;
2223  U8BIT num_entries;
2225  U16BIT i;
2226  U8BIT *tmp_ptr;
2227  U8BIT name_len;
2228  U8BIT tag;
2229 
2230  FUNCTION_START(ParseMultilingComponentDescriptor);
2231 
2232  ASSERT(dptr != NULL);
2233  ASSERT(num_ptr != NULL);
2234  ASSERT(array_ptr != NULL);
2235 
2236  dlen = *dptr;
2237  dptr++;
2238  end_ptr = dptr + dlen;
2239 
2240  if (dlen >= 4)
2241  {
2242  // work out number of entries
2243  num_entries = 0;
2244  tmp_ptr = dptr + 1; // skip component tag byte
2245  while (tmp_ptr < end_ptr)
2246  {
2247  name_len = tmp_ptr[3]; // read name length
2248  tmp_ptr += (name_len + 4); // skip language code, name length and name
2249  num_entries++;
2250  }
2251 
2252  #ifdef DEBUG_MULTILING_COMPONENT_DESC
2253  if (db_print == TRUE)
2254  {
2255  STB_SI_PRINT((" Multilingual component desc: %d entries", num_entries));
2256  }
2257  #else
2258  USE_UNWANTED_PARAM(db_print);
2259  #endif
2260 
2261  // check if there are already entries in the array (i.e. already received a descriptor)
2262  // if so add to the existing array, otherwise create new array
2263  if (*array_ptr == NULL)
2264  {
2265  // no entries already - create new array
2266  array = (SI_MULTILING_COMPONENT_DESC *)STB_GetMemory(num_entries * sizeof(SI_MULTILING_COMPONENT_DESC));
2267  }
2268  else
2269  {
2270  // already got entries - make array bigger
2271  num_entries += *num_ptr;
2272  array = (SI_MULTILING_COMPONENT_DESC *)STB_GetMemory(num_entries * sizeof(SI_MULTILING_COMPONENT_DESC));
2273  if (array != NULL)
2274  {
2275  // copy over previous entries and free old array
2276  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_MULTILING_COMPONENT_DESC)));
2277  STB_FreeMemory(*array_ptr);
2278  }
2279  }
2280 
2281  // add new entries to array
2282  if (array != NULL)
2283  {
2284  tag = dptr[0];
2285  dptr++;
2286  for (i = *num_ptr; i < num_entries; i++)
2287  {
2288  array[i].tag = tag;
2289  dptr = ReadLanguageCode(dptr, &array[i].lang_code);
2290  dptr = STB_SIReadString(dptr[0], dptr + 1, &array[i].desc_str);
2291 
2292  #ifdef DEBUG_MULTILING_COMPONENT_DESC
2293  {
2294  char *tmp_str = "NULL";
2295  if (db_print == TRUE)
2296  {
2297  if (array[i].desc_str != NULL)
2298  {
2299  if (array[i].desc_str->str_ptr != NULL)
2300  {
2301  tmp_str = (char *)array[i].desc_str->str_ptr;
2302  }
2303  }
2304  STB_SI_PRINT((" tag=%d, lang=%c%c%c, string=%s",
2305  array[i].tag, (array[i].lang_code >> 16), (array[i].lang_code >> 8),
2306  array[i].lang_code, tmp_str));
2307  }
2308  }
2309  #endif
2310  }
2311  *array_ptr = array;
2312  *num_ptr = num_entries;
2313  }
2314  else
2315  {
2316  #ifdef DEBUG_MULTILING_COMPONENT_DESC
2317  if (db_print == TRUE)
2318  {
2319  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
2320  }
2321  #endif
2322  }
2323  }
2324  else
2325  {
2326  #ifdef DEBUG_MULTILING_COMPONENT_DESC
2327  if (db_print == TRUE)
2328  {
2329  STB_SI_PRINT((" Invalid multilingual component desc: (%d bytes)", dlen));
2330  }
2331  #endif
2332  }
2333 
2334  FUNCTION_FINISH(ParseMultilingComponentDescriptor);
2335  return(end_ptr);
2336 }
2337 
2353 static U8BIT* ParseMultilingNetNameDescriptor(U8BIT *dptr, U16BIT *num_ptr,
2354  SI_MULTILING_NET_NAME_DESC **array_ptr, BOOLEAN db_print)
2355 {
2356  U8BIT dlen;
2357  U8BIT *end_ptr;
2358  U16BIT num_entries;
2360  U16BIT i;
2361  U8BIT *tmp_ptr;
2362  U8BIT name_len;
2363 
2364  FUNCTION_START(ParseMultilingNetNameDescriptor);
2365 
2366  ASSERT(dptr != NULL);
2367  ASSERT(num_ptr != NULL);
2368  ASSERT(array_ptr != NULL);
2369 
2370  dlen = *dptr;
2371  dptr++;
2372  end_ptr = dptr + dlen;
2373 
2374  if (dlen >= 4)
2375  {
2376  // work out number of entries
2377  num_entries = 0;
2378  tmp_ptr = dptr;
2379  while (tmp_ptr < end_ptr)
2380  {
2381  name_len = tmp_ptr[3]; // read name length
2382  tmp_ptr += (name_len + 4); // skip language code, name length and name
2383  num_entries++;
2384  }
2385 
2386  #ifdef DEBUG_MULTILING_NET_NAME_DESC
2387  if (db_print == TRUE)
2388  {
2389  STB_SI_PRINT((" Multilingual net name desc: %d entries", num_entries));
2390  }
2391  #else
2392  USE_UNWANTED_PARAM(db_print);
2393  #endif
2394 
2395  // check if there are already entries in the array (i.e. already received a descriptor)
2396  // if so add to the existing array, otherwise create new array
2397  if (*array_ptr == NULL)
2398  {
2399  // no entries already - create new array
2400  array = (SI_MULTILING_NET_NAME_DESC *)STB_GetMemory(num_entries * sizeof(SI_MULTILING_NET_NAME_DESC));
2401  }
2402  else
2403  {
2404  // already got entries - make array bigger
2405  num_entries += *num_ptr;
2406  array = (SI_MULTILING_NET_NAME_DESC *)STB_GetMemory(num_entries * sizeof(SI_MULTILING_NET_NAME_DESC));
2407  if (array != NULL)
2408  {
2409  // copy over previous entries and free old array
2410  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_MULTILING_NET_NAME_DESC)));
2411  STB_FreeMemory(*array_ptr);
2412  }
2413  }
2414 
2415  // add new entries to array
2416  if (array != NULL)
2417  {
2418  for (i = *num_ptr; i < num_entries; i++)
2419  {
2420  dptr = ReadLanguageCode(dptr, &array[i].lang_code);
2421  dptr = STB_SIReadString(dptr[0], dptr + 1, &array[i].name_str);
2422 
2423  #ifdef DEBUG_MULTILING_NET_NAME_DESC
2424  {
2425  char *tmp_str = "NULL";
2426  if (db_print == TRUE)
2427  {
2428  if (array[i].name_str != NULL)
2429  {
2430  if (array[i].name_str->str_ptr != NULL)
2431  {
2432  tmp_str = (char *)array[i].name_str->str_ptr;
2433  }
2434  }
2435  STB_SI_PRINT((" lang=%c%c%c, name=%s", (array[i].lang_code >> 16),
2436  (array[i].lang_code >> 8), array[i].lang_code, tmp_str));
2437  }
2438  }
2439  #endif
2440  }
2441  *array_ptr = array;
2442  *num_ptr = num_entries;
2443  }
2444  else
2445  {
2446  #ifdef DEBUG_MULTILING_NET_NAME_DESC
2447  if (db_print == TRUE)
2448  {
2449  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
2450  }
2451  #endif
2452  }
2453  }
2454  else
2455  {
2456  #ifdef DEBUG_MULTILING_NET_NAME_DESC
2457  if (db_print == TRUE)
2458  {
2459  STB_SI_PRINT((" Invalid multilingual net name desc: (%d bytes)", dlen));
2460  }
2461  #endif
2462  }
2463 
2464  FUNCTION_FINISH(ParseMultilingNetNameDescriptor);
2465  return(end_ptr);
2466 }
2467 
2483 static U8BIT* ParseMultilingServNameDescriptor(U8BIT *dptr, U16BIT *num_ptr,
2484  SI_MULTILING_SERV_NAME_DESC **array_ptr, BOOLEAN db_print)
2485 {
2486  U8BIT dlen;
2487  U8BIT *end_ptr;
2488  U16BIT num_entries;
2490  U16BIT i;
2491  U8BIT *tmp_ptr;
2492  U8BIT name_len;
2493 
2494  FUNCTION_START(ParseMultilingServNameDescriptor);
2495 
2496  ASSERT(dptr != NULL);
2497  ASSERT(num_ptr != NULL);
2498  ASSERT(array_ptr != NULL);
2499 
2500  dlen = *dptr;
2501  dptr++;
2502  end_ptr = dptr + dlen;
2503 
2504  if (dlen >= 4)
2505  {
2506  // work out number of entries
2507  num_entries = 0;
2508  tmp_ptr = dptr;
2509  while (tmp_ptr < end_ptr)
2510  {
2511  name_len = tmp_ptr[3]; // read provider name length
2512  tmp_ptr += (name_len + 4); // skip language code, name length and name
2513  name_len = tmp_ptr[0]; // read service name length
2514  tmp_ptr += (name_len + 1); // skip name and length
2515  num_entries++;
2516  }
2517 
2518  #ifdef DEBUG_MULTILING_SERV_NAME_DESC
2519  if (db_print == TRUE)
2520  {
2521  STB_SI_PRINT((" Multilingual serv name desc: %d entries", num_entries));
2522  }
2523  #else
2524  USE_UNWANTED_PARAM(db_print);
2525  #endif
2526 
2527  // check if there are already entries in the array (i.e. already received a descriptor)
2528  // if so add to the existing array, otherwise create new array
2529  if (*array_ptr == NULL)
2530  {
2531  // no entries already - create new array
2532  array = (SI_MULTILING_SERV_NAME_DESC *)STB_GetMemory(num_entries * sizeof(SI_MULTILING_SERV_NAME_DESC));
2533  }
2534  else
2535  {
2536  // already got entries - make array bigger
2537  num_entries += *num_ptr;
2538  array = (SI_MULTILING_SERV_NAME_DESC *)STB_GetMemory(num_entries * sizeof(SI_MULTILING_SERV_NAME_DESC));
2539  if (array != NULL)
2540  {
2541  // copy over previous entries and free old array
2542  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_MULTILING_SERV_NAME_DESC)));
2543  STB_FreeMemory(*array_ptr);
2544  }
2545  }
2546 
2547  // add new entries to array
2548  if (array != NULL)
2549  {
2550  for (i = *num_ptr; i < num_entries; i++)
2551  {
2552  dptr = ReadLanguageCode(dptr, &array[i].lang_code);
2553  dptr = STB_SIReadString(dptr[0], dptr + 1, &array[i].provider_str);
2554  dptr = STB_SIReadString(dptr[0], dptr + 1, &array[i].name_str);
2555 
2556  #ifdef DEBUG_MULTILING_SERV_NAME_DESC
2557  {
2558  char *tmp_prov_str = "NULL";
2559  char *tmp_name_str = "NULL";
2560 
2561  if (db_print == TRUE)
2562  {
2563  if (array[i].provider_str != NULL)
2564  {
2565  if (array[i].provider_str->str_ptr != NULL)
2566  {
2567  tmp_prov_str = (char *)array[i].provider_str->str_ptr;
2568  }
2569  }
2570  if (array[i].name_str != NULL)
2571  {
2572  if (array[i].name_str->str_ptr != NULL)
2573  {
2574  tmp_name_str = (char *)array[i].name_str->str_ptr;
2575  }
2576  }
2577 
2578  STB_SI_PRINT((" lang=%c%c%c, provider=%s, name=%s",
2579  (array[i].lang_code >> 16), (array[i].lang_code >> 8), array[i].lang_code,
2580  tmp_prov_str, tmp_name_str));
2581  }
2582  }
2583  #endif
2584  }
2585  *array_ptr = array;
2586  *num_ptr = num_entries;
2587  }
2588  else
2589  {
2590  #ifdef DEBUG_MULTILING_SERV_NAME_DESC
2591  if (db_print == TRUE)
2592  {
2593  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
2594  }
2595  #endif
2596  }
2597  }
2598  else
2599  {
2600  #ifdef DEBUG_MULTILING_SERV_NAME_DESC
2601  if (db_print == TRUE)
2602  {
2603  STB_SI_PRINT((" Invalid multilingual serv name desc: (%d bytes)", dlen));
2604  }
2605  #endif
2606  }
2607 
2608  FUNCTION_FINISH(ParseMultilingServNameDescriptor);
2609  return(end_ptr);
2610 }
2611 
2625 static U8BIT* ParseNetNameDescriptor(U8BIT *dptr, SI_STRING_DESC **name_ptr, BOOLEAN db_print)
2626 {
2627  U8BIT dlen;
2628  U8BIT *end_ptr;
2629 
2630  FUNCTION_START(ParseNetNameDescriptor);
2631 
2632  ASSERT(dptr != NULL);
2633  ASSERT(name_ptr != NULL);
2634 
2635  dlen = *dptr;
2636  dptr++;
2637  end_ptr = dptr + dlen;
2638 
2639  // this descriptor should only be received once in the NIT - if a name string already exists
2640  // then this must be a duplicate entry so ignore it
2641  if (*name_ptr == NULL)
2642  {
2643  dptr = STB_SIReadString(dlen, dptr, name_ptr);
2644  #ifdef DEBUG_NET_NAME_DESC
2645  {
2646  char *tmp_str = "NULL";
2647  if (db_print == TRUE)
2648  {
2649  if (*name_ptr != NULL)
2650  {
2651  if ((*name_ptr)->str_ptr != NULL)
2652  {
2653  tmp_str = (char *)(*name_ptr)->str_ptr;
2654  }
2655  }
2656  STB_SI_PRINT((" Net name desc=%s", tmp_str));
2657  }
2658  }
2659  #else
2660  USE_UNWANTED_PARAM(db_print);
2661  #endif
2662  }
2663  else
2664  {
2665  #ifdef DEBUG_NET_NAME_DESC
2666  if (db_print == TRUE)
2667  {
2668  STB_SI_PRINT((" Net name desc: duplicate entry ignored"));
2669  }
2670  #endif
2671  }
2672 
2673  USE_UNWANTED_PARAM(dptr);
2674  FUNCTION_FINISH(ParseNetNameDescriptor);
2675  return(end_ptr);
2676 }
2677 
2692 static U8BIT* ParseParentalRatingDescriptor(U8BIT *dptr, U8BIT *num_ptr,
2693  SI_PARENTAL_RATING_DESC **array_ptr, BOOLEAN db_print)
2694 {
2695  U8BIT dlen;
2696  U8BIT *end_ptr;
2697  U8BIT num_entries;
2698  SI_PARENTAL_RATING_DESC *array;
2699  U16BIT i;
2700 
2701  FUNCTION_START(ParseParentalRatingDescriptor);
2702 
2703  ASSERT(dptr != NULL);
2704  ASSERT(num_ptr != NULL);
2705  ASSERT(array_ptr != NULL);
2706 
2707  dlen = *dptr;
2708  dptr++;
2709  end_ptr = dptr + dlen;
2710 
2711  if (dlen >= 4)
2712  {
2713  num_entries = dlen / 4; // each entry in the descriptor is 4 bytes long
2714  #ifdef DEBUG_PARENTAL_RATING_DESC
2715  if (db_print == TRUE)
2716  {
2717  STB_SI_PRINT((" Parental rating desc: %d entries", num_entries));
2718  }
2719  #else
2720  USE_UNWANTED_PARAM(db_print);
2721  #endif
2722 
2723  // check if there are already entries in the array (i.e. already received a descriptor)
2724  // if so add to the existing array, otherwise create new array
2725  if (*array_ptr == NULL)
2726  {
2727  // no entries already - create new array
2728  array = (SI_PARENTAL_RATING_DESC *)STB_GetMemory(num_entries * sizeof(SI_PARENTAL_RATING_DESC));
2729  }
2730  else
2731  {
2732  // already got entries - make array bigger
2733  num_entries += *num_ptr;
2734  array = (SI_PARENTAL_RATING_DESC *)STB_GetMemory(num_entries * sizeof(SI_PARENTAL_RATING_DESC));
2735  if (array != NULL)
2736  {
2737  // copy over previous entries and free old array
2738  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_PARENTAL_RATING_DESC)));
2739  STB_FreeMemory(*array_ptr);
2740  }
2741  }
2742 
2743  // add new entries to array
2744  if (array != NULL)
2745  {
2746  for (i = *num_ptr; i < num_entries; i++)
2747  {
2748  dptr = ReadLanguageCode(dptr, &(array[i].country_code));
2749  array[i].rating = dptr[0];
2750  dptr++;
2751  #ifdef DEBUG_PARENTAL_RATING_DESC
2752  if (db_print == TRUE)
2753  {
2754  STB_SI_PRINT((" country=%c%c%c, rating=0x%02x", (array[i].country_code >> 16),
2755  (array[i].country_code >> 8), array[i].country_code, array[i].rating));
2756  }
2757  #endif
2758  }
2759  *array_ptr = array;
2760  *num_ptr = num_entries;
2761  }
2762  else
2763  {
2764  #ifdef DEBUG_PARENTAL_RATING_DESC
2765  if (db_print == TRUE)
2766  {
2767  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
2768  }
2769  #endif
2770  }
2771  }
2772  else
2773  {
2774  #ifdef DEBUG_PARENTAL_RATING_DESC
2775  if (db_print == TRUE)
2776  {
2777  STB_SI_PRINT((" Invalid parental rating desc: (%d bytes)", dlen));
2778  }
2779  #endif
2780  }
2781 
2782  FUNCTION_FINISH(ParseParentalRatingDescriptor);
2783  return(end_ptr);
2784 }
2785 
2801 static U8BIT* ParsePrivateDataSpecifierDescriptor(U8BIT *dptr, U32BIT *code_ptr, BOOLEAN db_print)
2802 {
2803  U8BIT dlen;
2804  U8BIT *end_ptr;
2805 
2806  FUNCTION_START(ParsePrivateDataSpecifierDescriptor);
2807 
2808  ASSERT(dptr != NULL);
2809  ASSERT(code_ptr != NULL);
2810 
2811  dlen = *dptr;
2812  dptr++;
2813  end_ptr = dptr + dlen;
2814 
2815  if (dlen == 4)
2816  {
2817  *code_ptr = (dptr[0] << 24) | (dptr[1] << 16) | (dptr[2] << 8) | dptr[3];
2818 
2819  #ifdef DEBUG_PRIV_DATA_SPEC_DESC
2820  if (db_print == TRUE)
2821  {
2822  STB_SI_PRINT((" Private data specifier desc: (returned 0x%08x)", *code_ptr));
2823  }
2824  #else
2825  USE_UNWANTED_PARAM(db_print);
2826  #endif
2827  }
2828  else
2829  {
2830  *code_ptr = 0;
2831  #ifdef DEBUG_PRIV_DATA_SPEC_DESC
2832  if (db_print == TRUE)
2833  {
2834  STB_SI_PRINT((" Invalid private data specifier desc: (%d bytes)", dlen));
2835  }
2836  #endif
2837  }
2838 
2839  FUNCTION_FINISH(ParsePrivateDataSpecifierDescriptor);
2840  return(end_ptr);
2841 }
2842 
2858 static U8BIT* ParseServiceDescriptor(U8BIT *dptr, U8BIT *type_ptr, SI_STRING_DESC **provider_ptr,
2859  SI_STRING_DESC **name_ptr, BOOLEAN db_print)
2860 {
2861  U8BIT dlen;
2862  U8BIT *end_ptr;
2863 
2864  FUNCTION_START(ParseServiceDescriptor);
2865 
2866  ASSERT(dptr != NULL);
2867  ASSERT(type_ptr != NULL);
2868  ASSERT(provider_ptr != NULL);
2869  ASSERT(name_ptr != NULL);
2870 
2871  dlen = *dptr;
2872  dptr++;
2873  end_ptr = dptr + dlen;
2874 
2875  if (dlen >= 3)
2876  {
2877  if (*provider_ptr != NULL)
2878  {
2879  STB_SIReleaseStringDesc(*provider_ptr);
2880  }
2881  if (*name_ptr != NULL)
2882  {
2883  STB_SIReleaseStringDesc(*name_ptr);
2884  }
2885 
2886  *type_ptr = dptr[0];
2887  dptr++;
2888  dptr = STB_SIReadString(dptr[0], dptr + 1, provider_ptr);
2889  dptr = STB_SIReadString(dptr[0], dptr + 1, name_ptr);
2890 
2891  #ifdef DEBUG_SERVICE_DESC
2892  {
2893  char *tmp_prov_str = "NULL";
2894  char *tmp_name_str = "NULL";
2895 
2896  if (db_print == TRUE)
2897  {
2898  if (*provider_ptr != NULL)
2899  {
2900  if ((*provider_ptr)->str_ptr != NULL)
2901  {
2902  tmp_prov_str = (char *)(*provider_ptr)->str_ptr;
2903  }
2904  }
2905  if (*name_ptr != NULL)
2906  {
2907  if ((*name_ptr)->str_ptr != NULL)
2908  {
2909  tmp_name_str = (char *)(*name_ptr)->str_ptr;
2910  }
2911  }
2912 
2913  STB_SI_PRINT((" Service desc: type=%d, prov=%s, name=%s", *type_ptr,
2914  tmp_prov_str, tmp_name_str));
2915  }
2916  }
2917  #else
2918  USE_UNWANTED_PARAM(db_print);
2919  #endif
2920  }
2921  else
2922  {
2923  #ifdef DEBUG_SERVICE_DESC
2924  if (db_print == TRUE)
2925  {
2926  STB_SI_PRINT((" Invalid service desc: (%d bytes)", dlen));
2927  }
2928  #endif
2929  }
2930 
2931  USE_UNWANTED_PARAM(dptr);
2932  FUNCTION_FINISH(ParseServiceDescriptor);
2933  return(end_ptr);
2934 }
2935 
2950 static U8BIT* ParseServiceListDescriptor(U8BIT *dptr, U16BIT *num_ptr,
2951  SI_SERV_LIST_DESC **array_ptr, BOOLEAN db_print)
2952 {
2953  U8BIT dlen;
2954  U8BIT *end_ptr;
2955  U16BIT num_entries;
2956  SI_SERV_LIST_DESC *array;
2957  U16BIT i;
2958 
2959  FUNCTION_START(ParseServiceListDescriptor);
2960 
2961  ASSERT(dptr != NULL);
2962  ASSERT(num_ptr != NULL);
2963  ASSERT(array_ptr != NULL);
2964 
2965  dlen = *dptr;
2966  dptr++;
2967  end_ptr = dptr + dlen;
2968 
2969  if (dlen >= 3)
2970  {
2971  num_entries = dlen / 3; // each entry in the descriptor is 3 bytes long
2972  #ifdef DEBUG_SERV_LIST_DESC
2973  if (db_print == TRUE)
2974  {
2975  STB_SI_PRINT((" Service list desc: %d entries", num_entries));
2976  }
2977  #else
2978  USE_UNWANTED_PARAM(db_print);
2979  #endif
2980 
2981  // check if there are already entries in the array (i.e. already received a descriptor)
2982  // if so add to the existing array, otherwise create new array
2983  if (*array_ptr == NULL)
2984  {
2985  // no entries already - create new array
2986  array = (SI_SERV_LIST_DESC *)STB_GetMemory(num_entries * sizeof(SI_SERV_LIST_DESC));
2987  }
2988  else
2989  {
2990  // already got entries - make array bigger
2991  num_entries += *num_ptr;
2992  array = (SI_SERV_LIST_DESC *)STB_GetMemory(num_entries * sizeof(SI_SERV_LIST_DESC));
2993  if (array != NULL)
2994  {
2995  // copy over previous entries and free old array
2996  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_SERV_LIST_DESC)));
2997  STB_FreeMemory(*array_ptr);
2998  }
2999  }
3000 
3001  // add new entries to array
3002  if (array != NULL)
3003  {
3004  for (i = *num_ptr; i < num_entries; i++)
3005  {
3006  array[i].serv_id = (dptr[0] << 8) | dptr[1];
3007  array[i].serv_type = dptr[2];
3008  dptr += 3;
3009  #ifdef DEBUG_SERV_LIST_DESC
3010  if (db_print == TRUE)
3011  {
3012  STB_SI_PRINT((" id=0x%04x, type=0x%02x", array[i].serv_id, array[i].serv_type));
3013  }
3014  #endif
3015  }
3016  *array_ptr = array;
3017  *num_ptr = num_entries;
3018  }
3019  else
3020  {
3021  #ifdef DEBUG_SERV_LIST_DESC
3022  if (db_print == TRUE)
3023  {
3024  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
3025  }
3026  #endif
3027  }
3028  }
3029  else
3030  {
3031  #ifdef DEBUG_SERV_LIST_DESC
3032  if (db_print == TRUE)
3033  {
3034  STB_SI_PRINT((" Invalid service list desc: (%d bytes)", dlen));
3035  }
3036  #endif
3037  }
3038 
3039  FUNCTION_FINISH(ParseServiceListDescriptor);
3040  return(end_ptr);
3041 }
3042 
3056 static U8BIT* ParseShortServiceNameDescriptor(U8BIT *dptr, SI_STRING_DESC **name_ptr, BOOLEAN db_print)
3057 {
3058  U8BIT dlen;
3059  U8BIT *end_ptr;
3060 
3061  FUNCTION_START(ParseShortServiceNameDescriptor);
3062 
3063  ASSERT(dptr != NULL);
3064  ASSERT(name_ptr != NULL);
3065 
3066  dlen = *dptr;
3067  dptr++;
3068  end_ptr = dptr + dlen;
3069 
3070  if (dlen > 1)
3071  {
3072  if (*name_ptr != NULL)
3073  {
3074  STB_SIReleaseStringDesc(*name_ptr);
3075  }
3076 
3077  dptr = STB_SIReadString(dlen, dptr, name_ptr);
3078 
3079  #ifdef DEBUG_SHORT_SERVICE_NAME
3080  {
3081  char *tmp_name_str = "NULL";
3082 
3083  if (db_print == TRUE)
3084  {
3085  if (*name_ptr != NULL)
3086  {
3087  if ((*name_ptr)->str_ptr != NULL)
3088  {
3089  tmp_name_str = (char *)(*name_ptr)->str_ptr;
3090  }
3091  }
3092 
3093  STB_SI_PRINT((" Short service name: name=%s", tmp_name_str));
3094  }
3095  }
3096  #else
3097  USE_UNWANTED_PARAM(db_print);
3098  #endif
3099  }
3100  else
3101  {
3102  #ifdef DEBUG_SHORT_SERVICE_NAME
3103  if (db_print == TRUE)
3104  {
3105  STB_SI_PRINT((" Invalid short service name: (%d bytes)", dlen));
3106  }
3107  #endif
3108  }
3109 
3110  USE_UNWANTED_PARAM(dptr);
3111  FUNCTION_FINISH(ParseShortServiceNameDescriptor);
3112  return(end_ptr);
3113 }
3114 
3129 static U8BIT* ParseShortEventDescriptor(U8BIT *dptr, U8BIT *num_ptr,
3130  SI_SHORT_EVENT_DESC **array_ptr, BOOLEAN db_print)
3131 {
3132  U8BIT dlen;
3133  U8BIT *end_ptr;
3134  U8BIT num_entries;
3135  SI_SHORT_EVENT_DESC *array;
3136  U32BIT lang_code;
3137  SI_STRING_DESC *name_str;
3138  SI_STRING_DESC *desc_str;
3139 
3140  FUNCTION_START(ParseShortEventDescriptor);
3141 
3142  ASSERT(dptr != NULL);
3143  ASSERT(num_ptr != NULL);
3144  ASSERT(array_ptr != NULL);
3145 
3146  dlen = *dptr;
3147  dptr++;
3148  end_ptr = dptr + dlen;
3149 
3150  if (dlen >= 5)
3151  {
3152  dptr = ReadLanguageCode(dptr, &lang_code);
3153  dptr = STB_SIReadString(dptr[0], dptr + 1, &name_str);
3154  dptr = STB_SIReadString(dptr[0], dptr + 1, &desc_str);
3155 
3156  #ifdef DEBUG_SHORT_EVENT_DESC
3157  {
3158  char *tmp_name_str = "NULL";
3159  char *tmp_desc_str = "NULL";
3160 
3161  if (db_print == TRUE)
3162  {
3163  if (name_str != NULL)
3164  {
3165  if (name_str->str_ptr != NULL)
3166  {
3167  tmp_name_str = (char *)name_str->str_ptr;
3168  }
3169  }
3170  if (desc_str != NULL)
3171  {
3172  if (desc_str->str_ptr != NULL)
3173  {
3174  tmp_desc_str = (char *)desc_str->str_ptr;
3175  }
3176  }
3177 
3178  STB_SI_PRINT((" Short event desc: lang=%c%c%c",
3179  (lang_code >> 16), (lang_code >> 8), lang_code));
3180  STB_SI_PRINT((" name: %s", tmp_name_str));
3181  STB_SI_PRINT((" text: %s", tmp_desc_str));
3182  }
3183  }
3184  #else
3185  USE_UNWANTED_PARAM(db_print);
3186  #endif
3187 
3188  // check if there are already entries in the array (i.e. already received a descriptor)
3189  // if so add to the existing array, otherwise create new array
3190  if (*array_ptr == NULL)
3191  {
3192  // no entries already - create new array
3193  num_entries = 1;
3195  }
3196  else
3197  {
3198  // already got entries - make array bigger
3199  num_entries = *num_ptr + 1;
3200  array = (SI_SHORT_EVENT_DESC *)STB_GetMemory(num_entries * sizeof(SI_SHORT_EVENT_DESC));
3201  if (array != NULL)
3202  {
3203  // copy over previous entries and free old array
3204  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_SHORT_EVENT_DESC)));
3205  STB_FreeMemory(*array_ptr);
3206  }
3207  }
3208 
3209  // add new entry to array
3210  if (array != NULL)
3211  {
3212  array[num_entries - 1].lang_code = lang_code;
3213  array[num_entries - 1].name_str = name_str;
3214  array[num_entries - 1].desc_str = desc_str;
3215 
3216  *array_ptr = array;
3217  *num_ptr = num_entries;
3218  }
3219  else
3220  {
3221  #ifdef DEBUG_SHORT_EVENT_DESC
3222  if (db_print == TRUE)
3223  {
3224  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
3225  }
3226  #endif
3227  }
3228  }
3229  else
3230  {
3231  #ifdef DEBUG_SHORT_EVENT_DESC
3232  if (db_print == TRUE)
3233  {
3234  STB_SI_PRINT((" Invalid short event desc: (%d bytes)", dlen));
3235  }
3236  #endif
3237  }
3238 
3239  USE_UNWANTED_PARAM(dptr);
3240  FUNCTION_FINISH(ParseShortEventDescriptor);
3241  return(end_ptr);
3242 }
3243 
3258 static U8BIT* ParseExtendedEventDescriptor(U8BIT *dptr, U8BIT *num_ptr,
3259  SI_EXTENDED_EVENT_DESC **array_ptr, BOOLEAN db_print)
3260 {
3261  U8BIT dlen;
3262  U8BIT *end_ptr;
3263  U8BIT num_entries;
3264  SI_EXTENDED_EVENT_DESC *array;
3265  U8BIT desc_num, last_desc_num;
3266  U32BIT lang_code;
3267  U8BIT num_items;
3268  U8BIT *item_end;
3269  SI_STRING_DESC **item_desc_array;
3270  SI_STRING_DESC **item_text_array;
3271  SI_STRING_DESC *text_str;
3272 
3273  FUNCTION_START(ParseExtendedEventDescriptor);
3274 
3275  ASSERT(dptr != NULL);
3276  ASSERT(num_ptr != NULL);
3277  ASSERT(array_ptr != NULL);
3278 
3279  dlen = *dptr;
3280  dptr++;
3281  end_ptr = dptr + dlen;
3282 
3283  if (dlen >= 5)
3284  {
3285  desc_num = *dptr >> 4;
3286  last_desc_num = *dptr & 0x0f;
3287  dptr++;
3288 
3289  dptr = ReadLanguageCode(dptr, &lang_code);
3290 
3291  item_end = dptr + *dptr + 1;
3292  dptr++;
3293 
3294  num_items = 0;
3295  item_desc_array = NULL;
3296  item_text_array = NULL;
3297 
3298  while ((dptr < item_end) && (dptr < end_ptr))
3299  {
3300  if (num_items == 0)
3301  {
3302  item_desc_array = (SI_STRING_DESC **)STB_GetMemory(sizeof(SI_STRING_DESC *));
3303  item_text_array = (SI_STRING_DESC **)STB_GetMemory(sizeof(SI_STRING_DESC *));
3304  }
3305  else
3306  {
3307  item_desc_array = (SI_STRING_DESC **)STB_ResizeMemory(item_desc_array,
3308  (num_items + 1) * sizeof(SI_STRING_DESC *));
3309  item_text_array = (SI_STRING_DESC **)STB_ResizeMemory(item_text_array,
3310  (num_items + 1) * sizeof(SI_STRING_DESC *));
3311  }
3312 
3313  dptr = STB_SIReadString(*dptr, dptr + 1, &item_desc_array[num_items]);
3314  dptr = STB_SIReadString(*dptr, dptr + 1, &item_text_array[num_items]);
3315 
3316  num_items++;
3317  }
3318 
3319  if (dptr < end_ptr)
3320  {
3321  dptr = STB_SIReadString(*dptr, dptr + 1, &text_str);
3322  }
3323  else
3324  {
3325  text_str = NULL;
3326  }
3327 
3328  #ifdef DEBUG_EXTENDED_EVENT_DESC
3329  {
3330  U8BIT i;
3331 
3332  if (db_print == TRUE)
3333  {
3334  STB_SI_PRINT((" Extended event desc: lang=%c%c%c",
3335  (lang_code >> 16), (lang_code >> 8), lang_code));
3336  STB_SI_PRINT((" desc num : %u", desc_num));
3337  STB_SI_PRINT((" last desc num: %u", last_desc_num));
3338  STB_SI_PRINT((" num items: %u", num_items));
3339 
3340  for (i = 0; i < num_items; i++)
3341  {
3342  STB_SI_PRINT((" %u: item_desc=%s, item=%s", i,
3343  ((item_desc_array[i]->str_ptr != NULL) ? (char *)item_desc_array[i]->str_ptr : "NULL"),
3344  ((item_text_array[i]->str_ptr != NULL) ? (char *)item_text_array[i]->str_ptr : "NULL")));
3345  }
3346 
3347  if (text_str != NULL)
3348  {
3349  STB_SI_PRINT((" text=%s", ((text_str->str_ptr != NULL) ? (char *)text_str->str_ptr : "NULL")));
3350  }
3351  }
3352  }
3353  #else
3354  USE_UNWANTED_PARAM(db_print);
3355  #endif
3356 
3357  /* Check if there are already entries in the array (i.e. already received a descriptor),
3358  * if so add to the existing array, otherwise create new array */
3359  if (*array_ptr == NULL)
3360  {
3361  /* No entries already - create new array */
3362  num_entries = 1;
3364  }
3365  else
3366  {
3367  /* Already got entries - make array bigger */
3368  num_entries = *num_ptr + 1;
3369  array = (SI_EXTENDED_EVENT_DESC *)STB_ResizeMemory(*array_ptr,
3370  num_entries * sizeof(SI_EXTENDED_EVENT_DESC));
3371  }
3372 
3373  /* Add new entry to array */
3374  if (array != NULL)
3375  {
3376  array[num_entries - 1].desc_number = desc_num;
3377  array[num_entries - 1].last_desc_number = last_desc_num;
3378  array[num_entries - 1].lang_code = lang_code;
3379  array[num_entries - 1].num_items = num_items;
3380  array[num_entries - 1].item_desc_array = item_desc_array;
3381  array[num_entries - 1].item_text_array = item_text_array;
3382  array[num_entries - 1].text_str = text_str;
3383 
3384  *array_ptr = array;
3385  *num_ptr = num_entries;
3386  }
3387  else
3388  {
3389  #ifdef DEBUG_EXTENDED_EVENT_DESC
3390  if (db_print == TRUE)
3391  {
3392  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
3393  }
3394  #endif
3395  }
3396  }
3397  else
3398  {
3399  #ifdef DEBUG_EXTENDED_EVENT_DESC
3400  if (db_print == TRUE)
3401  {
3402  STB_SI_PRINT((" Invalid extended event desc: (%d bytes)", dlen));
3403  }
3404  #endif
3405  }
3406 
3407  USE_UNWANTED_PARAM(dptr);
3408  FUNCTION_FINISH(ParseExtendedEventDescriptor);
3409  return(end_ptr);
3410 }
3411 
3425 static U8BIT* ParseStreamIdDescriptor(U8BIT *dptr, U8BIT **tag_array_ptr, U8BIT *num_entries_ptr, BOOLEAN db_print)
3426 {
3427  U8BIT dlen;
3428  U8BIT *end_ptr;
3429  U8BIT num_entries;
3430 
3431  FUNCTION_START(ParseStreamIdDescriptor);
3432 
3433  ASSERT(dptr != NULL);
3434 
3435 #ifndef DEBUG_STREAM_ID_DESC
3436  USE_UNWANTED_PARAM(db_print);
3437 #endif
3438 
3439  dlen = *dptr;
3440  dptr++;
3441  end_ptr = dptr + dlen;
3442 
3443  if (dlen == 1)
3444  {
3445  if (*tag_array_ptr == NULL)
3446  {
3447  /* No entries already - create new array */
3448  num_entries = 1;
3449  *tag_array_ptr = (U8BIT *)STB_GetMemory(sizeof(U8BIT));
3450  }
3451  else
3452  {
3453  /* Already got entries - make array bigger */
3454  num_entries = *num_entries_ptr + 1;
3455  *tag_array_ptr = (U8BIT *)STB_ResizeMemory(*tag_array_ptr,
3456  num_entries * sizeof(U8BIT));
3457  }
3458 
3459  /* Add new entry to array */
3460  if (*tag_array_ptr != NULL)
3461  {
3462  (*tag_array_ptr)[num_entries - 1] = dptr[0];
3463  *num_entries_ptr = num_entries;
3464  }
3465  else
3466  {
3467  #ifdef DEBUG_STREAM_ID_DESC
3468  if (db_print == TRUE)
3469  {
3470  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
3471  }
3472  #endif
3473  }
3474  }
3475  else
3476  {
3477  #ifdef DEBUG_STREAM_ID_DESC
3478  if (db_print == TRUE)
3479  {
3480  STB_SI_PRINT((" Invalid stream id desc: (%d bytes)", dlen));
3481  }
3482  #endif
3483  }
3484 
3485  FUNCTION_FINISH(ParseStreamIdDescriptor);
3486  return(end_ptr);
3487 }
3488 
3503 static U8BIT* ParseSubtitleDescriptor(U8BIT *dptr, U16BIT *num_ptr,
3504  SI_SUBTITLE_DESC **array_ptr, BOOLEAN db_print)
3505 {
3506  U8BIT dlen;
3507  U8BIT *end_ptr;
3508  U16BIT num_entries;
3509  SI_SUBTITLE_DESC *array;
3510  U16BIT i;
3511 
3512  FUNCTION_START(ParseSubtitleDescriptor);
3513 
3514  ASSERT(dptr != NULL);
3515  ASSERT(num_ptr != NULL);
3516  ASSERT(array_ptr != NULL);
3517 
3518  dlen = *dptr;
3519  dptr++;
3520  end_ptr = dptr + dlen;
3521 
3522  if (dlen >= 8)
3523  {
3524  num_entries = dlen / 8; // each entry in the descriptor is 8 bytes long
3525  #ifdef DEBUG_SUBTITLE_DESC
3526  if (db_print == TRUE)
3527  {
3528  STB_SI_PRINT((" Subtitle desc: %d entries", num_entries));
3529  }
3530  #else
3531  USE_UNWANTED_PARAM(db_print);
3532  #endif
3533 
3534  // check if there are already entries in the array (i.e. already received a descriptor)
3535  // if so add to the existing array, otherwise create new array
3536  if (*array_ptr == NULL)
3537  {
3538  // no entries already - create new array
3539  array = (SI_SUBTITLE_DESC *)STB_GetMemory(num_entries * sizeof(SI_SUBTITLE_DESC));
3540  }
3541  else
3542  {
3543  // already got entries - make array bigger
3544  num_entries += *num_ptr;
3545  array = (SI_SUBTITLE_DESC *)STB_GetMemory(num_entries * sizeof(SI_SUBTITLE_DESC));
3546  if (array != NULL)
3547  {
3548  // copy over previous entries and free old array
3549  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_SUBTITLE_DESC)));
3550  STB_FreeMemory(*array_ptr);
3551  }
3552  }
3553 
3554  // add new entries to array
3555  if (array != NULL)
3556  {
3557  for (i = *num_ptr; i < num_entries; i++)
3558  {
3559  dptr = ReadLanguageCode(dptr, &(array[i].lang_code));
3560  array[i].type = dptr[0];
3561  array[i].composition_page = (dptr[1] << 8) | dptr[2];
3562  array[i].ancillary_page = (dptr[3] << 8) | dptr[4];
3563  dptr += 5;
3564  #ifdef DEBUG_SUBTITLE_DESC
3565  if (db_print == TRUE)
3566  {
3567  STB_SI_PRINT((" lang=%c%c%c, type=0x%02x, comp pg=%d, anc pg=%d",
3568  (array[i].lang_code >> 16), (array[i].lang_code >> 8), array[i].lang_code,
3569  array[i].type, array[i].composition_page, array[i].ancillary_page));
3570  }
3571  #endif
3572  }
3573  *array_ptr = array;
3574  *num_ptr = num_entries;
3575  }
3576  else
3577  {
3578  #ifdef DEBUG_SUBTITLE_DESC
3579  if (db_print == TRUE)
3580  {
3581  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
3582  }
3583  #endif
3584  }
3585  }
3586  else
3587  {
3588  #ifdef DEBUG_SUBTITLE_DESC
3589  if (db_print == TRUE)
3590  {
3591  STB_SI_PRINT((" Invalid subtitle desc: (%d bytes)", dlen));
3592  }
3593  #endif
3594  }
3595 
3596  FUNCTION_FINISH(ParseSubtitleDescriptor);
3597  return(end_ptr);
3598 }
3599 
3614 static U8BIT* ParseTeletextDescriptor(U8BIT *dptr, U16BIT *num_ptr,
3615  SI_TELETEXT_DESC **array_ptr, BOOLEAN db_print)
3616 {
3617  U8BIT dlen;
3618  U8BIT *end_ptr;
3619  U16BIT num_entries;
3620  SI_TELETEXT_DESC *array;
3621  U16BIT i;
3622 
3623  FUNCTION_START(ParseTeletextDescriptor);
3624 
3625  ASSERT(dptr != NULL);
3626  ASSERT(num_ptr != NULL);
3627  ASSERT(array_ptr != NULL);
3628 
3629  dlen = *dptr;
3630  dptr++;
3631  end_ptr = dptr + dlen;
3632 
3633  if (dlen >= 5)
3634  {
3635  num_entries = dlen / 5; // each entry in the descriptor is 5 bytes long
3636  #ifdef DEBUG_TELETEXT_DESC
3637  if (db_print == TRUE)
3638  {
3639  STB_SI_PRINT((" Teletext desc: %d entries", num_entries));
3640  }
3641  #else
3642  USE_UNWANTED_PARAM(db_print);
3643  #endif
3644 
3645  // check if there are already entries in the array (i.e. already received a descriptor)
3646  // if so add to the existing array, otherwise create new array
3647  if (*array_ptr == NULL)
3648  {
3649  // no entries already - create new array
3650  array = (SI_TELETEXT_DESC *)STB_GetMemory(num_entries * sizeof(SI_TELETEXT_DESC));
3651  }
3652  else
3653  {
3654  // already got entries - make array bigger
3655  num_entries += *num_ptr;
3656  array = (SI_TELETEXT_DESC *)STB_GetMemory(num_entries * sizeof(SI_TELETEXT_DESC));
3657  if (array != NULL)
3658  {
3659  // copy over previous entries and free old array
3660  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_TELETEXT_DESC)));
3661  STB_FreeMemory(*array_ptr);
3662  }
3663  }
3664 
3665  // add new entries to array
3666  if (array != NULL)
3667  {
3668  for (i = *num_ptr; i < num_entries; i++)
3669  {
3670  dptr = ReadLanguageCode(dptr, &(array[i].lang_code));
3671  array[i].type = (dptr[0] >> 3);
3672  array[i].magazine = (dptr[0] & 0x07);
3673  array[i].page = dptr[1];
3674  dptr += 2;
3675  #ifdef DEBUG_TELETEXT_DESC
3676  if (db_print == TRUE)
3677  {
3678  STB_SI_PRINT((" lang=%c%c%c, type=%d, mag=%d, page=0x%02x",
3679  (array[i].lang_code >> 16), (array[i].lang_code >> 8), array[i].lang_code,
3680  array[i].type, array[i].magazine, array[i].page));
3681  }
3682  #endif
3683  }
3684  *array_ptr = array;
3685  *num_ptr = num_entries;
3686  }
3687  else
3688  {
3689  #ifdef DEBUG_TELETEXT_DESC
3690  if (db_print == TRUE)
3691  {
3692  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
3693  }
3694  #endif
3695  }
3696  }
3697  else
3698  {
3699  #ifdef DEBUG_TELETEXT_DESC
3700  if (db_print == TRUE)
3701  {
3702  STB_SI_PRINT((" Invalid teletext desc: (%d bytes)", dlen));
3703  }
3704  #endif
3705  }
3706 
3707  FUNCTION_FINISH(ParseTeletextDescriptor);
3708  return(end_ptr);
3709 }
3710 
3724 static U8BIT* ParseTerrestrialDeliverySysDescriptor(U8BIT *dptr, SI_DELIVERY_SYS_DESC **desc_ptr,
3725  BOOLEAN db_print)
3726 {
3727  U8BIT dlen;
3728  U8BIT *end_ptr;
3729  SI_DELIVERY_SYS_DESC *del_sys;
3730  #ifdef DEBUG_TERR_DEL_SYS_DESC
3731  U8BIT constellation;
3732  U8BIT hierarchy;
3733  U8BIT code_rate_hp;
3734  U8BIT code_rate_lp;
3735  U8BIT guard;
3736  U8BIT alt_freq;
3737  #endif
3738 
3739  FUNCTION_START(ParseTerrestrialDeliverySysDescriptor);
3740 
3741  ASSERT(dptr != NULL);
3742 
3743  dlen = *dptr;
3744  dptr++;
3745  end_ptr = dptr + dlen;
3746 
3747  #ifdef DEBUG_TERR_DEL_SYS_DESC
3748  if (db_print == TRUE)
3749  {
3750  STB_SI_PRINT((" Terrestrial delivery system desc:"));
3751  }
3752  #else
3753  USE_UNWANTED_PARAM(db_print);
3754  #endif
3755 
3756  if (*desc_ptr == NULL)
3757  {
3758  *desc_ptr = STB_GetMemory(sizeof(SI_DELIVERY_SYS_DESC));
3759  }
3760  del_sys = *desc_ptr;
3761 
3762  if (del_sys != NULL)
3763  {
3764  del_sys->terr.is_t2 = FALSE;
3765  del_sys->terr.u.t1.freq_hz = ((dptr[0] << 24) | (dptr[1] << 16) | (dptr[2] << 8) | dptr[3]) * 10;
3766 
3767  switch (dptr[4] >> 5)
3768  {
3769  case 0x00:
3770  del_sys->terr.u.t1.bwidth = TBWIDTH_8MHZ;
3771  break;
3772 
3773  case 0x01:
3774  del_sys->terr.u.t1.bwidth = TBWIDTH_7MHZ;
3775  break;
3776 
3777  case 0x02:
3778  del_sys->terr.u.t1.bwidth = TBWIDTH_6MHZ;
3779  break;
3780 
3781  case 0x03:
3782  del_sys->terr.u.t1.bwidth = TBWIDTH_5MHZ;
3783  break;
3784 
3785  default:
3786  del_sys->terr.u.t1.bwidth = TBWIDTH_UNDEFINED;
3787  break;
3788  }
3789 
3790  #ifdef DEBUG_TERR_DEL_SYS_DESC
3791  constellation = (dptr[5] >> 6);
3792  hierarchy = ((dptr[5] >> 3) & 0x07);
3793  code_rate_hp = (dptr[5] & 0x07);
3794  code_rate_lp = (dptr[6] >> 5);
3795  guard = ((dptr[6] >> 3) & 0x03);
3796  alt_freq = (dptr[6] & 0x01);
3797  #endif
3798 
3799  switch ((dptr[6] >> 1) & 0x03)
3800  {
3801  case 0x00:
3802  del_sys->terr.u.t1.mode = MODE_COFDM_2K;
3803  break;
3804 
3805  case 0x01:
3806  del_sys->terr.u.t1.mode = MODE_COFDM_8K;
3807  break;
3808 
3809  case 0x02:
3810  del_sys->terr.u.t1.mode = MODE_COFDM_4K;
3811  break;
3812 
3813  default:
3814  del_sys->terr.u.t1.mode = MODE_COFDM_UNDEFINED;
3815  break;
3816  }
3817 
3818  #ifdef DEBUG_TERR_DEL_SYS_DESC
3819  if (db_print == TRUE)
3820  {
3821  STB_SI_PRINT((" f=%dHz, bw=%d, m=%d, c=%d, h=%d, rhp=%d, rlp=%d, g=%d, alt=%d",
3822  del_sys->terr.u.t1.freq_hz, del_sys->terr.u.t1.bwidth, del_sys->terr.u.t1.mode,
3823  constellation, hierarchy, code_rate_hp, code_rate_lp, guard, alt_freq));
3824  }
3825  #endif
3826  }
3827 
3828  FUNCTION_FINISH(ParseTerrestrialDeliverySysDescriptor);
3829  return(end_ptr);
3830 }
3831 
3845 static U8BIT* ParseT2DeliverySysDescriptor(U8BIT *dptr, SI_DELIVERY_SYS_DESC **desc_ptr, BOOLEAN db_print)
3846 {
3847  U8BIT dlen;
3848  U8BIT *end_ptr;
3849  SI_DELIVERY_SYS_DESC *del_sys;
3850  U8BIT tfs;
3851  U8BIT num_cells;
3852  SI_T2_DEL_SYS_CELL *cell;
3853  U8BIT i;
3854  U8BIT *freq_ptr;
3855  #ifdef DEBUG_TERR_DEL_SYS_DESC
3856  U8BIT j;
3857  #endif
3858 
3859  FUNCTION_START(ParseT2DeliverySysDescriptor);
3860 
3861  ASSERT(dptr != NULL);
3862 
3863  dlen = *dptr;
3864  dptr++;
3865  end_ptr = dptr + dlen;
3866 
3867  /* Skip the desc tag extension value */
3868  dptr++;
3869 
3870  #ifdef DEBUG_TERR_DEL_SYS_DESC
3871  if (db_print == TRUE)
3872  {
3873  STB_SI_PRINT((" T2 delivery system desc:"));
3874  }
3875  #else
3876  USE_UNWANTED_PARAM(db_print);
3877  #endif
3878 
3879  if (*desc_ptr == NULL)
3880  {
3882  }
3883 
3884  del_sys = *desc_ptr;
3885 
3886  if (del_sys != NULL)
3887  {
3888  del_sys->terr.is_t2 = TRUE;
3889 
3890  /* Only interested in the first 2 fields of this descriptor, anything else is skipped */
3891  del_sys->terr.u.t2.plp_id = dptr[0];
3892  del_sys->terr.u.t2.t2_system_id = (dptr[1] << 8) + dptr[2];
3893 
3894  if (dlen > 4)
3895  {
3896  switch ((dptr[3] & 0x3c) >> 2)
3897  {
3898  case 0x00:
3899  del_sys->terr.u.t2.bwidth = TBWIDTH_8MHZ;
3900  break;
3901 
3902  case 0x01:
3903  del_sys->terr.u.t2.bwidth = TBWIDTH_7MHZ;
3904  break;
3905 
3906  case 0x02:
3907  del_sys->terr.u.t2.bwidth = TBWIDTH_6MHZ;
3908  break;
3909 
3910  case 0x03:
3911  del_sys->terr.u.t2.bwidth = TBWIDTH_5MHZ;
3912  break;
3913 
3914  case 0x04:
3915  del_sys->terr.u.t2.bwidth = TBWIDTH_10MHZ;
3916  break;
3917 
3918  default:
3919  del_sys->terr.u.t2.bwidth = TBWIDTH_UNDEFINED;
3920  break;
3921  }
3922 
3923  switch ((dptr[4] & 0x1c) >> 2)
3924  {
3925  case 0x00:
3926  del_sys->terr.u.t2.mode = MODE_COFDM_2K;
3927  break;
3928 
3929  case 0x01:
3930  del_sys->terr.u.t2.mode = MODE_COFDM_8K;
3931  break;
3932 
3933  case 0x02:
3934  del_sys->terr.u.t2.mode = MODE_COFDM_4K;
3935  break;
3936 
3937  case 0x03:
3938  del_sys->terr.u.t2.mode = MODE_COFDM_1K;
3939  break;
3940 
3941  case 0x04:
3942  del_sys->terr.u.t2.mode = MODE_COFDM_16K;
3943  break;
3944 
3945  case 0x05:
3946  del_sys->terr.u.t2.mode = MODE_COFDM_32K;
3947  break;
3948 
3949  default:
3950  del_sys->terr.u.t2.mode = MODE_COFDM_UNDEFINED;
3951  break;
3952  }
3953 
3954  tfs = dptr[4] & 0x01;
3955 
3956  del_sys->terr.u.t2.num_cells = 0;
3957  del_sys->terr.u.t2.cell = NULL;
3958 
3959  dptr += 5;
3960 
3961  num_cells = 0;
3962  cell = NULL;
3963 
3964  while (dptr < end_ptr)
3965  {
3966  num_cells++;
3967  if (cell == NULL)
3968  {
3970  }
3971  else
3972  {
3973  cell = (SI_T2_DEL_SYS_CELL *)STB_ResizeMemory(cell, num_cells * sizeof(SI_T2_DEL_SYS_CELL));
3974  }
3975 
3976  if (cell != NULL)
3977  {
3978  cell[num_cells - 1].cell_id = (dptr[0] << 8) + dptr[1];
3979 
3980  if (tfs == 1)
3981  {
3982  cell[num_cells - 1].num_freqs = dptr[2] / 4;
3983  dptr += 3;
3984 
3985  for (i = 0, freq_ptr = dptr; i < cell[num_cells - 1].num_freqs; freq_ptr += 4, i++)
3986  {
3987  cell[num_cells - 1].freq_hz[i] = ((freq_ptr[0] << 24) | (freq_ptr[1] << 16) |
3988  (freq_ptr[2] << 8) | freq_ptr[3]) * 10;
3989  dptr += 4;
3990  }
3991  }
3992  else
3993  {
3994  cell[num_cells - 1].num_freqs = 1;
3995  cell[num_cells - 1].freq_hz[0] = ((dptr[2] << 24) | (dptr[3] << 16) | (dptr[4] << 8) | dptr[5]) * 10;
3996 
3997  dptr += 6;
3998  }
3999 
4000  /* Next come the subcells, but these are currently being skipped - not sure how we'd use them */
4001  dptr += dptr[0];
4002  }
4003  }
4004 
4005  del_sys->terr.u.t2.num_cells = num_cells;
4006  del_sys->terr.u.t2.cell = cell;
4007  }
4008  else
4009  {
4010  del_sys->terr.u.t2.bwidth = TBWIDTH_UNDEFINED;
4011  del_sys->terr.u.t2.mode = MODE_COFDM_UNDEFINED;
4012  del_sys->terr.u.t2.num_cells = 0;
4013  del_sys->terr.u.t2.cell = NULL;
4014  }
4015 
4016  #ifdef DEBUG_TERR_DEL_SYS_DESC
4017  if (db_print == TRUE)
4018  {
4019  STB_SI_PRINT((" plp=%u, t2_system_id=0x%04x, bw=%d, m=%d", del_sys->terr.u.t2.plp_id,
4020  del_sys->terr.u.t2.t2_system_id, del_sys->terr.u.t2.bwidth, del_sys->terr.u.t2.mode));
4021  if (del_sys->terr.u.t2.num_cells > 0)
4022  {
4023  for (i = 0; i < del_sys->terr.u.t2.num_cells; i++)
4024  {
4025  STB_SI_PRINT((" cell=0x%04x", del_sys->terr.u.t2.cell[i].cell_id));
4026  for (j = 0; j < del_sys->terr.u.t2.cell[i].num_freqs; j++)
4027  {
4028  STB_SI_PRINT((" freq=%luHz", del_sys->terr.u.t2.cell[i].freq_hz[j]));
4029  }
4030  }
4031  }
4032  }
4033  #endif
4034  }
4035 
4036  FUNCTION_FINISH(ParseT2DeliverySysDescriptor);
4037 
4038  return(end_ptr);
4039 }
4040 
4041 static U8BIT* ParseSatelliteDeliverySysDescriptor(U8BIT *dptr, SI_DELIVERY_SYS_DESC **desc_ptr, BOOLEAN db_print)
4042 {
4043  U8BIT dlen;
4044  U8BIT *end_ptr;
4045  SI_DELIVERY_SYS_DESC *del_sys;
4046  FUNCTION_START(ParseSatelliteDeliverySysDescriptor);
4047 
4048  ASSERT(dptr != NULL);
4049 
4050  dlen = *dptr;
4051  dptr++;
4052  end_ptr = dptr + dlen;
4053 
4054  #ifdef DEBUG_SAT_DEL_SYS_DESC
4055  if (db_print == TRUE)
4056  {
4057  STB_SI_PRINT((" Satellite delivery system desc:"));
4058  }
4059  #else
4060  USE_UNWANTED_PARAM(db_print);
4061  #endif
4062 
4063  if (*desc_ptr == NULL)
4064  {
4065  *desc_ptr = STB_GetMemory(sizeof(SI_DELIVERY_SYS_DESC));
4066  }
4067  del_sys = *desc_ptr;
4068 
4069  if (del_sys != NULL)
4070  {
4071  del_sys->sat.freq_hz = (U32BIT)BCDToFloat(dptr, 8, 6);
4072  dptr += 4;
4073 
4074  /* Save the orbital position in 1/10ths degree */
4075  del_sys->sat.position = (U16BIT)(BCDToFloat(dptr, 4, 3) * 10);
4076  dptr += 2;
4077 
4078  del_sys->sat.east_west = ((((*dptr & 0x80) >> 7) == 1) ? TRUE : FALSE);
4079  del_sys->sat.polarity = (E_STB_DP_POLARITY)((*dptr & 0x60) >> 5);
4080  del_sys->sat.dvb_s2 = (((*dptr & 0x04) != 0) ? TRUE : FALSE);
4081 
4082  switch (*dptr & 0x03)
4083  {
4084  case 0x00: /* Auto */
4085  del_sys->sat.modulation = MOD_AUTO;
4086  break;
4087 
4088  case 0x01:
4089  del_sys->sat.modulation = MOD_QPSK;
4090  break;
4091 
4092  case 0x02:
4093  del_sys->sat.modulation = MOD_8PSK;
4094  break;
4095 
4096  case 0x03:
4097  del_sys->sat.modulation = MOD_16QAM;
4098  break;
4099  }
4100  dptr++;
4101 
4102  del_sys->sat.sym_rate = (U16BIT)((BCDToFloat(dptr, 7, 3) * 1000) + 0.5);
4103  dptr += 3;
4104  del_sys->sat.fec_code = (E_STB_DP_FEC)(*dptr & 0x0f);
4105 
4106  #ifdef DEBUG_SAT_DEL_SYS_DESC
4107  if (db_print == TRUE)
4108  {
4109  STB_SI_PRINT((" f=%dHz, sym=%d, fec=%d, pol=%d, [pos=%d, we=%s, s2=%u, mod=%s]\n",
4110  del_sys->sat.freq_hz,
4111  del_sys->sat.sym_rate,
4112  del_sys->sat.fec_code,
4113  del_sys->sat.polarity,
4114  del_sys->sat.position,
4115  (del_sys->sat.east_west ? "E" : "W"),
4116  del_sys->sat.dvb_s2,
4117  ((del_sys->sat.modulation == MOD_QPSK) ? "QPSK" :
4118  ((del_sys->sat.modulation == MOD_8PSK) ? "8PSK" :
4119  ((del_sys->sat.modulation == MOD_16QAM) ? "16QAM" : "Auto")))));
4120  }
4121  #endif
4122  }
4123 
4124  FUNCTION_FINISH(ParseSatelliteDeliverySysDescriptor);
4125 
4126  return(end_ptr);
4127 }
4128 
4129 static U8BIT* ParseCableDeliverySysDescriptor(U8BIT *dptr, SI_DELIVERY_SYS_DESC **desc_ptr, BOOLEAN db_print)
4130 {
4131  U8BIT dlen;
4132  U8BIT *end_ptr;
4133  SI_DELIVERY_SYS_DESC *del_sys;
4134 
4135  FUNCTION_START(ParseCableDeliverySysDescriptor);
4136 
4137  ASSERT(dptr != NULL);
4138 
4139  dlen = *dptr;
4140  dptr++;
4141  end_ptr = dptr + dlen;
4142 
4143  #ifdef DEBUG_CABLE_DEL_SYS_DESC
4144  if (db_print == TRUE)
4145  {
4146  STB_SI_PRINT((" Cable delivery system desc:"));
4147  }
4148  #else
4149  USE_UNWANTED_PARAM(db_print);
4150  #endif
4151 
4152  if (*desc_ptr == NULL)
4153  {
4155  }
4156 
4157  del_sys = *desc_ptr;
4158 
4159  if (del_sys != NULL)
4160  {
4161  /* Read the value and convert to MHz */
4162  del_sys->cable.freq_hz = (U32BIT)(BCDToFloat(dptr, 8, 4) * 1000000);
4163  dptr += 4;
4164 
4165  /* Skip reserved field */
4166  dptr++;
4167 
4168  del_sys->cable.fec_outer = *dptr & 0x0f;
4169  dptr++;
4170 
4171  del_sys->cable.modulation = *dptr;
4172  dptr++;
4173 
4174  del_sys->cable.symbol_rate = (U32BIT)(BCDToFloat(dptr, 7, 3) * 1000);
4175  dptr += 3;
4176 
4177  del_sys->cable.fec_inner = *dptr & 0x0f;
4178 
4179  #ifdef DEBUG_CABLE_DEL_SYS_DESC
4180  if (db_print == TRUE)
4181  {
4182  STB_SI_PRINT((" freq=%u, fec_outer=0x%x, modulation=0x%02x, symbol_rate=%u, fec_inner=0x%x",
4183  del_sys->cable.freq_hz, del_sys->cable.fec_outer, del_sys->cable.modulation,
4184  del_sys->cable.symbol_rate, del_sys->cable.fec_inner));
4185  }
4186  #endif
4187  }
4188 
4189  FUNCTION_FINISH(ParseCableDeliverySysDescriptor);
4190 
4191  return(end_ptr);
4192 }
4193 
4194 static U8BIT* ParseFreesatLinkageDescriptor(U8BIT *dptr, SI_FREESAT_LINKAGE_DESC **desc, BOOLEAN db_print)
4195 {
4196  U8BIT dlen;
4197  U8BIT *end_ptr;
4198  SI_FREESAT_LINKAGE_DESC *new_item;
4199  SI_FREESAT_LINKAGE_DESC *last_item;
4200  U8BIT tun_loop_length;
4201  U8BIT i;
4202 
4203  FUNCTION_START(ParseFreesatLinkageDescriptor);
4204 
4205  ASSERT(dptr != NULL);
4206 
4207  dlen = *dptr;
4208  dptr++;
4209  end_ptr = dptr + dlen;
4210 
4211  #ifdef DEBUG_FREESAT_LINKAGE_DESC
4212  if (db_print == TRUE)
4213  {
4214  STB_SI_PRINT((" Free sat linkage desc: len=%u", dlen));
4215  }
4216  #else
4217  USE_UNWANTED_PARAM(db_print);
4218  #endif
4219 
4220  /* There should only be one of these descriptors, so ignore this if there's already parsed data */
4221  if (*desc == NULL)
4222  {
4223  last_item = NULL;
4224 
4225  while (dptr < end_ptr)
4226  {
4228  if (new_item != NULL)
4229  {
4230  new_item->next = NULL;
4231  new_item->trans_id = (dptr[0] << 8) | dptr[1];
4232  new_item->onet_id = (dptr[2] << 8) | dptr[3];
4233  dptr += 4;
4234 
4235  /* According to Freesat spec, the standard loop length should be 0, but skip it anyway */
4236  dptr += (*dptr) + 1;
4237 
4238  new_item->serv_id = (dptr[0] << 8) | dptr[1];
4239 
4240  #ifdef DEBUG_FREESAT_LINKAGE_DESC
4241  STB_SI_PRINT((" onid=0x%04x, tid=0x%04x, sid=0x%04x",
4242  new_item->onet_id, new_item->trans_id, new_item->serv_id));
4243  #endif
4244 
4245  tun_loop_length = dptr[2];
4246  dptr += 3;
4247 
4248  if (tun_loop_length > 0)
4249  {
4250  new_item->num_data_types = tun_loop_length;
4251 
4252  /* Allocate memory to hold the tunnelled data types */
4253  new_item->data_types = (U8BIT *)STB_GetMemory(tun_loop_length * sizeof(U8BIT));
4254  if (new_item->data_types != NULL)
4255  {
4256  for (i = 0; i < tun_loop_length; i++)
4257  {
4258  new_item->data_types[i] = dptr[i];
4259 
4260  #ifdef DEBUG_FREESAT_LINKAGE_DESC
4261  STB_SI_PRINT((" tunnelled data type 0x%02x", dptr[i]));
4262  #endif
4263  }
4264  }
4265  else
4266  {
4267  /* Descriptor is of no use without the types */
4268  STB_FreeMemory(new_item);
4269  new_item = NULL;
4270  #ifdef DEBUG_FREESAT_LINKAGE_DESC
4271  STB_SI_PRINT((" Failed to allocate memory for tunnelled data types, descriptor ignored"));
4272  #endif
4273  }
4274  }
4275  else
4276  {
4277  /* If no tunnelled data is defined then this descriptor isn't any use */
4278  STB_FreeMemory(new_item);
4279  new_item = NULL;
4280  #ifdef DEBUG_FREESAT_LINKAGE_DESC
4281  STB_SI_PRINT((" No tunnelled data, descriptor ignored"));
4282  #endif
4283  }
4284 
4285  dptr += tun_loop_length;
4286 
4287  if (new_item != NULL)
4288  {
4289  /* Add this linkage descriptor to the list */
4290  if (*desc == NULL)
4291  {
4292  *desc = new_item;
4293  }
4294  else
4295  {
4296  last_item->next = new_item;
4297  }
4298 
4299  last_item = new_item;
4300  }
4301  }
4302  #ifdef DEBUG_FREESAT_LINKAGE_DESC
4303  else
4304  {
4305  STB_SI_PRINT((" Failed to allocate memory for freesat linkage desc"));
4306  }
4307  #endif
4308  }
4309  }
4310 
4311  FUNCTION_FINISH(ParseFreesatLinkageDescriptor);
4312 
4313  return(end_ptr);
4314 }
4315 
4316 static U8BIT* ParseFreesatPrefixDescriptor(U8BIT *dptr, SI_FREESAT_PREFIX_DESC **list, BOOLEAN db_print)
4317 {
4318  U8BIT dlen;
4319  U8BIT *end_ptr;
4320  SI_FREESAT_PREFIX_DESC *prefix;
4321 
4322  FUNCTION_START(ParseFreesatPrefixDescriptor);
4323 
4324  ASSERT(dptr != NULL);
4325 
4326  dlen = *dptr;
4327  dptr++;
4328  end_ptr = dptr + dlen;
4329 
4330  #ifdef DEBUG_FREESAT_PREFIX_DESC
4331  if (db_print)
4332  {
4333  STB_SI_PRINT((" Freesat prefix desc: len=%u", dlen));
4334  }
4335  #else
4336  USE_UNWANTED_PARAM(db_print);
4337  #endif
4338 
4339  while (dptr < end_ptr)
4340  {
4342  if (prefix != NULL)
4343  {
4344  prefix->prefix_index = *dptr & 0x7f;
4345  dptr++;
4346 
4347  dptr = STB_SIReadString(*dptr, dptr + 1, &prefix->uri_prefix);
4348 
4349  #ifdef DEBUG_FREESAT_PREFIX_DESC
4350  STB_SI_PRINT((" index=%u, prefix=\"%s\"", prefix->prefix_index, prefix->uri_prefix->str_ptr));
4351  #endif
4352 
4353  /* Prepend this descriptor to the list */
4354  prefix->next = *list;
4355  *list = prefix;
4356  }
4357  #ifdef DEBUG_FREESAT_PREFIX_DESC
4358  else
4359  {
4360  STB_SI_PRINT((" Failed to allocate memory for freesat prefix desc"));
4361  }
4362  #endif
4363  }
4364 
4365  FUNCTION_FINISH(ParseFreesatPrefixDescriptor);
4366 
4367  return(end_ptr);
4368 }
4369 
4385 static U8BIT* ParseLogicalChannelDescriptor(U8BIT *dptr, U8BIT dtag, U16BIT *num_ptr,
4386  SI_LCN_DESC **array_ptr, BOOLEAN db_print)
4387 {
4388  U8BIT dlen;
4389  U8BIT *end_ptr;
4390  U16BIT num_entries;
4391  SI_LCN_DESC *lcns;
4392  U16BIT i;
4393 
4394  FUNCTION_START(ParseLogicalChannelDescriptor);
4395 
4396  ASSERT(dptr != NULL);
4397  ASSERT(num_ptr != NULL);
4398  ASSERT(array_ptr != NULL);
4399 
4400  USE_UNWANTED_PARAM(dtag);
4401 
4402 #ifndef DEBUG_LCN_DESC
4403  USE_UNWANTED_PARAM(db_print);
4404 #endif
4405 
4406  dlen = *dptr;
4407  dptr++;
4408  end_ptr = dptr + dlen;
4409 
4410  if (dlen >= 4)
4411  {
4412  num_entries = dlen / 4; // each entry in the descriptor is 4 bytes long
4413  #ifdef DEBUG_LCN_DESC
4414  if (db_print == TRUE)
4415  {
4416  STB_SI_PRINT((" Logical channel desc 0x%02x: %d entries", dtag, num_entries));
4417  }
4418  #else
4419  USE_UNWANTED_PARAM(db_print);
4420  #endif
4421 
4422  // check if there are already entries in the array (i.e. already received a descriptor)
4423  // if so add to the existing array, otherwise create new array
4424  if (*array_ptr == NULL)
4425  {
4426  // no entries already - create new array
4427  lcns = (SI_LCN_DESC *)STB_GetMemory(num_entries * sizeof(SI_LCN_DESC));
4428  }
4429  else
4430  {
4431  // already got entries - make array bigger
4432  num_entries += *num_ptr;
4433  lcns = (SI_LCN_DESC *)STB_GetMemory(num_entries * sizeof(SI_LCN_DESC));
4434  if (lcns != NULL)
4435  {
4436  // copy over previous entries and free old array
4437  memcpy(lcns, *array_ptr, (*num_ptr * sizeof(SI_LCN_DESC)));
4438  STB_FreeMemory(*array_ptr);
4439  }
4440  }
4441 
4442  // add new entries to array
4443  if (lcns != NULL)
4444  {
4445  for (i = *num_ptr; i < num_entries; i++)
4446  {
4447  lcns[i].serv_id = (dptr[0] << 8) | dptr[1];
4448  lcns[i].serv_lcn = ((dptr[2] & 0x03) << 8) | dptr[3];
4449 
4450  /* The 1-bit field 'service visible' flag is defined in the E-Book
4451  * but not in the UK's D-Book, where this bit is a reserved bit. However,
4452  * all reserved bits are defined as being set to '1' */
4453  if ((dptr[2] & 0x80) != 0)
4454  {
4455  lcns[i].visible = TRUE;
4456  }
4457  else
4458  {
4459  lcns[i].visible = FALSE;
4460  }
4461 
4462  dptr += 4;
4463  #ifdef DEBUG_LCN_DESC
4464  if (db_print == TRUE)
4465  {
4466  STB_SI_PRINT((" id=0x%04x, lcn=%d, visible=%s", lcns[i].serv_id, lcns[i].serv_lcn,
4467  (lcns[i].visible ? "TRUE" : "FALSE")));
4468  }
4469  #endif
4470  }
4471  *array_ptr = lcns;
4472  *num_ptr = num_entries;
4473  }
4474  else
4475  {
4476  #ifdef DEBUG_LCN_DESC
4477  if (db_print == TRUE)
4478  {
4479  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
4480  }
4481  #endif
4482  }
4483  }
4484  else
4485  {
4486  #ifdef DEBUG_LCN_DESC
4487  if (db_print == TRUE)
4488  {
4489  STB_SI_PRINT((" Invalid Logical channel desc: (%d bytes)", dlen));
4490  }
4491  #endif
4492  }
4493 
4494  FUNCTION_FINISH(ParseLogicalChannelDescriptor);
4495  return(end_ptr);
4496 }
4497 
4512 static U8BIT* ParseServiceAttributeDescriptor(U8BIT *dptr, U16BIT *num_ptr,
4513  SI_SERV_ATTRIBUTE_DESC **array_ptr, BOOLEAN db_print)
4514 {
4515  U8BIT dlen;
4516  U8BIT *end_ptr;
4517  U16BIT num_entries;
4518  SI_SERV_ATTRIBUTE_DESC *array;
4519  U16BIT i;
4520 
4521  FUNCTION_START(ParseServiceAttributeDescriptor);
4522 
4523  ASSERT(dptr != NULL);
4524  ASSERT(num_ptr != NULL);
4525  ASSERT(array_ptr != NULL);
4526 
4527  dlen = *dptr;
4528  dptr++;
4529  end_ptr = dptr + dlen;
4530 
4531  if (dlen >= 3)
4532  {
4533  num_entries = dlen / 3; // each entry in the descriptor is 3 bytes long
4534 #ifdef DEBUG_LCN_DESC
4535  if (db_print == TRUE)
4536  {
4537  STB_SI_PRINT((" Service attribute desc: %d entries", num_entries));
4538  }
4539  #else
4540  USE_UNWANTED_PARAM(db_print);
4541 #endif
4542 
4543  // check if there are already entries in the array (i.e. already received a descriptor)
4544  // if so add to the existing array, otherwise create new array
4545  if (*array_ptr == NULL)
4546  {
4547  // no entries already - create new array
4548  array = (SI_SERV_ATTRIBUTE_DESC *)STB_GetMemory(num_entries * sizeof(SI_SERV_ATTRIBUTE_DESC));
4549  }
4550  else
4551  {
4552  // already got entries - make array bigger
4553  num_entries += *num_ptr;
4554  array = (SI_SERV_ATTRIBUTE_DESC *)STB_GetMemory(num_entries * sizeof(SI_SERV_ATTRIBUTE_DESC));
4555  if (array != NULL)
4556  {
4557  // copy over previous entries and free old array
4558  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_SERV_ATTRIBUTE_DESC)));
4559  STB_FreeMemory(*array_ptr);
4560  }
4561  }
4562 
4563  // add new entries to array
4564  if (array != NULL)
4565  {
4566  for (i = *num_ptr; i < num_entries; i++)
4567  {
4568  array[i].serv_id = (dptr[0] << 8) | dptr[1];
4569  /* If the service is visible then it is also selectable */
4570  if ((dptr[2] & 0x01) != 0)
4571  {
4572  array[i].service_visible = TRUE;
4573  array[i].service_selectable = TRUE;
4574  }
4575  else
4576  {
4577  array[i].service_visible = FALSE;
4578  if ((dptr[2] & 0x02) != 0)
4579  {
4580  array[i].service_selectable = TRUE;
4581  }
4582  else
4583  {
4584  array[i].service_selectable = FALSE;
4585  }
4586  }
4587 
4588  dptr += 3;
4589 #ifdef DEBUG_LCN_DESC
4590  if (db_print == TRUE)
4591  {
4592  STB_SI_PRINT((" id=0x%04x, visible=%d, selectable=%d", array[i].serv_id,
4593  array[i].service_visible, array[i].service_selectable));
4594  }
4595 #endif
4596  }
4597  *array_ptr = array;
4598  *num_ptr = num_entries;
4599  }
4600  else
4601  {
4602 #ifdef DEBUG_LCN_DESC
4603  if (db_print == TRUE)
4604  {
4605  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
4606  }
4607 #endif
4608  }
4609  }
4610  else
4611  {
4612 #ifdef DEBUG_LCN_DESC
4613  if (db_print == TRUE)
4614  {
4615  STB_SI_PRINT((" Invalid service attribute desc: (%d bytes)", dlen));
4616  }
4617 #endif
4618  }
4619 
4620  FUNCTION_FINISH(ParseServiceAttributeDescriptor);
4621  return(end_ptr);
4622 }
4623 
4638 static U8BIT* ParseNordigLCN2Descriptor(U8BIT *dptr, U16BIT *num_ptr, SI_NORDIG_LCN_DESC **array_ptr,
4639  BOOLEAN db_print)
4640 {
4641  U8BIT dlen;
4642  U8BIT *end_ptr;
4643  U16BIT num_entries;
4644  SI_NORDIG_LCN_DESC *array;
4645  U16BIT i, j;
4646 
4647  FUNCTION_START(ParseNordigLCN2Descriptor);
4648 
4649  ASSERT(dptr != NULL);
4650  ASSERT(num_ptr != NULL);
4651  ASSERT(array_ptr != NULL);
4652 
4653  dlen = *dptr;
4654  dptr++;
4655  end_ptr = dptr + dlen;
4656 
4657  num_entries = *num_ptr;
4658 
4659  #ifdef DEBUG_LCN_DESC
4660  if (db_print == TRUE)
4661  {
4662  STB_SI_PRINT((" Nordig logical channel desc:"));
4663  }
4664  #else
4665  USE_UNWANTED_PARAM(db_print);
4666  #endif
4667 
4668  for (i = num_entries; dlen > 6; i++)
4669  {
4670  /* Check if there are already entries in the array (i.e. already received a descriptor)
4671  * and if so add to the existing array, otherwise create new array */
4672  array = (SI_NORDIG_LCN_DESC *)STB_GetMemory((num_entries + 1) * sizeof(SI_NORDIG_LCN_DESC));
4673 
4674  num_entries++;
4675  if ((array != NULL) && (*array_ptr != NULL))
4676  {
4677  /* already got entries - copy over previous entries and free old array */
4678  memcpy(array, *array_ptr, (num_entries * sizeof(SI_NORDIG_LCN_DESC)));
4679  STB_FreeMemory(*array_ptr);
4680  }
4681 
4682  /* add new entries to array */
4683  if (array != NULL)
4684  {
4685  array[i].chan_list_id = *dptr;
4686  dptr++;
4687 
4688  /* Read the channel list name */
4689  dptr = STB_SIReadString(*dptr, dptr + 1, &array[i].chan_list_name);
4690 
4691  dptr = ReadLanguageCode(dptr, &array[i].country_code);
4692 
4693  /* Each entry in serv/LCN list is 4 bytes in size */
4694  array[i].num_services = *dptr / 4;
4695 
4696  #ifdef DEBUG_LCN_DESC
4697  if (db_print)
4698  {
4699  char *tmp_str = "";
4700  U32BIT lang = array[i].country_code;
4701 
4702  if (array[i].chan_list_name != NULL)
4703  {
4704  if (array[i].chan_list_name->str_ptr != NULL)
4705  {
4706  tmp_str = (char *)array[i].chan_list_name->str_ptr;
4707  }
4708  }
4709 
4710  STB_SI_PRINT((" list_id=%u, list_name=\"%s\", lang=%c%c%c, num servs=%u",
4711  array[i].chan_list_id, tmp_str, (lang >> 16), (lang >> 8), lang,
4712  array[i].num_services));
4713  }
4714  #endif
4715 
4716  if (array[i].num_services > 0)
4717  {
4718  array[i].serv_array = (SI_NORDIG_SERV_LCN *)STB_GetMemory(array[i].num_services * sizeof(SI_NORDIG_SERV_LCN));
4719  if (array[i].serv_array != NULL)
4720  {
4721  dptr++;
4722 
4723  for (j = 0; j < array[i].num_services; j++)
4724  {
4725  array[i].serv_array[j].serv_id = (dptr[0] << 8) | dptr[1];
4726  array[i].serv_array[j].visible = ((dptr[2] & 0x80) != 0) ? TRUE : FALSE;
4727  array[i].serv_array[j].serv_lcn = ((dptr[2] & 0x03) << 8) | dptr[3];
4728  dptr += 4;
4729 
4730  #ifdef DEBUG_LCN_DESC
4731  if (db_print == TRUE)
4732  {
4733  STB_SI_PRINT((" id=0x%04x, lcn=%d, visible=%s", array[i].serv_array[j].serv_id,
4734  array[i].serv_array[j].serv_lcn,
4735  (array[i].serv_array[j].visible ? "TRUE" : "FALSE")));
4736  }
4737  #endif
4738  }
4739  }
4740  else
4741  {
4742  array[i].num_services = 0;
4743  dptr += *dptr;
4744  dptr++;
4745  }
4746  }
4747  else
4748  {
4749  array[i].serv_array = NULL;
4750  dptr += *dptr;
4751  dptr++;
4752  }
4753 
4754  *array_ptr = array;
4755  }
4756  else
4757  {
4758  #ifdef DEBUG_LCN_DESC
4759  if (db_print == TRUE)
4760  {
4761  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
4762  }
4763  #endif
4764  }
4765 
4766  /* Calculate the number of bytes left to be processed */
4767  dlen = end_ptr - dptr;
4768  }
4769 
4770  *num_ptr = num_entries;
4771 
4772  FUNCTION_FINISH(ParseNordigLCN2Descriptor);
4773  return(end_ptr);
4774 }
4775 
4789 static U8BIT* ParsePreferredNameIdDescriptor(U8BIT *dptr, U8BIT *id_ptr, BOOLEAN db_print)
4790 {
4791  U8BIT dlen;
4792  U8BIT *end_ptr;
4793 
4794  FUNCTION_START(ParsePreferredNameIdDescriptor);
4795 
4796  ASSERT(dptr != NULL);
4797  ASSERT(id_ptr != NULL);
4798 
4799  dlen = *dptr;
4800  dptr++;
4801  end_ptr = dptr + dlen;
4802 
4803  if (dlen == 1)
4804  {
4805  *id_ptr = dptr[0];
4806  #ifdef DEBUG_PREF_NAME_ID_DESC
4807  if (db_print == TRUE)
4808  {
4809  STB_SI_PRINT((" Preferred name id desc: id=%d", *id_ptr));
4810  }
4811  #else
4812  USE_UNWANTED_PARAM(db_print);
4813  #endif
4814  }
4815  else
4816  {
4817  *id_ptr = 0;
4818  #ifdef DEBUG_PREF_NAME_ID_DESC
4819  if (db_print == TRUE)
4820  {
4821  STB_SI_PRINT((" Invalid Preferred name id desc: (%d bytes)", dlen));
4822  }
4823  #endif
4824  }
4825 
4826  FUNCTION_FINISH(ParsePreferredNameIdDescriptor);
4827  return(end_ptr);
4828 }
4829 
4844 static U8BIT* ParsePreferredNameListDescriptor(U8BIT *dptr, U16BIT *num_ptr,
4845  SI_PREFERRED_NAME_DESC **array_ptr, BOOLEAN db_print)
4846 {
4847  U8BIT dlen;
4848  U8BIT *end_ptr;
4849  U16BIT num_entries;
4850  SI_PREFERRED_NAME_DESC *array;
4851  U16BIT i;
4852  U8BIT *tmp_ptr;
4853  U8BIT name_len;
4854  U16BIT name_count;
4855  U16BIT entry_no;
4856  U32BIT lang_code;
4857 
4858  FUNCTION_START(ParsePreferredNameListDescriptor);
4859 
4860  ASSERT(dptr != NULL);
4861  ASSERT(num_ptr != NULL);
4862  ASSERT(array_ptr != NULL);
4863 
4864  dlen = *dptr;
4865  dptr++;
4866  end_ptr = dptr + dlen;
4867 
4868  if (dlen >= 4)
4869  {
4870  // work out number of entries
4871  num_entries = 0;
4872  tmp_ptr = dptr;
4873  while (tmp_ptr < end_ptr)
4874  {
4875  name_count = tmp_ptr[3]; // read name count
4876  tmp_ptr += 4; // skip language code and name count
4877  for (i = 0; i < name_count; i++)
4878  {
4879  name_len = tmp_ptr[1]; // read name length
4880  tmp_ptr += (name_len + 2); // skip name id, name length and name
4881  }
4882  num_entries += name_count;
4883  }
4884 
4885  #ifdef DEBUG_PREF_NAME_LIST_DESC
4886  if (db_print == TRUE)
4887  {
4888  STB_SI_PRINT((" Preferred name list desc: %d entries", num_entries));
4889  }
4890  #else
4891  USE_UNWANTED_PARAM(db_print);
4892  #endif
4893 
4894  // check if there are already entries in the array (i.e. already received a descriptor)
4895  // if so add to the existing array, otherwise create new array
4896  if (*array_ptr == NULL)
4897  {
4898  // no entries already - create new array
4899  array = (SI_PREFERRED_NAME_DESC *)STB_GetMemory(num_entries * sizeof(SI_PREFERRED_NAME_DESC));
4900  }
4901  else
4902  {
4903  // already got entries - make array bigger
4904  num_entries += *num_ptr;
4905  array = (SI_PREFERRED_NAME_DESC *)STB_GetMemory(num_entries * sizeof(SI_PREFERRED_NAME_DESC));
4906  if (array != NULL)
4907  {
4908  // copy over previous entries and free old array
4909  memcpy(array, *array_ptr, (*num_ptr * sizeof(SI_PREFERRED_NAME_DESC)));
4910  STB_FreeMemory(*array_ptr);
4911  }
4912  }
4913 
4914  // add new entries to array
4915  if (array != NULL)
4916  {
4917  entry_no = *num_ptr;
4918  while ((dptr < end_ptr) && (entry_no < num_entries))
4919  {
4920  dptr = ReadLanguageCode(dptr, &lang_code);
4921  name_count = dptr[0];
4922  dptr++;
4923  for (i = 0; i < name_count; i++, entry_no++)
4924  {
4925  array[entry_no].lang_code = lang_code;
4926  array[entry_no].name_id = dptr[0];
4927  dptr++;
4928  dptr = STB_SIReadString(dptr[0], dptr + 1, &array[entry_no].name_str);
4929 
4930  #ifdef DEBUG_PREF_NAME_LIST_DESC
4931  {
4932  char *tmp_str = "NULL";
4933 
4934  if (db_print == TRUE)
4935  {
4936  if (array[entry_no].name_str != NULL)
4937  {
4938  if (array[entry_no].name_str->str_ptr != NULL)
4939  {
4940  tmp_str = (char *)array[entry_no].name_str->str_ptr;
4941  }
4942  }
4943 
4944  STB_SI_PRINT((" lang=%c%c%c, id=%d, name=%s",
4945  (lang_code >> 16), (lang_code >> 8), lang_code, array[entry_no].name_id, tmp_str));
4946  }
4947  }
4948  #endif
4949  }
4950  }
4951  *array_ptr = array;
4952  *num_ptr = num_entries;
4953  }
4954  else
4955  {
4956  #ifdef DEBUG_PREF_NAME_LIST_DESC
4957  if (db_print == TRUE)
4958  {
4959  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
4960  }
4961  #endif
4962  }
4963  }
4964  else
4965  {
4966  #ifdef DEBUG_PREF_NAME_LIST_DESC
4967  if (db_print == TRUE)
4968  {
4969  STB_SI_PRINT((" Invalid Preferred name list desc: (%d bytes)", dlen));
4970  }
4971  #endif
4972  }
4973 
4974  FUNCTION_FINISH(ParsePreferredNameListDescriptor);
4975  return(end_ptr);
4976 }
4977 
4991 static U8BIT* ParseDefaultAuthorityDescriptor(U8BIT *dptr, SI_STRING_DESC **auth_ptr, BOOLEAN db_print)
4992 {
4993  U8BIT dlen;
4994  U8BIT *end_ptr;
4995 
4996  FUNCTION_START(ParseDefaultAuthorityDescriptor);
4997 
4998  ASSERT(dptr != NULL);
4999  ASSERT(auth_ptr != NULL);
5000 
5001  dlen = *dptr;
5002  dptr++;
5003  end_ptr = dptr + dlen;
5004 
5005  // this descriptor should only be received once in the NIT - if a name string already exists
5006  // then this must be a duplicate entry so ignore it
5007  if (*auth_ptr == NULL)
5008  {
5009  dptr = STB_SIReadString(dlen, dptr, auth_ptr);
5010 #ifdef DEBUG_DEF_AUTH_DESC
5011  {
5012  char *tmp_str = "NULL";
5013  if (db_print == TRUE)
5014  {
5015  if (*auth_ptr != NULL)
5016  {
5017  if ((*auth_ptr)->str_ptr != NULL)
5018  {
5019  tmp_str = (char *)(*auth_ptr)->str_ptr;
5020  }
5021  }
5022  STB_SI_PRINT((" Default authority desc=\"%s\"", tmp_str));
5023  }
5024  }
5025  #else
5026  USE_UNWANTED_PARAM(db_print);
5027 #endif
5028  }
5029  else
5030  {
5031 #ifdef DEBUG_DEF_AUTH_DESC
5032  if (db_print == TRUE)
5033  {
5034  STB_SI_PRINT((" Default authority desc: duplicate entry ignored"));
5035  }
5036 #endif
5037  }
5038 
5039  USE_UNWANTED_PARAM(dptr);
5040  FUNCTION_FINISH(ParseDefaultAuthorityDescriptor);
5041  return(end_ptr);
5042 }
5043 
5059 static U8BIT* ParseContentIdentifierDescriptor(U8BIT *dptr, U8BIT *num_ptr,
5060  SI_CRID_DESC **list_ptr, SI_CRID_DESC **last_entry_ptr,
5061  BOOLEAN db_print)
5062 {
5063  U8BIT dlen;
5064  U8BIT *end_ptr;
5065  U8BIT crid_type;
5066  U8BIT location;
5067  SI_CRID_DESC *crid_entry;
5068 
5069  FUNCTION_START(ParseContentIdentifierDescriptor);
5070 
5071  ASSERT(dptr != NULL);
5072  ASSERT(num_ptr != NULL);
5073  ASSERT(list_ptr != NULL);
5074  ASSERT(last_entry_ptr != NULL);
5075 
5076  dlen = *dptr;
5077  dptr++;
5078  end_ptr = dptr + dlen;
5079 
5080  if (dlen >= 3)
5081  {
5082  while (dptr < end_ptr)
5083  {
5084  crid_type = *dptr;
5085  dptr++;
5086 
5087  /* Top 2 bits of the first byte define the 'location'. The current profile
5088  * only supports location='00' */
5089  location = (crid_type & CRID_LOCATION_MASK);
5090  if (location == CRID_LOCATION_0)
5091  {
5092  /* Location is valid so it can now be ignored. The rest of the byte defines the CRID type */
5093  crid_type &= CRID_TYPE_MASK;
5094  crid_type >>= CRID_TYPE_SHIFT;
5095 
5096  crid_entry = (SI_CRID_DESC *)STB_GetMemory(sizeof(SI_CRID_DESC));
5097 
5098  crid_entry->next = NULL;
5099  crid_entry->type = crid_type;
5100 
5101  dptr = STB_SIReadString(dptr[0], dptr + 1, &crid_entry->crid_str);
5102 
5103 #ifdef DEBUG_CID_DESC
5104  if (db_print == TRUE)
5105  {
5106  STB_SI_PRINT((" EIT CRID type: 0x%x, CRID=\"%s\"", crid_type, crid_entry->crid_str->str_ptr));
5107  }
5108  #else
5109  USE_UNWANTED_PARAM(db_print);
5110 #endif
5111 
5112  if (*last_entry_ptr == NULL)
5113  {
5114  /* First entry in the list */
5115  *list_ptr = crid_entry;
5116  }
5117  else
5118  {
5119  /* Not the first entry */
5120  (*last_entry_ptr)->next = crid_entry;
5121  }
5122 
5123  *last_entry_ptr = crid_entry;
5124  (*num_ptr)++;
5125  }
5126  else
5127  {
5128 #ifdef DEBUG_CID_DESC
5129  if (db_print == TRUE)
5130  {
5131  STB_SI_PRINT((" Invalid CRID location: 0x%x", (U32BIT)location));
5132  }
5133 #endif
5134  if (location == CRID_LOCATION_1)
5135  {
5136  dptr += 2;
5137  }
5138  }
5139  }
5140  }
5141  else
5142  {
5143 #ifdef DEBUG_CID_DESC
5144  if ((db_print == TRUE) && (dlen != 0))
5145  {
5146  STB_SI_PRINT((" Invalid content identifier desc: (%d bytes)", dlen));
5147  }
5148 #endif
5149  }
5150 
5151  FUNCTION_FINISH(ParseContentIdentifierDescriptor);
5152  return(end_ptr);
5153 }
5154 
5155 /*!**************************************************************************
5156  * @brief Reads the network change notify descriptor that is being defined for use
5157  * in broadcasts to indicate when automatic rescans should be performed. Only
5158  * one change notify entry can be present, so if one already exists then this
5159  * one won't be parsed.
5160  * @param dptr - pointer to length byte of descriptor
5161  * @param num_change_notifies - pointer to return new number of entries in the array
5162  * @param desc_ptr - address of pointer so that the parsed structure can be returned
5163  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
5164  * @return Updated value of current data byte address i.e. at end of descriptor
5165  ****************************************************************************/
5166 static U8BIT* ParseNetworkChangeNotifyDescriptor(U8BIT *dptr, U16BIT *num_change_notifies,
5167  SI_NIT_CHANGE_NOTIFY_DESC **desc_ptr, BOOLEAN db_print)
5168 {
5169  U8BIT dlen;
5170  U8BIT *end_ptr;
5171  U8BIT loop_length;
5172  U8BIT i;
5174  SI_NIT_CHANGE_ENTRY *entry;
5175 
5176  FUNCTION_START(ParseNetworkChangeNotifyDescriptor);
5177 
5178  #ifndef DEBUG_SI_NIT_CONTENT
5179  USE_UNWANTED_PARAM(db_print);
5180  #endif
5181 
5182  dlen = *dptr;
5183  dptr++;
5184  end_ptr = dptr + dlen;
5185 
5186  /* Skip the extension descriptor tag as this has already been checked */
5187  dptr++;
5188 
5189  if (dlen >= 3)
5190  {
5191  /* There can be more than one descriptor per NIT */
5192  if (*num_change_notifies == 0)
5193  {
5195  *num_change_notifies = 1;
5196  desc = *desc_ptr;
5197  }
5198  else
5199  {
5200  *num_change_notifies += 1;
5201  *desc_ptr = (SI_NIT_CHANGE_NOTIFY_DESC *)STB_ResizeMemory(*desc_ptr,
5202  *num_change_notifies * sizeof(SI_NIT_CHANGE_NOTIFY_DESC));
5203  desc = &(*desc_ptr)[*num_change_notifies - 1];
5204  }
5205 
5206  if (desc != NULL)
5207  {
5208  desc->cell_id = (dptr[0] << 8) + dptr[1];
5209  dptr += 2;
5210 
5211  #ifdef DEBUG_SI_NIT_CONTENT
5212  if (db_print)
5213  {
5214  STB_SI_PRINT((" Change notify for cell_id 0x%04x", desc->cell_id));
5215  }
5216  #endif
5217 
5218  loop_length = *dptr;
5219  dptr++;
5220 
5221  desc->num_changes = 0;
5222  desc->change_array = NULL;
5223 
5224  /* As the size of an entry in the array can vary depending on whether it includes
5225  * the invariant IDs, the array has to be built as each entry is decoded */
5226  for (i = 0; (loop_length >= 12) && (dptr < end_ptr); i++)
5227  {
5228  if (desc->change_array == NULL)
5229  {
5230  desc->change_array = (SI_NIT_CHANGE_ENTRY *)STB_GetMemory(sizeof(SI_NIT_CHANGE_ENTRY));
5231  }
5232  else
5233  {
5234  desc->change_array = (SI_NIT_CHANGE_ENTRY *)STB_ResizeMemory(desc->change_array,
5235  (desc->num_changes + 1) * sizeof(SI_NIT_CHANGE_ENTRY));
5236  }
5237 
5238  entry = &desc->change_array[desc->num_changes];
5239 
5240  desc->num_changes++;
5241 
5242  memset(entry, 0, sizeof(SI_NIT_CHANGE_ENTRY));
5243 
5244  entry->change_id = *dptr;
5245  dptr++;
5246 
5247  entry->version = *dptr;
5248  dptr++;
5249 
5250  #ifdef DEBUG_SI_NIT_CONTENT
5251  if (db_print)
5252  {
5253  STB_SI_PRINT((" Change id %u, version %u", entry->change_id, entry->version));
5254  }
5255  #endif
5256 
5257  entry->start_date = (dptr[0] << 8) | dptr[1];
5258  entry->start_hours = ((dptr[2] >> 4) * 10) + (dptr[2] & 0x0f);
5259  entry->start_mins = ((dptr[3] >> 4) * 10) + (dptr[3] & 0x0f);
5260  entry->start_secs = ((dptr[4] >> 4) * 10) + (dptr[4] & 0x0f);
5261  dptr += 5;
5262 
5263  entry->dur_hours = ((dptr[0] >> 4) * 10) + (dptr[0] & 0x0f);
5264  entry->dur_mins = ((dptr[1] >> 4) * 10) + (dptr[1] & 0x0f);
5265  entry->dur_secs = ((dptr[2] >> 4) * 10) + (dptr[2] & 0x0f);
5266  dptr += 3;
5267 
5268  entry->receiver_category = (*dptr >> 5);
5269 
5270  if ((*dptr & 0x10) != 0)
5271  {
5272  entry->invariant_ts_present = TRUE;
5273  }
5274 
5275  entry->change_type = *dptr & 0x0f;
5276  dptr++;
5277 
5278  entry->message_id = *dptr;
5279  dptr++;
5280 
5281  loop_length -= 12;
5282 
5283  #ifdef DEBUG_SI_NIT_CONTENT
5284  if (db_print)
5285  {
5286  STB_SI_PRINT((" Starts on %u @ %02u:%02u:%02u, duration %02u:%02u:%02u",
5287  entry->start_date, entry->start_hours, entry->start_mins, entry->start_secs,
5288  entry->dur_hours, entry->dur_mins, entry->dur_secs));
5289  STB_SI_PRINT((" Receiver type %u, change type %u", entry->receiver_category,
5290  entry->change_type));
5291  STB_SI_PRINT((" Message id %u", entry->message_id));
5292  }
5293  #endif
5294 
5295  if (entry->invariant_ts_present && (loop_length >= 4))
5296  {
5297  /* Read invariant transport stream ids */
5298  entry->invariant_ts_tsid = (U16BIT)(dptr[0] << 8) + dptr[1];
5299  entry->invariant_ts_onid = (U16BIT)(dptr[2] << 8) + dptr[3];
5300 
5301  dptr += 4;
5302  loop_length -= 4;
5303 
5304  #ifdef DEBUG_SI_NIT_CONTENT
5305  if (db_print)
5306  {
5307  STB_SI_PRINT((" Invariant TS ids: tsid=0x%04x, onid=0x%04x", entry->invariant_ts_tsid,
5308  entry->invariant_ts_onid));
5309  }
5310  #endif
5311  }
5312  }
5313  }
5314  }
5315 
5316  FUNCTION_FINISH(ParseNetworkChangeNotifyDescriptor);
5317 
5318  return(end_ptr);
5319 }
5320 
5321 /*!**************************************************************************
5322  * @brief Reads the network change info descriptor that contains messages to be
5323  * presented to the user. More than one of these can exist in the NIT.
5324  * @param dptr - pointer to length byte of descriptor
5325  * @param num_messages - pointer to the count of entries already in the following array.
5326  * The value will be updated in this function.
5327  * @param message_array - address of array containing info descriptors already found in the NIT.
5328  * The array may be increased in this function, so the array pointer
5329  * may be different on exit from this function.
5330  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
5331  * @return Updated value of current data byte address i.e. at end of descriptor
5332  ****************************************************************************/
5333 static U8BIT* ParseMessageDescriptor(U8BIT *dptr, U16BIT *num_messages,
5334  SI_NIT_MESSAGE_ENTRY **message_array, BOOLEAN db_print)
5335 {
5336  U8BIT dlen;
5337  U8BIT *end_ptr;
5338  SI_NIT_MESSAGE_ENTRY *entry;
5339 
5340  FUNCTION_START(ParseMessageDescriptor);
5341 
5342  #ifndef DEBUG_SI_NIT_CONTENT
5343  USE_UNWANTED_PARAM(db_print);
5344  #endif
5345 
5346  dlen = *dptr;
5347  dptr++;
5348  end_ptr = dptr + dlen;
5349 
5350  /* Skip the extension descriptor tag as this has already been checked */
5351  dptr++;
5352 
5353  if (dlen > 5)
5354  {
5355  if (*message_array == NULL)
5356  {
5357  /* No entries in the array yet */
5358  *message_array = (SI_NIT_MESSAGE_ENTRY *)STB_GetMemory(sizeof(SI_NIT_MESSAGE_ENTRY));
5359  *num_messages = 1;
5360  entry = *message_array;
5361  }
5362  else
5363  {
5364  *num_messages += 1;
5365  *message_array = (SI_NIT_MESSAGE_ENTRY *)STB_ResizeMemory(*message_array,
5366  *num_messages * sizeof(SI_NIT_MESSAGE_ENTRY));
5367  entry = &(*message_array)[*num_messages - 1];
5368  }
5369 
5370  if (entry != NULL)
5371  {
5372  entry->message_id = *dptr;
5373  dptr++;
5374 
5375  dptr = ReadLanguageCode(dptr, &entry->lang_code);
5376 
5377  dptr = STB_SIReadString(dlen - 5, dptr, &entry->message);
5378 
5379  #ifdef DEBUG_SI_NIT_CONTENT
5380  if (db_print)
5381  {
5382  STB_SI_PRINT((" Message id %u, lang \"%c%c%c\"", entry->message_id,
5383  (entry->lang_code >> 16) & 0xff, (entry->lang_code >> 8) & 0xff, entry->lang_code & 0xff));
5384  if ((*entry->message->str_ptr >= 0x20) && (*entry->message->str_ptr <= 0x7f))
5385  {
5386  STB_SI_PRINT((" \"%s\"", entry->message->str_ptr));
5387  }
5388  else
5389  {
5390  STB_SI_PRINT((" message is non-ascii"));
5391  }
5392  }
5393  #endif
5394  }
5395  }
5396 
5397  USE_UNWANTED_PARAM(dptr);
5398  FUNCTION_FINISH(ParseMessageDescriptor);
5399 
5400  return(end_ptr);
5401 }
5402 
5403 /*!**************************************************************************
5404  * @brief Reads the target region name descriptor. More than one of these can exist in an NIT
5405  * @param dptr - pointer to length byte of descriptor
5406  * @param desc_list - address of pointer to the first entry in the list
5407  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
5408  * @return Updated value of current data byte address i.e. at end of descriptor
5409  ****************************************************************************/
5410 static U8BIT* ParseTargetRegionNameDescriptor(U8BIT *dptr, SI_NIT_TARGET_REGION_NAME_DESC **desc_list,
5411  BOOLEAN db_print)
5412 {
5413  U8BIT dlen;
5414  U8BIT *end_ptr;
5415  U8BIT *eptr;
5416  U8BIT region_depth;
5417  U8BIT name_len;
5418  U8BIT i;
5420  SI_NIT_REGION_NAME *name_entry;
5421 
5422  FUNCTION_START(ParseTargetRegionNameDescriptor);
5423 
5424  #ifndef DEBUG_TARGET_REGION_DESC
5425  USE_UNWANTED_PARAM(db_print);
5426  #endif
5427 
5428  dlen = *dptr;
5429  dptr++;
5430  end_ptr = dptr + dlen;
5431 
5432  /* Skip the extension descriptor tag as this has already been checked */
5433  dptr++;
5434 
5435  if (dlen > 7)
5436  {
5438  if (entry != NULL)
5439  {
5440  dptr = ReadLanguageCode(dptr, &entry->country_code);
5441  dptr = ReadLanguageCode(dptr, &entry->lang_code);
5442 
5443  dlen -= 7;
5444 
5445  entry->num_names = 0;
5446  entry->name_array = NULL;
5447 
5448  /* Calculate the number of names in the descriptor */
5449  for (eptr = dptr; dlen > 0; )
5450  {
5451  region_depth = (*eptr >> 6) & 0x03;
5452  name_len = *eptr & 0x3f;
5453  eptr++;
5454  dlen--;
5455  if (name_len > 0)
5456  {
5457  entry->num_names++;
5458  }
5459  eptr += name_len;
5460  dlen -= name_len;
5461  eptr++;
5462  dlen--;
5463  if (region_depth >= 2)
5464  {
5465  eptr++;
5466  dlen--;
5467  if (region_depth == 3)
5468  {
5469  eptr += 2;
5470  dlen -= 2;
5471  }
5472  }
5473  }
5474 
5475 #ifdef DEBUG_TARGET_REGION_DESC
5476  if (db_print)
5477  {
5478  STB_SI_PRINT((" Target region name: country=%c%c%c, lang=%c%c%c, num_names=%u",
5479  entry->country_code >> 16, entry->country_code >> 8, entry->country_code & 0xff,
5480  entry->lang_code >> 16, entry->lang_code >> 8, entry->lang_code & 0xff,
5481  entry->num_names));
5482  }
5483 #endif
5484 
5485  if (entry->num_names > 0)
5486  {
5487  entry->name_array = (SI_NIT_REGION_NAME *)STB_GetMemory(entry->num_names * sizeof(SI_NIT_REGION_NAME));
5488  if (entry->name_array != NULL)
5489  {
5490  for (i = 0; i < entry->num_names; i++)
5491  {
5492  name_entry = &entry->name_array[i];
5493  name_entry->region_depth = (*dptr >> 6) & 0x03;
5494 
5495  dptr = STB_SIReadString((dptr[0] & 0x3f), dptr + 1, &name_entry->region_name);
5496 
5497  name_entry->primary_region_code = *dptr;
5498  dptr++;
5499  if (name_entry->region_depth >= 2)
5500  {
5501  name_entry->secondary_region_code = *dptr;
5502  dptr++;
5503  if (name_entry->region_depth == 3)
5504  {
5505  name_entry->tertiary_region_code = (dptr[0] << 8) | dptr[1];
5506  dptr += 2;
5507  }
5508  }
5509 #ifdef DEBUG_TARGET_REGION_DESC
5510  if (db_print)
5511  {
5512  if (name_entry->region_depth == 3)
5513  {
5514  STB_SI_PRINT((" Tertiary region name: %u:%u:%u = \"%s\"",
5515  name_entry->primary_region_code, name_entry->secondary_region_code,
5516  name_entry->tertiary_region_code, name_entry->region_name->str_ptr));
5517  }
5518  else if (name_entry->region_depth == 2)
5519  {
5520  STB_SI_PRINT((" Secondary region name: %u:%u = \"%s\"",
5521  name_entry->primary_region_code, name_entry->secondary_region_code,
5522  name_entry->region_name->str_ptr));
5523  }
5524  else
5525  {
5526  STB_SI_PRINT((" Primary region name: %u = \"%s\"",
5527  name_entry->primary_region_code, name_entry->region_name->str_ptr));
5528  }
5529  }
5530 #endif
5531  }
5532  }
5533  }
5534 
5535  /* Add the entry to the start of the existing list */
5536  entry->next = *desc_list;
5537  *desc_list = entry;
5538  }
5539  }
5540 #ifdef DEBUG_TARGET_REGION_DESC
5541  else if (db_print)
5542  {
5543  STB_SI_PRINT((" Target region name desc, skipped, invalid size: %u", dlen));
5544  }
5545 #endif
5546 
5547  FUNCTION_FINISH(ParseTargetRegionNameDescriptor);
5548 
5549  return(end_ptr);
5550 }
5551 
5552 /*!**************************************************************************
5553  * @brief Reads the target region descriptor. More than one of these can exist in an NIT
5554  * @param dptr - pointer to length byte of descriptor
5555  * @param desc_list - address of pointer to the first entry in the list
5556  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
5557  * @return Updated value of current data byte address i.e. at end of descriptor
5558  ****************************************************************************/
5559 static U8BIT* ParseTargetRegionDescriptor(U8BIT *dptr, SI_TARGET_REGION_DESC **desc_list,
5560  BOOLEAN db_print)
5561 {
5562  U8BIT dlen;
5563  U8BIT *end_ptr;
5564  U32BIT country_code;
5565  U8BIT region_depth;
5566  SI_TARGET_REGION_DESC *cptr;
5567  SI_TARGET_REGION *rptr;
5568  BOOLEAN read_country;
5569 
5570  FUNCTION_START(ParseTargetRegionDescriptor);
5571 
5572  #ifndef DEBUG_TARGET_REGION_DESC
5573  USE_UNWANTED_PARAM(db_print);
5574  #endif
5575 
5576  dlen = *dptr;
5577  dptr++;
5578  end_ptr = dptr + dlen;
5579 
5580  /* Skip the extension descriptor tag as this has already been checked */
5581  dptr++;
5582  dlen--;
5583 
5584  read_country = TRUE;
5585 
5586  while (dlen >= 3)
5587  {
5588  cptr = NULL;
5589 
5590  if (read_country)
5591  {
5592  /* Descriptor starts with a country code */
5593  dptr = ReadLanguageCode(dptr, &country_code);
5594  dlen -= 3;
5595 
5596 #ifdef DEBUG_TARGET_REGION_DESC
5597  if (db_print)
5598  {
5599  STB_SI_PRINT((" Target region: country=%c%c%c",
5600  country_code >> 16, country_code >> 8, country_code & 0xff));
5601  }
5602 #endif
5603 
5604  /* Check whether there's an entry in the list for this country already */
5605  for (cptr = *desc_list; (cptr != NULL) && (cptr->country_code != country_code); )
5606  {
5607  cptr = cptr->next;
5608  }
5609 
5610  if (cptr == NULL)
5611  {
5612  /* This is a new country code */
5614  if (cptr != NULL)
5615  {
5616  cptr->country_code = country_code;
5617  cptr->region_list = NULL;
5618 
5619  /* Add the new entry to the start of the list */
5620  cptr->next = *desc_list;
5621  *desc_list = cptr;
5622  }
5623  }
5624 
5625  read_country = FALSE;
5626  }
5627 
5628  if (cptr != NULL)
5629  {
5630  while (!read_country && (dlen > 0))
5631  {
5632  if ((*dptr & 0x04) != 0)
5633  {
5634  read_country = TRUE;
5635  }
5636  else
5637  {
5638  /* Read the region codes */
5639  region_depth = *dptr & 0x03;
5640  dptr++;
5641  dlen--;
5642 
5643  if (region_depth > 0)
5644  {
5645  /* Create a new entry in the region list */
5646  rptr = (SI_TARGET_REGION *)STB_GetMemory(sizeof(SI_TARGET_REGION));
5647  if (rptr != NULL)
5648  {
5649  rptr->region_depth = region_depth;
5650  rptr->primary_region_code = *dptr;
5651  dptr++;
5652  dlen--;
5653 
5654  if (region_depth > 1)
5655  {
5656  rptr->secondary_region_code = *dptr;
5657  dptr++;
5658  dlen--;
5659 
5660  if (region_depth > 2)
5661  {
5662  rptr->tertiary_region_code = (dptr[0] << 8) | dptr[1];
5663  dptr += 2;
5664  dlen -= 2;
5665  }
5666  }
5667 
5668 #ifdef DEBUG_TARGET_REGION_DESC
5669  if (db_print)
5670  {
5671  if (rptr->region_depth == 3)
5672  {
5673  STB_SI_PRINT((" Tertiary region: %u:%u:%u",
5674  rptr->primary_region_code, rptr->secondary_region_code,
5675  rptr->tertiary_region_code));
5676  }
5677  else if (rptr->region_depth == 2)
5678  {
5679  STB_SI_PRINT((" Secondary region: %u:%u",
5680  rptr->primary_region_code, rptr->secondary_region_code));
5681  }
5682  else
5683  {
5684  STB_SI_PRINT((" Primary region: %u",
5685  rptr->primary_region_code));
5686  }
5687  }
5688 #endif
5689 
5690  /* Add the region to the start of the country's list */
5691  rptr->next = cptr->region_list;
5692  cptr->region_list = rptr;
5693  }
5694  }
5695  }
5696  }
5697  }
5698  }
5699 
5700  FUNCTION_FINISH(ParseTargetRegionDescriptor);
5701 
5702  return(end_ptr);
5703 }
5704 
5705 /*!**************************************************************************
5706  * @brief Reads the service availability descriptor.
5707  * @param dptr - pointer to length byte of descriptor
5708  * @param serv_avail_list - address of pointer to the first descriptor in
5709  * the list
5710  * @param db_print - if TRUE debug prints the contents of the descriptor
5711  * (for debug only)
5712  * @return Updated value of current data byte address i.e. at end of
5713  * descriptor
5714  ****************************************************************************/
5715 static U8BIT* ParseServiceAvailabilityDescriptor(U8BIT *dptr, SI_SERV_AVAIL_DESC **serv_avail_list, BOOLEAN db_print)
5716 {
5717  U8BIT dlen;
5718  U8BIT *end_ptr;
5719  U16BIT num_of_ids;
5720  U16BIT i;
5721  SI_SERV_AVAIL_DESC *desc;
5722 
5723  FUNCTION_START(ParseServiceAvailabilityDescriptor);
5724 
5725  #ifndef DEBUG_SI_SDT_CONTENT
5726  USE_UNWANTED_PARAM(db_print);
5727  #endif
5728 
5729  dlen = *dptr;
5730  dptr++;
5731  end_ptr = dptr + dlen;
5732 
5733 #ifdef DEBUG_SERV_AVAIL_DESC
5734  STB_SI_PRINT(("ParseServiceAvailabilityDescriptor: descriptor length = %d", dlen));
5735 #endif
5736  if (dlen >= 3)
5737  {
5738  num_of_ids = (dlen - 1) / 2;
5739 
5741  if (desc != NULL)
5742  {
5743  desc->next = *serv_avail_list;
5744  *serv_avail_list = desc;
5745 
5746 #ifdef DEBUG_SERV_AVAIL_DESC
5747  STB_SI_PRINT(("ParseServiceAvailabilityDescriptor: availability flag = %s", ((*dptr & 0x80) == 0) ? "FALSE" : "TRUE"));
5748 #endif
5749  if ((*dptr & 0x80) == 0)
5750  {
5751  desc->availability_flag = FALSE;
5752  }
5753  else
5754  {
5755  desc->availability_flag = TRUE;
5756  }
5757 
5758  dptr++;
5759 
5760  desc->cell_ids = (U16BIT *)STB_GetMemory(num_of_ids * 2);
5761  if (desc->cell_ids != NULL)
5762  {
5763  desc->num_of_cell_ids = num_of_ids;
5764  for (i = 0; i < num_of_ids; i++)
5765  {
5766  desc->cell_ids[i] = (dptr[0] << 8) + dptr[1];
5767 #ifdef DEBUG_SERV_AVAIL_DESC
5768  STB_SI_PRINT(("ParseServiceAvailabilityDescriptor: id[%d]=0x%x", i, desc->cell_ids[i]));
5769 #endif
5770  dptr += 2;
5771  }
5772  }
5773  }
5774  }
5775 
5776 #ifdef DEBUG_SERV_AVAIL_DESC
5777  STB_SI_PRINT(("ParseServiceAvailabilityDescriptor: end"));
5778 #endif
5779 
5780  FUNCTION_FINISH(ParseServiceAvailabilityDescriptor);
5781 
5782  return(end_ptr);
5783 }
5784 
5785 /*!**************************************************************************
5786  * @brief Reads the Supplementary Audio descriptor.
5787  * @param dptr - pointer to length byte of descriptor
5788  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
5789  * @return Updated value of current data byte address i.e. at end of descriptor
5790  ****************************************************************************/
5791 static U8BIT* ParseSupplementaryAudioDescriptor(U8BIT *dptr, SI_AD_DESC **audio_desc, BOOLEAN db_print)
5792 {
5793  U8BIT dlen;
5794  U8BIT *end_ptr;
5795  U8BIT lang_present;
5796 
5797  FUNCTION_START(ParseSupplementaryAudioDescriptor);
5798 
5799  ASSERT(dptr != NULL);
5800 
5801 #ifndef DEBUG_SUPP_AUDIO_DESC
5802  USE_UNWANTED_PARAM(db_print);
5803 #endif
5804 
5805  dlen = *dptr;
5806  dptr++;
5807  end_ptr = dptr + dlen;
5808 
5809  /* Skip the extension desc tag */
5810  dptr++;
5811 
5812  *audio_desc = (SI_AD_DESC *)STB_GetMemory(sizeof(SI_AD_DESC));
5813  if (*audio_desc != NULL)
5814  {
5815  (*audio_desc)->mix_type = (*dptr >> 7) & 0x1;
5816  (*audio_desc)->edit_class = (*dptr >> 2) & 0x1f;
5817  /* (*dptr & 0x2) is reserved */
5818  lang_present = *dptr & 0x1;
5819 
5820  if ((dlen >= 2) && (lang_present != 0))
5821  {
5822  dptr = ReadLanguageCode(&dptr[1], &((*audio_desc)->lang_code));
5823  }
5824  #ifdef DEBUG_SUPP_AUDIO_DESC
5825  else if (db_print)
5826  {
5827  STB_SI_PRINT((" Supplementary audio: invalid desc len %u", dlen));
5828  }
5829  #endif
5830 
5831 #ifdef DEBUG_SUPP_AUDIO_DESC
5832  if (db_print)
5833  {
5834  STB_SI_PRINT((" Supplementary audio: mix %s, class %u lang=%c%c%c",
5835  ((*audio_desc)->mix_type == 1 ? "independent" : "supplementary"),
5836  (*audio_desc)->edit_class,
5837  (char)((*audio_desc)->lang_code >> 16),
5838  (char)((*audio_desc)->lang_code >> 8),
5839  (char)(*audio_desc)->lang_code));
5840  STB_SI_PRINT((" data(%d):%*.*s", dlen - 5, dlen - 5, dlen - 5, dptr));
5841  }
5842 #endif
5843  }
5844  else
5845  {
5846 #ifdef DEBUG_SUPP_AUDIO_DESC
5847  if (db_print)
5848  {
5849  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
5850  }
5851 #endif
5852  }
5853 
5854  USE_UNWANTED_PARAM(dptr);
5855  FUNCTION_FINISH(ParseSupplementaryAudioDescriptor);
5856  return(end_ptr);
5857 }
5858 
5874 static U8BIT* ParseFreesatTunnelledDataDescriptor(U8BIT *dptr, U8BIT *num_entries,
5875  SI_FREESAT_TUNNELLED_DATA_DESC **desc_array, BOOLEAN alt_descriptor, BOOLEAN db_print)
5876 {
5877  U8BIT dlen;
5878  U8BIT *end_ptr;
5879  U8BIT i, num;
5880 
5881  FUNCTION_START(ParseFreesatTunnelledDataDescriptor);
5882 
5883  dlen = *dptr;
5884  dptr++;
5885  end_ptr = dptr + dlen;
5886 
5887  /* Work out the number of entries defined in the descriptor */
5888  if (alt_descriptor)
5889  {
5890  num = dlen;
5891  }
5892  else
5893  {
5894  num = dlen / 2;
5895  }
5896 
5897  if (num > 0)
5898  {
5899 #ifdef DEBUG_FREESAT_TUNNELLED_DATA_DESC
5900  if (db_print)
5901  {
5902  STB_SI_PRINT((" Freesat tunnelled data desc: alternative=%u, %u entries", alt_descriptor, num));
5903  }
5904 #else
5905  USE_UNWANTED_PARAM(db_print);
5906 #endif
5907  if (*desc_array != NULL)
5908  {
5909  *desc_array = (SI_FREESAT_TUNNELLED_DATA_DESC *)STB_ResizeMemory(*desc_array,
5910  (num + *num_entries) * sizeof(SI_FREESAT_TUNNELLED_DATA_DESC));
5911  }
5912  else
5913  {
5915  }
5916 
5917  if (*desc_array != NULL)
5918  {
5919  for (i = 0; i < num; i++)
5920  {
5921  (*desc_array)[i + *num_entries].data_type = *dptr;
5922  dptr++;
5923 
5924  if (!alt_descriptor)
5925  {
5926  /* Read the component tag */
5927  (*desc_array)[i + *num_entries].component_tag = *dptr;
5928  dptr++;
5929  }
5930 #ifdef DEBUG_FREESAT_TUNNELLED_DATA_DESC
5931  if (db_print)
5932  {
5933  if (alt_descriptor)
5934  {
5935  STB_SI_PRINT((" type=%u", (*desc_array)[i + *num_entries].data_type));
5936  }
5937  else
5938  {
5939  STB_SI_PRINT((" type=%u, tag=%u", (*desc_array)[i + *num_entries].data_type,
5940  (*desc_array)[i + *num_entries].component_tag));
5941  }
5942  }
5943 #endif
5944  }
5945 
5946  *num_entries += num;
5947  }
5948  }
5949 
5950  FUNCTION_FINISH(ParseFreesatTunnelledDataDescriptor);
5951 
5952  return(end_ptr);
5953 }
5954 
5968 static U8BIT* ParseRegionNameDescriptor(U8BIT *dptr, SI_BAT_FREESAT_REGION **region_list, BOOLEAN db_print)
5969 {
5970  U8BIT dlen;
5971  U8BIT *end_ptr;
5973 
5974  FUNCTION_START(ParseRegionNameDescriptor);
5975 
5976  USE_UNWANTED_PARAM(db_print);
5977 
5978  dlen = *dptr;
5979  dptr++;
5980  end_ptr = dptr + dlen;
5981 
5982  while (dptr < end_ptr)
5983  {
5984  if ((region = (SI_BAT_FREESAT_REGION *)STB_GetMemory(sizeof(SI_BAT_FREESAT_REGION))) != NULL)
5985  {
5986  region->region_id = (dptr[0] << 8) | (dptr[1]);
5987  dptr += 2;
5988  dptr = ReadLanguageCode(dptr, &region->lang_code);
5989  dptr = STB_SIReadString(dptr[0], dptr + 1, &region->region_name);
5990 
5991  /* Add the new region to the start of the list */
5992  region->next = *region_list;
5993  *region_list = region;
5994  }
5995  }
5996 
5997  FUNCTION_FINISH(ParseRegionNameDescriptor);
5998 
5999  return(end_ptr);
6000 }
6001 
6015 static U8BIT* ParseIActiveStorageDescriptor(U8BIT *dptr,
6016  SI_BAT_FREESAT_IACTIVE_STORAGE_DESC **desc_list, BOOLEAN db_print)
6017 {
6018  U8BIT dlen;
6019  U8BIT *end_ptr;
6021 
6022  FUNCTION_START(ParseIActiveStorageDescriptor);
6023 
6024  ASSERT(dptr != NULL);
6025 
6026  dlen = *dptr;
6027  dptr++;
6028  end_ptr = dptr + dlen;
6029 
6030  if (dlen > 0)
6031  {
6032  #ifdef DEBUG_PRIV_DATA_SPEC_DESC
6033  if (db_print == TRUE)
6034  {
6035  STB_SI_PRINT((" Interactive storage descriptor : (len = %d)", dlen));
6036  }
6037  #else
6038  USE_UNWANTED_PARAM(db_print);
6039  #endif
6040 
6042  if (new_entry != NULL)
6043  {
6044  memset(new_entry, 0, sizeof(SI_BAT_FREESAT_IACTIVE_STORAGE_DESC));
6045  new_entry->data = STB_GetMemory(dlen);
6046  if (new_entry->data != NULL)
6047  {
6048  memcpy(new_entry->data, dptr, dlen);
6049  new_entry->next_desc = *desc_list;
6050  new_entry->length = dlen;
6051  *desc_list = new_entry;
6052  }
6053  else
6054  {
6055  STB_FreeMemory(new_entry);
6056  }
6057  }
6058  }
6059  else
6060  {
6061  #ifdef DEBUG_PRIV_DATA_SPEC_DESC
6062  if (db_print == TRUE)
6063  {
6064  STB_SI_PRINT((" Invalid interactive storage descriptor: (%d bytes)", dlen));
6065  }
6066  #endif
6067  }
6068 
6069  FUNCTION_FINISH(ParseIActiveStorageDescriptor);
6070  return(end_ptr);
6071 }
6072 
6073 static U8BIT* ParseFreesatInfoLocationDescriptor(U8BIT *dptr,
6074  SI_BAT_FREESAT_INFO_LOCATION **location_list, BOOLEAN db_print)
6075 {
6076  U8BIT dlen;
6077  U8BIT *end_ptr;
6078  U8BIT loop_len;
6079  SI_BAT_FREESAT_INFO_LOCATION *new_entry;
6080  SI_BAT_FREESAT_INFO_LOCATION **last_pointer;
6081 
6082  FUNCTION_START(ParseFreesatInfoLocationDescriptor);
6083 
6084  dlen = *dptr;
6085  dptr++;
6086  end_ptr = dptr + dlen;
6087 
6088  /* find the last pointer in the list (i.e. pointing to NULL) */
6089  last_pointer = location_list;
6090  while (*last_pointer)
6091  last_pointer = &((*last_pointer)->next);
6092 
6093  if (dlen > 2)
6094  {
6095  #ifdef DEBUG_FREESAT_INFO_LOCATION_DESC
6096  if (db_print)
6097  {
6098  STB_SI_PRINT((" %s:", __FUNCTION__));
6099  }
6100  #else
6101  USE_UNWANTED_PARAM(db_print);
6102  #endif
6103 
6104  while (dptr < end_ptr)
6105  {
6106  /* Home loop length is profiled to be 0 bytes long, but skip it anyway */
6107  dptr += *dptr + 1;
6108 
6109  /* Extract the tunnelled values */
6110  loop_len = *dptr;
6111  dptr++;
6112  #ifdef DEBUG_FREESAT_INFO_LOCATION_DESC
6113  if (db_print)
6114  {
6115  STB_SI_PRINT((" tunnelled loop length = %u", loop_len));
6116  }
6117  #endif
6118 
6119  while ((loop_len >= 6) && (dptr < end_ptr))
6120  {
6122  if (new_entry != NULL)
6123  {
6124  memset(new_entry, 0, sizeof(*new_entry));
6125 
6126  new_entry->transport_id = (dptr[0] << 8) | dptr[1];
6127  new_entry->orig_net_id = (dptr[2] << 8) | dptr[3];
6128  new_entry->service_id = (dptr[4] << 8) | dptr[5];
6129 
6130  dptr += 6;
6131  loop_len -= 6;
6132 
6133  #ifdef DEBUG_FREESAT_INFO_LOCATION_DESC
6134  if (db_print)
6135  {
6136  STB_SI_PRINT((" service = 0x%04x/0x%04x/0x%04x", new_entry->orig_net_id,
6137  new_entry->transport_id, new_entry->service_id));
6138  }
6139  #endif
6140 
6141  /* Add the new location to the end of the list */
6142  new_entry->next = NULL;
6143  *last_pointer = new_entry;
6144  last_pointer = &(new_entry->next);
6145  }
6146  else
6147  {
6148  #ifdef DEBUG_FREESAT_INFO_LOCATION_DESC
6149  if (db_print)
6150  {
6151  STB_SI_PRINT((" Failed to allocate memory"));
6152  }
6153  #endif
6154  dptr = end_ptr;
6155  }
6156  }
6157  }
6158  }
6159 
6160  FUNCTION_FINISH(ParseFreesatInfoLocationDescriptor);
6161 
6162  return(end_ptr);
6163 }
6164 
6178 static U8BIT* ParseRegionLcnDescriptor(U8BIT *dptr, SI_BAT_FREESAT_REGION_LCN_ENTRY **lcn_array, BOOLEAN db_print)
6179 {
6180  U8BIT dlen;
6181  U8BIT *end_ptr;
6182  U8BIT *loop_ptr;
6183  U8BIT *end_loop;
6184  SI_BAT_FREESAT_REGION_LCN_ENTRY *region_entry;
6185  SI_BAT_FREESAT_REGION_LCN_ENTRY *last_region;
6186  SI_FREESAT_LCN *lcn_entry;
6187  SI_FREESAT_LCN *last_lcn;
6188 
6189  FUNCTION_START(ParseRegionLcnDescriptor);
6190 
6191 #ifndef DEBUG_FREESAT_LCN_DESC
6192  USE_UNWANTED_PARAM(db_print);
6193 #endif
6194 
6195  last_region = *lcn_array;
6196  while (last_region != NULL)
6197  {
6198  if (last_region->next != NULL)
6199  {
6200  last_region = last_region->next;
6201  }
6202  else
6203  {
6204  /* This is the last item in the list */
6205  break;
6206  }
6207  }
6208 
6209  dlen = *dptr;
6210  dptr++;
6211  end_ptr = dptr + dlen;
6212 
6213  while (dptr < end_ptr)
6214  {
6215  region_entry = STB_GetMemory(sizeof(SI_BAT_FREESAT_REGION_LCN_ENTRY));
6216  if (region_entry != NULL)
6217  {
6218  memset(region_entry, 0, sizeof(*region_entry));
6219 
6220  region_entry->service_id = (dptr[0] << 8) | dptr[1];
6221  dptr += 2;
6222 
6223  region_entry->freesat_id = ((dptr[0] & 0x7F) << 8) | dptr[1];
6224  dptr += 2;
6225 
6226 #ifdef DEBUG_FREESAT_LCN_DESC
6227  if (db_print)
6228  {
6229  STB_SI_PRINT((" ParseRegionLcnDescriptor: serv_id = 0x%04x, freesat_id = 0x%04x",
6230  region_entry->service_id, region_entry->freesat_id));
6231  }
6232 #endif
6233 
6234  loop_ptr = dptr + 1;
6235  end_loop = loop_ptr + dptr[0];
6236 
6237  last_lcn = NULL;
6238 
6239  while (loop_ptr < end_loop)
6240  {
6241  if (end_loop - loop_ptr >= 4)
6242  {
6243  lcn_entry = (SI_FREESAT_LCN *)STB_GetMemory(sizeof(SI_FREESAT_LCN));
6244  if (lcn_entry != NULL)
6245  {
6246  memset(lcn_entry, 0, sizeof(*lcn_entry));
6247 
6248  lcn_entry->numeric_selection = ((loop_ptr[0] & 0x80) >> 7);
6249  lcn_entry->visible_flag = ((loop_ptr[0] & 0x40) >> 6);
6250  lcn_entry->user_cust = ((loop_ptr[0] & 0x20) >> 5);
6251  lcn_entry->lcn = (((loop_ptr[0] & 0x0F) << 8) | (loop_ptr[1]));
6252  lcn_entry->region_id = (loop_ptr[2] << 8) | (loop_ptr[3]);
6253  loop_ptr += 4;
6254 
6255 #ifdef DEBUG_FREESAT_LCN_DESC
6256  STB_SI_PRINT((" numeric_selection=%d, visible=%d, user_cust=%d, lcn=%d, region_id=0x%04x",
6257  lcn_entry->numeric_selection, lcn_entry->visible_flag, lcn_entry->user_cust,
6258  lcn_entry->lcn, lcn_entry->region_id));
6259 #endif
6260 
6261  if (last_lcn == NULL)
6262  {
6263  /* First item in the list */
6264  region_entry->freesat_lcn_list = lcn_entry;
6265  }
6266  else
6267  {
6268  /* Add item to the end of the list */
6269  last_lcn->next = lcn_entry;
6270  }
6271 
6272  last_lcn = lcn_entry;
6273  }
6274  else
6275  {
6276  loop_ptr = end_loop;
6277  }
6278  }
6279  else
6280  {
6281  loop_ptr = end_loop;
6282  }
6283  }
6284 
6285  dptr = loop_ptr;
6286 
6287  if (last_region == NULL)
6288  {
6289  /* First item in the list */
6290  *lcn_array = region_entry;
6291  }
6292  else
6293  {
6294  /* Add the item to the end of the list */
6295  last_region->next = region_entry;
6296  }
6297 
6298  last_region = region_entry;
6299  }
6300  else
6301  {
6302  dptr = end_ptr;
6303  }
6304  }
6305 
6306  FUNCTION_FINISH(ParseRegionLcnDescriptor);
6307 
6308  return(end_ptr);
6309 }
6310 
6311 static U8BIT* ParseFreesatShortServiceNameDescriptor(U8BIT *dptr, U16BIT *num_ptr,
6312  SI_MULTILING_SHORT_NAME_DESC **array_ptr, BOOLEAN db_print)
6313 {
6314  U8BIT dlen;
6315  U8BIT *end_ptr;
6316  U16BIT num_entries;
6318  U16BIT i;
6319  U8BIT *tmp_ptr;
6320  U8BIT name_len;
6321 
6322  FUNCTION_START(ParseFreesatShortServiceNameDescriptor);
6323 
6324  ASSERT(dptr != NULL);
6325  ASSERT(num_ptr != NULL);
6326  ASSERT(array_ptr != NULL);
6327 
6328  dlen = *dptr;
6329  dptr++;
6330  end_ptr = dptr + dlen;
6331 
6332  if (dlen >= 4)
6333  {
6334  // work out number of entries
6335  num_entries = 0;
6336  tmp_ptr = dptr;
6337  while (tmp_ptr < end_ptr)
6338  {
6339  name_len = tmp_ptr[3]; // read name length
6340  tmp_ptr += (name_len + 4); // skip language code, name length and name
6341  num_entries++;
6342  }
6343 
6344  #ifdef DEBUG_MULTILING_SHORT_NAME_DESC
6345  if (db_print == TRUE)
6346  {
6347  STB_SI_PRINT((" Multilingual short name desc: %d entries", num_entries));
6348  }
6349  #else
6350  USE_UNWANTED_PARAM(db_print);
6351  #endif
6352 
6353  // check if there are already entries in the array (i.e. already received a descriptor)
6354  // if so add to the existing array, otherwise create new array
6355  if (*array_ptr == NULL)
6356  {
6357  // no entries already - create new array
6359  }
6360  else
6361  {
6362  // already got entries - make array bigger
6363  num_entries += *num_ptr;
6364  array = (SI_MULTILING_SHORT_NAME_DESC *)STB_ResizeMemory(*array_ptr,
6365  num_entries * sizeof(SI_MULTILING_SHORT_NAME_DESC));
6366  }
6367 
6368  // add new entries to array
6369  if (array != NULL)
6370  {
6371  for (i = *num_ptr; i < num_entries; i++)
6372  {
6373  dptr = ReadLanguageCode(dptr, &array[i].lang_code);
6374  dptr = STB_SIReadString(dptr[0], dptr + 1, &array[i].name_str);
6375 
6376  #ifdef DEBUG_MULTILING_SHORT_NAME_DESC
6377  {
6378  char *tmp_name_str = "NULL";
6379 
6380  if (db_print == TRUE)
6381  {
6382  if (array[i].name_str != NULL)
6383  {
6384  if (array[i].name_str->str_ptr != NULL)
6385  {
6386  tmp_name_str = (char *)array[i].name_str->str_ptr;
6387  }
6388  }
6389 
6390  STB_SI_PRINT((" lang=%c%c%c, name=%s",
6391  (array[i].lang_code >> 16), (array[i].lang_code >> 8), array[i].lang_code,
6392  tmp_name_str));
6393  }
6394  }
6395  #endif
6396  }
6397  *array_ptr = array;
6398  *num_ptr = num_entries;
6399  }
6400  else
6401  {
6402  #ifdef DEBUG_MULTILING_SHORT_NAME_DESC
6403  if (db_print == TRUE)
6404  {
6405  STB_SI_PRINT((" CAN'T ALLOCATE MEMORY FOR DESCRIPTOR ARRAY ENTRY"));
6406  }
6407  #endif
6408  }
6409  }
6410  else
6411  {
6412  #ifdef DEBUG_MULTILING_SHORT_NAME_DESC
6413  if (db_print == TRUE)
6414  {
6415  STB_SI_PRINT((" Invalid multilingual short name desc: (%d bytes)", dlen));
6416  }
6417  #endif
6418  }
6419 
6420  FUNCTION_FINISH(ParseFreesatShortServiceNameDescriptor);
6421  return(end_ptr);
6422 }
6423 
6424 /*!**************************************************************************
6425  * @brief Reads the Freesat Service Group Name Descripter
6426  * @param data_ptr - pointer to length byte of descriptor
6427  * @param name_list - pointer to structure to parse data into
6428  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
6429  * @return Updated value of current data byte address i.e. at end of descriptor
6430  ****************************************************************************/
6431 static U8BIT* ParseFreesatServiceGroupNameDescriptor(U8BIT *dptr,
6432  SI_BAT_FREESAT_GROUP_NAME_ENTRY **name_list, BOOLEAN db_print)
6433 {
6434  U8BIT dlen;
6435  U8BIT *end_ptr;
6436  U8BIT *end_name_loop_ptr;
6438  U8BIT *temp_dptr;
6439 
6440  FUNCTION_START(ParseFreesatServiceGroupNameDescriptor);
6441 
6442 #ifndef DEBUG_FREESAT_GROUP_NAME_DESC
6443  USE_UNWANTED_PARAM(db_print);
6444 #endif
6445 
6446  dlen = *dptr;
6447  dptr++;
6448  end_ptr = dptr + dlen;
6449 
6450  while (dptr < end_ptr)
6451  {
6452  new_entry = STB_GetMemory(sizeof(SI_BAT_FREESAT_GROUP_NAME_ENTRY));
6453  if (new_entry != NULL)
6454  {
6455  memset(new_entry, 0, sizeof(*new_entry));
6456 
6457  new_entry->group_type = (dptr[0] & 0xF8) >> 3;
6458  new_entry->group_id = (((dptr[0] & 0x07) << 8) | dptr[1]);
6459  dptr += 2;
6460 
6461 #ifdef DEBUG_FREESAT_GROUP_NAME_DESC
6462  if (db_print)
6463  {
6464  STB_SI_PRINT((" Freesat service group name: group type=%d, group ID=%u",
6465  new_entry->group_type, new_entry->group_id));
6466  }
6467 #endif
6468  dlen = dptr[0];
6469  dptr++;
6470  end_name_loop_ptr = dptr + dlen;
6471 
6472  /* Work out how many names are defined */
6473  new_entry->num_group_names = 0;
6474  temp_dptr = dptr;
6475 
6476  while (temp_dptr < end_name_loop_ptr)
6477  {
6478  temp_dptr += 3; /* Language code */
6479  temp_dptr += *temp_dptr; /* Length of name */
6480  temp_dptr++;
6481  new_entry->num_group_names++;
6482  }
6483 
6484  /* Allocate array for name strings */
6485  new_entry->string_array = STB_GetMemory(new_entry->num_group_names *
6487  if (new_entry->string_array != NULL)
6488  {
6489  new_entry->num_group_names = 0;
6490 
6491  while (dptr < end_name_loop_ptr)
6492  {
6493  dptr = ReadLanguageCode(dptr, &new_entry->string_array[new_entry->num_group_names].lang_code);
6494  dptr = STB_SIReadString(*dptr, dptr + 1,
6495  &new_entry->string_array[new_entry->num_group_names].name_str);
6496 
6497 #ifdef DEBUG_FREESAT_GROUP_NAME_DESC
6498  if (db_print)
6499  {
6500  STB_SI_PRINT((" lang_code = %c%c%c, name = \"%s\"",
6501  new_entry->string_array[new_entry->num_group_names].lang_code >> 16,
6502  new_entry->string_array[new_entry->num_group_names].lang_code >> 8,
6503  new_entry->string_array[new_entry->num_group_names].lang_code & 0xff,
6504  new_entry->string_array[new_entry->num_group_names].name_str->str_ptr));
6505  }
6506 #endif
6507  new_entry->num_group_names++;
6508  }
6509 
6510  /* Add group name entry to start of the list */
6511  new_entry->next_group = *name_list;
6512  *name_list = new_entry;
6513  }
6514  else
6515  {
6516  new_entry->num_group_names = 0;
6517  dptr = end_ptr;
6518  }
6519  }
6520  else
6521  {
6522  dptr = end_ptr;
6523  }
6524  }
6525 
6526  FUNCTION_FINISH(ParseFreesatServiceGroupNameDescriptor);
6527 
6528  return(end_ptr);
6529 }
6530 
6531 /*!**************************************************************************
6532  * @brief Reads the Freesat Interactive Restriction Descripter
6533  * @param data_ptr - pointer to length byte of descriptor
6534  * @param serv_array - pointer to structure to parse data into
6535  * @param num_entries - number of name entries
6536  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
6537  * @return Updated value of current data byte address i.e. at end of descriptor
6538  ****************************************************************************/
6539 static U8BIT* ParseFreesatInteractiveRestrictionDescriptor(U8BIT *dptr, U16BIT **int_res_array,
6540  U8BIT *num_entries, BOOLEAN db_print)
6541 {
6542  U8BIT dlen;
6543  U8BIT *end_ptr;
6544  U8BIT count;
6545 
6546  FUNCTION_START(ParseFreesatInteractiveRestrictionDescriptor);
6547 
6548  USE_UNWANTED_PARAM(db_print);
6549 
6550  dlen = *dptr;
6551  dptr++;
6552  end_ptr = dptr + dlen;
6553  count = 0;
6554 
6555  *int_res_array = STB_GetMemory(((dlen / 2) * sizeof(U16BIT)));
6556  if (*int_res_array != NULL)
6557  {
6558  while (dptr < end_ptr)
6559  {
6560  (*int_res_array)[count] = ((dptr[0] << 8) | dptr[1]);
6561  count++;
6562  dptr += 2;
6563  }
6564  }
6565 
6566  *num_entries = count;
6567 
6568  FUNCTION_FINISH(ParseFreesatInteractiveRestrictionDescriptor);
6569 
6570  return(end_ptr);
6571 }
6572 
6573 /*!**************************************************************************
6574  * @brief Reads the Freesat Service Group Descripter
6575  * @param data_ptr - pointer to length byte of descriptor
6576  * @param serv_array - pointer to structure to parse data into
6577  * @param num_entries - number of name entries
6578  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
6579  * @return Updated value of current data byte address i.e. at end of descriptor
6580  ****************************************************************************/
6581 static U8BIT* ParseFreesatServiceGroupDescriptor(U8BIT *dptr, SI_BAT_FREESAT_SERV_GROUP_ENTRY **serv_array,
6582  U16BIT *num_entries, BOOLEAN db_print)
6583 {
6584  U8BIT dlen;
6585  U8BIT *end_ptr;
6587  U16BIT group_id;
6588  U16BIT index;
6589  U8BIT group_size;
6590 
6591  FUNCTION_START(ParseFreesatServiceGroupDescriptor);
6592 
6593  USE_UNWANTED_PARAM(db_print);
6594 
6595  dlen = *dptr;
6596  dptr++;
6597  end_ptr = dptr + dlen;
6598 
6599  while (dptr < end_ptr)
6600  {
6601  group_id = ((dptr[0] & 0x07) << 8) | dptr[1];
6602 
6603  /* See if there's an entry for this group already */
6604  for (entry_ptr = *serv_array; entry_ptr != NULL; entry_ptr = entry_ptr->next_group)
6605  {
6606  if (entry_ptr->group_id == group_id)
6607  {
6608  /* Already have an entry for this group */
6609  break;
6610  }
6611  }
6612 
6613  if (entry_ptr == NULL)
6614  {
6615  /* No existing entry for this group, so create one */
6617  if (entry_ptr != NULL)
6618  {
6619  memset(entry_ptr, 0, sizeof(*entry_ptr));
6620  entry_ptr->next_group = *serv_array;
6621  *serv_array = entry_ptr;
6622  (*num_entries)++;
6623  }
6624  }
6625 
6626  if (entry_ptr != NULL)
6627  {
6628  entry_ptr->non_destructive_flag = ((dptr[0] & 0x80) >> 7);
6629  entry_ptr->return_channel_access_flag = ((dptr[0] & 0x40) >> 6);
6630  entry_ptr->g2_extension_flag = ((dptr[0] & 0x20) >> 5);
6631  entry_ptr->group_id = group_id;
6632 
6633  group_size = dptr[2] / 2;
6634  dptr += 3;
6635 
6636  if (group_size != 0)
6637  {
6638  /* Allocate space for the Freesat IDs of the services in the group */
6639  if (entry_ptr->freesat_id == NULL)
6640  {
6641  /* */
6642  entry_ptr->freesat_id = (U16BIT *)STB_GetMemory(group_size * sizeof(U16BIT));
6643  index = 0;
6644  }
6645  else
6646  {
6647  /* Increase the number of IDs */
6648  entry_ptr->freesat_id = (U16BIT *)STB_ResizeMemory(entry_ptr->freesat_id,
6649  (entry_ptr->num_services + group_size) * sizeof(U16BIT));
6650  index = entry_ptr->num_services;
6651  }
6652 
6653  if (entry_ptr->freesat_id != NULL)
6654  {
6655  /* Copy the new IDs into the array */
6656  entry_ptr->num_services += group_size;
6657 
6658  for (; group_size > 0; group_size--, index++)
6659  {
6660  entry_ptr->freesat_id[index] = ((dptr[0] & 0x7F) << 8) | dptr[1];
6661  dptr += 2;
6662  }
6663  }
6664  }
6665 
6666  if (entry_ptr->g2_extension_flag != 0)
6667  {
6668  entry_ptr->g2_flags = *dptr;
6669  dptr++;
6670  }
6671  }
6672  else
6673  {
6674  dptr = end_ptr;
6675  }
6676  }
6677 
6678  FUNCTION_FINISH(ParseFreesatServiceGroupDescriptor);
6679 
6680  return(end_ptr);
6681 }
6682 
6683 #if 0
6684 
6697 static U8BIT* ParseServiceMoveDescriptor(U8BIT *dptr, SI_SERVICE_MOVE_DESC **desc_ptr, BOOLEAN db_print)
6698 {
6699  U8BIT dlen;
6700  U8BIT *end_ptr;
6701 
6702  FUNCTION_START(ParseServiceMoveDescriptor);
6703 
6704  dlen = *dptr;
6705  dptr++;
6706  end_ptr = dptr + dlen;
6707 
6708  /* There should be only one service move descriptor in a PMT
6709  * so skip this one if it already exists */
6710  if ((*desc_ptr == NULL) && (dlen == 6))
6711  {
6713  if (*desc_ptr != NULL)
6714  {
6715  (*desc_ptr)->onet_id = (dptr[0] << 8) | dptr[1];
6716  (*desc_ptr)->ts_id = (dptr[2] << 8) | dptr[3];
6717  (*desc_ptr)->service_id = (dptr[4] << 8) | dptr[5];
6718 
6719 #ifdef DEBUG_SERVICE_MOVE_DESC
6720  if (db_print == TRUE)
6721  {
6722  STB_SI_PRINT((" service move desc: onet=0x%04x, ts=0x%04x, service=0x%04x",
6723  (*desc_ptr)->onet_id, (*desc_ptr)->ts_id, (*desc_ptr)->service_id));
6724  }
6725 #else
6726  USE_UNWANTED_PARAM(db_print);
6727 #endif
6728  }
6729  }
6730 
6731  FUNCTION_FINISH(ParseServiceMoveDescriptor);
6732 
6733  return(end_ptr);
6734 }
6735 
6736 #endif
6737 
6738 /*!**************************************************************************
6739  * @brief Reads the RCT link_info structure
6740  * @param dptr - pointer to length byte of descriptor
6741  * @param link_info - pointer to structure to parse data into
6742  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
6743  * @return Updated value of current data byte address i.e. at end of descriptor
6744  ****************************************************************************/
6745 static U8BIT* ParseRctLinkInfo(U8BIT *dptr, SI_RCT_LINK_INFO *link_info, BOOLEAN db_print)
6746 {
6747  U16BIT dlen;
6748  U8BIT *end_ptr;
6749  U8BIT text_len, i;
6750  U16BIT dloop_len;
6751  U8BIT *dloop_end;
6752  U8BIT dtag;
6753 
6754  FUNCTION_START(ParseRctLinkInfo);
6755 
6756 #ifndef DEBUG_RCT_LINK_INFO
6757  USE_UNWANTED_PARAM(db_print);
6758 #endif
6759 
6760  dlen = ((dptr[0] & 0x0f) << 8) | dptr[1];
6761  dptr += 2;
6762  end_ptr = dptr + dlen;
6763 
6764  memset(link_info, 0, sizeof(SI_RCT_LINK_INFO));
6765 
6766  if (dlen >= 7)
6767  {
6768  link_info->link_type = dptr[0] >> 4;
6769 
6770 #ifdef DEBUG_RCT_LINK_INFO
6771  if (db_print)
6772  {
6773  STB_SI_PRINT((" RCT link_info: link_type=0x%x", link_info->link_type));
6774  }
6775 #endif
6776 
6777  /* Only link type 0x00 (URI) is supported by D-Book 6.2.1 */
6778  if (link_info->link_type == RCT_LINK_TYPE_URI)
6779  {
6780  link_info->how_related = ((dptr[0] & 0x03) << 4) | (dptr[1] >> 4);
6781  link_info->term_id = ((dptr[1] & 0x0f) << 8) | dptr[2];
6782  link_info->group_id = dptr[3] >> 4;
6783  link_info->precedence = dptr[3] & 0x0f;
6784 
6785 #ifdef DEBUG_RCT_LINK_INFO
6786  if (db_print)
6787  {
6788  STB_SI_PRINT((" how_related=0x%02x, term_id=%u, group_id=0x%02x, precedence=%u",
6789  link_info->how_related, link_info->term_id, link_info->group_id, link_info->precedence));
6790  }
6791 #endif
6792  text_len = dptr[4];
6793  dptr += 5;
6794 
6795  if (text_len > 0)
6796  {
6797  link_info->uri_string = (U8BIT *)STB_GetMemory(text_len + 1);
6798  if (link_info->uri_string != NULL)
6799  {
6800  memcpy(link_info->uri_string, dptr, text_len);
6801  link_info->uri_string[text_len] = '\0';
6802 #ifdef DEBUG_RCT_LINK_INFO
6803  if (db_print)
6804  {
6805  STB_SI_PRINT((" len=%u, URI=\"%s\"", text_len, link_info->uri_string));
6806  }
6807 #endif
6808  }
6809 
6810  dptr += text_len;
6811  }
6812 
6813  /* Process the promotional text items */
6814  link_info->num_items = dptr[0] & 0x3f;
6815  dptr++;
6816 
6817 #ifdef DEBUG_RCT_LINK_INFO
6818  if (db_print)
6819  {
6820  STB_SI_PRINT((" num promo items=%u", link_info->num_items));
6821  }
6822 #endif
6823 
6824  if (link_info->num_items > 0)
6825  {
6826  link_info->promo_text_array =
6827  (SI_RCT_PROMO_TEXT *)STB_GetMemory(link_info->num_items * sizeof(SI_RCT_PROMO_TEXT));
6828  if (link_info->promo_text_array != NULL)
6829  {
6830  for (i = 0; i < link_info->num_items; i++)
6831  {
6832  memset(&link_info->promo_text_array[i], 0, sizeof(SI_RCT_PROMO_TEXT));
6833 
6834  dptr = ReadLanguageCode(dptr, &link_info->promo_text_array[i].lang_code);
6835  dptr = STB_SIReadString(dptr[0], dptr + 1, &link_info->promo_text_array[i].string);
6836 
6837 #ifdef DEBUG_RCT_LINK_INFO
6838  if (db_print)
6839  {
6840  STB_SI_PRINT((" lang=%c%c%c, promo text len=%u bytes",
6841  link_info->promo_text_array[i].lang_code >> 16,
6842  link_info->promo_text_array[i].lang_code >> 8,
6843  link_info->promo_text_array[i].lang_code & 0xff,
6844  link_info->promo_text_array[i].string->nbytes));
6845 
6846  if ((*link_info->promo_text_array[i].string->str_ptr >= 0x20) &&
6847  (*link_info->promo_text_array[i].string->str_ptr < 0x7f))
6848  {
6849  STB_SI_PRINT((" \"%s\"", link_info->promo_text_array[i].string->str_ptr));
6850  }
6851  }
6852 #endif
6853  }
6854  }
6855  else
6856  {
6857  link_info->num_items = 0;
6858  }
6859  }
6860 
6861  if ((dptr[0] & 0x80) != 0)
6862  {
6863  link_info->can_use_default_icon = TRUE;
6864  }
6865  else
6866  {
6867  link_info->can_use_default_icon = FALSE;
6868  }
6869 
6870  link_info->icon_id = (dptr[0] & 0x70) >> 4;
6871 
6872 #ifdef DEBUG_RCT_LINK_INFO
6873  if (db_print)
6874  {
6875  STB_SI_PRINT((" default_icon_flag=%u, icon_id=%u", link_info->can_use_default_icon,
6876  link_info->icon_id));
6877  }
6878 #endif
6879 
6880  /* Process the descriptor loop */
6881  dloop_len = ((dptr[0] & 0x0f) << 8) | dptr[1];
6882  dptr += 2;
6883 
6884  dloop_end = dptr + dloop_len;
6885  while (dptr < dloop_end)
6886  {
6887  dtag = dptr[0];
6888  dptr++;
6889 
6890  switch (dtag)
6891  {
6892  case SHORT_EVENT_DTAG:
6893  {
6894  text_len = 0;
6895  dptr = ParseShortEventDescriptor(dptr, &text_len, &link_info->event_desc, DEBUG_RCT_LINK_INFO_VALUE);
6896  break;
6897  }
6898 
6899  case EXT_DTAG:
6900  {
6901  /* Examine the extension tag for the table being signalled */
6902  switch (dptr[1])
6903  {
6904  case IMAGE_ICON_DTAG:
6905  {
6906  dptr = ParseImageIconDesc(dptr, &link_info->num_icons, &link_info->icon_array, DEBUG_RCT_LINK_INFO_VALUE);
6907  break;
6908  }
6909 
6910  default:
6911  {
6912  dptr = SkipDescriptor(dptr, dtag, DEBUG_RCT_LINK_INFO_VALUE);
6913  break;
6914  }
6915  }
6916  break;
6917  }
6918 
6919  default:
6920  {
6921  dptr = SkipDescriptor(dptr, dtag, DEBUG_RCT_LINK_INFO_VALUE);
6922  break;
6923  }
6924  }
6925  }
6926  }
6927  }
6928 #ifdef DEBUG_RCT_LINK_INFO
6929  else if (db_print)
6930  {
6931  STB_SI_PRINT((" Invalid RCT link_info, len=%u, descriptor skipped", dlen));
6932  }
6933 #endif
6934 
6935  FUNCTION_FINISH(ParseRctLinkInfo);
6936 
6937  return(end_ptr);
6938 }
6939 
6940 /*!**************************************************************************
6941  * @brief Reads the image icon descriptor
6942  * @param dptr - pointer to length byte of descriptor
6943  * @param num_icons - pointer to number of icons currently in array, number is updated on return
6944  * @param icon_array - pointer to array of icon structures, array is updated on return
6945  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
6946  * @return Updated value of current data byte address i.e. at end of descriptor
6947  ****************************************************************************/
6948 static U8BIT* ParseImageIconDesc(U8BIT *dptr, U8BIT *num_icons, SI_IMAGE_ICON_DESC **icon_array, BOOLEAN db_print)
6949 {
6950  U8BIT dlen;
6951  U8BIT *end_ptr;
6952  U8BIT data_len;
6953  U8BIT desc_num, last_desc_num;
6954  U8BIT icon_id;
6955  SI_IMAGE_ICON_DESC *icon;
6956  U8BIT i;
6957 
6958  FUNCTION_START(ParseImageIconDesc);
6959 
6960 #ifndef DEBUG_IMAGE_ICON_DESC
6961  USE_UNWANTED_PARAM(db_print);
6962 #endif
6963 
6964  dlen = *dptr;
6965 
6966  /* Skip the length and tag extension */
6967  dptr += 2;
6968 
6969  end_ptr = dptr + (dlen - 1);
6970 
6971  if (dlen >= 4)
6972  {
6973  desc_num = dptr[0] >> 4;
6974  last_desc_num = dptr[0] & 0x0f;
6975  icon_id = dptr[1] & 0x07;
6976 
6977 #ifdef DEBUG_IMAGE_ICON_DESC
6978  if (db_print)
6979  {
6980  STB_SI_PRINT((" Image icon: desc_num=%u, last_desc_num=%u, icon_id=%u", desc_num,
6981  last_desc_num, icon_id));
6982  }
6983 #endif
6984 
6985  if (desc_num == 0)
6986  {
6987  /* This is a new icon, add an entry to the array */
6988  if (*num_icons > 0)
6989  {
6990  *icon_array = (SI_IMAGE_ICON_DESC *)STB_ResizeMemory(*icon_array, (*num_icons + 1) * sizeof(SI_IMAGE_ICON_DESC));
6991  if (*icon_array != NULL)
6992  {
6993  icon = &(*icon_array)[*num_icons];
6994  (*num_icons)++;
6995  }
6996  else
6997  {
6998  icon = NULL;
6999 #ifdef DEBUG_IMAGE_ICON_DESC
7000  if (db_print)
7001  {
7002  STB_SI_PRINT(("Failed to allocate memory for new image icon!"));
7003  }
7004 #endif
7005  }
7006  }
7007  else
7008  {
7009  *icon_array = (SI_IMAGE_ICON_DESC *)STB_GetMemory(sizeof(SI_IMAGE_ICON_DESC));
7010  icon = *icon_array;
7011  *num_icons = 1;
7012  }
7013 
7014  if (icon != NULL)
7015  {
7016  memset(icon, 0, sizeof(SI_IMAGE_ICON_DESC));
7017 
7018  icon->desc_num = desc_num;
7019  icon->last_desc_num = last_desc_num;
7020  icon->icon_id = icon_id;
7021 
7022  icon->transport_mode = dptr[2] >> 6;
7023 
7024 #ifdef DEBUG_IMAGE_ICON_DESC
7025  if (db_print)
7026  {
7027  STB_SI_PRINT((" transport_mode=%u", icon->transport_mode));
7028  }
7029 #endif
7030 
7031  if ((dptr[2] & 0x20) != 0)
7032  {
7033  icon->position_defined = TRUE;
7034  icon->coord_system = (dptr[2] >> 2) & 0x07;
7035  icon->x_pos = (dptr[3] << 4) | (dptr[4] >> 4);
7036  icon->y_pos = ((dptr[4] & 0x0f) << 8) | dptr[5];
7037  dptr += 6;
7038 #ifdef DEBUG_IMAGE_ICON_DESC
7039  if (db_print)
7040  {
7041  STB_SI_PRINT((" coord system=%u, pos=%u,%u", icon->coord_system, icon->x_pos, icon->y_pos));
7042  }
7043 #endif
7044  }
7045  else
7046  {
7047  icon->position_defined = FALSE;
7048  dptr += 3;
7049  }
7050 
7051  data_len = dptr[0];
7052  dptr++;
7053 
7054  if (data_len > 0)
7055  {
7056  icon->icon_type = (U8BIT *)STB_GetMemory(data_len + 1);
7057  memcpy(icon->icon_type, dptr, data_len);
7058  icon->icon_type[data_len] = '\0';
7059  dptr += data_len;
7060 #ifdef DEBUG_IMAGE_ICON_DESC
7061  if (db_print)
7062  {
7063  STB_SI_PRINT((" icon_type=\"%s\"", icon->icon_type));
7064  }
7065 #endif
7066  }
7067 
7068  if (icon->transport_mode == ICON_TRANS_LOCAL)
7069  {
7070  icon->data_len = dptr[0];
7071 
7072 #ifdef DEBUG_IMAGE_ICON_DESC
7073  if (db_print)
7074  {
7075  STB_SI_PRINT((" %u icon data bytes", icon->data_len));
7076  }
7077 #endif
7078  if (icon->data_len > 0)
7079  {
7080  icon->icon_data = (U8BIT *)STB_GetMemory(icon->data_len);
7081  if (icon->icon_data != NULL)
7082  {
7083  memcpy(icon->icon_data, &dptr[1], icon->data_len);
7084  }
7085  else
7086  {
7087  icon->data_len = 0;
7088  }
7089  }
7090  }
7091  else if (icon->transport_mode == ICON_TRANS_URL)
7092  {
7093  icon->data_len = dptr[0];
7094 
7095  if (icon->data_len > 0)
7096  {
7097  /* Allocate an extra byte to store a null string terminator */
7098  icon->data_len++;
7099 
7100  icon->icon_data = (U8BIT *)STB_GetMemory(icon->data_len);
7101  if (icon->icon_data != NULL)
7102  {
7103  memcpy(icon->icon_data, &dptr[1], icon->data_len - 1);
7104  icon->icon_data[icon->data_len - 1] = '\0';
7105 #ifdef DEBUG_IMAGE_ICON_DESC
7106  if (db_print)
7107  {
7108  STB_SI_PRINT((" icon url=\"%s\"", icon->icon_data));
7109  }
7110 #endif
7111  }
7112  else
7113  {
7114  icon->data_len = 0;
7115  }
7116  }
7117  }
7118  }
7119  }
7120  else
7121  {
7122  /* This is additional data for an icon that should already have been added */
7123  for (i = 0; i < *num_icons; i++)
7124  {
7125  if ((*icon_array)[i].icon_id == icon_id)
7126  {
7127  icon = &(*icon_array)[i];
7128 
7129  /* Icon found, check that the desc number follows on from the last one */
7130  if ((desc_num == icon->desc_num + 1) && (desc_num <= icon->last_desc_num))
7131  {
7132  /* Update the last desc num seen */
7133  icon->desc_num = desc_num;
7134 
7135  data_len = dptr[2];
7136 
7137 #ifdef DEBUG_IMAGE_ICON_DESC
7138  if (db_print)
7139  {
7140  STB_SI_PRINT((" %u icon data bytes", data_len));
7141  }
7142 #endif
7143  if (data_len > 0)
7144  {
7145  /* Add the new data to the end of the existing data */
7146  icon->icon_data = (U8BIT *)STB_ResizeMemory(icon->icon_data, data_len + icon->data_len);
7147  if (icon->icon_data != NULL)
7148  {
7149  /* Copy new data into the buffer */
7150  memcpy(icon->icon_data + icon->data_len, &dptr[3], data_len);
7151  icon->data_len += data_len;
7152  }
7153  else
7154  {
7155  icon->data_len = 0;
7156  }
7157  }
7158  break;
7159  }
7160  }
7161  }
7162  }
7163  }
7164 #ifdef DEBUG_IMAGE_ICON_DESC
7165  else
7166  {
7167  if (db_print)
7168  {
7169  STB_SI_PRINT((" Image icon: invalid desc len %u", dlen));
7170  }
7171  }
7172 #endif
7173 
7174  FUNCTION_FINISH(ParseImageIconDesc);
7175 
7176  return(end_ptr);
7177 }
7178 
7187 static U8BIT* ParseURILinkageDesc(U8BIT *dptr, SI_URI_LINKAGE_DESC **desc_list, U32BIT private_data_code,
7188  BOOLEAN db_print)
7189 {
7190  U8BIT dlen;
7191  U8BIT *end_ptr;
7192  SI_URI_LINKAGE_DESC *entry;
7193 
7194  FUNCTION_START(ParseURILinkageDesc);
7195 
7196  #ifndef DEBUG_URI_LINKAGE_DESC
7197  USE_UNWANTED_PARAM(db_print);
7198  #endif
7199 
7200  dlen = *dptr;
7201  dptr++;
7202  end_ptr = dptr + dlen;
7203 
7204  /* Skip the extension descriptor tag as this has already been checked */
7205  dptr++;
7206  dlen--;
7207 
7208  if (dlen >= 2)
7209  {
7211  if (entry != NULL)
7212  {
7213  memset(entry, 0, sizeof(SI_URI_LINKAGE_DESC));
7214 
7215  entry->private_data_code = private_data_code;
7216  entry->uri_linkage_type = *dptr;
7217  dptr++;
7218 
7219  /* For the uri linkage type and uri length */
7220  dlen -= 2;
7221 
7222  if (dlen != 0)
7223  {
7224  dlen -= *dptr;
7225 
7226  dptr = STB_SIReadString(dptr[0], dptr + 1, &entry->uri);
7227 
7228  if ((entry->uri_linkage_type == 0x00) || (entry->uri_linkage_type == 0x01))
7229  {
7230  if (dlen >= 2)
7231  {
7232  entry->min_polling_interval = (dptr[0] << 8) | dptr[1];
7233  dptr += 2;
7234  dlen -= 2;
7235  }
7236  else
7237  {
7238  /* Wrong number of bytes left so ignore the rest */
7239  dlen = 0;
7240  }
7241  }
7242 
7243  if (dlen != 0)
7244  {
7245  /* The rest is private data */
7246  entry->private_data = STB_GetMemory(dlen);
7247  if (entry->private_data != NULL)
7248  {
7249  entry->private_data_length = dlen;
7250  memcpy(entry->private_data, dptr, dlen);
7251  dlen = 0;
7252  }
7253  }
7254  }
7255 
7256  #ifdef DEBUG_URI_LINKAGE_DESC
7257  if (db_print)
7258  {
7259  STB_SI_PRINT((" URI linkage desc: type=0x%02x (private_data_specifier 0x%02x)",
7260  entry->uri_linkage_type, entry->private_data_code));
7261  if (entry->uri != NULL)
7262  {
7263  STB_SI_PRINT((" URI=\"%s\"", entry->uri->str_ptr));
7264  }
7265  if ((entry->uri_linkage_type == 0x00) || (entry->uri_linkage_type == 0x01))
7266  {
7267  STB_SI_PRINT((" min_polling_interval=%u", entry->min_polling_interval));
7268  }
7269  STB_SI_PRINT((" %u bytes of private data", entry->private_data_length));
7270  }
7271  #endif
7272 
7273  /* Add the new entry to the beginning of the uri linkage list */
7274  entry->next = *desc_list;
7275  *desc_list = entry;
7276  }
7277  }
7278 
7279  FUNCTION_FINISH(ParseURILinkageDesc);
7280 
7281  return(end_ptr);
7282 }
7283 
7291 static U8BIT* ParseNordigContentProtectionDesc(U8BIT *dptr, U8BIT *protection_level, BOOLEAN db_print)
7292 {
7293  U8BIT dlen;
7294  U8BIT *end_ptr;
7295 
7296  FUNCTION_START(ParseNordigContentProtectionDesc);
7297 
7298 #ifndef DEBUG_NORDIG_CONTENT_PROTECTION_DESC
7299  USE_UNWANTED_PARAM(db_print);
7300 #endif
7301 
7302  dlen = *dptr;
7303  dptr++;
7304  end_ptr = dptr + dlen;
7305 
7306  /* This descriptor contains just 1 byte */
7307  if (dlen == 1)
7308  {
7309  *protection_level = *dptr;
7310 #ifdef DEBUG_NORDIG_CONTENT_PROTECTION_DESC
7311  if (db_print)
7312  {
7313  STB_SI_PRINT((" Nordig content protection desc: level=0x%02x", *protection_level));
7314  }
7315 #endif
7316  }
7317 #ifdef DEBUG_NORDIG_CONTENT_PROTECTION_DESC
7318  else if (db_print)
7319  {
7320  STB_SI_PRINT((" Nordig content protection desc: wrong length %u, expected 1", dlen));
7321  }
7322 #endif
7323 
7324  FUNCTION_FINISH(ParseNordigContentProtectionDesc);
7325 
7326  return(end_ptr);
7327 }
7328 
7329 /*!**************************************************************************
7330  * @brief Allocates memory for and copies the unparsed descriptor.
7331  * Only one desc per service is allowed.
7332  * @param dptr - pointer to length byte of descriptor
7333  * @param desc - pointer to variable takign the descriptor data
7334  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
7335  * @return Updated value of current data byte address i.e. at end of descriptor
7336  ****************************************************************************/
7337 static U8BIT* SaveCIProtectionDescriptor(U8BIT *dptr, U8BIT **desc, BOOLEAN db_print)
7338 {
7339  U8BIT dlen;
7340  U8BIT *end_ptr;
7341 
7342  FUNCTION_START(SaveCIProtectionDescriptor);
7343 
7344 #ifndef DEBUG_SI_SDT_CONTENT
7345  USE_UNWANTED_PARAM(db_print);
7346 #endif
7347 
7348  dlen = *dptr;
7349  dptr++;
7350  end_ptr = dptr + dlen;
7351 
7352  if (*desc == NULL)
7353  {
7354  /* No parsing is done, just save the raw data */
7355  *desc = STB_GetMemory(dlen + 2);
7356  if (*desc != NULL)
7357  {
7358  memcpy(*desc, dptr - 2, dlen + 2);
7359  }
7360 #ifdef DEBUG_SI_SDT_CONTENT
7361  else if (db_print)
7362  {
7363  STB_SI_PRINT((" Failed to allocate %u bytes for CI protection desc", dlen));
7364  }
7365 #endif
7366  }
7367 #ifdef DEBUG_SI_SDT_CONTENT
7368  else if (db_print)
7369  {
7370  STB_SI_PRINT((" CI protection desc found but service already has one!"));
7371  }
7372 #endif
7373 
7374  FUNCTION_FINISH(SaveCIProtectionDescriptor);
7375 
7376  return(end_ptr);
7377 }
7378 
7379 /*!**************************************************************************
7380  * @brief Parses the CI+ service descriptor
7381  * @param dptr - pointer to length byte of descriptor
7382  * @param num_services - pointer to count of services, updated on return
7383  * @param service_list - pointer to list of service descriptor structures
7384  * @param last_service - pointer to last service descriptor structure in the list
7385  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
7386  * @return Updated value of current data byte address i.e. at end of descriptor
7387  ****************************************************************************/
7388 static U8BIT* ParseCIPlusServiceDescriptor(U8BIT *dptr, U16BIT *num_services,
7389  SI_CIPLUS_SERVICE **service_list, SI_CIPLUS_SERVICE **last_service, BOOLEAN db_print)
7390 {
7391  U8BIT dlen;
7392  U8BIT *end_ptr;
7393  SI_CIPLUS_SERVICE *new_serv;
7394 
7395  FUNCTION_START(ParseCIPlusServiceDescriptor);
7396 
7397  #ifndef DEBUG_SI_NIT_CONTENT
7398  USE_UNWANTED_PARAM(db_print);
7399  #endif
7400 
7401  dlen = *dptr;
7402  dptr++;
7403  end_ptr = dptr + dlen;
7404 
7405  if (dlen >= 7)
7406  {
7407  if ((new_serv = (SI_CIPLUS_SERVICE *)STB_GetMemory(sizeof(SI_CIPLUS_SERVICE))) != NULL)
7408  {
7409  memset(new_serv, 0, sizeof(SI_CIPLUS_SERVICE));
7410 
7411  new_serv->id = (*dptr << 8) + *(dptr + 1);
7412  dptr += 2;
7413 
7414  new_serv->type = *dptr;
7415  dptr++;
7416 
7417  if ((*dptr & 0x80) != 0)
7418  {
7419  new_serv->visible = TRUE;
7420  }
7421 
7422  if ((*dptr & 0x40) != 0)
7423  {
7424  new_serv->selectable = TRUE;
7425  }
7426 
7427  new_serv->lcn = ((*dptr & 0x3f) << 8) + *(dptr + 1);
7428  dptr += 2;
7429 
7430  dptr = STB_SIReadString(*dptr, dptr + 1, &new_serv->provider_str);
7431  dptr = STB_SIReadString(*dptr, dptr + 1, &new_serv->name_str);
7432 
7433 #ifdef DEBUG_SI_NIT_CONTENT
7434  if (db_print)
7435  {
7436  STB_SI_PRINT((" CI+ service: id=%u, type=%u, visible=%u, selectable=%u, lcn=%u",
7437  new_serv->id, new_serv->type, new_serv->visible, new_serv->selectable, new_serv->lcn));
7438  if (new_serv->name_str != NULL)
7439  {
7440  STB_SI_PRINT((" Name=\"%s\"", new_serv->name_str->str_ptr));
7441  }
7442  if (new_serv->provider_str != NULL)
7443  {
7444  STB_SI_PRINT((" Provider=\"%s\"", new_serv->provider_str->str_ptr));
7445  }
7446  }
7447 #endif
7448 
7449  /* Append the service to the end of the list */
7450  if (*num_services == 0)
7451  {
7452  *service_list = new_serv;
7453  }
7454  else
7455  {
7456  (*last_service)->next = new_serv;
7457  }
7458 
7459  *last_service = new_serv;
7460  (*num_services)++;
7461  }
7462 #ifdef DEBUG_SI_NIT_CONTENT
7463  else if (db_print)
7464  {
7465  STB_SI_PRINT((" CI+ service: Failed to allocate %u bytes", sizeof(SI_CIPLUS_SERVICE)));
7466  }
7467 #endif
7468  }
7469 #ifdef DEBUG_SI_NIT_CONTENT
7470  else if (db_print)
7471  {
7472  STB_SI_PRINT((" CI+ service: Expected a minimum of 7 bytes, but desc is %u bytes", dlen));
7473  }
7474 #endif
7475 
7476  USE_UNWANTED_PARAM(dptr);
7477  FUNCTION_FINISH(ParseCIPlusServiceDescriptor);
7478 
7479  return(end_ptr);
7480 }
7481 
7482 /*!**************************************************************************
7483  * @brief Parses the CI+ service descriptor
7484  * @param dptr - pointer to length byte of descriptor
7485  * @param virtual_chan - pointer for return for virtual channel descriptor
7486  * @param db_print - if TRUE debug prints the contents of the descriptor (for debug only)
7487  * @return Updated value of current data byte address i.e. at end of descriptor
7488  ****************************************************************************/
7489 static U8BIT* ParseCIPlusVirtualChannelDescriptor(U8BIT *dptr,
7490  SI_CIPLUS_VIRTUAL_CHANNEL **virtual_chan, BOOLEAN db_print)
7491 {
7492  U8BIT dlen;
7493  U8BIT *end_ptr;
7494  SI_CIPLUS_VIRTUAL_CHANNEL *v_chan;
7495 
7496  FUNCTION_START(ParseCIPlusVirtualChannelDescriptor);
7497 
7498  #ifndef DEBUG_SI_NIT_CONTENT
7499  USE_UNWANTED_PARAM(db_print);
7500  #endif
7501 
7502  dlen = *dptr;
7503  dptr++;
7504  end_ptr = dptr + dlen;
7505 
7506  if (dlen >= 6)
7507  {
7508  if ((v_chan = (SI_CIPLUS_VIRTUAL_CHANNEL *)STB_GetMemory(sizeof(SI_CIPLUS_VIRTUAL_CHANNEL))) != NULL)
7509  {
7510  memset(v_chan, 0, sizeof(SI_CIPLUS_SERVICE));
7511 
7512  v_chan->lcn = ((*dptr & 0x3f) << 8) + *(dptr + 1);
7513  dptr += 2;
7514 
7515  dptr = STB_SIReadString(*dptr, dptr + 1, &v_chan->provider_str);
7516  dptr = STB_SIReadString(*dptr, dptr + 1, &v_chan->name_str);
7517 
7518  dlen = *dptr;
7519  dptr++;
7520  v_chan->event_info = (U8BIT *)STB_GetMemory(dlen * sizeof(U8BIT));
7521  if (v_chan->event_info != NULL)
7522  {
7523  memcpy(v_chan->event_info, dptr, dlen);
7524  v_chan->event_info_len = dlen;
7525  }
7526  dptr += dlen;
7527 
7528  dlen = *dptr;
7529  dptr++;
7530  v_chan->app_domain_id = (U8BIT *)STB_GetMemory((dlen+1) * sizeof(U8BIT));
7531  if (v_chan->app_domain_id != NULL)
7532  {
7533  memcpy(v_chan->app_domain_id, dptr, dlen);
7534  v_chan->app_domain_id[dlen] = 0;
7535  v_chan->app_domain_len = dlen;
7536  }
7537 
7538 #ifdef DEBUG_SI_NIT_CONTENT
7539  if (db_print)
7540  {
7541  STB_SI_PRINT((" CI+ virtual: lcn=%u", v_chan->lcn));
7542  if (v_chan->name_str != NULL)
7543  {
7544  STB_SI_PRINT((" Name=\"%s\"", v_chan->name_str->str_ptr));
7545  }
7546  if (v_chan->provider_str != NULL)
7547  {
7548  STB_SI_PRINT((" Provider=\"%s\"", v_chan->provider_str->str_ptr));
7549  }
7550  if (v_chan->event_info != NULL)
7551  {
7552  STB_SI_PRINT((" Event Info=\"%s\"", v_chan->event_info));
7553  }
7554  if (v_chan->app_domain_id != NULL)
7555  {
7556  STB_SI_PRINT((" AppDomainId=\"%s\"", v_chan->app_domain_id));
7557  }
7558  }
7559 #endif
7560 
7561  *virtual_chan = v_chan;
7562  }
7563 #ifdef DEBUG_SI_NIT_CONTENT
7564  else if (db_print)
7565  {
7566  STB_SI_PRINT((" CI+ virtual: Failed to allocate %u bytes", sizeof(SI_CIPLUS_VIRTUAL_CHANNEL)));
7567  }
7568 #endif
7569  }
7570 #ifdef DEBUG_SI_NIT_CONTENT
7571  else if (db_print)
7572  {
7573  STB_SI_PRINT((" CI+ virtual: Expected a minimum of 6 bytes, but desc is %u bytes", dlen));
7574  }
7575 #endif
7576 
7577  FUNCTION_FINISH(ParseCIPlusVirtualChannelDescriptor);
7578 
7579  return(end_ptr);
7580 }
7581 
7595 static float BCDToFloat(U8BIT *data_ptr, U8BIT len, U8BIT point)
7596 {
7597  U8BIT i, ival;
7598  float mult = 0.1f;
7599  float fval = 0.0f;
7600 
7601  FUNCTION_START(BCDToFloat);
7602 
7603  ASSERT(data_ptr != NULL);
7604 
7605  for (i = 0; i < point; i++)
7606  mult *= 10.0f;
7607 
7608  for (i = 0; i < len; i++)
7609  {
7610  if ((i % 2) != 0)
7611  ival = (data_ptr[i / 2] & 0x0f); // odd digit
7612  else
7613  ival = ((data_ptr[i / 2] >> 4) & 0x0f); // even digit
7614  fval += ((float)ival * mult);
7615  mult /= 10.0f;
7616  }
7617 
7618  FUNCTION_FINISH(BCDToFloat);
7619 
7620  return(fval);
7621 }
7622 
7623 //---global function definitions-----------------------------------------------
7624 
7631 {
7632  FUNCTION_START(STB_SISetCountryPrivateDataSpecifier);
7633 
7634  country_private_data_specifier_code = code;
7635  STB_SI_PRINT(("Set country private data specifier 0x%08x", code));
7636 
7637  FUNCTION_FINISH(STB_SISetCountryPrivateDataSpecifier);
7638 }
7639 
7645 {
7646  FUNCTION_START(STB_SISetPrivateDataSpecifier);
7647 
7648  freesat_private_data_specifier = mode;
7649 
7650  FUNCTION_FINISH(STB_SISetPrivateDataSpecifier);
7651 }
7652 
7658 {
7659  FUNCTION_START(STB_SISetPrivateDataSpecifier);
7660 
7661  ciplus_private_data_specifier = mode;
7662 
7663  FUNCTION_FINISH(STB_SISetPrivateDataSpecifier);
7664 }
7665 
7671 {
7672  FUNCTION_START(STB_SISetPrivateDataSpecifier);
7673 
7674  eacem_private_data_specifier = mode;
7675 
7676  FUNCTION_FINISH(STB_SISetPrivateDataSpecifier);
7677 }
7678 
7684 {
7685  FUNCTION_START(STB_SISetPrivateDataSpecifier);
7686 
7687  nzsat_private_data_specifier = mode;
7688 
7689  FUNCTION_FINISH(STB_SISetPrivateDataSpecifier);
7690 }
7691 
7697 {
7699 
7700  nordig_private_data_specifier = mode;
7701 
7702  FUNCTION_FINISH(STB_SISetNordigPrivateDataSpecifierMode);
7703 }
7704 
7717 void STB_SISetUserDefinedDescriptorFunction(U8BIT dtag, STB_SI_USER_DEF_DESCRIP_FUNCTION func)
7718 {
7720 
7721  if ((FIRST_USER_DEFINED_DTAG <= dtag) && (dtag <= LAST_USER_DEFINED_DTAG))
7722  {
7723  user_defined_dtag_function[dtag - FIRST_USER_DEFINED_DTAG] = func;
7724  #ifdef STB_DEBUG
7725  {
7726  U8BIT *func_str;
7727  switch (func)
7728  {
7729  case USER_DEF_DESCRIP_NOT_USED: {func_str = (U8BIT *)"not used"; break; }
7730  case USER_DEF_DESCRIP_LOGICAL_CHAN_NUM: {func_str = (U8BIT *)"logical chan num"; break; }
7731  case USER_DEF_DESCRIP_PREF_NAME_LIST: {func_str = (U8BIT *)"pref name list"; break; }
7732  case USER_DEF_DESCRIP_PREF_NAME_ID: {func_str = (U8BIT *)"pref name id"; break; }
7733  default: {func_str = (U8BIT *)"INVALID"; break; }
7734  }
7735  STB_SI_PRINT(("Set user defined descriptor: 0x%02x = %s", dtag, func_str));
7736  }
7737  #endif
7738  }
7739  FUNCTION_FINISH(STB_SISetUserDefinedDescriptorFunction);
7740 }
7741 
7742 /*!**************************************************************************
7743  * @brief Clear all entries in the user defined SI descriptor table
7744  ****************************************************************************/
7746 {
7747  U8BIT index;
7748 
7750 
7751  for (index = FIRST_USER_DEFINED_DTAG; index <= LAST_USER_DEFINED_DTAG; index++)
7752  {
7753  user_defined_dtag_function[index - FIRST_USER_DEFINED_DTAG] = USER_DEF_DESCRIP_NOT_USED;
7754  }
7755 
7757 }
7758 
7773 void* STB_SIRequestPat(U8BIT path, E_SI_REQUEST_TYPE req_type,
7774  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
7775 {
7776  void *filter_ptr;
7777 
7778  FUNCTION_START(STB_SIRequestPat);
7779 
7780  #ifdef DEBUG_SI_PAT_REQUEST
7781  STB_SI_PRINT(("STB_SIRequestPat: path %d", path));
7782  #endif
7783 
7784  filter_ptr = STB_SIRequestTable(path, SI_PAT_PID, SI_PAT_TID, 0xff, MULTI_SECT, 1,
7785  SI_XTID_MATCH_DONT_CARE, SI_XTID_MASK_DONT_CARE, req_type,
7786  SI_BUFFER_4K, TRUE, FALSE, callback, ret_param);
7787 
7788  FUNCTION_FINISH(STB_SIRequestPat);
7789  return((void *)filter_ptr);
7790 }
7791 
7810 void* STB_SIRequestPmt(U8BIT path, E_SI_REQUEST_TYPE req_type, U16BIT pmt_pid,
7811  U16BIT sid_match, U16BIT sid_mask, U16BIT table_count,
7812  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
7813 {
7814  void *filter_ptr;
7815 
7816  FUNCTION_START(STB_SIRequestPmt);
7817 
7818  #ifdef DEBUG_SI_PMT_REQUEST
7819  STB_SI_PRINT(("STB_SIRequestPmt: path %d pid 0x%04x sid 0x%04x[0x%04x]",
7820  path, pmt_pid, sid_match, sid_mask));
7821  #endif
7822  filter_ptr = STB_SIRequestTable(path, pmt_pid, SI_PMT_TID, 0xff, MULTI_SECT, table_count,
7823  sid_match, sid_mask, req_type, SI_BUFFER_4K, TRUE, FALSE,
7824  callback, ret_param);
7825 
7826  FUNCTION_FINISH(STB_SIRequestPmt);
7827  return((void *)filter_ptr);
7828 }
7829 
7844 void STB_SIModifyPmtRequest(void *fhandle, U16BIT sid_match, U16BIT sid_mask, U16BIT table_count)
7845 {
7846  FUNCTION_START(STB_SIModifyPmtRequest);
7847 
7848  #ifdef DEBUG_SI_PMT_REQUEST
7849  STB_SI_PRINT(("STB_SIModifyPmtRequest: sid 0x%04x[0x%04x]", sid_match, sid_mask));
7850  #endif
7851  STB_SIModifyTableRequest(fhandle, SI_PMT_TID, 0xff, sid_match, sid_mask, table_count);
7852 
7853  FUNCTION_FINISH(STB_SIModifyPmtRequest);
7854 }
7855 
7870 void* STB_SIRequestNit(U8BIT path, E_SI_REQUEST_TYPE req_type,
7871  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
7872 {
7873  void *filter_ptr;
7874 
7875  FUNCTION_START(STB_SIRequestNit);
7876 
7877  #ifdef DEBUG_SI_NIT_REQUEST
7878  STB_SI_PRINT(("STB_SIRequestNit: path %d pid 0x%04x", path, SI_NIT_PID));
7879  #endif
7880 
7881  filter_ptr = STB_SIRequestTable(path, SI_NIT_PID, SI_NIT_ACTUAL_TID, 0xff, MULTI_SECT, 1,
7882  SI_XTID_MATCH_DONT_CARE, SI_XTID_MASK_DONT_CARE, req_type,
7883  SI_BUFFER_4K, TRUE, FALSE, callback, ret_param);
7884 
7885  FUNCTION_FINISH(STB_SIRequestNit);
7886  return((void *)filter_ptr);
7887 }
7888 
7899 void* STB_SIRequestNitFromPid(U8BIT path, U16BIT pid, BOOLEAN actual, E_SI_REQUEST_TYPE req_type,
7900  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
7901 {
7902  void *filter_ptr;
7903  U8BIT tid;
7904 
7905  FUNCTION_START(STB_SIRequestNitFromPid);
7906 
7907  #ifdef DEBUG_SI_NIT_REQUEST
7908  STB_SI_PRINT(("STB_SIRequestNit: path %d pid 0x%04x", path, pid));
7909  #endif
7910 
7911  if (actual)
7912  {
7913  tid = SI_NIT_ACTUAL_TID;
7914  }
7915  else
7916  {
7917  tid = SI_NIT_OTHER_TID;
7918  }
7919 
7920  filter_ptr = STB_SIRequestTable(path, pid, tid, 0xff, MULTI_SECT, 1,
7921  SI_XTID_MATCH_DONT_CARE, SI_XTID_MASK_DONT_CARE, req_type,
7922  SI_BUFFER_4K, TRUE, FALSE, callback, ret_param);
7923 
7924  FUNCTION_FINISH(STB_SIRequestNitFromPid);
7925 
7926  return(filter_ptr);
7927 }
7928 
7938 void* STB_SIRequestNitWithId(U8BIT path, U16BIT network_id, E_SI_REQUEST_TYPE req_type,
7939  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
7940 {
7941  void *filter_ptr;
7942 
7943  FUNCTION_START(STB_SIRequestNitWithId);
7944 
7945  #ifdef DEBUG_SI_NIT_REQUEST
7946  STB_SI_PRINT(("STB_SIRequestNitWithId: path %d pid 0x%04x", path, SI_NIT_PID));
7947  #endif
7948 
7949  filter_ptr = STB_SIRequestTable(path, SI_NIT_PID, SI_NIT_ACTUAL_TID, 0xfe, MULTI_SECT, 1,
7950  network_id, 0xffff, req_type, SI_BUFFER_4K, TRUE, FALSE, callback, ret_param);
7951 
7952  FUNCTION_FINISH(STB_SIRequestNitWithId);
7953 
7954  return((void *)filter_ptr);
7955 }
7956 
7976 void* STB_SIRequestSdt(U8BIT path, E_SI_REQUEST_TYPE req_type,
7977  BOOLEAN inc_sdt_actual, BOOLEAN inc_sdt_other,
7978  U16BIT tran_id_match, U16BIT tran_id_mask, U16BIT table_count,
7979  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
7980 {
7981  void *filter_ptr;
7982  U8BIT tid_match;
7983  U8BIT tid_mask;
7984 
7985  FUNCTION_START(STB_SIRequestSdt);
7986 
7987 
7988  tid_match = SI_SDT_ACTUAL_TID;
7989  tid_mask = 0xff;
7990 
7991  if (inc_sdt_other == TRUE)
7992  {
7993  tid_match = SI_SDT_OTHER_TID;
7994  if (inc_sdt_actual == TRUE)
7995  {
7996  tid_mask = (U8BIT)(~(SI_SDT_ACTUAL_TID ^ SI_SDT_OTHER_TID));
7997  }
7998  }
7999 
8000  #ifdef DEBUG_SI_SDT_REQUEST
8001  STB_SI_PRINT(("STB_SIRequestSdt: path %d pid 0x%04x tid 0x%02x[0x%02x] tran_id 0x%04x[0x%04x]",
8002  path, SI_SDT_PID, tid_match, tid_mask, tran_id_match, tran_id_mask));
8003  #endif
8004 
8005  filter_ptr = STB_SIRequestTable(path, SI_SDT_PID, tid_match, tid_mask, MULTI_SECT, table_count,
8006  tran_id_match, tran_id_mask, req_type, SI_BUFFER_4K,
8007  TRUE, FALSE, callback, ret_param);
8008 
8009  FUNCTION_FINISH(STB_SIRequestSdt);
8010  return((void *)filter_ptr);
8011 }
8012 
8033 void* STB_SIRequestSdtFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type,
8034  BOOLEAN inc_sdt_actual, BOOLEAN inc_sdt_other,
8035  U16BIT tran_id_match, U16BIT tran_id_mask, U16BIT table_count,
8036  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8037 {
8038  void *filter_ptr;
8039  U8BIT tid_match;
8040  U8BIT tid_mask;
8041 
8042  FUNCTION_START(STB_SIRequestSdtFromPid);
8043 
8044 
8045  tid_match = SI_SDT_ACTUAL_TID;
8046  tid_mask = 0xff;
8047 
8048  if (inc_sdt_other == TRUE)
8049  {
8050  tid_match = SI_SDT_OTHER_TID;
8051  if (inc_sdt_actual == TRUE)
8052  {
8053  tid_mask = (U8BIT)(~(SI_SDT_ACTUAL_TID ^ SI_SDT_OTHER_TID));
8054  }
8055  }
8056 
8057  #ifdef DEBUG_SI_SDT_REQUEST
8058  STB_SI_PRINT(("STB_SIRequestSdt: path %d pid 0x%04x tid 0x%02x[0x%02x] tran_id 0x%04x[0x%04x]",
8059  path, pid, tid_match, tid_mask, tran_id_match, tran_id_mask));
8060  #endif
8061 
8062  filter_ptr = STB_SIRequestTable(path, pid, tid_match, tid_mask, MULTI_SECT, table_count,
8063  tran_id_match, tran_id_mask, req_type, SI_BUFFER_4K,
8064  TRUE, FALSE, callback, ret_param);
8065 
8066  FUNCTION_FINISH(STB_SIRequestSdtFromPid);
8067  return((void *)filter_ptr);
8068 }
8069 
8086 void STB_SIModifySdtRequest(void *fhandle, BOOLEAN inc_sdt_actual, BOOLEAN inc_sdt_other,
8087  U16BIT tran_id_match, U16BIT tran_id_mask, U16BIT table_count)
8088 {
8089  U8BIT tid_match;
8090  U8BIT tid_mask;
8091 
8092  FUNCTION_START(STB_SIModifySdtRequest);
8093 
8094  tid_match = SI_SDT_ACTUAL_TID;
8095  tid_mask = 0xff;
8096 
8097  if (inc_sdt_other == TRUE)
8098  {
8099  tid_match = SI_SDT_OTHER_TID;
8100  if (inc_sdt_actual == TRUE)
8101  {
8102  tid_mask = (U8BIT)(~(SI_SDT_ACTUAL_TID ^ SI_SDT_OTHER_TID));
8103  }
8104  }
8105 
8106  #ifdef DEBUG_SI_SDT_REQUEST
8107  STB_SI_PRINT(("STB_SIModifySdtRequest: tid 0x%02x[0x%02x] tran_id 0x%04x[0x%04x]",
8108  tid_match, tid_mask, tran_id_match, tran_id_mask));
8109  #endif
8110 
8111  STB_SIModifyTableRequest(fhandle, tid_match, tid_mask, tran_id_match, tran_id_mask, table_count);
8112 
8113  FUNCTION_FINISH(STB_SIModifySdtRequest);
8114 }
8115 
8133 void* STB_SIRequestBat(U8BIT path, E_SI_REQUEST_TYPE req_type, U16BIT bouquet_id_match,
8134  U16BIT bouquet_id_mask, U16BIT table_count, void (*callback)(void *, U32BIT, SI_TABLE_RECORD *),
8135  U32BIT ret_param)
8136 {
8137  void *filter_ptr;
8138 
8139  FUNCTION_START(STB_SIRequestBat);
8140 
8141  #ifdef DEBUG_SI_BAT_REQUEST
8142  STB_SI_PRINT(("STB_SIRequestBat: path %d pid 0x%04x tid 0x%02x[0xff] tran_id 0x%04x[0x%04x]",
8143  path, SI_BAT_PID, SI_BAT_TID, bouquet_id_match, bouquet_id_mask));
8144  #endif
8145 
8146  filter_ptr = STB_SIRequestTable(path, SI_BAT_PID, SI_BAT_TID, 0xff, MULTI_SECT, table_count,
8147  bouquet_id_match, bouquet_id_mask, req_type, SI_BUFFER_4K,
8148  TRUE, FALSE, callback, ret_param);
8149 
8150  FUNCTION_FINISH(STB_SIRequestBat);
8151  return((void *)filter_ptr);
8152 }
8153 
8172 void* STB_SIRequestBatFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type,
8173  U16BIT bouquet_id_match, U16BIT bouquet_id_mask, U16BIT table_count,
8174  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8175 {
8176  void *filter_ptr;
8177  U8BIT tid_match;
8178 
8179  FUNCTION_START(STB_SIRequestBatFromPid);
8180 
8181  tid_match = SI_BAT_TID;
8182 
8183  #ifdef DEBUG_SI_BAT_REQUEST
8184  STB_SI_PRINT(("STB_SIRequestBat: path %d pid 0x%04x tid 0x%02x[0xff] tran_id 0x%04x[0x%04x]",
8185  path, pid, tid_match, bouquet_id_match, bouquet_id_mask));
8186  #endif
8187 
8188  filter_ptr = STB_SIRequestTable(path, pid, tid_match, 0xff, MULTI_SECT, table_count,
8189  bouquet_id_match, bouquet_id_mask, req_type, SI_BUFFER_4K,
8190  TRUE, FALSE, callback, ret_param);
8191 
8192  FUNCTION_FINISH(STB_SIRequestBatFromPid);
8193  return((void *)filter_ptr);
8194 }
8195 
8214 void* STB_SIRequestEit(U8BIT path, E_SI_REQUEST_TYPE req_type, E_SI_EIT_TABLE_REQ reqd_eit_tables,
8215  U16BIT sid_match, U16BIT sid_mask, U16BIT table_count,
8216  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8217 {
8218  void *filter_ptr;
8219 
8220  FUNCTION_START(STB_SIRequestEit);
8221 
8222  #ifdef DEBUG_SI_EIT_REQUEST
8223  STB_SI_PRINT(("STB_SIRequestEit: path %d pid 0x%04x tid 0x%02x[0x%02x] tran_id 0x%04x[0x%04x]",
8224  path, SI_EIT_PID, eit_tid_match[reqd_eit_tables], eit_tid_mask[reqd_eit_tables],
8225  sid_match, sid_mask));
8226  #endif
8227 
8228  filter_ptr = STB_SIRequestTable(path, SI_EIT_PID, eit_tid_match[reqd_eit_tables],
8229  eit_tid_mask[reqd_eit_tables], MULTI_SECT, table_count,
8230  sid_match, sid_mask, req_type, SI_BUFFER_8K, TRUE, TRUE,
8231  callback, ret_param);
8232 
8233  FUNCTION_FINISH(STB_SIRequestEit);
8234  return((void *)filter_ptr);
8235 }
8236 
8256 void* STB_SIRequestEitFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type, E_SI_EIT_TABLE_REQ reqd_eit_tables,
8257  U16BIT sid_match, U16BIT sid_mask, U16BIT table_count,
8258  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8259 {
8260  void *filter_ptr;
8261 
8262  FUNCTION_START(STB_SIRequestEitFromPid);
8263 
8264  #ifdef DEBUG_SI_EIT_REQUEST
8265  STB_SI_PRINT(("STB_SIRequestEit: path %d pid 0x%04x tid 0x%02x[0x%02x] tran_id 0x%04x[0x%04x]",
8266  path, pid, eit_tid_match[reqd_eit_tables], eit_tid_mask[reqd_eit_tables],
8267  sid_match, sid_mask));
8268  #endif
8269 
8270  filter_ptr = STB_SIRequestTable(path, pid, eit_tid_match[reqd_eit_tables],
8271  eit_tid_mask[reqd_eit_tables], MULTI_SECT, table_count,
8272  sid_match, sid_mask, req_type, SI_BUFFER_8K, TRUE, TRUE,
8273  callback, ret_param);
8274 
8275  FUNCTION_FINISH(STB_SIRequestEitFromPid);
8276  return((void *)filter_ptr);
8277 }
8278 
8294 void STB_SIModifyEitRequest(void *fhandle, E_SI_EIT_TABLE_REQ reqd_eit_tables,
8295  U16BIT sid_match, U16BIT sid_mask, U16BIT table_count)
8296 {
8297  FUNCTION_START(STB_SIModifyEitRequest);
8298 
8299  #ifdef DEBUG_SI_EIT_REQUEST
8300  STB_SI_PRINT(("STB_SIModifyEitRequest: tid 0x%02x[0x%02x] tran_id 0x%04x[0x%04x]",
8301  eit_tid_match[reqd_eit_tables], eit_tid_mask[reqd_eit_tables],
8302  sid_match, sid_mask));
8303  #endif
8304 
8305  STB_SIModifyTableRequest(fhandle, eit_tid_match[reqd_eit_tables], eit_tid_mask[reqd_eit_tables],
8306  sid_match, sid_mask, table_count);
8307 
8308  FUNCTION_FINISH(STB_SIModifyEitRequest);
8309 }
8310 
8329 void* STB_SIRequestSched(U8BIT path, E_SI_REQUEST_TYPE req_type, E_SI_SCHED_TABLE_REQ reqd_eit_tables,
8330  U16BIT sid_match, U16BIT sid_mask, U16BIT table_count,
8331  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8332 {
8333  void *filter_ptr;
8334 
8335  FUNCTION_START(STB_SIRequestSched);
8336 
8337  #ifdef DEBUG_SI_EIT_REQUEST
8338  STB_SI_PRINT(("STB_SIRequestSched: path %d tid 0x%02x[0x%02x] tran_id 0x%04x[0x%04x]",
8339  path, sched_tid_match[reqd_eit_tables], sched_tid_mask[reqd_eit_tables],
8340  sid_match, sid_mask));
8341  #endif
8342 
8343  filter_ptr = STB_SIRequestTable(path, SI_EIT_PID, sched_tid_match[reqd_eit_tables],
8344  sched_tid_mask[reqd_eit_tables], MULTI_SECT, table_count,
8345  sid_match, sid_mask, req_type, SI_BUFFER_32K, TRUE, TRUE,
8346  callback, ret_param);
8347 
8348  FUNCTION_FINISH(STB_SIRequestSched);
8349  return((void *)filter_ptr);
8350 }
8351 
8371 void* STB_SIRequestSchedFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type, E_SI_SCHED_TABLE_REQ reqd_eit_tables,
8372  U16BIT sid_match, U16BIT sid_mask, U16BIT table_count,
8373  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8374 {
8375  void *filter_ptr;
8376 
8377  FUNCTION_START(STB_SIRequestSchedFromPid);
8378 
8379  #ifdef DEBUG_SI_EIT_REQUEST
8380  STB_SI_PRINT(("STB_SIRequestSched: path %d tid 0x%02x[0x%02x] tran_id 0x%04x[0x%04x]",
8381  path, sched_tid_match[reqd_eit_tables], sched_tid_mask[reqd_eit_tables],
8382  sid_match, sid_mask));
8383  #endif
8384 
8385  filter_ptr = STB_SIRequestTable(path, pid, sched_tid_match[reqd_eit_tables],
8386  sched_tid_mask[reqd_eit_tables], MULTI_SECT, table_count,
8387  sid_match, sid_mask, req_type, SI_BUFFER_64K, TRUE, TRUE,
8388  callback, ret_param);
8389 
8390  FUNCTION_FINISH(STB_SIRequestSchedFromPid);
8391  return((void *)filter_ptr);
8392 }
8393 
8408 void* STB_SIRequestTdt(U8BIT path, E_SI_REQUEST_TYPE req_type,
8409  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8410 {
8411  void *filter_ptr;
8412 
8413  FUNCTION_START(STB_SIRequestTdt);
8414 
8415  #ifdef DEBUG_SI_TDT_REQUEST
8416  STB_SI_PRINT(("STB_SIRequestTdt: path %d pid 0x%04x", path, SI_TDT_PID));
8417  #endif
8418 
8419  filter_ptr = STB_SIRequestTable(path, SI_TDT_PID, SI_TDT_TID, 0xff, SINGLE_SECT, 1,
8420  SI_XTID_MATCH_DONT_CARE, SI_XTID_MASK_DONT_CARE, req_type,
8421  SI_BUFFER_1K, FALSE, FALSE, callback, ret_param);
8422 
8423  FUNCTION_FINISH(STB_SIRequestTdt);
8424  return((void *)filter_ptr);
8425 }
8426 
8442 void* STB_SIRequestTdtFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type,
8443  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8444 {
8445  void *filter_ptr;
8446 
8447  FUNCTION_START(STB_SIRequestTdtFromPid);
8448 
8449  #ifdef DEBUG_SI_TDT_REQUEST
8450  STB_SI_PRINT(("STB_SIRequestTdt: path %d pid 0x%04x", path, pid));
8451  #endif
8452 
8453  filter_ptr = STB_SIRequestTable(path, pid, SI_TDT_TID, 0xff, SINGLE_SECT, 1,
8454  SI_XTID_MATCH_DONT_CARE, SI_XTID_MASK_DONT_CARE, req_type,
8455  SI_BUFFER_1K, FALSE, FALSE, callback, ret_param);
8456 
8457  FUNCTION_FINISH(STB_SIRequestTdtFromPid);
8458  return((void *)filter_ptr);
8459 }
8460 
8475 void* STB_SIRequestTot(U8BIT path, E_SI_REQUEST_TYPE req_type,
8476  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8477 {
8478  void *filter_ptr;
8479 
8480  FUNCTION_START(STB_SIRequestTot);
8481 
8482  #ifdef DEBUG_SI_TOT_REQUEST
8483  STB_SI_PRINT(("STB_SIRequestTot: path %d pid 0x%04x", path, SI_TOT_PID));
8484  #endif
8485 
8486  filter_ptr = STB_SIRequestTable(path, SI_TOT_PID, SI_TOT_TID, 0xff, SINGLE_SECT, 1,
8487  SI_XTID_MATCH_DONT_CARE, SI_XTID_MASK_DONT_CARE, req_type,
8488  SI_BUFFER_1K, TRUE, FALSE, callback, ret_param);
8489 
8490  FUNCTION_FINISH(STB_SIRequestTot);
8491  return((void *)filter_ptr);
8492 }
8493 
8508 void* STB_SIRequestTotFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type,
8509  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8510 {
8511  void *filter_ptr;
8512 
8513  FUNCTION_START(STB_SIRequestTotFromPid);
8514 
8515  #ifdef DEBUG_SI_TOT_REQUEST
8516  STB_SI_PRINT(("STB_SIRequestTot: path %d pid 0x%04x", path, pid));
8517  #endif
8518 
8519  filter_ptr = STB_SIRequestTable(path, pid, SI_TOT_TID, 0xff, SINGLE_SECT, 1,
8520  SI_XTID_MATCH_DONT_CARE, SI_XTID_MASK_DONT_CARE, req_type,
8521  SI_BUFFER_1K, TRUE, FALSE, callback, ret_param);
8522 
8523  FUNCTION_FINISH(STB_SIRequestTotFromPid);
8524  return((void *)filter_ptr);
8525 }
8526 
8541 void* STB_SIRequestCat(U8BIT path, E_SI_REQUEST_TYPE req_type,
8542  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8543 {
8544  void *filter_ptr;
8545 
8546  FUNCTION_START(STB_SIRequestCat);
8547 
8548  #ifdef DEBUG_SI_CAT_REQUEST
8549  STB_SI_PRINT(("STB_SIRequestCat: path %d pid 0x%04x", path, SI_CAT_PID));
8550  #endif
8551 
8552  filter_ptr = STB_SIRequestTable(path, SI_CAT_PID, SI_CAT_TID, 0xff, MULTI_SECT, 1,
8553  SI_XTID_MATCH_DONT_CARE, SI_XTID_MASK_DONT_CARE, req_type,
8554  SI_BUFFER_4K, TRUE, FALSE, callback, ret_param);
8555 
8556  FUNCTION_FINISH(STB_SIRequestCat);
8557  return((void *)filter_ptr);
8558 }
8559 
8575 void* STB_SIRequestRct(U8BIT path, E_SI_REQUEST_TYPE req_type, U16BIT rct_pid,
8576  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
8577 {
8578  void *filter_ptr;
8579 
8580  FUNCTION_START(STB_SIRequestRct);
8581 
8582  #ifdef DEBUG_SI_RCT_REQUEST
8583  STB_SI_PRINT(("STB_SIRequestRct: path %d pid 0x%04x", path, rct_pid));
8584  #endif
8585  filter_ptr = STB_SIRequestTable(path, rct_pid, SI_RCT_TID, 0xff, MULTI_SECT, 1,
8586  SI_XTID_MATCH_DONT_CARE, SI_XTID_MASK_DONT_CARE, req_type,
8587  SI_BUFFER_4K, TRUE, FALSE, callback, ret_param);
8588 
8589  FUNCTION_FINISH(STB_SIRequestRct);
8590 
8591  return((void *)filter_ptr);
8592 }
8593 
8594 //--------------------------------------------------------------------------------------------------
8595 // Table parsing functions
8596 //--------------------------------------------------------------------------------------------------
8597 
8612 {
8613  SI_PAT_TABLE *pat_table;
8614  SI_SECTION_RECORD *section_rec;
8615  U8BIT *data_ptr;
8616  U8BIT *data_end;
8617  U16BIT prog_no;
8618  U16BIT pmt_pid;
8619  SI_PAT_SERVICE_ENTRY *serv_entry;
8620 
8621  FUNCTION_START(STB_SIParsePatTable);
8622 
8623  ASSERT(table_rec != NULL);
8624 
8625  pat_table = NULL;
8626  if (table_rec != NULL)
8627  {
8628  if (table_rec->tid == SI_PAT_TID)
8629  {
8630  #ifdef DEBUG_SI_PAT_SUMMARY
8631  STB_SI_PRINT(("STB_SIParsePatTable: tid 0x%02x/0x%04x, v%d, nsect %d",
8632  table_rec->tid, table_rec->xtid, table_rec->version,
8633  table_rec->num_sect));
8634  #endif
8635 
8636  // grab memory for the table
8637  pat_table = STB_GetMemory(sizeof(SI_PAT_TABLE));
8638  if (pat_table != NULL)
8639  {
8640  memset(pat_table, 0, sizeof(SI_PAT_TABLE));
8641 
8642  pat_table->version = table_rec->version;
8643  pat_table->tran_id = table_rec->xtid;
8644 
8645  section_rec = table_rec->section_list;
8646  while (section_rec != NULL)
8647  {
8648  #ifdef DEBUG_SI_PAT_CONTENT
8649  STB_SI_PRINT((" section %d", section_rec->sect_num));
8650  #endif
8651 
8652  // get pointer to section data and end of section
8653  data_ptr = &(section_rec->data_start);
8654  data_end = data_ptr + section_rec->data_len - 4; // -4 for crc
8655 
8656  // skip section header
8657  data_ptr += 8;
8658 
8659  while (data_ptr < data_end)
8660  {
8661  // read next entry from section - if it is not 0 (nit pid) and it is not a
8662  // duplicate of an entry we have already had add it to the pat table
8663  prog_no = (data_ptr[0] << 8) | data_ptr[1];
8664  pmt_pid = ((data_ptr[2] & 0x1f) << 8) | data_ptr[3];
8665  data_ptr += 4;
8666 
8667  if (prog_no != 0)
8668  {
8669  // check if this is a duplicate or new entry
8670  serv_entry = pat_table->service_list;
8671  while (serv_entry != NULL)
8672  {
8673  if ((serv_entry->serv_id == prog_no) && (serv_entry->pmt_pid == pmt_pid))
8674  {
8675  #ifdef DEBUG_SI_PAT_CONTENT
8676  STB_SI_PRINT((" sid=0x%04x, pmt=0x%04x - duplicated", prog_no,
8677  pmt_pid));
8678  #endif
8679  break;
8680  }
8681  serv_entry = serv_entry->next;
8682  }
8683  if (serv_entry == NULL)
8684  {
8685  // not found - create a new entry
8686  serv_entry = STB_GetMemory(sizeof(SI_PAT_SERVICE_ENTRY));
8687  if (serv_entry != NULL)
8688  {
8689  serv_entry->next = NULL;
8690  serv_entry->serv_id = prog_no;
8691  serv_entry->pmt_pid = pmt_pid;
8692 
8693  // add to the end of the entry list in the pat table
8694  if (pat_table->last_service_entry == NULL)
8695  {
8696  // first entry in the list
8697  pat_table->service_list = serv_entry;
8698  }
8699  else
8700  {
8701  // not the first entry
8702  pat_table->last_service_entry->next = serv_entry;
8703  }
8704  pat_table->last_service_entry = serv_entry;
8705  pat_table->num_services++;
8706 
8707  #ifdef DEBUG_SI_PAT_CONTENT
8708  STB_SI_PRINT((" sid=0x%04x, pmt=0x%04x", prog_no, pmt_pid));
8709  #endif
8710  }
8711  }
8712  }
8713  }
8714  // move on to next section
8715  section_rec = section_rec->next;
8716  }
8717  }
8718  }
8719  }
8720 
8721  FUNCTION_FINISH(STB_SIParsePatTable);
8722  return(pat_table);
8723 }
8724 
8739 {
8740  SI_PMT_TABLE *pmt_table;
8741  SI_SECTION_RECORD *section_rec;
8742  U8BIT *data_ptr;
8743  U8BIT *data_end;
8744  U16BIT dloop_len;
8745  U8BIT *dloop_end;
8746  U8BIT dtag;
8747  SI_PMT_STREAM_ENTRY *stream_entry;
8748  U32BIT priv_data_code;
8749 
8750  FUNCTION_START(STB_SIParsePmtTable);
8751 
8752  ASSERT(table_rec != NULL);
8753 
8754  pmt_table = NULL;
8755  if (table_rec != NULL)
8756  {
8757  if (table_rec->tid == SI_PMT_TID)
8758  {
8759  #ifdef DEBUG_SI_PMT_SUMMARY
8760  STB_SI_PRINT(("STB_SIParsePmtTable: tid 0x%02x/0x%04x, v%d, nsect %d",
8761  table_rec->tid, table_rec->xtid, table_rec->version,
8762  table_rec->num_sect));
8763  #endif
8764 
8765  pmt_table = STB_GetMemory(sizeof(SI_PMT_TABLE));
8766  if (pmt_table != NULL)
8767  {
8768  memset(pmt_table, 0, sizeof(SI_PMT_TABLE));
8769 
8770  pmt_table->version = table_rec->version;
8771  pmt_table->serv_id = table_rec->xtid;
8772 
8773  section_rec = table_rec->section_list;
8774  while (section_rec != NULL)
8775  {
8776  #ifdef DEBUG_SI_PMT_CONTENT
8777  STB_SI_PRINT((" section %d", section_rec->sect_num));
8778  #endif
8779 
8780  // get pointer to section data and end of section
8781  data_ptr = &(section_rec->data_start);
8782  data_end = data_ptr + section_rec->data_len - 4; // -4 for crc
8783 
8784  // skip section header
8785  data_ptr += 8;
8786 
8787  // get pcr pid and descriptor loop length
8788  pmt_table->pcr_pid = ((data_ptr[0] & 0x1f) << 8) | data_ptr[1];
8789  dloop_len = ((data_ptr[2] & 0x0f) << 8) | data_ptr[3];
8790  data_ptr += 4;
8791 
8792  #ifdef DEBUG_SI_PMT_CONTENT
8793  STB_SI_PRINT((" pcr pid=0x%04x (first loop len %d)", pmt_table->pcr_pid,
8794  dloop_len));
8795  STB_SI_PRINT((" {"));
8796  #endif
8797 
8798  /* According to Nordig v2.5.1, the default setting for content protection is 0x01,
8799  * which means content protection isn't required and the content protectionxi
8800  * mechanism, e.g. HDCP, can be either on or off */
8801  pmt_table->content_protection_level = 0x01;
8802 
8803  // process first descriptor loop
8804  priv_data_code = 0;
8805  dloop_end = data_ptr + dloop_len;
8806  while (data_ptr < dloop_end)
8807  {
8808  dtag = data_ptr[0];
8809  data_ptr++;
8810  #ifdef DEBUG_SI_PMT_CONTENT
8811  if (dtag != 00)
8812  {
8813  STB_SI_PRINT((" tag %02x len %04x", dtag, *data_ptr));
8814  }
8815  #endif
8816 
8817  switch (dtag)
8818  {
8819  case CA_DTAG:
8820  {
8821  data_ptr = ParseCaDescriptor(data_ptr, &pmt_table->num_ca_entries,
8822  &pmt_table->ca_desc_array, DEBUG_SI_PMT_CONTENT_VALUE);
8823  break;
8824  }
8825 
8826  case PRIV_DATA_INDICATOR_DTAG:
8827  {
8828  /* In Freesat when there is an indicator it should end the scope of the
8829  * private data specifier */
8830  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_PMT_CONTENT_VALUE);
8831  priv_data_code = 0;
8832  break;
8833  }
8834 
8835  case PRIV_DATA_SPEC_DTAG:
8836  {
8837  data_ptr = ParsePrivateDataSpecifierDescriptor(data_ptr, &priv_data_code, DEBUG_SI_PMT_CONTENT_VALUE);
8838  break;
8839  }
8840 
8841  case FREESAT_TUNNELLED_DTAG:
8842  {
8843  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
8844  (freesat_private_data_specifier == TRUE))
8845  {
8846  data_ptr = ParseFreesatTunnelledDataDescriptor(data_ptr,
8847  &pmt_table->num_tunnelled_entries,
8848  &pmt_table->tunnelled_desc_array,
8849  FALSE, DEBUG_SI_PMT_CONTENT_VALUE);
8850  }
8851  else
8852  {
8853  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_PMT_CONTENT_VALUE);
8854  }
8855  break;
8856  }
8857 
8858  case USER_DEFINED_DTAG_0xA0:
8859  {
8860  if (nordig_private_data_specifier)
8861  {
8862  /* This is the Nordig content protection descriptor */
8863  data_ptr = ParseNordigContentProtectionDesc(data_ptr,
8864  &pmt_table->content_protection_level, DEBUG_SI_PMT_CONTENT_VALUE);
8865  }
8866  else
8867  {
8868  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_PMT_CONTENT_VALUE);
8869  }
8870  break;
8871  }
8872 
8873  default:
8874  {
8875  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_PMT_CONTENT_VALUE);
8876  break;
8877  }
8878  }
8879  }
8880  #ifdef DEBUG_SI_PMT_CONTENT
8881  STB_SI_PRINT((" }"));
8882  #endif
8883 
8884  // read entry for each stream
8885  while (data_ptr < data_end)
8886  {
8887  stream_entry = (SI_PMT_STREAM_ENTRY *)STB_GetMemory(sizeof(SI_PMT_STREAM_ENTRY));
8888  if (stream_entry != NULL)
8889  {
8890  // initialise new stream structure
8891  memset(stream_entry, 0, sizeof(SI_PMT_STREAM_ENTRY));
8892 
8893  // add to the end of the stream list in the pmt table
8894  if (pmt_table->last_stream_entry == NULL)
8895  {
8896  // first entry in the list
8897  pmt_table->stream_list = stream_entry;
8898  }
8899  else
8900  {
8901  // not the first entry
8902  pmt_table->last_stream_entry->next = stream_entry;
8903  }
8904  pmt_table->last_stream_entry = stream_entry;
8905  pmt_table->num_streams++;
8906 
8907  // read stream data and descriptor loop length
8908  stream_entry->type = data_ptr[0];
8909  stream_entry->pid = ((data_ptr[1] & 0x1f) << 8) | data_ptr[2];
8910  dloop_len = ((data_ptr[3] & 0x0f) << 8) | data_ptr[4];
8911  data_ptr += 5;
8912 
8913  stream_entry->carousel_id = DVB_INVALID_CAROUSEL_ID;
8914 
8915  #ifdef DEBUG_SI_PMT_CONTENT
8916  STB_SI_PRINT((" type=0x%02x, pid=0x%02x (desc loop len %d)",
8917  stream_entry->type, stream_entry->pid, dloop_len));
8918  STB_SI_PRINT((" {"));
8919  #endif
8920 
8921  // process stream descriptor loop
8922  priv_data_code = 0;
8923  dloop_end = data_ptr + dloop_len;
8924  while ((data_ptr < dloop_end) && (data_ptr < data_end))
8925  {
8926  dtag = data_ptr[0];
8927  data_ptr++;
8928  #ifdef DEBUG_SI_PMT_CONTENT
8929  if (dtag > 0)
8930  {
8931  STB_SI_PRINT((" tag %02x len %04x", dtag, *data_ptr));
8932  }
8933  #endif
8934 
8935  switch (dtag)
8936  {
8937  case CAROUSEL_ID_DTAG:
8938  {
8939  if ((stream_entry->type == SI_STREAM_TYPE_DATA_B) ||
8940  (stream_entry->type == SI_STREAM_TYPE_DATA_C) ||
8941  (stream_entry->type == SI_STREAM_TYPE_DATA_D))
8942  {
8943  data_ptr = ParseCarouselIdDescriptor(data_ptr,
8944  &stream_entry->carousel_id, DEBUG_SI_PMT_CONTENT_VALUE);
8945  }
8946  else
8947  {
8948  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_PMT_CONTENT_VALUE);
8949  }
8950  break;
8951  }
8952 
8953  case CA_DTAG:
8954  {
8955  data_ptr = ParseCaDescriptor(data_ptr, &stream_entry->num_ca_entries,
8956  &stream_entry->ca_desc_array, DEBUG_SI_PMT_CONTENT_VALUE);
8957  break;
8958  }
8959 
8960  case ISO_LANG_DTAG:
8961  {
8962  data_ptr = ParseIsoLangDescriptor(data_ptr,
8963  &stream_entry->num_iso_lang_entries,
8964  &stream_entry->iso_lang_desc_array, DEBUG_SI_PMT_CONTENT_VALUE);
8965  break;
8966  }
8967 
8968  case STREAM_ID_DTAG:
8969  {
8970  data_ptr = ParseStreamIdDescriptor(data_ptr, &stream_entry->tag_array_ptr,
8971  &stream_entry->num_tag_entries, DEBUG_SI_PMT_CONTENT_VALUE);
8972  break;
8973  }
8974 
8975  case SUBTITLE_DTAG:
8976  {
8977  data_ptr = ParseSubtitleDescriptor(data_ptr,
8978  &stream_entry->num_subtitle_entries,
8979  &stream_entry->subtitle_desc_array, DEBUG_SI_PMT_CONTENT_VALUE);
8980  break;
8981  }
8982 
8983  case TELETEXT_DTAG:
8984  {
8985  data_ptr = ParseTeletextDescriptor(data_ptr,
8986  &stream_entry->num_teletext_entries,
8987  &stream_entry->teletext_desc_array, DEBUG_SI_PMT_CONTENT_VALUE);
8988  break;
8989  }
8990 
8991  case PRIV_DATA_INDICATOR_DTAG:
8992  {
8993  /* In Freesat when there is an indicator it should end the scope of the
8994  * private data specifier */
8995  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_PMT_CONTENT_VALUE);
8996  priv_data_code = 0;
8997  break;
8998  }
8999 
9000  case PRIV_DATA_SPEC_DTAG:
9001  {
9002  data_ptr = ParsePrivateDataSpecifierDescriptor(data_ptr,
9003  &priv_data_code, DEBUG_SI_PMT_CONTENT_VALUE);
9004  break;
9005  }
9006 
9007  case AC3_DTAG:
9008  case EAC3_DTAG:
9009  {
9010  stream_entry->tag_array_ptr = (U8BIT *)STB_GetMemory(sizeof(U8BIT));
9011  stream_entry->tag_array_ptr[0] = dtag;
9012  stream_entry->num_tag_entries = 1;
9013  data_ptr = ParseAC3Descriptor(data_ptr, dtag,
9014  &stream_entry->ac3_descriptor, DEBUG_SI_PMT_CONTENT_VALUE);
9015  break;
9016  }
9017 
9018  case AAC_DTAG:
9019  {
9020  data_ptr = ParseAACDescriptor(data_ptr,
9021  &stream_entry->aac_descriptor, DEBUG_SI_PMT_CONTENT_VALUE);
9022  break;
9023  }
9024 
9025  case EXT_DTAG:
9026  {
9027  /* Examine the extension tag for the table being signalled */
9028  switch (data_ptr[1])
9029  {
9030  case SUPPLEMENTARY_AUDIO_DTAG:
9031  data_ptr = ParseSupplementaryAudioDescriptor(data_ptr,
9032  &stream_entry->audio_desc, DEBUG_SI_PMT_CONTENT_VALUE);
9033  break;
9034 
9035  default:
9036  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_PMT_CONTENT_VALUE);
9037  break;
9038  }
9039  break;
9040  }
9041 
9042  case FREESAT_ALT_TUNNELLED_DTAG:
9043  {
9044  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
9045  (freesat_private_data_specifier == TRUE) &&
9046  ((stream_entry->type == SI_STREAM_TYPE_PRIVATE) ||
9047  (stream_entry->type == SI_STREAM_TYPE_DATA_B)))
9048  {
9049  data_ptr = ParseFreesatTunnelledDataDescriptor(data_ptr,
9050  &stream_entry->num_tunnelled_entries,
9051  &stream_entry->tunnelled_desc_array,
9052  TRUE, DEBUG_SI_PMT_CONTENT_VALUE);
9053  }
9054  else
9055  {
9056  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_PMT_CONTENT_VALUE);
9057  }
9058  break;
9059  }
9060 
9061 #if 0
9062  case SERVICE_MOVE_DTAG:
9063  {
9064  data_ptr = ParseServiceMoveDescriptor(data_ptr,
9065  &stream_entry->service_move, DEBUG_SI_PMT_CONTENT_VALUE);
9066  break;
9067  }
9068 #endif
9069 
9070  case APP_SIG_DTAG:
9071  {
9072  /* The application signalling descriptor is only
9073  * valid for private stream types */
9074  if (stream_entry->type == SI_STREAM_TYPE_PRIVATE)
9075  {
9076  /* Even if the descriptor doesn't actually contain any info, it indicates
9077  * that this is the PID to be used to collect the AIT table */
9078  stream_entry->has_ait = TRUE;
9079 
9080  data_ptr = ParseAppSignallingDescriptor(data_ptr,
9081  &stream_entry->num_app_sig_entries, &stream_entry->app_sig_desc_array, DEBUG_SI_PMT_CONTENT_VALUE);
9082  }
9083  else
9084  {
9085  /* Descriptor shouldn't be here so skip it */
9086  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_PMT_CONTENT_VALUE);
9087  }
9088  break;
9089  }
9090 
9091  case RELATED_CONTENT_DTAG:
9092  {
9093  /* The related content descriptor is only
9094  * valid for private stream types */
9095  if (stream_entry->type == SI_STREAM_TYPE_PRIVATE)
9096  {
9097  /* The descriptor doesn't actually contain any info, it just indicates
9098  * that this is the PID to be used to collect the RCT table */
9099  stream_entry->has_rct = TRUE;
9100  }
9101 
9102  /* Ensure the descriptor is skipped */
9103  data_ptr = SkipDescriptor(data_ptr, dtag, FALSE);
9104  break;
9105  }
9106 
9107  default:
9108  {
9109  #ifdef DEBUG_SI_PMT_CONTENT
9110  if (dtag == 0x6f)
9111  {
9112  U8BIT *dptr = data_ptr + 1;
9113  U8BIT len;
9114 
9115  STB_SI_PRINT((" loop2: dtag 0x%02x, len %u\n", dtag, *data_ptr));
9116  for (len = 0; len < *data_ptr; dptr++, len++)
9117  {
9118  STB_SI_PRINT((" %02x", *dptr));
9119  }
9120  }
9121  #endif
9122  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_PMT_CONTENT_VALUE);
9123  break;
9124  }
9125  }
9126  }
9127  #ifdef DEBUG_SI_PMT_CONTENT
9128  STB_SI_PRINT((" }"));
9129  #endif
9130  }
9131  }
9132  // move on to next section
9133  section_rec = section_rec->next;
9134  }
9135  }
9136  }
9137  }
9138  FUNCTION_FINISH(STB_SIParsePmtTable);
9139  return(pmt_table);
9140 }
9141 
9156 {
9157  SI_NIT_TABLE *nit_table;
9158  SI_SECTION_RECORD *section_rec;
9159  U8BIT *data_ptr;
9160  U8BIT *data_end;
9161  U16BIT dloop_len;
9162  U8BIT *dloop_end;
9163  U8BIT dtag;
9164  U32BIT priv_data_code;
9165  SI_NIT_TRANSPORT_ENTRY *trans_entry;
9166 
9167  FUNCTION_START(STB_SIParseNitTable);
9168 
9169  ASSERT(table_rec != NULL);
9170 
9171  nit_table = NULL;
9172  if (table_rec != NULL)
9173  {
9174  if ((table_rec->tid == SI_NIT_ACTUAL_TID) || (table_rec->tid == SI_NIT_OTHER_TID))
9175  {
9176  #ifdef DEBUG_SI_NIT_SUMMARY
9177  STB_SI_PRINT(("STB_SIParseNitTable: tid 0x%02x/0x%04x, v%d, nsect %d",
9178  table_rec->tid, table_rec->xtid, table_rec->version, table_rec->num_sect));
9179  #endif
9180 
9181  nit_table = STB_GetMemory(sizeof(SI_NIT_TABLE));
9182  if (nit_table != NULL)
9183  {
9184  memset(nit_table, 0, sizeof(SI_NIT_TABLE));
9185 
9186  nit_table->version = table_rec->version;
9187  nit_table->net_id = table_rec->xtid;
9188 
9189  section_rec = table_rec->section_list;
9190  while (section_rec != NULL)
9191  {
9192  #ifdef DEBUG_SI_NIT_CONTENT
9193  STB_SI_PRINT((" section %d", section_rec->sect_num));
9194  #endif
9195 
9196  // get pointer to section data and end of section
9197  data_ptr = &(section_rec->data_start);
9198  data_end = data_ptr + section_rec->data_len - 4; // -4 for crc
9199 
9200  // skip section header
9201  data_ptr += 8;
9202 
9203  // read first descriptor loop length
9204  dloop_len = ((data_ptr[0] & 0x0f) << 8) | data_ptr[1];
9205  data_ptr += 2;
9206 
9207  #ifdef DEBUG_SI_NIT_CONTENT
9208  STB_SI_PRINT((" (first loop len %d)", dloop_len));
9209  #endif
9210 
9211  // process first (network) descriptor loop
9212  priv_data_code = 0;
9213  dloop_end = data_ptr + dloop_len;
9214  while (data_ptr < dloop_end)
9215  {
9216  dtag = data_ptr[0];
9217 
9218  #ifdef DEBUG_SI_NIT_CONTENT
9219  STB_SI_PRINT((" dtag=0x%02x", (int)dtag));
9220  #endif
9221 
9222  data_ptr++;
9223  switch (dtag)
9224  {
9225  case NET_NAME_DTAG:
9226  {
9227  data_ptr = ParseNetNameDescriptor(data_ptr, &nit_table->name_str, DEBUG_SI_NIT_CONTENT_VALUE);
9228  break;
9229  }
9230 
9231  case MULTILING_NET_NAME_DTAG:
9232  {
9233  data_ptr = ParseMultilingNetNameDescriptor(data_ptr,
9234  &nit_table->num_multiling_net_names,
9235  &nit_table->multiling_net_name_desc_array, DEBUG_SI_NIT_CONTENT_VALUE);
9236  break;
9237  }
9238 
9239  case LINKAGE_DTAG:
9240  {
9241  data_ptr = ParseLinkageDescriptor(data_ptr,
9242  &nit_table->num_linkage_entries,
9243  &nit_table->linkage_desc_list,
9244  &nit_table->last_linkage_entry, priv_data_code,
9245  DEBUG_SI_NIT_CONTENT_VALUE);
9246  break;
9247  }
9248 
9249  case PRIV_DATA_SPEC_DTAG:
9250  {
9251  data_ptr = ParsePrivateDataSpecifierDescriptor(data_ptr, &priv_data_code, DEBUG_SI_NIT_CONTENT_VALUE);
9252  break;
9253  }
9254 
9255  case DEF_AUTH_DTAG:
9256  {
9257  data_ptr = ParseDefaultAuthorityDescriptor(data_ptr, &nit_table->def_authority, DEBUG_SI_NIT_CONTENT_VALUE);
9258  break;
9259  }
9260 
9261  case FTA_CONTENT_DTAG:
9262  {
9263  data_ptr = ParseFTAContentDescriptor(data_ptr, &nit_table->fta_content_desc, DEBUG_SI_NIT_CONTENT_VALUE);
9264  break;
9265  }
9266 
9267  case FREESAT_LINK_DTAG: /* or CIPLUS_VIRTUAL_CHAN_DTAG */
9268  {
9269  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
9270  (freesat_private_data_specifier == TRUE))
9271  {
9272  data_ptr = ParseFreesatLinkageDescriptor(data_ptr,
9273  &nit_table->freesat_linkage_desc, DEBUG_SI_NIT_CONTENT_VALUE);
9274  }
9275  else if ((priv_data_code == CIPLUS_PRIVATE_DATA_SPECIFIER) &&
9276  (ciplus_private_data_specifier == TRUE))
9277  {
9278  data_ptr = ParseCIPlusVirtualChannelDescriptor(data_ptr,
9279  &nit_table->ciplus_virtual_channel, DEBUG_SI_NIT_CONTENT_VALUE);
9280  }
9281  else
9282  {
9283  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_NIT_CONTENT_VALUE);
9284  }
9285  break;
9286  }
9287 
9288  case FREESAT_PREFIX_DTAG:
9289  {
9290  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
9291  (freesat_private_data_specifier == TRUE))
9292  {
9293  data_ptr = ParseFreesatPrefixDescriptor(data_ptr,
9294  &nit_table->freesat_prefix_list, DEBUG_SI_NIT_CONTENT_VALUE);
9295  }
9296  else
9297  {
9298  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_NIT_CONTENT_VALUE);
9299  }
9300  break;
9301  }
9302 
9303  case EXT_DTAG:
9304  {
9305  /* Examine the extension tag for the table being signalled */
9306  switch (data_ptr[1])
9307  {
9308  case NETWORK_CHANGE_NOTIFY_DTAG:
9309  data_ptr = ParseNetworkChangeNotifyDescriptor(data_ptr,
9310  &nit_table->num_change_notifies,
9311  &nit_table->change_notify_array, DEBUG_SI_NIT_CONTENT_VALUE);
9312  break;
9313 
9314  case MESSAGE_DTAG:
9315  data_ptr = ParseMessageDescriptor(data_ptr,
9316  &nit_table->num_messages,
9317  &nit_table->message_array, DEBUG_SI_NIT_CONTENT_VALUE);
9318  break;
9319 
9320  case TARGET_REGION_NAME_DTAG:
9321  data_ptr = ParseTargetRegionNameDescriptor(data_ptr,
9322  &nit_table->target_region_name_list, DEBUG_SI_NIT_CONTENT_VALUE);
9323  break;
9324 
9325  case TARGET_REGION_DTAG:
9326  data_ptr = ParseTargetRegionDescriptor(data_ptr,
9327  &nit_table->target_region_list, DEBUG_SI_NIT_CONTENT_VALUE);
9328  break;
9329 
9330  case URI_LINKAGE_DTAG:
9331  data_ptr = ParseURILinkageDesc(data_ptr,
9332  &nit_table->uri_linkage_list, priv_data_code, DEBUG_SI_NIT_CONTENT_VALUE);
9333  break;
9334 
9335  default:
9336  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_NIT_CONTENT_VALUE);
9337  break;
9338  }
9339  break;
9340  }
9341 
9342  default:
9343  {
9344  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_NIT_CONTENT_VALUE);
9345  break;
9346  }
9347  }
9348  }
9349 
9350  // skip transport stream loop length - not needed because we keep reading transports
9351  // until we reach the end of the table
9352  data_ptr += 2;
9353 
9354  // read entry for each transport
9355  while (data_ptr < data_end)
9356  {
9358  if (trans_entry != NULL)
9359  {
9360  // initialise new transport structure
9361  memset(trans_entry, 0, sizeof(SI_NIT_TRANSPORT_ENTRY));
9362 
9363  // add to the end of the stream list in the nit table
9364  if (nit_table->last_transport_entry == NULL)
9365  {
9366  // first entry in the list
9367  nit_table->transport_list = trans_entry;
9368  }
9369  else
9370  {
9371  // not the first entry
9372  nit_table->last_transport_entry->next = trans_entry;
9373  }
9374  nit_table->last_transport_entry = trans_entry;
9375  nit_table->num_transports++;
9376 
9377  // read stream data and descriptor loop length
9378  trans_entry->tran_id = (data_ptr[0] << 8) | data_ptr[1];
9379  trans_entry->orig_net_id = (data_ptr[2] << 8) | data_ptr[3];
9380  dloop_len = ((data_ptr[4] & 0x0f) << 8) | data_ptr[5];
9381  data_ptr += 6;
9382 
9383  #ifdef DEBUG_SI_NIT_CONTENT
9384  STB_SI_PRINT((" tid=0x%04x, onid=0x%04x (desc loop len %d)",
9385  trans_entry->tran_id, trans_entry->orig_net_id, dloop_len));
9386  #endif
9387 
9388  // process transport descriptor loop
9389  priv_data_code = 0;
9390  dloop_end = data_ptr + dloop_len;
9391  while (data_ptr < dloop_end)
9392  {
9393  dtag = data_ptr[0];
9394 
9395  #ifdef DEBUG_SI_NIT_CONTENT
9396  STB_SI_PRINT((" dtag=0x%02x", (int)dtag));
9397  #endif
9398 
9399  data_ptr++;
9400  switch (dtag)
9401  {
9402  case FREQ_LIST_DTAG:
9403  {
9404  data_ptr = ParseFrequencyListDescriptor(data_ptr,
9405  &trans_entry->freq_list, DEBUG_SI_NIT_CONTENT_VALUE);
9406  break;
9407  }
9408 
9409  case SERV_LIST_DTAG:
9410  {
9411  data_ptr = ParseServiceListDescriptor(data_ptr,
9412  &trans_entry->num_serv_list_entries,
9413  &trans_entry->serv_list_desc_array, DEBUG_SI_NIT_CONTENT_VALUE);
9414  break;
9415  }
9416 
9417  case TERR_DEL_SYS_DTAG:
9418  {
9419  trans_entry->del_sys_desc_type = SI_DEL_SYS_DESC_TYPE_TERR;
9420 
9421  data_ptr = ParseTerrestrialDeliverySysDescriptor(data_ptr,
9422  &trans_entry->del_sys_desc, DEBUG_SI_NIT_CONTENT_VALUE);
9423  break;
9424  }
9425 
9426  case SAT_DEL_SYS_DTAG:
9427  {
9428  trans_entry->del_sys_desc_type = SI_DEL_SYS_DESC_TYPE_SAT;
9429 
9430  data_ptr = ParseSatelliteDeliverySysDescriptor(data_ptr,
9431  &trans_entry->del_sys_desc, DEBUG_SI_NIT_CONTENT_VALUE);
9432  break;
9433  }
9434 
9435  case CABLE_DEL_SYS_DTAG:
9436  {
9437  trans_entry->del_sys_desc_type = SI_DEL_SYS_DESC_TYPE_CABLE;
9438 
9439  data_ptr = ParseCableDeliverySysDescriptor(data_ptr,
9440  &trans_entry->del_sys_desc, DEBUG_SI_NIT_CONTENT_VALUE);
9441  break;
9442  }
9443 
9444  case PRIV_DATA_SPEC_DTAG:
9445  {
9446  data_ptr = ParsePrivateDataSpecifierDescriptor(data_ptr,
9447  &priv_data_code, DEBUG_SI_NIT_CONTENT_VALUE);
9448  break;
9449  }
9450 
9451  case DEF_AUTH_DTAG:
9452  {
9453  data_ptr = ParseDefaultAuthorityDescriptor(data_ptr,
9454  &trans_entry->def_authority, DEBUG_SI_NIT_CONTENT_VALUE);
9455  break;
9456  }
9457 
9458  case FTA_CONTENT_DTAG:
9459  {
9460  data_ptr = ParseFTAContentDescriptor(data_ptr, &trans_entry->fta_content_desc, DEBUG_SI_NIT_CONTENT_VALUE);
9461  break;
9462  }
9463 
9464  case EXT_DTAG:
9465  {
9466  /* Examine the extension tag for the table being signalled */
9467  switch (data_ptr[1])
9468  {
9469  case T2_DELIVERY_SYS_DTAG:
9470  trans_entry->del_sys_desc_type = SI_DEL_SYS_DESC_TYPE_TERR;
9471  data_ptr = ParseT2DeliverySysDescriptor(data_ptr,
9472  &trans_entry->del_sys_desc, DEBUG_SI_NIT_CONTENT_VALUE);
9473  break;
9474 
9475  case TARGET_REGION_DTAG:
9476  data_ptr = ParseTargetRegionDescriptor(data_ptr,
9477  &trans_entry->target_region_list, DEBUG_SI_NIT_CONTENT_VALUE);
9478  break;
9479 
9480  default:
9481  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_NIT_CONTENT_VALUE);
9482  break;
9483  }
9484  break;
9485  }
9486 
9487  case USER_DEFINED_DTAG_0x83:
9488  {
9489  /* For UK DTT this is logical chan number and private data
9490  * descriptor will have been set. This will also be true for
9491  * some other countries that comply with the E-Book, but in
9492  * this case the descriptor is almost identical except for the
9493  * inclusion of a 1-bit 'visible service' flag. And finally, some
9494  * other countries use this descriptor tag but don't set a private
9495  * data specifier, so in this case the app will have set the user
9496  * defined descriptor function */
9497  if (((priv_data_code == UK_DTT_PRIVATE_DATA_SPECIFIER) &&
9498  (priv_data_code == country_private_data_specifier_code)) ||
9499  ((priv_data_code == ZAF_DTT_PRIVATE_DATA_SPECIFIER) &&
9500  (priv_data_code == country_private_data_specifier_code)) ||
9501  ((priv_data_code == NORDIG_PRIVATE_DATA_SPECIFIER) &&
9502  (nordig_private_data_specifier == TRUE)) ||
9503  (GetUserDefinedDescriptorFunction(dtag) == USER_DEF_DESCRIP_LOGICAL_CHAN_NUM))
9504  {
9505  data_ptr = ParseLogicalChannelDescriptor(data_ptr, dtag,
9506  &trans_entry->num_lcn_entries,
9507  &trans_entry->lcn_desc_array, DEBUG_SI_NIT_CONTENT_VALUE);
9508  }
9509  else
9510  {
9511  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_NIT_CONTENT_VALUE);
9512  }
9513  break;
9514  }
9515 
9516  case USER_DEFINED_DTAG_0x86:
9517  {
9518  if (((priv_data_code == UK_DTT_PRIVATE_DATA_SPECIFIER) &&
9519  (priv_data_code == country_private_data_specifier_code)) ||
9520  ((priv_data_code == ZAF_DTT_PRIVATE_DATA_SPECIFIER) &&
9521  (priv_data_code == country_private_data_specifier_code)))
9522  {
9523  data_ptr = ParseServiceAttributeDescriptor(data_ptr,
9524  &trans_entry->num_serv_attr_entries,
9525  &trans_entry->serv_attr_array, DEBUG_SI_NIT_CONTENT_VALUE);
9526  }
9527  else
9528  {
9529  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_NIT_CONTENT_VALUE);
9530  }
9531  break;
9532  }
9533 
9534  case USER_DEFINED_DTAG_0x87:
9535  {
9536  if(((priv_data_code == NORDIG_PRIVATE_DATA_SPECIFIER) &&
9537  (nordig_private_data_specifier == TRUE)) ||
9538  (priv_data_code == country_private_data_specifier_code) ||
9539  ((priv_data_code == NZ_SAT_PRIVATE_DATA_SPECIFIER) &&
9540  (nzsat_private_data_specifier == TRUE)))
9541  {
9542  /* Nordig LCN descriptor, version 2 */
9543  data_ptr = ParseNordigLCN2Descriptor(data_ptr,
9544  &trans_entry->num_nordig_lcn_entries,
9545  &trans_entry->nordig_lcn_desc_array, DEBUG_SI_NIT_CONTENT_VALUE);
9546  }
9547  else
9548  {
9549  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_NIT_CONTENT_VALUE);
9550  }
9551  break;
9552  }
9553 
9554  case USER_DEFINED_DTAG_0x88:
9555  {
9556  /* In the E-Book this is defined as the HD simulcast LCN descriptor,
9557  * but the definition is identical to the normal LCN descriptor. */
9558  if (((priv_data_code == UK_DTT_PRIVATE_DATA_SPECIFIER) &&
9559  (priv_data_code == country_private_data_specifier_code)) ||
9560  ((priv_data_code == EACEM_PRIVATE_DATA_SPECIFIER) &&
9561  (eacem_private_data_specifier == TRUE)))
9562  {
9563  data_ptr = ParseLogicalChannelDescriptor(data_ptr, dtag,
9564  &trans_entry->num_hd_lcn_entries,
9565  &trans_entry->hd_lcn_desc_array, DEBUG_SI_NIT_CONTENT_VALUE);
9566  }
9567  else
9568  {
9569  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_NIT_CONTENT_VALUE);
9570  }
9571  break;
9572  }
9573 
9574  case CIPLUS_SERVICE_DTAG:
9575  {
9576  if ((priv_data_code == CIPLUS_PRIVATE_DATA_SPECIFIER) &&
9577  (ciplus_private_data_specifier == TRUE))
9578  {
9579  data_ptr = ParseCIPlusServiceDescriptor(data_ptr,
9580  &trans_entry->num_ciplus_services,
9581  &trans_entry->ciplus_service_list,
9582  &trans_entry->last_ciplus_service, DEBUG_SI_NIT_CONTENT_VALUE);
9583  }
9584  else
9585  {
9586  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_NIT_CONTENT_VALUE);
9587  }
9588  break;
9589  }
9590 
9591  default:
9592  {
9593  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_NIT_CONTENT_VALUE);
9594  break;
9595  }
9596  }
9597  }
9598  }
9599  }
9600  // move on to next section
9601  section_rec = section_rec->next;
9602  }
9603  }
9604  }
9605  }
9606  FUNCTION_FINISH(STB_SIParseNitTable);
9607  return(nit_table);
9608 }
9609 
9624 {
9625  SI_SDT_TABLE *sdt_table;
9626  SI_SECTION_RECORD *section_rec;
9627  U8BIT *data_ptr;
9628  U8BIT *data_end;
9629  U16BIT dloop_len;
9630  U8BIT *dloop_end;
9631  U8BIT dtag;
9632  SI_SDT_SERVICE_ENTRY *serv_entry;
9633  U32BIT priv_data_code;
9634 
9635 
9636  FUNCTION_START(STB_SIParseSdtTable);
9637 
9638  ASSERT(table_rec != NULL);
9639 
9640  sdt_table = NULL;
9641  if (table_rec != NULL)
9642  {
9643  if ((table_rec->tid == SI_SDT_ACTUAL_TID) || (table_rec->tid == SI_SDT_OTHER_TID))
9644  {
9645  #ifdef DEBUG_SI_SDT_SUMMARY
9646  STB_SI_PRINT(("STB_SIParseSdtTable: tid 0x%02x/0x%04x, v%d, nsect %d",
9647  table_rec->tid, table_rec->xtid, table_rec->version, table_rec->num_sect));
9648  #endif
9649 
9650 
9651  sdt_table = STB_GetMemory(sizeof(SI_SDT_TABLE));
9652  if (sdt_table != NULL)
9653  {
9654  memset(sdt_table, 0, sizeof(SI_SDT_TABLE));
9655 
9656  sdt_table->version = table_rec->version;
9657  sdt_table->tran_id = table_rec->xtid;
9658 
9659  section_rec = table_rec->section_list;
9660  while (section_rec != NULL)
9661  {
9662  // get pointer to section data and end of section
9663  data_ptr = &(section_rec->data_start);
9664  data_end = data_ptr + section_rec->data_len - 4; // -4 for crc
9665 
9666  // skip section header
9667  data_ptr += 8;
9668 
9669  // read original network id. If there is more than omne section all sections should
9670  // contain the same value, so we will allow later sections to overwrite the value
9671  // i.e. the value in the last section will be used
9672  sdt_table->orig_net_id = (data_ptr[0] << 8) | data_ptr[1];
9673  data_ptr += 3; // move past onid field and unused reserved byte
9674 
9675  #ifdef DEBUG_SI_SDT_CONTENT
9676  STB_SI_PRINT((" section %d, onid=0x%04x",
9677  section_rec->sect_num, sdt_table->orig_net_id));
9678  #endif
9679 
9680  // read entry for each service
9681  while (data_ptr < data_end)
9682  {
9683  serv_entry = (SI_SDT_SERVICE_ENTRY *)STB_GetMemory(sizeof(SI_SDT_SERVICE_ENTRY));
9684  if (serv_entry != NULL)
9685  {
9686  // initialise new service structure
9687  memset(serv_entry, 0, sizeof(SI_SDT_SERVICE_ENTRY));
9688 
9689  // add to the end of the stream list in the sdt table
9690  if (sdt_table->last_service_entry == NULL)
9691  {
9692  // first entry in the list
9693  sdt_table->service_list = serv_entry;
9694  }
9695  else
9696  {
9697  // not the first entry
9698  sdt_table->last_service_entry->next = serv_entry;
9699  }
9700  sdt_table->last_service_entry = serv_entry;
9701  sdt_table->num_services++;
9702 
9703  // read service data and descriptor loop length
9704  serv_entry->serv_id = (data_ptr[0] << 8) | data_ptr[1];
9705  serv_entry->eit_sched_avail = (((data_ptr[2] >> 1) & 0x01) == 0x01);
9706  serv_entry->eit_now_next_avail = ((data_ptr[2] & 0x01) == 0x01);
9707  serv_entry->running_status = data_ptr[3] >> 5;
9708  serv_entry->all_streams_free = (((data_ptr[3] >> 4) & 0x01) == 0x00);
9709 
9710  dloop_len = ((data_ptr[3] & 0x0f) << 8) | data_ptr[4];
9711  data_ptr += 5;
9712 
9713  #ifdef DEBUG_SI_SDT_CONTENT
9714  STB_SI_PRINT((" sid=0x%04x, eis=%d, eit=%d, rs=%d, free=%d (desc loop len %d)",
9715  serv_entry->serv_id, serv_entry->eit_sched_avail,
9716  serv_entry->eit_now_next_avail, serv_entry->running_status,
9717  serv_entry->all_streams_free, dloop_len));
9718  #endif
9719 
9720  // process descriptor loop
9721  priv_data_code = 0;
9722  dloop_end = data_ptr + dloop_len;
9723  while (data_ptr < dloop_end)
9724  {
9725  dtag = data_ptr[0];
9726  data_ptr++;
9727  switch (dtag)
9728  {
9729  case CA_ID_DTAG:
9730  {
9731  data_ptr = ParseCaIdentifierDescriptor(data_ptr,
9732  &serv_entry->num_ca_id_entries,
9733  &serv_entry->ca_id_desc_array, DEBUG_SI_SDT_CONTENT_VALUE);
9734  break;
9735  }
9736 
9737  case LINKAGE_DTAG:
9738  {
9739  data_ptr = ParseLinkageDescriptor(data_ptr,
9740  &serv_entry->num_linkage_entries,
9741  &serv_entry->linkage_desc_list,
9742  &serv_entry->last_linkage_entry, priv_data_code,
9743  DEBUG_SI_SDT_CONTENT_VALUE);
9744  break;
9745  }
9746 
9747  case MULTILING_SERV_NAME_DTAG:
9748  {
9749  data_ptr = ParseMultilingServNameDescriptor(data_ptr,
9750  &serv_entry->num_multiling_names,
9751  &serv_entry->multiling_name_desc_array, DEBUG_SI_SDT_CONTENT_VALUE);
9752  break;
9753  }
9754 
9755  case SERVICE_DTAG:
9756  {
9757  data_ptr = ParseServiceDescriptor(data_ptr, &serv_entry->serv_type,
9758  &serv_entry->provider_str,
9759  &serv_entry->name_str, DEBUG_SI_SDT_CONTENT_VALUE);
9760  break;
9761  }
9762 
9763  case PRIV_DATA_SPEC_DTAG:
9764  {
9765  data_ptr = ParsePrivateDataSpecifierDescriptor(data_ptr,
9766  &priv_data_code, DEBUG_SI_SDT_CONTENT_VALUE);
9767  break;
9768  }
9769 
9770  case FTA_CONTENT_DTAG:
9771  {
9772  data_ptr = ParseFTAContentDescriptor(data_ptr, &serv_entry->fta_content_desc, DEBUG_SI_SDT_CONTENT_VALUE);
9773  break;
9774  }
9775 
9776  case FREESAT_CONTENT_MANAGE_DTAG:
9777  {
9778  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
9779  (freesat_private_data_specifier == TRUE))
9780  {
9781  data_ptr = ParseFTAContentDescriptor(data_ptr, &serv_entry->fta_content_desc, DEBUG_SI_SDT_CONTENT_VALUE);
9782  }
9783  else
9784  {
9785  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_SDT_CONTENT_VALUE);
9786  }
9787  break;
9788  }
9789 
9790  case USER_DEFINED_DTAG_0x84:
9791  {
9792  // for uk dtt this is preferred name list and private data
9793  // descriptor will have been sent. For Australia it is
9794  // also preferred name list but there won't be a private data
9795  // specifier so the application will have set the user defined
9796  // descriptor function
9797  if (((priv_data_code == UK_DTT_PRIVATE_DATA_SPECIFIER) &&
9798  (priv_data_code == country_private_data_specifier_code)) ||
9799  (GetUserDefinedDescriptorFunction(dtag) == USER_DEF_DESCRIP_PREF_NAME_LIST))
9800  {
9801  data_ptr = ParsePreferredNameListDescriptor(data_ptr,
9802  &serv_entry->num_preferred_names,
9803  &serv_entry->preferred_name_desc_array, DEBUG_SI_SDT_CONTENT_VALUE);
9804  }
9805  else
9806  {
9807  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_SDT_CONTENT_VALUE);
9808  }
9809  break;
9810  }
9811 
9812  case USER_DEFINED_DTAG_0x87:
9813  {
9814  // For UK DTT this is the short service name descriptor
9815  if (((priv_data_code == UK_DTT_PRIVATE_DATA_SPECIFIER) &&
9816  (priv_data_code == country_private_data_specifier_code)))
9817  {
9818  data_ptr = ParseShortServiceNameDescriptor(data_ptr,
9819  &serv_entry->short_name_str, DEBUG_SI_SDT_CONTENT_VALUE);
9820  }
9821  else
9822  {
9823  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_SDT_CONTENT_VALUE);
9824  }
9825  break;
9826  }
9827 
9828  case DEF_AUTH_DTAG:
9829  {
9830  data_ptr = ParseDefaultAuthorityDescriptor(data_ptr,
9831  &serv_entry->def_authority, DEBUG_SI_SDT_CONTENT_VALUE);
9832  break;
9833  }
9834 
9835  case USER_DEFINED_DTAG_0x89:
9836  case FREESAT_GUIDANCE_DTAG:
9837  {
9838  if (((priv_data_code == UK_DTT_PRIVATE_DATA_SPECIFIER) &&
9839  (priv_data_code == country_private_data_specifier_code) &&
9840  (freesat_private_data_specifier == FALSE)) ||
9841  ((priv_data_code == ZAF_DTT_PRIVATE_DATA_SPECIFIER) &&
9842  (priv_data_code == country_private_data_specifier_code) &&
9843  (freesat_private_data_specifier == FALSE)) ||
9844  ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
9845  (freesat_private_data_specifier == TRUE)))
9846  {
9847  /* For the UK this is the guidance descriptor and it is
9848  * only valid after a private data specifier descriptor */
9849  data_ptr = ParseGuidanceDescriptor(data_ptr, &serv_entry->guidance, DEBUG_SI_SDT_CONTENT_VALUE);
9850  }
9851  else
9852  {
9853  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_SDT_CONTENT_VALUE);
9854  }
9855  break;
9856  }
9857 
9858  case FREESAT_SERV_NAME_DTAG:
9859  {
9860  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
9861  (freesat_private_data_specifier == TRUE))
9862  {
9863  /* Freesat short service name descriptor */
9864  data_ptr = ParseFreesatShortServiceNameDescriptor(data_ptr,
9865  &serv_entry->num_multiling_short_names,
9866  &serv_entry->multiling_short_name_array, DEBUG_SI_SDT_CONTENT_VALUE);
9867  }
9868  else
9869  {
9870  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_SDT_CONTENT_VALUE);
9871  }
9872  break;
9873  }
9874 
9875  case EXT_DTAG:
9876  {
9877  switch (data_ptr[1])
9878  {
9879  case TARGET_REGION_DTAG:
9880  data_ptr = ParseTargetRegionDescriptor(data_ptr,
9881  &serv_entry->target_region_list, DEBUG_SI_SDT_CONTENT_VALUE);
9882  break;
9883 
9884  case URI_LINKAGE_DTAG:
9885  data_ptr = ParseURILinkageDesc(data_ptr,
9886  &serv_entry->uri_linkage_list, priv_data_code,
9887  DEBUG_SI_SDT_CONTENT_VALUE);
9888  break;
9889 
9890  default:
9891  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_SDT_CONTENT_VALUE);
9892  break;
9893  }
9894  break;
9895  }
9896 
9897  case CIPLUS_PROTECTION_DTAG:
9898  {
9899  /* This descriptor is only valid on SDT actual */
9900  if ((table_rec->tid == SI_SDT_ACTUAL_TID) &&
9901  ((priv_data_code == CIPLUS_PRIVATE_DATA_SPECIFIER) &&
9902  (ciplus_private_data_specifier == TRUE)))
9903  {
9904  data_ptr = SaveCIProtectionDescriptor(data_ptr,
9905  &serv_entry->ci_protection_desc, DEBUG_SI_SDT_CONTENT_VALUE);
9906  }
9907  else
9908  {
9909  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_SDT_CONTENT_VALUE);
9910  }
9911  break;
9912  }
9913 
9914  case SERV_AVAIL_DESC_DTAG:
9915  {
9916  data_ptr = ParseServiceAvailabilityDescriptor(data_ptr,
9917  &serv_entry->serv_avail_desc_list, DEBUG_SI_SDT_CONTENT_VALUE);
9918  break;
9919  }
9920 
9921  case FREESAT_PREFIX_DTAG:
9922  {
9923  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
9924  (freesat_private_data_specifier == TRUE))
9925  {
9926  data_ptr = ParseFreesatPrefixDescriptor(data_ptr,
9927  &serv_entry->freesat_prefix_list, DEBUG_SI_SDT_CONTENT_VALUE);
9928  }
9929  else
9930  {
9931  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_SDT_CONTENT_VALUE);
9932  }
9933  break;
9934  }
9935 
9936  default:
9937  {
9938  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_SDT_CONTENT_VALUE);
9939  break;
9940  }
9941  }
9942  }
9943  }
9944  }
9945  // move on to next section
9946  section_rec = section_rec->next;
9947  }
9948  }
9949  }
9950  }
9951 
9952  FUNCTION_FINISH(STB_SIParseSdtTable);
9953  return(sdt_table);
9954 }
9955 
9970 {
9971  SI_BAT_TABLE *bat_table;
9972  SI_SECTION_RECORD *section_rec;
9973  U8BIT *data_ptr;
9974  U8BIT *tran_dloop_end;
9975  U16BIT tran_dloop_len;
9976  U16BIT dloop_len;
9977  U8BIT *dloop_end;
9978  U8BIT dtag;
9979  U32BIT priv_data_code;
9980  SI_BAT_TRANSPORT_ENTRY *trans_entry;
9981 
9982  FUNCTION_START(STB_SIParseBatTable);
9983 
9984  ASSERT(table_rec != NULL);
9985 
9986  bat_table = NULL;
9987  if (table_rec != NULL)
9988  {
9989  if (table_rec->tid == SI_BAT_TID)
9990  {
9991  #ifdef DEBUG_SI_BAT_SUMMARY
9992  STB_SI_PRINT(("STB_SIParseBatTable: tid 0x%02x/0x%04x, v%d, nsect %d",
9993  table_rec->tid, table_rec->xtid, table_rec->version, table_rec->num_sect));
9994  #endif
9995 
9996  bat_table = STB_GetMemory(sizeof(SI_BAT_TABLE));
9997  if (bat_table != NULL)
9998  {
9999  memset(bat_table, 0, sizeof(SI_BAT_TABLE));
10000 
10001  bat_table->version = table_rec->version;
10002  bat_table->bouquet_id = table_rec->xtid;
10003 
10004  section_rec = table_rec->section_list;
10005  while (section_rec != NULL)
10006  {
10007  // get pointer to section data and end of section
10008  data_ptr = &(section_rec->data_start);
10009 
10010  // skip section header
10011  data_ptr += 8;
10012  priv_data_code = 0;
10013  // read bouquet descriptor length
10014  dloop_len = (((data_ptr[0] & 0x0F) << 8) | (data_ptr[1]));
10015  data_ptr += 2; // move past bouquet length
10016 
10017  // process descriptor loop
10018  dloop_end = data_ptr + dloop_len;
10019  while (data_ptr < dloop_end)
10020  {
10021  dtag = data_ptr[0];
10022  data_ptr++;
10023 
10024  #ifdef DEBUG_SI_BAT_CONTENT
10025  STB_SI_PRINT((" dtag=0x%02x", (int)dtag));
10026  #endif
10027 
10028  switch (dtag)
10029  {
10030  case PRIV_DATA_SPEC_DTAG:
10031  {
10032  data_ptr = ParsePrivateDataSpecifierDescriptor(data_ptr,
10033  &priv_data_code, DEBUG_SI_BAT_CONTENT_VALUE);
10034  break;
10035  }
10036 
10037  case LINKAGE_DTAG:
10038  {
10039  data_ptr = ParseLinkageDescriptor(data_ptr,
10040  &bat_table->num_linkage_entries,
10041  &bat_table->linkage_desc_list,
10042  &bat_table->last_linkage_entry, priv_data_code,
10043  DEBUG_SI_BAT_CONTENT_VALUE);
10044  break;
10045  }
10046 
10047  case DEF_AUTH_DTAG:
10048  {
10049  data_ptr = ParseDefaultAuthorityDescriptor(data_ptr, &bat_table->def_authority, DEBUG_SI_BAT_CONTENT_VALUE);
10050  break;
10051  }
10052 
10053  case FREESAT_SERV_GROUP_NAME_DTAG:
10054  {
10055  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
10056  (freesat_private_data_specifier == TRUE))
10057  {
10058  data_ptr = ParseFreesatServiceGroupNameDescriptor(data_ptr,
10059  &bat_table->group_name_list, DEBUG_SI_BAT_CONTENT_VALUE);
10060  }
10061  else
10062  {
10063  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10064  }
10065  break;
10066  }
10067 
10068  case FREESAT_SERV_GROUP_DTAG:
10069  {
10070  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
10071  (freesat_private_data_specifier == TRUE))
10072  {
10073  data_ptr = ParseFreesatServiceGroupDescriptor(data_ptr, &bat_table->serv_group_array,
10074  &bat_table->num_serv_groups, DEBUG_SI_BAT_CONTENT_VALUE);
10075  }
10076  else
10077  {
10078  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10079  }
10080  break;
10081  }
10082 
10083  case FREESAT_IACTIVE_STORAGE_DTAG:
10084  {
10085  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
10086  (freesat_private_data_specifier == TRUE))
10087  {
10088  data_ptr = ParseIActiveStorageDescriptor(data_ptr,
10089  &bat_table->iactive_storage_desc_list, DEBUG_SI_BAT_CONTENT_VALUE);
10090  }
10091  else
10092  {
10093  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10094  }
10095  break;
10096  }
10097 
10098  case FREESAT_INFO_LOCATION_DTAG:
10099  {
10100  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
10101  (freesat_private_data_specifier == TRUE))
10102  {
10103  data_ptr = ParseFreesatInfoLocationDescriptor(data_ptr,
10104  &bat_table->info_location_list, DEBUG_SI_BAT_CONTENT_VALUE);
10105  }
10106  else
10107  {
10108  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10109  }
10110  break;
10111  }
10112 
10113  case FREESAT_REGION_NAME_DTAG:
10114  {
10115  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
10116  (freesat_private_data_specifier == TRUE))
10117  {
10118  data_ptr = ParseRegionNameDescriptor(data_ptr, &bat_table->region_list, DEBUG_SI_BAT_CONTENT_VALUE);
10119  }
10120  else
10121  {
10122  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10123  }
10124  break;
10125  }
10126 
10127  case BOUQUET_NAME_DTAG:
10128  {
10129  data_ptr = ParseNetNameDescriptor(data_ptr, &bat_table->bouquet_name, DEBUG_SI_BAT_CONTENT_VALUE);
10130  break;
10131  }
10132 
10133  case FREESAT_CONTENT_MANAGE_DTAG:
10134  {
10135  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
10136  (freesat_private_data_specifier == TRUE))
10137  {
10138  data_ptr = ParseFTAContentDescriptor(data_ptr, &bat_table->fta_content_desc, DEBUG_SI_BAT_CONTENT_VALUE);
10139  }
10140  else
10141  {
10142  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10143  }
10144  break;
10145  }
10146 
10147  case FREESAT_PREFIX_DTAG:
10148  {
10149  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
10150  (freesat_private_data_specifier == TRUE))
10151  {
10152  data_ptr = ParseFreesatPrefixDescriptor(data_ptr,
10153  &bat_table->freesat_prefix_list, DEBUG_SI_BAT_CONTENT_VALUE);
10154  }
10155  else
10156  {
10157  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10158  }
10159  break;
10160  }
10161 
10162  case EXT_DTAG:
10163  {
10164  /* Examine the extension tag for the table being signalled */
10165  switch (data_ptr[1])
10166  {
10167  case URI_LINKAGE_DTAG:
10168  data_ptr = ParseURILinkageDesc(data_ptr,
10169  &bat_table->uri_linkage_list, priv_data_code, DEBUG_SI_BAT_CONTENT_VALUE);
10170  break;
10171 
10172  default:
10173  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10174  break;
10175  }
10176  break;
10177  }
10178 
10179  default:
10180  {
10181  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10182  break;
10183  }
10184  }
10185  }
10186 
10187  dloop_len = (((data_ptr[0] & 0x0F) << 8) | (data_ptr[1]));
10188  data_ptr += 2; // move past bouquet length
10189 
10190  // process descriptor loop
10191  dloop_end = data_ptr + dloop_len;
10192  while (data_ptr < dloop_end)
10193  {
10195  if (trans_entry != NULL)
10196  {
10197  // initialise new transport structure
10198  memset(trans_entry, 0, sizeof(SI_BAT_TRANSPORT_ENTRY));
10199 
10200  // add to the end of the stream list in the nit table
10201  if (bat_table->last_transport_entry == NULL)
10202  {
10203  // first entry in the list
10204  bat_table->transport_list = trans_entry;
10205  }
10206  else
10207  {
10208  // not the first entry
10209  bat_table->last_transport_entry->next = trans_entry;
10210  }
10211 
10212  bat_table->last_transport_entry = trans_entry;
10213  bat_table->num_transports++;
10214 
10215  trans_entry->tran_id = ((data_ptr[0]) << 8 | (data_ptr[1]));
10216  data_ptr += 2;
10217  trans_entry->orig_net_id = ((data_ptr[0] << 8) | (data_ptr[1]));
10218  data_ptr += 2;
10219  tran_dloop_len = (((data_ptr[0] & 0x0F) << 8) | (data_ptr[1]));
10220  data_ptr += 2;
10221 
10222  #ifdef DEBUG_SI_BAT_CONTENT
10223  STB_SI_PRINT((" tid 0x%04x, onet 0x%04x", trans_entry->tran_id, trans_entry->orig_net_id));
10224  #endif
10225 
10226  // process transport descriptor loop
10227  priv_data_code = 0;
10228  tran_dloop_end = data_ptr + tran_dloop_len;
10229  while (data_ptr < tran_dloop_end)
10230  {
10231  dtag = data_ptr[0];
10232  data_ptr++;
10233 
10234  #ifdef DEBUG_SI_BAT_CONTENT
10235  STB_SI_PRINT((" dtag=0x%02x", (int)dtag));
10236  #endif
10237 
10238  switch (dtag)
10239  {
10240  case PRIV_DATA_SPEC_DTAG:
10241  {
10242  data_ptr = ParsePrivateDataSpecifierDescriptor(data_ptr,
10243  &priv_data_code, DEBUG_SI_BAT_CONTENT_VALUE);
10244  break;
10245  }
10246 
10247  case SERV_LIST_DTAG:
10248  {
10249  data_ptr = ParseServiceListDescriptor(data_ptr,
10250  &trans_entry->num_serv_list_entries,
10251  &trans_entry->serv_list_desc_array, DEBUG_SI_BAT_CONTENT_VALUE);
10252  break;
10253  }
10254 
10255  case LOGICAL_CHANNEL_DTAG:
10256  {
10257  /* NZ Freeview, free-to-air */
10258  if ((priv_data_code == NZ_SAT_PRIVATE_DATA_SPECIFIER) &&
10259  (nzsat_private_data_specifier == TRUE))
10260  {
10261  data_ptr = ParseLogicalChannelDescriptor(data_ptr, dtag,
10262  &trans_entry->num_lcn_entries,
10263  &trans_entry->lcn_desc_array, DEBUG_SI_BAT_CONTENT_VALUE);
10264  }
10265  else
10266  {
10267  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10268  }
10269  break;
10270  }
10271 
10272  case DEF_AUTH_DTAG:
10273  {
10274  data_ptr = ParseDefaultAuthorityDescriptor(data_ptr, &trans_entry->def_authority, DEBUG_SI_BAT_CONTENT_VALUE);
10275  break;
10276  }
10277 
10278  case FREESAT_REGION_LCN_DTAG:
10279  {
10280  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
10281  (freesat_private_data_specifier == TRUE))
10282  {
10283  data_ptr = ParseRegionLcnDescriptor(data_ptr, &trans_entry->lcn_region_list, DEBUG_SI_BAT_CONTENT_VALUE);
10284  }
10285  else
10286  {
10287  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10288  }
10289  break;
10290  }
10291 
10292  case FREESAT_CONTENT_MANAGE_DTAG:
10293  {
10294  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
10295  (freesat_private_data_specifier == TRUE))
10296  {
10297  data_ptr = ParseFTAContentDescriptor(data_ptr, &trans_entry->fta_content_desc, DEBUG_SI_BAT_CONTENT_VALUE);
10298  }
10299  else
10300  {
10301  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10302  }
10303  break;
10304  }
10305 
10306  case FREESAT_IACTIVE_RESTRICT_DTAG:
10307  {
10308  if ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
10309  (freesat_private_data_specifier == TRUE))
10310  {
10311  data_ptr = ParseFreesatInteractiveRestrictionDescriptor(data_ptr,
10312  &trans_entry->int_rest_serv_array,
10313  &trans_entry->num_int_rest_serv, DEBUG_SI_BAT_CONTENT_VALUE);
10314  }
10315  else
10316  {
10317  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10318  }
10319  break;
10320  }
10321 
10322  default:
10323  {
10324  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_BAT_CONTENT_VALUE);
10325  break;
10326  }
10327  }
10328  }
10329  }
10330  }
10331  // move on to next section
10332  section_rec = section_rec->next;
10333  }
10334  }
10335  }
10336  }
10337 
10338  FUNCTION_FINISH(STB_SIParseBatTable);
10339  return(bat_table);
10340 }
10341 
10356 {
10357  U8BIT tid;
10358  SI_EIT_TABLE *eit_table;
10359  SI_SECTION_RECORD *section_rec;
10360  U8BIT *data_ptr;
10361  U8BIT *data_end;
10362  U16BIT dloop_len;
10363  U8BIT *dloop_end;
10364  U8BIT dtag;
10365  SI_EIT_EVENT_ENTRY *event_entry;
10366  U32BIT priv_data_code;
10367  BOOLEAN abort;
10368 
10369  FUNCTION_START(STB_SIParseEitTable);
10370 
10371  ASSERT(table_rec != NULL);
10372 
10373  abort = FALSE;
10374  eit_table = NULL;
10375 
10376  if (table_rec != NULL)
10377  {
10378  tid = table_rec->tid;
10379  if ((tid == SI_EITPF_ACTUAL_TID) || (tid == SI_EITPF_OTHER_TID) ||
10380  ((tid & 0xf0) == SI_EITSC_ACTUAL_TID) || ((tid & 0xf0) == SI_EITSC_OTHER_TID))
10381  {
10382  #ifdef DEBUG_SI_EIT_SUMMARY
10383  STB_SI_PRINT(("STB_SIParseEitTable: tid 0x%02x/0x%04x, v%d, nsect %d",
10384  table_rec->tid, table_rec->xtid, table_rec->version, table_rec->num_sect));
10385  #endif
10386 
10387  eit_table = STB_GetMemory(sizeof(SI_EIT_TABLE));
10388  if (eit_table != NULL)
10389  {
10390  memset(eit_table, 0, sizeof(SI_EIT_TABLE));
10391 
10392  eit_table->version = table_rec->version;
10393  eit_table->table_id = table_rec->tid;
10394  eit_table->serv_id = table_rec->xtid;
10395 
10396  // loop through all sections in the list - they will be in section order
10397  section_rec = table_rec->section_list;
10398  while ((section_rec != NULL) && !abort)
10399  {
10400  // get pointer to section data and end of section
10401  data_ptr = &(section_rec->data_start);
10402  data_end = data_ptr + section_rec->data_len - 4; // -4 for crc
10403 
10404  // skip section header
10405  data_ptr += 8;
10406 
10407  // read transport id, original network id and last table id. If there is more than
10408  // one section all sections should contain the same value, so we will allow later
10409  // sections to overwrite the values i.e. the values in the last section will be used
10410  eit_table->tran_id = (data_ptr[0] << 8) | data_ptr[1];
10411  eit_table->orig_net_id = (data_ptr[2] << 8) | data_ptr[3];
10412  eit_table->last_table_id = data_ptr[5];
10413  data_ptr += 6;
10414 
10415  #ifdef DEBUG_SI_EIT_CONTENT
10416  STB_SI_PRINT((" section %d, tranid=0x%04x, onid=0x%04x, last tid=0x%02x",
10417  section_rec->sect_num, eit_table->tran_id, eit_table->orig_net_id,
10418  eit_table->last_table_id));
10419  #endif
10420 
10421  // read entry for each event
10422  while ((data_ptr < data_end) && !abort)
10423  {
10424  event_entry = (SI_EIT_EVENT_ENTRY *)STB_GetMemory(sizeof(SI_EIT_EVENT_ENTRY));
10425  if (event_entry != NULL)
10426  {
10427  // initialise new event structure
10428  memset(event_entry, 0, sizeof(SI_EIT_EVENT_ENTRY));
10429 
10430  // add to the end of the event list in the eit table
10431  if (eit_table->last_event_entry == NULL)
10432  {
10433  // first entry in the list
10434  eit_table->event_list = event_entry;
10435  }
10436  else
10437  {
10438  // not the first entry
10439  eit_table->last_event_entry->next = event_entry;
10440  }
10441  eit_table->last_event_entry = event_entry;
10442  eit_table->num_events++;
10443 
10444  // read event data and descriptor loop length
10445  event_entry->sect_num = section_rec->sect_num;
10446  event_entry->event_id = (data_ptr[0] << 8) | data_ptr[1];
10447  event_entry->start_date = (data_ptr[2] << 8) | data_ptr[3];
10448  event_entry->start_hrs = ((data_ptr[4] >> 4) * 10) + (data_ptr[4] & 0x0f);
10449  event_entry->start_mins = ((data_ptr[5] >> 4) * 10) + (data_ptr[5] & 0x0f);
10450  event_entry->start_secs = ((data_ptr[6] >> 4) * 10) + (data_ptr[6] & 0x0f);
10451  event_entry->duration_hrs = ((data_ptr[7] >> 4) * 10) + (data_ptr[7] & 0x0f);
10452  event_entry->duration_mins = ((data_ptr[8] >> 4) * 10) + (data_ptr[8] & 0x0f);
10453  event_entry->duration_secs = ((data_ptr[9] >> 4) * 10) + (data_ptr[9] & 0x0f);
10454  event_entry->running_status = data_ptr[10] >> 5;
10455  event_entry->all_streams_free = (((data_ptr[10] >> 4) & 0x01) == 0x00);
10456  dloop_len = ((data_ptr[10] & 0x0f) << 8) | data_ptr[11];
10457  data_ptr += 12;
10458 
10459  #ifdef DEBUG_SI_EIT_CONTENT
10460  STB_SI_PRINT((" eid=0x%04x on %d @ %02d:%02d:%02d for %02d:%02d:%02d, rs=%d, free=%d (desc loop len %d)",
10461  event_entry->event_id, event_entry->start_date,
10462  event_entry->start_hrs, event_entry->start_mins,
10463  event_entry->start_secs, event_entry->duration_hrs,
10464  event_entry->duration_mins, event_entry->duration_secs,
10465  event_entry->running_status, event_entry->all_streams_free,
10466  dloop_len));
10467  #endif
10468 
10469  // process descriptor loop
10470  priv_data_code = 0;
10471  dloop_end = data_ptr + dloop_len;
10472  while (data_ptr < dloop_end)
10473  {
10474  dtag = data_ptr[0];
10475  data_ptr++;
10476  switch (dtag)
10477  {
10478  case CA_ID_DTAG:
10479  {
10480  data_ptr = ParseCaIdentifierDescriptor(data_ptr,
10481  &event_entry->num_ca_id_entries,
10482  &event_entry->ca_id_desc_array, DEBUG_SI_EIT_CONTENT_VALUE);
10483  break;
10484  }
10485 
10486  case COMPONENT_DTAG:
10487  {
10488  data_ptr = ParseComponentDescriptor(data_ptr,
10489  &event_entry->num_component_entries,
10490  &event_entry->component_desc_array, DEBUG_SI_EIT_CONTENT_VALUE);
10491  break;
10492  }
10493 
10494  case CONTENT_DTAG:
10495  {
10496  data_ptr = ParseContentDescriptor(data_ptr,
10497  &event_entry->num_content_entries,
10498  &event_entry->content_desc_array, DEBUG_SI_EIT_CONTENT_VALUE);
10499  break;
10500  }
10501 
10502  case PARENTAL_RATING_DTAG:
10503  {
10504  data_ptr = ParseParentalRatingDescriptor(data_ptr,
10505  &event_entry->num_parental_rating_entries,
10506  &event_entry->parental_rating_desc_array, DEBUG_SI_EIT_CONTENT_VALUE);
10507  break;
10508  }
10509 
10510  case MULTILING_COMPONENT_DTAG:
10511  {
10512  data_ptr = ParseMultilingComponentDescriptor(data_ptr,
10513  &event_entry->num_multiling_component_entries,
10514  &event_entry->multiling_component_desc_array, DEBUG_SI_EIT_CONTENT_VALUE);
10515  break;
10516  }
10517 
10518  case SHORT_EVENT_DTAG:
10519  {
10520  data_ptr = ParseShortEventDescriptor(data_ptr,
10521  &event_entry->num_short_event_entries,
10522  &event_entry->short_event_desc_array, DEBUG_SI_EIT_CONTENT_VALUE);
10523  break;
10524  }
10525 
10526  case EXTENDED_EVENT_DTAG:
10527  {
10528  data_ptr = ParseExtendedEventDescriptor(data_ptr,
10529  &event_entry->num_extended_event_entries,
10530  &event_entry->extended_event_desc_array, DEBUG_SI_EIT_CONTENT_VALUE);
10531  break;
10532  }
10533 
10534  case PRIV_DATA_SPEC_DTAG:
10535  {
10536  data_ptr = ParsePrivateDataSpecifierDescriptor(data_ptr,
10537  &priv_data_code, DEBUG_SI_EIT_CONTENT_VALUE);
10538  break;
10539  }
10540 
10541  case USER_DEFINED_DTAG_0x85:
10542  {
10543  // for uk dtt this is preferred name id and private data
10544  // descriptor will have been sent. For Australia it is
10545  // also preferred name id but there won't be a private data
10546  // specifier so the application will have set the user defined
10547  // descriptor function
10548  if (((priv_data_code == UK_DTT_PRIVATE_DATA_SPECIFIER) &&
10549  (priv_data_code == country_private_data_specifier_code)) ||
10550  (GetUserDefinedDescriptorFunction(dtag) == USER_DEF_DESCRIP_PREF_NAME_ID))
10551  {
10552  data_ptr = ParsePreferredNameIdDescriptor(data_ptr,
10553  &event_entry->preferred_name_id, DEBUG_SI_EIT_CONTENT_VALUE);
10554  }
10555  else
10556  {
10557  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_EIT_CONTENT_VALUE);
10558  }
10559  break;
10560  }
10561 
10562  case CONT_ID_DTAG:
10563  {
10564  data_ptr = ParseContentIdentifierDescriptor(data_ptr, &event_entry->num_crids,
10565  &event_entry->crid_list, &event_entry->last_crid_entry, DEBUG_SI_EIT_CONTENT_VALUE);
10566  break;
10567  }
10568 
10569  case USER_DEFINED_DTAG_0x89:
10570  case FREESAT_GUIDANCE_DTAG:
10571  {
10572  if (((priv_data_code == UK_DTT_PRIVATE_DATA_SPECIFIER) &&
10573  (priv_data_code == country_private_data_specifier_code) &&
10574  (freesat_private_data_specifier == FALSE)) ||
10575  ((priv_data_code == ZAF_DTT_PRIVATE_DATA_SPECIFIER) &&
10576  (priv_data_code == country_private_data_specifier_code) &&
10577  (freesat_private_data_specifier == FALSE)) ||
10578  ((priv_data_code == FREESAT_PRIVATE_DATA_SPECIFIER) &&
10579  (freesat_private_data_specifier == TRUE)))
10580  {
10581  /* For the UK this is the guidance descriptor and it is
10582  * only valid after a private data specifier descriptor */
10583  data_ptr = ParseGuidanceDescriptor(data_ptr, &event_entry->guidance, DEBUG_SI_EIT_CONTENT_VALUE);
10584  }
10585  else
10586  {
10587  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_EIT_CONTENT_VALUE);
10588  }
10589  break;
10590  }
10591 
10592  default:
10593  {
10594  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_EIT_CONTENT_VALUE);
10595  break;
10596  }
10597  }
10598  }
10599  }
10600  else
10601  {
10602  /* Failed to allocate memory, so abort and return whatever data has been collected */
10603  abort = TRUE;
10604  }
10605  }
10606 
10607  // move on to next section
10608  section_rec = section_rec->next;
10609  }
10610  }
10611  }
10612  }
10613 
10614  FUNCTION_FINISH(STB_SIParseEitTable);
10615  return(eit_table);
10616 }
10617 
10632 {
10633  SI_TIME_TABLE *time_table;
10634  SI_SECTION_RECORD *section_rec;
10635  U8BIT *data_ptr;
10636  U16BIT dloop_len;
10637  U8BIT *dloop_end;
10638  U8BIT dtag;
10639 
10640  FUNCTION_START(STB_SIParseTimeTable);
10641 
10642  ASSERT(table_rec != NULL);
10643 
10644  time_table = NULL;
10645  if (table_rec != NULL)
10646  {
10647  if ((table_rec->tid == SI_TDT_TID) || (table_rec->tid == SI_TOT_TID))
10648  {
10649  #ifdef DEBUG_SI_TDT_TOT_SUMMARY
10650  STB_SI_PRINT(("STB_SIParseTimeTable: tid 0x%02x", table_rec->tid));
10651  #endif
10652 
10653  time_table = STB_GetMemory(sizeof(SI_TIME_TABLE));
10654  if (time_table != NULL)
10655  {
10656  memset(time_table, 0, sizeof(SI_TIME_TABLE));
10657 
10658  // get pointer to section data
10659  section_rec = table_rec->section_list;
10660  data_ptr = &(section_rec->data_start);
10661  data_ptr += 3; // skip section header
10662 
10663  // read time
10664  time_table->date = (data_ptr[0] << 8) | data_ptr[1];
10665  time_table->hrs = ((data_ptr[2] >> 4) * 10) + (data_ptr[2] & 0x0f);
10666  time_table->mins = ((data_ptr[3] >> 4) * 10) + (data_ptr[3] & 0x0f);
10667  time_table->secs = ((data_ptr[4] >> 4) * 10) + (data_ptr[4] & 0x0f);
10668  data_ptr += 5;
10669 
10670  #ifdef DEBUG_SI_TDT_TOT_CONTENT
10671  STB_SI_PRINT((" %d %02d:%02d:%02d", time_table->date, time_table->hrs,
10672  time_table->mins, time_table->secs));
10673  #endif
10674 
10675  if (table_rec->tid == SI_TOT_TID)
10676  {
10677  // process descriptor loop
10678  dloop_len = ((data_ptr[0] & 0x0f) << 8) | data_ptr[1];
10679  data_ptr += 2;
10680  dloop_end = data_ptr + dloop_len;
10681  #ifdef DEBUG_SI_TDT_TOT_CONTENT
10682  STB_SI_PRINT((" Tot desc loop (len %d)", dloop_len));
10683  #endif
10684  while (data_ptr < dloop_end)
10685  {
10686  dtag = data_ptr[0];
10687  data_ptr++;
10688 
10689  switch (dtag)
10690  {
10691  case LOCAL_TIME_OFFSET_DTAG:
10692  {
10693  data_ptr = ParseLocalTimeOffsetDescriptor(data_ptr,
10694  &time_table->num_lto_entries,
10695  &time_table->lto_desc_array, DEBUG_SI_TDT_TOT_CONTENT_VALUE);
10696  break;
10697  }
10698 
10699  default:
10700  {
10701  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_TDT_TOT_CONTENT_VALUE);
10702  break;
10703  }
10704  }
10705  }
10706  }
10707  }
10708  }
10709  }
10710 
10711  FUNCTION_FINISH(STB_SIParseTimeTable);
10712  return(time_table);
10713 }
10714 
10715 /*!**************************************************************************
10716  * @brief Parses the related content table (RCT) to create an SI_RCT_TABLE structure.
10717  * @param table_rec - pointer to the table record to be parsed
10718  * @return Pointer to the parsed RCT table which must be freed using STB_SIReleaseRctTable
10719  ****************************************************************************/
10721 {
10722  SI_RCT_TABLE *rct_table;
10723  SI_SECTION_RECORD *section_rec;
10724  U8BIT *data_ptr;
10725  U16BIT dloop_len;
10726  U8BIT *dloop_end;
10727  U8BIT dtag;
10728  U16BIT service_id;
10729  SI_RCT_SUBTABLE *subtable;
10730  SI_RCT_SUBTABLE *sub_ptr;
10731  SI_RCT_SUBTABLE_DATA *sub_data;
10732  SI_RCT_SUBTABLE_DATA *next_data;
10733  U8BIT i;
10734 
10735  FUNCTION_START(STB_SIParseRctTable);
10736 
10737  ASSERT(table_rec != NULL);
10738 
10739  rct_table = NULL;
10740 
10741  if (table_rec != NULL)
10742  {
10743  if (table_rec->tid == SI_RCT_TID)
10744  {
10745  #ifdef DEBUG_SI_RCT_SUMMARY
10746  STB_SI_PRINT(("STB_SIParseRctTable: tid 0x%02x/0x%04x, v%d, nsect %d",
10747  table_rec->tid, table_rec->xtid, table_rec->version, table_rec->num_sect));
10748  #endif
10749 
10750  rct_table = STB_GetMemory(sizeof(SI_RCT_TABLE));
10751  if (rct_table != NULL)
10752  {
10753  memset(rct_table, 0, sizeof(SI_RCT_TABLE));
10754 
10755  section_rec = table_rec->section_list;
10756  while (section_rec != NULL)
10757  {
10758  /* Get pointer to section data and end of section */
10759  data_ptr = &(section_rec->data_start);
10760 
10761  /* Check the table_id_extension flag that indicates whether the xtid defines the service ID */
10762  if ((data_ptr[1] & 0x40) == 0)
10763  {
10764  service_id = table_rec->xtid;
10765  }
10766  else
10767  {
10768  service_id = 0;
10769  }
10770 
10771  #ifdef DEBUG_SI_RCT_CONTENT
10772  STB_SI_PRINT((" service_id=0x%04x", service_id));
10773  #endif
10774 
10775  /* Skip section header */
10776  data_ptr += 8;
10777 
10778  /* Does a subtable for this service already exist? */
10779  for (subtable = rct_table->subtables; subtable != NULL; subtable = subtable->next)
10780  {
10781  if ((subtable->version == table_rec->version) && (subtable->service_id == service_id))
10782  {
10783  /* Subtable found */
10784  break;
10785  }
10786  }
10787 
10788  if (subtable == NULL)
10789  {
10790  /* Need a new subtable */
10791  subtable = (SI_RCT_SUBTABLE *)STB_GetMemory(sizeof(SI_RCT_SUBTABLE));
10792  if (subtable != NULL)
10793  {
10794  memset(subtable, 0, sizeof(SI_RCT_SUBTABLE));
10795 
10796  subtable->version = table_rec->version;
10797  subtable->service_id = service_id;
10798 
10799  /* Add the subtable to the RCT */
10800  if (rct_table->subtables == NULL)
10801  {
10802  rct_table->subtables = subtable;
10803  }
10804  else
10805  {
10806  /* Find the end of the list */
10807  for (sub_ptr = rct_table->subtables; sub_ptr->next != NULL; sub_ptr = sub_ptr->next)
10808  ;
10809 
10810  sub_ptr->next = subtable;
10811  }
10812  }
10813  }
10814 
10815  if (subtable != NULL)
10816  {
10817  /* Create a new subtable data structure to hold the info contained in this section */
10819  if (sub_data != NULL)
10820  {
10821  memset(sub_data, 0, sizeof(SI_RCT_SUBTABLE_DATA));
10822 
10823  /* Add the subtable's data to the end of the list */
10824  if (subtable->data == NULL)
10825  {
10826  subtable->data = sub_data;
10827  }
10828  else
10829  {
10830  for (next_data = subtable->data; next_data->next != NULL; next_data = next_data->next)
10831  ;
10832 
10833  next_data->next = sub_data;
10834  }
10835 
10836  /* Read the year offset to be used for all dates in this table */
10837  sub_data->year_offset = (data_ptr[0] << 8) | data_ptr[1];
10838 
10839  /* Process the links */
10840  sub_data->link_count = data_ptr[2];
10841  data_ptr += 3;
10842 
10843  #ifdef DEBUG_SI_RCT_CONTENT
10844  STB_SI_PRINT((" year_offset=%u", sub_data->year_offset));
10845  STB_SI_PRINT((" link_count=%u", sub_data->link_count));
10846  #endif
10847 
10848  if (sub_data->link_count > 0)
10849  {
10850  /* Allocate memory for the links and read each one */
10851  sub_data->link_array = (SI_RCT_LINK_INFO *)STB_GetMemory(sub_data->link_count * sizeof(SI_RCT_LINK_INFO));
10852  if (sub_data->link_array != NULL)
10853  {
10854  for (i = 0; i < sub_data->link_count; i++)
10855  {
10856  #ifdef DEBUG_SI_RCT_CONTENT
10857  STB_SI_PRINT((" link=%u:", i));
10858  #endif
10859 
10860  data_ptr = ParseRctLinkInfo(data_ptr, &sub_data->link_array[i], DEBUG_SI_RCT_CONTENT_VALUE);
10861  }
10862  }
10863  else
10864  {
10865  sub_data->link_count = 0;
10866  }
10867  }
10868 
10869  /* Process the descriptor loop */
10870  dloop_len = ((data_ptr[0] & 0x0f) << 8) | data_ptr[1];
10871  data_ptr += 2;
10872 
10873  dloop_end = data_ptr + dloop_len;
10874  while (data_ptr < dloop_end)
10875  {
10876  dtag = data_ptr[0];
10877  data_ptr++;
10878  switch (dtag)
10879  {
10880  case EXT_DTAG:
10881  {
10882  /* Examine the extension tag for the table being signalled */
10883  switch (data_ptr[1])
10884  {
10885  case IMAGE_ICON_DTAG:
10886  {
10887  data_ptr = ParseImageIconDesc(data_ptr, &sub_data->num_icons, &sub_data->icon_array, DEBUG_SI_RCT_CONTENT_VALUE);
10888  break;
10889  }
10890 
10891  default:
10892  {
10893  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_RCT_CONTENT_VALUE);
10894  break;
10895  }
10896  }
10897  break;
10898  }
10899 #if 0
10900  case SHORT_EVENT_DTAG:
10901  {
10902  data_ptr = ParseShortEventDescriptor(data_ptr,
10903  &event_entry->num_short_event_entries,
10904  &event_entry->short_event_desc_array, DEBUG_SI_RCT_CONTENT_VALUE);
10905  break;
10906  }
10907 #endif
10908 
10909  default:
10910  {
10911  data_ptr = SkipDescriptor(data_ptr, dtag, DEBUG_SI_RCT_CONTENT_VALUE);
10912  break;
10913  }
10914  }
10915  }
10916  }
10917  }
10918 
10919  /* Move on to next section */
10920  section_rec = section_rec->next;
10921  }
10922  }
10923  }
10924  }
10925 
10926  FUNCTION_FINISH(STB_SIParseRctTable);
10927 
10928  return(rct_table);
10929 }
10930 
10947 U8BIT* STB_SIReadString(U8BIT nbytes, U8BIT *dptr, SI_STRING_DESC **str_ptr)
10948 {
10949  U8BIT *end_ptr;
10950  SI_STRING_DESC *str_desc;
10951  U8BIT *tmp_ptr;
10952  BOOLEAN unicode;
10953  U8BIT byte_val;
10954  U8BIT byte_count;
10955 
10956  S16BIT num_bytes;
10957 
10958  FUNCTION_START(STB_SIReadString);
10959 
10960  end_ptr = dptr + nbytes;
10961 
10962  str_desc = (SI_STRING_DESC *)STB_GetMemory(sizeof(SI_STRING_DESC) + nbytes + 2); // worst case need +2 for unicode null term
10963  if (str_desc != NULL)
10964  {
10965  num_bytes = nbytes;
10966  byte_count = 0;
10967  tmp_ptr = ((U8BIT *)str_desc) + sizeof(SI_STRING_DESC);
10968  str_desc->str_ptr = tmp_ptr;
10969  unicode = FALSE;
10970 
10971  if (nbytes > 0)
10972  {
10973  // check type of dvb string coding
10974  byte_val = *dptr;
10975  if ((byte_val >= 0x01) && (byte_val <= 0x0b))
10976  {
10977  // one of the 11 Latin tables specified in the DVB SI specification from ISO 8859.
10978  *tmp_ptr = byte_val;
10979  tmp_ptr++;
10980  dptr++;
10981  num_bytes--;
10982  byte_count++;
10983  }
10984  else if (byte_val == 0x10)
10985  {
10986  // next 2 bytes indicate the table from ISO 8859 - copy the 3 bytes header across
10987  memcpy(tmp_ptr, dptr, 3);
10988  tmp_ptr += 3;
10989  dptr += 3;
10990  num_bytes -= 3;
10991  byte_count += 3;
10992  }
10993  else if ((byte_val == 0x11) || (byte_val == 0x14))
10994  {
10995  // unicode coded (2 byte codes) - copy header across
10996  *tmp_ptr = byte_val;
10997  tmp_ptr++;
10998  dptr++;
10999  num_bytes--;
11000  byte_count++;
11001  unicode = TRUE;
11002  }
11003  else if (byte_val == 0x1f)
11004  {
11005  /* Compressed string, just read all available bytes */
11006  memcpy(tmp_ptr, dptr, num_bytes);
11007  tmp_ptr += num_bytes;
11008  dptr += num_bytes;
11009  byte_count += num_bytes;
11010  num_bytes = 0;
11011  }
11012 
11013  // for remainder of string copy across removing null codes embedded in the string before
11014  // we reach the end
11015  while (num_bytes > 0)
11016  {
11017  if (unicode == TRUE)
11018  {
11019  // two bytes per character code
11020  if ((dptr[0] != 0) || (dptr[1] != 0))
11021  {
11022  // not null - copy the character across
11023  tmp_ptr[0] = dptr[0];
11024  tmp_ptr[1] = dptr[1];
11025  tmp_ptr += 2;
11026  byte_count += 2;
11027  }
11028  dptr += 2;
11029  num_bytes -= 2;
11030  }
11031  else
11032  {
11033  // single byte ascii
11034  if (dptr[0] != 0)
11035  {
11036  // not null - copy the character across
11037  tmp_ptr[0] = dptr[0];
11038  tmp_ptr++;
11039  byte_count++;
11040  }
11041  dptr++;
11042  num_bytes--;
11043  }
11044  }
11045  }
11046 
11047  // add double null terminator (suitable for unicode)
11048  tmp_ptr[0] = 0;
11049  tmp_ptr[1] = 0;
11050  byte_count += 2;
11051 
11052  str_desc->nbytes = byte_count;
11053  }
11054 
11055  *str_ptr = str_desc;
11056 
11057  FUNCTION_FINISH(STB_SIReadString);
11058 
11059  return(end_ptr);
11060 }
11061 
11062 /*!**************************************************************************
11063  * @brief Parses and allocates a system delivery descriptor which should be freed
11064  * by calling STB_SIReleaseDelSysDesc. Currently supports DVB-T/T2, DVB-C and
11065  * DVB-S/S2 descriptors.
11066  * @param data - pointer to SI data, where the first byte is the desc tag
11067  * @param type - returned with type of descriptor parsed
11068  * @param desc - returned with pointer to parsed and descriptor
11069  * @return TRUE if a descriptor is parsed, FALSE otherwise
11070  ****************************************************************************/
11071 BOOLEAN STB_SIParseDelSysDesc(U8BIT *data, SI_DELIVERY_SYS_DESC_TYPE *type, SI_DELIVERY_SYS_DESC **desc)
11072 {
11073  BOOLEAN retval;
11074 
11075  FUNCTION_START(STB_SIParseDelSysDesc);
11076 
11077  retval = TRUE;
11078 
11079  switch (data[0])
11080  {
11081  case TERR_DEL_SYS_DTAG:
11082  *type = SI_DEL_SYS_DESC_TYPE_TERR;
11083  ParseTerrestrialDeliverySysDescriptor(&data[1], desc, DEBUG_TERR_DEL_SYS_DESC_VALUE);
11084  if (*desc == NULL)
11085  {
11086  retval = FALSE;
11087  }
11088  break;
11089 
11090  case SAT_DEL_SYS_DTAG:
11091  *type = SI_DEL_SYS_DESC_TYPE_SAT;
11092  ParseSatelliteDeliverySysDescriptor(&data[1], desc, DEBUG_SAT_DEL_SYS_DESC_VALUE);
11093  if (*desc == NULL)
11094  {
11095  retval = FALSE;
11096  }
11097  break;
11098 
11099  case CABLE_DEL_SYS_DTAG:
11100  *type = SI_DEL_SYS_DESC_TYPE_CABLE;
11101  ParseCableDeliverySysDescriptor(&data[1], desc, DEBUG_CABLE_DEL_SYS_DESC_VALUE);
11102  if (*desc == NULL)
11103  {
11104  retval = FALSE;
11105  }
11106  break;
11107 
11108  case EXT_DTAG:
11109  {
11110  /* Extended tag uses the 3rd byte to identify the descriptor */
11111  switch (data[2])
11112  {
11113  case T2_DELIVERY_SYS_DTAG:
11114  *type = SI_DEL_SYS_DESC_TYPE_TERR;
11115  ParseT2DeliverySysDescriptor(&data[1], desc, DEBUG_TERR_DEL_SYS_DESC_VALUE);
11116  if (*desc == NULL)
11117  {
11118  retval = FALSE;
11119  }
11120  break;
11121 
11122  default:
11123  retval = FALSE;
11124  break;
11125  }
11126  break;
11127  }
11128 
11129  default:
11130  retval = FALSE;
11131  break;
11132  }
11133 
11134  FUNCTION_FINISH(STB_SIParseDelSysDesc);
11135 
11136  return(retval);
11137 }
11138 
11139 /*!**************************************************************************
11140  * @brief Parses a service descriptor, tag 0x48, allocating SI strings that must
11141  * be freed using STB_SIReleaseStringDesc.
11142  * @param data - pointer to SI data, where the first byte is the desc tag
11143  * @param type - pointer to return service type
11144  * @param provider - an SI_STRING_DESC will be allocated to return the provider string, if present
11145  * @param name - an SI_STRING_DESC will be allocated to return the service name string, if present
11146  * @return TRUE if a descriptor is parsed, FALSE otherwise
11147  ****************************************************************************/
11148 BOOLEAN STB_SIParseServiceDescriptor(U8BIT *data, U8BIT *type, SI_STRING_DESC **provider,
11149  SI_STRING_DESC **name)
11150 {
11151  BOOLEAN retval;
11152 
11153  FUNCTION_START(STB_SIParseServiceDescriptor);
11154 
11155  if (data[0] == SERVICE_DTAG)
11156  {
11157  *provider = NULL;
11158  *name = NULL;
11159 
11160  ParseServiceDescriptor(&data[1], type, provider, name, DEBUG_SERVICE_DESC_VALUE);
11161  retval = TRUE;
11162  }
11163  else
11164  {
11165  retval = FALSE;
11166  }
11167 
11168  FUNCTION_FINISH(STB_SIParseServiceDescriptor);
11169 
11170  return(retval);
11171 }
11172 
11173 /*!**************************************************************************
11174  * @brief Parses a short event descriptor, tag 0x4d, that must be released by
11175  * calling STB_SIReleaseShortEventDescArray
11176  * @param data - pointer to SI data, where the first byte is the desc tag
11177  * @param event_desc - pointer to return an array (always 1) of parsed descriptors
11178  * @return TRUE if a descriptor is parsed, FALSE otherwise
11179  ****************************************************************************/
11180 BOOLEAN STB_SIParseShortEventDescriptor(U8BIT *data, SI_SHORT_EVENT_DESC **event_desc)
11181 {
11182  BOOLEAN retval;
11183  U8BIT num;
11184 
11185  FUNCTION_START(STB_SIParseShortEventDescriptor);
11186 
11187  retval = FALSE;
11188 
11189  if (data[0] == SHORT_EVENT_DTAG)
11190  {
11191  num = 0;
11192  *event_desc = NULL;
11193 
11194  ParseShortEventDescriptor(&data[1], &num, event_desc, DEBUG_SHORT_EVENT_DESC_VALUE);
11195  if ((num == 1) && (*event_desc != NULL))
11196  {
11197  retval = TRUE;
11198  }
11199  }
11200 
11201  FUNCTION_FINISH(STB_SIParseShortEventDescriptor);
11202 
11203  return(retval);
11204 }
11205 
11206 //--------------------------------------------------------------------------------------------------
11207 // Table releasing functions
11208 //--------------------------------------------------------------------------------------------------
11209 
11210 
11223 {
11224  SI_PAT_SERVICE_ENTRY *serv_entry;
11225  SI_PAT_SERVICE_ENTRY *next_entry;
11226 
11227  FUNCTION_START(STB_SIReleasePatTable);
11228 
11229  ASSERT(pat_table != NULL);
11230 
11231  // release the memory used by the pat table
11232  if (pat_table != NULL)
11233  {
11234  serv_entry = pat_table->service_list;
11235  while (serv_entry != NULL)
11236  {
11237  next_entry = serv_entry->next;
11238  STB_SIReleasePatStreamEntry(serv_entry);
11239  serv_entry = next_entry;
11240  }
11241  STB_FreeMemory(pat_table);
11242  }
11243 
11244  FUNCTION_FINISH(STB_SIReleasePatTable);
11245 }
11246 
11259 {
11260  SI_PMT_STREAM_ENTRY *stream_entry;
11261  SI_PMT_STREAM_ENTRY *next_entry;
11262 
11263  FUNCTION_START(STB_SIReleasePmtTable);
11264 
11265  ASSERT(pmt_table != NULL);
11266 
11267  // release the memory used by the pmt table
11268  if (pmt_table != NULL)
11269  {
11270  stream_entry = pmt_table->stream_list;
11271  while (stream_entry != NULL)
11272  {
11273  next_entry = stream_entry->next;
11274  STB_SIReleasePmtStreamEntry(stream_entry);
11275  stream_entry = next_entry;
11276  }
11277  STB_SIReleaseCaDescArray(pmt_table->ca_desc_array, pmt_table->num_ca_entries);
11278  if (pmt_table->tunnelled_desc_array != NULL)
11279  {
11280  STB_FreeMemory(pmt_table->tunnelled_desc_array);
11281  }
11282  STB_FreeMemory(pmt_table);
11283  }
11284 
11285  FUNCTION_FINISH(STB_SIReleasePmtTable);
11286 }
11287 
11300 {
11301  SI_NIT_TRANSPORT_ENTRY *trans_entry;
11302  SI_NIT_TRANSPORT_ENTRY *next_entry;
11303  U16BIT i;
11304 
11305  FUNCTION_START(STB_SIReleaseNitTable);
11306 
11307  ASSERT(nit_table != NULL);
11308 
11309  // release the memory used by the nit table
11310  if (nit_table != NULL)
11311  {
11312  trans_entry = nit_table->transport_list;
11313  while (trans_entry != NULL)
11314  {
11315  next_entry = trans_entry->next;
11316  STB_SIReleaseNitTransportEntry(trans_entry);
11317  trans_entry = next_entry;
11318  }
11319 
11320  STB_SIReleaseStringDesc(nit_table->name_str);
11321  STB_SIReleaseStringDesc(nit_table->def_authority);
11322  STB_SIReleaseMultilingNetNameDescArray(nit_table->multiling_net_name_desc_array,
11323  nit_table->num_multiling_net_names);
11324  STB_SIReleaseLinkageDescList(nit_table->linkage_desc_list, nit_table->num_linkage_entries);
11325 
11326  if (nit_table->change_notify_array != NULL)
11327  {
11328  for (i = 0; i < nit_table->num_change_notifies; i++)
11329  {
11330  if (nit_table->change_notify_array[i].change_array != NULL)
11331  {
11332  STB_FreeMemory(nit_table->change_notify_array[i].change_array);
11333  }
11334  }
11335 
11336  STB_FreeMemory(nit_table->change_notify_array);
11337  }
11338 
11339  if ((nit_table->num_messages > 0) && (nit_table->message_array != NULL))
11340  {
11341  for (i = 0; i < nit_table->num_messages; i++)
11342  {
11343  if (nit_table->message_array[i].message != NULL)
11344  {
11345  STB_SIReleaseStringDesc(nit_table->message_array[i].message);
11346  }
11347  }
11348 
11349  STB_FreeMemory(nit_table->message_array);
11350  }
11351 
11352  if (nit_table->fta_content_desc != NULL)
11353  {
11354  STB_FreeMemory(nit_table->fta_content_desc);
11355  }
11356 
11357  if (nit_table->ciplus_virtual_channel != NULL)
11358  {
11359  STB_SIReleaseStringDesc(nit_table->ciplus_virtual_channel->provider_str);
11360  STB_SIReleaseStringDesc(nit_table->ciplus_virtual_channel->name_str);
11361  STB_FreeMemory(nit_table->ciplus_virtual_channel->event_info);
11362  STB_FreeMemory(nit_table->ciplus_virtual_channel->app_domain_id);
11363  STB_FreeMemory(nit_table->ciplus_virtual_channel);
11364  }
11365 
11366  STB_SIReleaseTargetRegionNameList(nit_table->target_region_name_list);
11367  STB_SIReleaseTargetRegionList(nit_table->target_region_list);
11368 
11369  STB_SIReleaseFreesatLinkageDesc(nit_table->freesat_linkage_desc);
11370  STB_SIReleaseFreesatPrefixList(nit_table->freesat_prefix_list);
11371 
11372  STB_SIReleaseURILinkageList(nit_table->uri_linkage_list);
11373 
11374  STB_FreeMemory(nit_table);
11375  }
11376 
11377  FUNCTION_FINISH(STB_SIReleaseNitTable);
11378 }
11379 
11392 {
11393  SI_SDT_SERVICE_ENTRY *serv_entry;
11394  SI_SDT_SERVICE_ENTRY *next_entry;
11395 
11396  FUNCTION_START(STB_SIReleaseSdtTable);
11397 
11398  ASSERT(sdt_table != NULL);
11399 
11400  // release the memory used by the sdt table
11401  if (sdt_table != NULL)
11402  {
11403  serv_entry = sdt_table->service_list;
11404  while (serv_entry != NULL)
11405  {
11406  next_entry = serv_entry->next;
11407  STB_SIReleaseSdtServiceEntry(serv_entry);
11408  serv_entry = next_entry;
11409  }
11410  STB_FreeMemory(sdt_table);
11411  }
11412 
11413  FUNCTION_FINISH(STB_SIReleaseSdtTable);
11414 }
11415 
11428 {
11429  SI_BAT_TRANSPORT_ENTRY *trans_entry;
11430  SI_BAT_TRANSPORT_ENTRY *next_entry;
11431  SI_BAT_FREESAT_REGION *region_ptr;
11432  SI_BAT_FREESAT_GROUP_NAME_ENTRY *name_entry;
11433  SI_BAT_FREESAT_GROUP_NAME_ENTRY *next_name_entry;
11434  SI_BAT_FREESAT_SERV_GROUP_ENTRY *serv_entry;
11435  SI_BAT_FREESAT_SERV_GROUP_ENTRY *next_serv_entry;
11436  SI_BAT_FREESAT_IACTIVE_STORAGE_DESC *iactive_storage_desc;
11438  SI_BAT_FREESAT_INFO_LOCATION *location_desc;
11439  U16BIT i;
11440 
11441  FUNCTION_START(STB_SIReleaseBatTable);
11442 
11443  ASSERT(bat_table != NULL);
11444 
11445  /* release the memory used by the bat table */
11446  if (bat_table != NULL)
11447  {
11448  trans_entry = bat_table->transport_list;
11449  while (trans_entry != NULL)
11450  {
11451  next_entry = trans_entry->next;
11452  STB_SIReleaseBatTransportEntry(trans_entry);
11453  trans_entry = next_entry;
11454  }
11455 
11456  STB_SIReleaseStringDesc(bat_table->bouquet_name);
11457  STB_SIReleaseLinkageDescList(bat_table->linkage_desc_list, bat_table->num_linkage_entries);
11458 
11459  while (bat_table->region_list != NULL)
11460  {
11461  region_ptr = bat_table->region_list;
11462  if (region_ptr->region_name != NULL)
11463  {
11464  STB_SIReleaseStringDesc(region_ptr->region_name);
11465  }
11466 
11467  bat_table->region_list = region_ptr->next;
11468 
11469  STB_FreeMemory(region_ptr);
11470  }
11471 
11472  /* Release Group names */
11473  name_entry = bat_table->group_name_list;
11474  while (name_entry != NULL)
11475  {
11476  next_name_entry = name_entry->next_group;
11477  for (i = 0; i < name_entry->num_group_names; i++)
11478  {
11479  STB_SIReleaseStringDesc(name_entry->string_array[i].name_str);
11480  }
11481  STB_FreeMemory(name_entry->string_array);
11482  STB_FreeMemory(name_entry);
11483  name_entry = next_name_entry;
11484  }
11485 
11486  /* Release group services */
11487  serv_entry = bat_table->serv_group_array;
11488  while (serv_entry != NULL)
11489  {
11490  next_serv_entry = serv_entry->next_group;
11491  //for (i=0; i<serv_entry->num_services; i++)
11492  {
11493  STB_FreeMemory(serv_entry->freesat_id);
11494  }
11495  STB_FreeMemory(serv_entry);
11496  serv_entry = next_serv_entry;
11497  }
11498 
11499  /* Release interactive storage descriptors */
11500  iactive_storage_desc = bat_table->iactive_storage_desc_list;
11501  while (iactive_storage_desc != NULL)
11502  {
11503  STB_FreeMemory(iactive_storage_desc->data);
11504  next_desc = iactive_storage_desc->next_desc;
11505  STB_FreeMemory(iactive_storage_desc);
11506  iactive_storage_desc = next_desc;
11507  }
11508 
11509  /* Release the info location list */
11510  location_desc = bat_table->info_location_list;
11511  while (location_desc != NULL)
11512  {
11513  bat_table->info_location_list = location_desc->next;
11514  STB_FreeMemory(location_desc);
11515  location_desc = bat_table->info_location_list;
11516  }
11517 
11518  STB_SIReleaseFreesatPrefixList(bat_table->freesat_prefix_list);
11519 
11520  STB_SIReleaseURILinkageList(bat_table->uri_linkage_list);
11521 
11522  STB_FreeMemory(bat_table);
11523  }
11524 
11525  FUNCTION_FINISH(STB_SIReleaseBatTable);
11526 }
11527 
11540 {
11541  SI_EIT_EVENT_ENTRY *event_entry;
11542  SI_EIT_EVENT_ENTRY *next_entry;
11543 
11544  FUNCTION_START(STB_SIReleaseEitTable);
11545 
11546  ASSERT(eit_table != NULL);
11547 
11548  // release the memory used by the eit table
11549  if (eit_table != NULL)
11550  {
11551  event_entry = eit_table->event_list;
11552  while (event_entry != NULL)
11553  {
11554  next_entry = event_entry->next;
11555  STB_SIReleaseEitEventEntry(event_entry);
11556  event_entry = next_entry;
11557  }
11558 
11559  STB_FreeMemory(eit_table);
11560  }
11561 
11562  FUNCTION_FINISH(STB_SIReleaseEitTable);
11563 }
11564 
11577 {
11578  FUNCTION_START(STB_SIReleaseTimeTable);
11579 
11580  ASSERT(time_table != NULL);
11581 
11582  if (time_table != NULL)
11583  {
11584  // release the memory used by the table
11585  STB_SIReleaseLtoDescArray(time_table->lto_desc_array, time_table->num_lto_entries);
11586  STB_FreeMemory(time_table);
11587  }
11588 
11589  FUNCTION_FINISH(STB_SIReleaseTimeTable);
11590 }
11591 
11592 /*!**************************************************************************
11593  * @brief Frees memory used by an RCT table
11594  * @param rct_table - pointer to the SI_RCT_TABLE structure to be freed
11595  ****************************************************************************/
11597 {
11598  SI_RCT_SUBTABLE *sub_ptr;
11599  SI_RCT_SUBTABLE *next_subtable;
11600 
11601  FUNCTION_START(STB_SIReleaseRctTable);
11602 
11603  ASSERT(rct_table != NULL);
11604 
11605  if (rct_table != NULL)
11606  {
11607  sub_ptr = rct_table->subtables;
11608  while (sub_ptr != NULL)
11609  {
11610  next_subtable = sub_ptr->next;
11611  STB_SIReleaseRctSubtable(sub_ptr);
11612  sub_ptr = next_subtable;
11613  }
11614 
11615  STB_FreeMemory(rct_table);
11616  }
11617 
11618  FUNCTION_FINISH(STB_SIReleaseRctTable);
11619 }
11620 
11621 //--------------------------------------------------------------------------------------------------
11622 // Table entry releasing functions
11623 //--------------------------------------------------------------------------------------------------
11624 // the following functions can be used to release individual table entry structures from the parsed
11625 // tables. They are mainly intended for releasing entries which have been transferred
11626 // out of the parsed tables by the application SI handler and are therefore not released when the
11627 // table is released.
11628 
11641 {
11642  FUNCTION_START(STB_SIReleasePatStreamEntry);
11643 
11644  STB_FreeMemory(entry_ptr);
11645 
11646  FUNCTION_FINISH(STB_SIReleasePatStreamEntry);
11647 }
11648 
11661 {
11662  FUNCTION_START(STB_SIReleasePmtStreamEntry);
11663 
11664  STB_SIReleaseIsoLangDescArray(entry_ptr->iso_lang_desc_array,
11665  entry_ptr->num_iso_lang_entries);
11666  STB_SIReleaseCaDescArray(entry_ptr->ca_desc_array, entry_ptr->num_ca_entries);
11667  STB_SIReleaseSubtitleDescArray(entry_ptr->subtitle_desc_array,
11668  entry_ptr->num_subtitle_entries);
11669  STB_SIReleaseTeletextDescArray(entry_ptr->teletext_desc_array,
11670  entry_ptr->num_teletext_entries);
11671 
11672  if (entry_ptr->ac3_descriptor != NULL)
11673  {
11674  STB_FreeMemory(entry_ptr->ac3_descriptor);
11675  }
11676 
11677  if (entry_ptr->aac_descriptor != NULL)
11678  {
11679  STB_FreeMemory(entry_ptr->aac_descriptor);
11680  }
11681 
11682  if (entry_ptr->app_sig_desc_array != NULL)
11683  {
11684  STB_FreeMemory(entry_ptr->app_sig_desc_array);
11685  }
11686 
11687  if (entry_ptr->tag_array_ptr != NULL)
11688  {
11689  STB_FreeMemory(entry_ptr->tag_array_ptr);
11690  }
11691 
11692  if (entry_ptr->audio_desc != NULL)
11693  {
11694  STB_FreeMemory(entry_ptr->audio_desc);
11695  }
11696 
11697 #if 0
11698  if (entry_ptr->service_move != NULL)
11699  {
11700  STB_FreeMemory(entry_ptr->service_move);
11701  }
11702 #endif
11703 
11704  if (entry_ptr->tunnelled_desc_array != NULL)
11705  {
11706  STB_FreeMemory(entry_ptr->tunnelled_desc_array);
11707  }
11708 
11709  STB_FreeMemory(entry_ptr);
11710 
11711  FUNCTION_FINISH(STB_SIReleasePmtStreamEntry);
11712 }
11713 
11726 {
11727  FUNCTION_START(STB_SIReleaseNitTransportEntry);
11728 
11729  STB_SIReleaseDelSysDesc(entry_ptr->del_sys_desc, entry_ptr->del_sys_desc_type);
11730  STB_SIReleaseFreqListDescArray(entry_ptr->freq_list);
11731  STB_SIReleaseServListDescArray(entry_ptr->serv_list_desc_array,
11732  entry_ptr->num_serv_list_entries);
11733  STB_SIReleaseLcnDescArray(entry_ptr->lcn_desc_array, entry_ptr->num_lcn_entries);
11734  STB_SIReleaseStringDesc(entry_ptr->def_authority);
11735  STB_SIReleaseLcnDescArray(entry_ptr->hd_lcn_desc_array, entry_ptr->num_hd_lcn_entries);
11736  STB_SIReleaseNordigLcn2DescArray(entry_ptr->nordig_lcn_desc_array, entry_ptr->num_nordig_lcn_entries);
11737 
11738  if (entry_ptr->serv_attr_array != NULL)
11739  {
11740  STB_FreeMemory(entry_ptr->serv_attr_array);
11741  }
11742 
11743  if (entry_ptr->fta_content_desc != NULL)
11744  {
11745  STB_FreeMemory(entry_ptr->fta_content_desc);
11746  }
11747 
11748  STB_SIReleaseTargetRegionList(entry_ptr->target_region_list);
11749  STB_SIReleaseCIPlusServiceList(entry_ptr->ciplus_service_list);
11750 
11751  STB_FreeMemory(entry_ptr);
11752 
11753  FUNCTION_FINISH(STB_SIReleaseNitTransportEntry);
11754 }
11755 
11768 {
11770  SI_BAT_FREESAT_REGION_LCN_ENTRY *next_entry;
11771 
11772  FUNCTION_START(STB_SIReleaseBatTransportEntry);
11773 
11774  STB_SIReleaseLcnDescArray(entry_ptr->lcn_desc_array, entry_ptr->num_lcn_entries);
11775 
11776  lcn_entry = entry_ptr->lcn_region_list;
11777  while (lcn_entry != NULL)
11778  {
11779  next_entry = lcn_entry->next;
11780  STB_SIReleaseBatLcnEntry(lcn_entry);
11781  lcn_entry = next_entry;
11782  }
11783 
11784  STB_SIReleaseServListDescArray(entry_ptr->serv_list_desc_array, entry_ptr->num_serv_list_entries);
11785 
11786  STB_FreeMemory(entry_ptr);
11787 
11788  FUNCTION_FINISH(STB_SIReleaseBatTransportEntry);
11789 }
11790 
11803 {
11804  SI_FREESAT_LCN *freesat_lcn;
11805  SI_FREESAT_LCN *next_entry;
11806 
11807  FUNCTION_START(STB_SIReleaseBatLcnEntry);
11808 
11809  freesat_lcn = entry_ptr->freesat_lcn_list;
11810  while (freesat_lcn != NULL)
11811  {
11812  next_entry = freesat_lcn->next;
11813  STB_FreeMemory((void *)freesat_lcn);
11814  freesat_lcn = next_entry;
11815  }
11816 
11817  STB_FreeMemory(entry_ptr);
11818 
11819  FUNCTION_FINISH(STB_SIReleaseBatLcnEntry);
11820 }
11821 
11834 {
11835  FUNCTION_START(STB_SIReleaseSdtServiceEntry);
11836 
11837  STB_SIReleaseStringDesc(entry_ptr->name_str);
11838  STB_SIReleaseStringDesc(entry_ptr->provider_str);
11839  STB_SIReleaseCaIdDescArray(entry_ptr->ca_id_desc_array, entry_ptr->num_ca_id_entries);
11840  STB_SIReleaseMultilingServNameDescArray(entry_ptr->multiling_name_desc_array,
11841  entry_ptr->num_multiling_names);
11842  STB_SIReleasePrefNameDescArray(entry_ptr->preferred_name_desc_array,
11843  entry_ptr->num_preferred_names);
11844  STB_SIReleaseLinkageDescList(entry_ptr->linkage_desc_list, entry_ptr->num_linkage_entries);
11845  STB_SIReleaseStringDesc(entry_ptr->def_authority);
11846  STB_SIReleaseStringDesc(entry_ptr->short_name_str);
11847  STB_SIReleaseMultilingShortNameArray(entry_ptr->multiling_short_name_array,
11848  entry_ptr->num_multiling_short_names);
11849  STB_SIReleaseGuidanceDesc(entry_ptr->guidance);
11850 
11851  if (entry_ptr->fta_content_desc != NULL)
11852  {
11853  STB_FreeMemory(entry_ptr->fta_content_desc);
11854  }
11855 
11856  STB_SIReleaseTargetRegionList(entry_ptr->target_region_list);
11857 
11858  if (entry_ptr->ci_protection_desc != NULL)
11859  {
11860  STB_FreeMemory(entry_ptr->ci_protection_desc);
11861  }
11862  STB_SIReleaseAvailabilityDescriptorList(entry_ptr->serv_avail_desc_list);
11863  STB_SIReleaseFreesatPrefixList(entry_ptr->freesat_prefix_list);
11864  STB_SIReleaseURILinkageList(entry_ptr->uri_linkage_list);
11865 
11866  STB_FreeMemory(entry_ptr);
11867 
11868  FUNCTION_FINISH(STB_SIReleaseSdtServiceEntry);
11869 }
11870 
11883 {
11884  FUNCTION_START(STB_SIReleaseEitEventEntry);
11885 
11886  STB_SIReleaseCaIdDescArray(entry_ptr->ca_id_desc_array, entry_ptr->num_ca_id_entries);
11887  STB_SIReleaseComponentDescArray(entry_ptr->component_desc_array,
11888  entry_ptr->num_component_entries);
11889  STB_SIReleaseMultilingComponentDescArray(entry_ptr->multiling_component_desc_array,
11890  entry_ptr->num_multiling_component_entries);
11891 
11892  STB_SIReleaseContentDescArray(entry_ptr->content_desc_array, entry_ptr->num_content_entries);
11893  STB_SIReleaseParentalRatingDescArray(entry_ptr->parental_rating_desc_array,
11894  entry_ptr->num_parental_rating_entries);
11895  STB_SIReleaseShortEventDescArray(entry_ptr->short_event_desc_array,
11896  entry_ptr->num_short_event_entries);
11897  STB_SIReleaseExtendedEventDescArray(entry_ptr->extended_event_desc_array,
11898  entry_ptr->num_extended_event_entries);
11899  STB_SIReleaseCRIDList(entry_ptr->crid_list);
11900  STB_SIReleaseGuidanceDesc(entry_ptr->guidance);
11901 
11902  if (entry_ptr->fta_content_desc != NULL)
11903  {
11904  STB_FreeMemory(entry_ptr->fta_content_desc);
11905  }
11906 
11907  STB_FreeMemory(entry_ptr);
11908 
11909  FUNCTION_FINISH(STB_SIReleaseEitEventEntry);
11910 }
11911 
11912 /*!**************************************************************************
11913  * @brief Frees memory used by an RCT subtable
11914  * @param sub_ptr - pointer to the SI_RCT_SUBTABLE structure to be freed
11915  ****************************************************************************/
11917 {
11918  SI_RCT_SUBTABLE_DATA *data_ptr;
11919  SI_RCT_SUBTABLE_DATA *next_data_ptr;
11920 
11921  FUNCTION_START(STB_SIReleaseRctSubtable);
11922 
11923  if (sub_ptr != NULL)
11924  {
11925  data_ptr = sub_ptr->data;
11926  while (data_ptr != NULL)
11927  {
11928  next_data_ptr = data_ptr->next;
11929  STB_SIReleaseRctSubtableData(data_ptr);
11930  data_ptr = next_data_ptr;
11931  }
11932 
11933  STB_FreeMemory(sub_ptr);
11934  }
11935 
11936  FUNCTION_FINISH(STB_SIReleaseRctSubtable);
11937 }
11938 
11939 /*!**************************************************************************
11940  * @brief Frees memory used by an SI_RCT_SUBTABLE_DATA structure
11941  * @param data_ptr - pointer to the SI_RCT_SUBTABLE_DATA structure to be freed
11942  ****************************************************************************/
11944 {
11945  U8BIT i;
11946 
11947  FUNCTION_START(STB_SIReleaseRctSubtableData);
11948 
11949  if (data_ptr != NULL)
11950  {
11951  if ((data_ptr->link_count > 0) && (data_ptr->link_array != NULL))
11952  {
11953  for (i = 0; i < data_ptr->link_count; i++)
11954  {
11955  STB_SIReleaseRctLinkInfo(&data_ptr->link_array[i]);
11956  }
11957 
11958  STB_FreeMemory(data_ptr->link_array);
11959  }
11960 
11961  STB_SIReleaseImageIconDescArray(data_ptr->icon_array, data_ptr->num_icons);
11962 
11963  STB_FreeMemory(data_ptr);
11964  }
11965 
11966  FUNCTION_FINISH(STB_SIReleaseRctSubtableData);
11967 }
11968 
11969 //--------------------------------------------------------------------------------------------------
11970 // Descriptor releasing functions
11971 //--------------------------------------------------------------------------------------------------
11972 // the following functions can be used to release individual descriptor arrays from the parsed
11973 // tables. They are mainly intended for releasing descriptor arrays which have been transferred
11974 // out of the parsed tables by the application SI handler (by setting the structure element pointing
11975 // to the descriptor array to NULL), and are therefore not released when the table is released.
11976 
11989 void STB_SIReleaseDelSysDesc(SI_DELIVERY_SYS_DESC *desc, SI_DELIVERY_SYS_DESC_TYPE type)
11990 {
11991  FUNCTION_START(STB_SIReleaseDelSysDesc);
11992 
11993  if (desc != NULL)
11994  {
11995  switch (type)
11996  {
11997  case SI_DEL_SYS_DESC_TYPE_SAT:
11998  {
11999  break;
12000  }
12001  case SI_DEL_SYS_DESC_TYPE_CABLE:
12002  {
12003  break;
12004  }
12005  case SI_DEL_SYS_DESC_TYPE_TERR:
12006  {
12007  if (desc->terr.is_t2)
12008  {
12009  if ((desc->terr.u.t2.num_cells > 0) && (desc->terr.u.t2.cell != NULL))
12010  {
12011  STB_FreeMemory(desc->terr.u.t2.cell);
12012  }
12013  }
12014  break;
12015  }
12016  default:
12017  {
12018  STB_SI_PRINT(("SI_DELIVERY_SYS_DESC_TYPE release not supported!"));
12019  break;
12020  }
12021  }
12022 
12023  STB_FreeMemory(desc);
12024  }
12025 
12026  FUNCTION_FINISH(STB_SIReleaseDelSysDesc);
12027 }
12028 
12041 {
12042  FUNCTION_START(STB_SIReleaseStringDesc);
12043 
12044  if (desc != NULL)
12045  {
12046  STB_FreeMemory(desc);
12047  }
12048 
12049  FUNCTION_FINISH(STB_SIReleaseStringDesc);
12050 }
12051 
12064 void STB_SIReleaseCaDescArray(SI_CA_DESC *desc_array, U16BIT num_entries)
12065 {
12066  FUNCTION_START(STB_SIReleaseCaDescArray);
12067 
12068  USE_UNWANTED_PARAM(num_entries);
12069 
12070  if (desc_array != NULL)
12071  {
12072  STB_FreeMemory(desc_array);
12073  }
12074 
12075  FUNCTION_FINISH(STB_SIReleaseCaDescArray);
12076 }
12077 
12090 void STB_SIReleaseCaIdDescArray(U16BIT *desc_array, U8BIT num_entries)
12091 {
12092  FUNCTION_START(STB_SIReleaseCaIdDescArray);
12093 
12094  USE_UNWANTED_PARAM(num_entries);
12095 
12096  if (desc_array != NULL)
12097  {
12098  STB_FreeMemory(desc_array);
12099  }
12100 
12101  FUNCTION_FINISH(STB_SIReleaseCaIdDescArray);
12102 }
12103 
12116 void STB_SIReleaseComponentDescArray(SI_COMPONENT_DESC *desc_array, U8BIT num_entries)
12117 {
12118  SI_COMPONENT_DESC *comp_desc_ptr;
12119  U8BIT i;
12120 
12121  FUNCTION_START(STB_SIReleaseComponentDescArray);
12122  if (desc_array != NULL)
12123  {
12124  comp_desc_ptr = desc_array;
12125  for (i = 0; i < num_entries; i++, comp_desc_ptr++)
12126  {
12127  STB_SIReleaseStringDesc(comp_desc_ptr->desc_str);
12128  }
12129  STB_FreeMemory(desc_array);
12130  }
12131  FUNCTION_FINISH(STB_SIReleaseComponentDescArray);
12132 }
12133 
12146 void STB_SIReleaseContentDescArray(SI_CONTENT_DESC *desc_array, U8BIT num_entries)
12147 {
12148  FUNCTION_START(STB_SIReleaseContentDescArray);
12149 
12150  USE_UNWANTED_PARAM(num_entries);
12151 
12152  if (desc_array != NULL)
12153  {
12154  STB_FreeMemory(desc_array);
12155  }
12156  FUNCTION_FINISH(STB_SIReleaseContentDescArray);
12157 }
12158 
12164 {
12166 
12167  FUNCTION_START(STB_SIReleaseFreqListDescArray);
12168 
12169  if (freq_list != NULL)
12170  {
12171  for ( ; freq_list != NULL; freq_list = next)
12172  {
12173  next = freq_list->next;
12174  if (freq_list->frequency_array != NULL)
12175  {
12176  STB_FreeMemory(freq_list->frequency_array);
12177  }
12178  STB_FreeMemory(freq_list);
12179  }
12180  }
12181 
12182  FUNCTION_FINISH(STB_SIReleaseFreqListDescArray);
12183 }
12184 
12198 {
12199  U8BIT index;
12200 
12201  FUNCTION_START(STB_SIReleaseGuidanceDesc);
12202 
12203  if (desc_ptr != NULL)
12204  {
12205  if (desc_ptr->strings != NULL)
12206  {
12207  for (index = 0; index < desc_ptr->num_langs; index++)
12208  {
12209  if (desc_ptr->strings[index] != NULL)
12210  {
12211  STB_SIReleaseStringDesc(desc_ptr->strings[index]);
12212  }
12213  }
12214 
12215  STB_FreeMemory(desc_ptr->strings);
12216  }
12217 
12218  if (desc_ptr->lang_codes != NULL)
12219  {
12220  STB_FreeMemory(desc_ptr->lang_codes);
12221  }
12222 
12223  STB_FreeMemory(desc_ptr);
12224  }
12225 
12226  FUNCTION_FINISH(STB_SIReleaseGuidanceDesc);
12227 }
12228 
12229 /*!**************************************************************************
12230  * @brief Frees an array of image icons, including the memory used by each one
12231  * @param icon_array - image icon array
12232  * @param num_icons - number of icons in the array
12233  ****************************************************************************/
12234 void STB_SIReleaseImageIconDescArray(SI_IMAGE_ICON_DESC *icon_array, U8BIT num_icons)
12235 {
12236  U8BIT i;
12237 
12238  FUNCTION_START(STB_SIReleaseImageIconDesc);
12239 
12240  if (icon_array != NULL)
12241  {
12242  for (i = 0; i < num_icons; i++)
12243  {
12244  if (icon_array[i].icon_type != NULL)
12245  {
12246  STB_FreeMemory(icon_array[i].icon_type);
12247  }
12248 
12249  if (icon_array[i].icon_data != NULL)
12250  {
12251  STB_FreeMemory(icon_array[i].icon_data);
12252  }
12253  }
12254 
12255  STB_FreeMemory(icon_array);
12256  }
12257 
12258  FUNCTION_FINISH(STB_SIReleaseImageIconDesc);
12259 }
12260 
12273 void STB_SIReleaseIsoLangDescArray(SI_ISO_LANG_DESC *desc_array, U16BIT num_entries)
12274 {
12275  FUNCTION_START(STB_SIReleaseIsoLangDescArray);
12276 
12277  USE_UNWANTED_PARAM(num_entries);
12278 
12279  if (desc_array != NULL)
12280  {
12281  STB_FreeMemory(desc_array);
12282  }
12283  FUNCTION_FINISH(STB_SIReleaseIsoLangDescArray);
12284 }
12285 
12298 void STB_SIReleaseLinkageDescList(SI_LINKAGE_DESC_ENTRY *list_ptr, U16BIT num_entries)
12299 {
12300  SI_LINKAGE_DESC_ENTRY *desc_ptr;
12301  SI_LINKAGE_DESC_ENTRY *tmp_ptr;
12302 
12303  FUNCTION_START(STB_SIReleaseLinkageDescArray);
12304 
12305  USE_UNWANTED_PARAM(num_entries);
12306 
12307  desc_ptr = list_ptr;
12308  while (desc_ptr != NULL)
12309  {
12310  tmp_ptr = desc_ptr->next;
12311  STB_FreeMemory(desc_ptr);
12312  desc_ptr = tmp_ptr;
12313  }
12314  FUNCTION_FINISH(STB_SIReleaseLinkageDescArray);
12315 }
12316 
12329 void STB_SIReleaseLtoDescArray(SI_LTO_DESC *desc_array, U16BIT num_entries)
12330 {
12331  FUNCTION_START(STB_SIReleaseLtoDescArray);
12332 
12333  USE_UNWANTED_PARAM(num_entries);
12334 
12335  if (desc_array != NULL)
12336  {
12337  STB_FreeMemory(desc_array);
12338  }
12339  FUNCTION_FINISH(STB_SIReleaseLtoDescArray);
12340 }
12341 
12355  U8BIT num_entries)
12356 {
12357  U8BIT i;
12358  SI_MULTILING_COMPONENT_DESC *ml_comp_desc_ptr;
12359 
12361 
12362  if (desc_array != NULL)
12363  {
12364  ml_comp_desc_ptr = desc_array;
12365  for (i = 0; i < num_entries; i++, ml_comp_desc_ptr++)
12366  {
12367  STB_SIReleaseStringDesc(ml_comp_desc_ptr->desc_str);
12368  }
12369  STB_FreeMemory(desc_array);
12370  }
12371 
12373 }
12374 
12388  U16BIT num_entries)
12389 {
12390  SI_MULTILING_NET_NAME_DESC *mlnn_desc_ptr;
12391  U16BIT i;
12392 
12394 
12395  if (desc_array != NULL)
12396  {
12397  mlnn_desc_ptr = desc_array;
12398  for (i = 0; i < num_entries; i++, mlnn_desc_ptr++)
12399  {
12400  STB_SIReleaseStringDesc(mlnn_desc_ptr->name_str);
12401  }
12402  STB_FreeMemory(desc_array);
12403  }
12404 
12405  FUNCTION_FINISH(STB_SIReleaseMultilingNetNameDescArray);
12406 }
12407 
12421  U16BIT num_entries)
12422 {
12423  SI_MULTILING_SERV_NAME_DESC *ml_name_desc_ptr;
12424  U16BIT i;
12425 
12427 
12428  if (desc_array != NULL)
12429  {
12430  ml_name_desc_ptr = desc_array;
12431  for (i = 0; i < num_entries; i++, ml_name_desc_ptr++)
12432  {
12433  STB_SIReleaseStringDesc(ml_name_desc_ptr->name_str);
12434  STB_SIReleaseStringDesc(ml_name_desc_ptr->provider_str);
12435  }
12436  STB_FreeMemory(desc_array);
12437  }
12438 
12439  FUNCTION_FINISH(STB_SIReleaseMultilingServNameDescArray);
12440 }
12441 
12442 void STB_SIReleaseMultilingShortNameArray(SI_MULTILING_SHORT_NAME_DESC *desc_array,
12443  U16BIT num_entries)
12444 {
12445  SI_MULTILING_SHORT_NAME_DESC *name_desc_ptr;
12446  U16BIT i;
12447 
12448  FUNCTION_START(STB_SIReleaseMultilingShortNameArray);
12449 
12450  if (desc_array != NULL)
12451  {
12452  name_desc_ptr = desc_array;
12453  for (i = 0; i < num_entries; i++, name_desc_ptr++)
12454  {
12455  STB_SIReleaseStringDesc(name_desc_ptr->name_str);
12456  }
12457  STB_FreeMemory(desc_array);
12458  }
12459 
12460  FUNCTION_FINISH(STB_SIReleaseMultilingShortNameArray);
12461 }
12462 
12476 {
12477  FUNCTION_START(STB_SIReleaseParentalRatingDescArray);
12478 
12479  USE_UNWANTED_PARAM(num_entries);
12480 
12481  if (desc_array != NULL)
12482  {
12483  STB_FreeMemory(desc_array);
12484  }
12485  FUNCTION_FINISH(STB_SIReleaseParentalRatingDescArray);
12486 }
12487 
12500 void STB_SIReleaseServListDescArray(SI_SERV_LIST_DESC *desc_array, U16BIT num_entries)
12501 {
12502  FUNCTION_START(STB_SIReleaseServListDescArray);
12503 
12504  USE_UNWANTED_PARAM(num_entries);
12505 
12506  if (desc_array != NULL)
12507  {
12508  STB_FreeMemory(desc_array);
12509  }
12510  FUNCTION_FINISH(STB_SIReleaseServListDescArray);
12511 }
12512 
12525 void STB_SIReleaseShortEventDescArray(SI_SHORT_EVENT_DESC *desc_array, U8BIT num_entries)
12526 {
12527  SI_SHORT_EVENT_DESC *sevnt_desc_ptr;
12528  U8BIT i;
12529 
12530  FUNCTION_START(STB_SIReleaseShortEventDescArray);
12531 
12532  if (desc_array != NULL)
12533  {
12534  sevnt_desc_ptr = desc_array;
12535  for (i = 0; i < num_entries; i++, sevnt_desc_ptr++)
12536  {
12537  STB_SIReleaseStringDesc(sevnt_desc_ptr->desc_str);
12538  STB_SIReleaseStringDesc(sevnt_desc_ptr->name_str);
12539  }
12540  STB_FreeMemory(desc_array);
12541  }
12542 
12543  FUNCTION_FINISH(STB_SIReleaseShortEventDescArray);
12544 }
12545 
12559 {
12560  SI_EXTENDED_EVENT_DESC *evnt_desc_ptr;
12561  U8BIT i, j;
12562 
12563  FUNCTION_START(STB_SIReleaseExtendedEventDescArray);
12564 
12565  if (desc_array != NULL)
12566  {
12567  evnt_desc_ptr = desc_array;
12568  for (i = 0; i < num_entries; i++, evnt_desc_ptr++)
12569  {
12570  for (j = 0; j < evnt_desc_ptr->num_items; j++)
12571  {
12572  STB_SIReleaseStringDesc(evnt_desc_ptr->item_desc_array[j]);
12573  STB_SIReleaseStringDesc(evnt_desc_ptr->item_text_array[j]);
12574  }
12575 
12576  if (evnt_desc_ptr->item_desc_array != NULL)
12577  {
12578  STB_FreeMemory(evnt_desc_ptr->item_desc_array);
12579  }
12580  if (evnt_desc_ptr->item_text_array != NULL)
12581  {
12582  STB_FreeMemory(evnt_desc_ptr->item_text_array);
12583  }
12584 
12585  STB_SIReleaseStringDesc(evnt_desc_ptr->text_str);
12586  }
12587 
12588  STB_FreeMemory(desc_array);
12589  }
12590 
12591  FUNCTION_FINISH(STB_SIReleaseExtendedEventDescArray);
12592 }
12593 
12606 void STB_SIReleaseSubtitleDescArray(SI_SUBTITLE_DESC *desc_array, U16BIT num_entries)
12607 {
12608  FUNCTION_START(STB_SIReleaseSubtitleDescArray);
12609 
12610  USE_UNWANTED_PARAM(num_entries);
12611 
12612  if (desc_array != NULL)
12613  {
12614  STB_FreeMemory(desc_array);
12615  }
12616  FUNCTION_FINISH(STB_SIReleaseSubtitleDescArray);
12617 }
12618 
12631 {
12634  U8BIT i;
12635 
12636  FUNCTION_START(STB_SIReleaseTargetRegionNameList);
12637 
12638  for (ptr = desc_list; ptr != NULL; ptr = next)
12639  {
12640  next = ptr->next;
12641 
12642  if (ptr->name_array != NULL)
12643  {
12644  for (i = 0; i < ptr->num_names; i++)
12645  {
12646  STB_SIReleaseStringDesc(ptr->name_array[i].region_name);
12647  }
12648 
12649  STB_FreeMemory(ptr->name_array);
12650  }
12651 
12652  STB_FreeMemory(ptr);
12653  }
12654 
12655  FUNCTION_FINISH(STB_SIReleaseTargetRegionNameList);
12656 }
12657 
12670 {
12671  SI_TARGET_REGION_DESC *cptr;
12672  SI_TARGET_REGION_DESC *cnext;
12673  SI_TARGET_REGION *rptr;
12674  SI_TARGET_REGION *rnext;
12675 
12676  FUNCTION_START(STB_SIReleaseTargetRegionList);
12677 
12678  for (cptr = desc_list; cptr != NULL; cptr = cnext)
12679  {
12680  cnext = cptr->next;
12681 
12682  for (rptr = cptr->region_list; rptr != NULL; rptr = rnext)
12683  {
12684  rnext = rptr->next;
12685 
12686  STB_FreeMemory(rptr);
12687  }
12688 
12689  STB_FreeMemory(cptr);
12690  }
12691 
12692  FUNCTION_FINISH(STB_SIReleaseTargetRegionList);
12693 }
12694 
12707 {
12708  SI_SERV_AVAIL_DESC *desc, *next;
12709 
12710  desc = desc_list;
12711  while (desc != NULL)
12712  {
12713  if (desc->cell_ids != NULL)
12714  {
12715 #ifdef DEBUG_SERV_AVAIL_DESC
12716  STB_SI_PRINT(("STB_SIReleaseSdtServiceEntry: Freeing cell_ids"));
12717 #endif
12718  STB_FreeMemory(desc->cell_ids);
12719  }
12720  next = desc->next;
12721 #ifdef DEBUG_SERV_AVAIL_DESC
12722  STB_SI_PRINT(("STB_SIReleaseSdtServiceEntry: Freeing serv_avail_desc"));
12723 #endif
12724  STB_FreeMemory(desc);
12725  desc = next;
12726  }
12727 }
12728 
12741 void STB_SIReleaseTeletextDescArray(SI_TELETEXT_DESC *desc_array, U16BIT num_entries)
12742 {
12743  FUNCTION_START(STB_SIReleaseTeletextDescArray);
12744 
12745  USE_UNWANTED_PARAM(num_entries);
12746 
12747  if (desc_array != NULL)
12748  {
12749  STB_FreeMemory(desc_array);
12750  }
12751  FUNCTION_FINISH(STB_SIReleaseTeletextDescArray);
12752 }
12753 
12766 void STB_SIReleaseLcnDescArray(SI_LCN_DESC *desc_array, U16BIT num_entries)
12767 {
12768  FUNCTION_START(STB_SIReleaseLcnDescArray);
12769 
12770  USE_UNWANTED_PARAM(num_entries);
12771 
12772  if (desc_array != NULL)
12773  {
12774  STB_FreeMemory(desc_array);
12775  }
12776  FUNCTION_FINISH(STB_SIReleaseLcnDescArray);
12777 }
12778 
12791 void STB_SIReleaseNordigLcn2DescArray(SI_NORDIG_LCN_DESC *desc_array, U16BIT num_entries)
12792 {
12793  U16BIT i;
12794 
12795  FUNCTION_START(STB_SIReleaseNordigLcn2DescArray);
12796 
12797  if (desc_array != NULL)
12798  {
12799  for (i = 0; i < num_entries; i++)
12800  {
12801  STB_SIReleaseStringDesc(desc_array[i].chan_list_name);
12802 
12803  if (desc_array[i].serv_array != NULL)
12804  {
12805  STB_FreeMemory(desc_array[i].serv_array);
12806  }
12807  }
12808 
12809  STB_FreeMemory(desc_array);
12810  }
12811  FUNCTION_FINISH(STB_SIReleaseNordigLcn2DescArray);
12812 }
12813 
12826 void STB_SIReleasePrefNameDescArray(SI_PREFERRED_NAME_DESC *desc_array, U16BIT num_entries)
12827 {
12828  SI_PREFERRED_NAME_DESC *pref_name_desc_ptr;
12829  U16BIT i;
12830 
12831  FUNCTION_START(STB_SIReleasePrefNameDescArray);
12832 
12833  if (desc_array != NULL)
12834  {
12835  pref_name_desc_ptr = desc_array;
12836  for (i = 0; i < num_entries; i++, pref_name_desc_ptr++)
12837  {
12838  STB_SIReleaseStringDesc(pref_name_desc_ptr->name_str);
12839  }
12840  STB_FreeMemory(desc_array);
12841  }
12842  FUNCTION_FINISH(STB_SIReleasePrefNameDescArray);
12843 }
12844 
12857 {
12858  SI_CRID_DESC *next_crid_ptr;
12859 
12860  FUNCTION_START(STB_SIReleaseCRIDList);
12861 
12862  while (crid_list != NULL)
12863  {
12864  STB_SIReleaseStringDesc(crid_list->crid_str);
12865  next_crid_ptr = crid_list->next;
12866  STB_FreeMemory(crid_list);
12867  crid_list = next_crid_ptr;
12868  }
12869 
12870  FUNCTION_FINISH(STB_SIReleaseCRIDList);
12871 }
12872 
12873 /*!**************************************************************************
12874  * @brief Frees memory used by an SI_RCT_LINK_INFO structure
12875  * @param data_ptr - pointer to the SI_RCT_LINK_INFO structure
12876  ****************************************************************************/
12878 {
12879  U8BIT i;
12880 
12881  FUNCTION_START(STB_SIReleaseRctLinkInfo);
12882 
12883  if (link_info != NULL)
12884  {
12885  if (link_info->uri_string != NULL)
12886  {
12887  STB_FreeMemory(link_info->uri_string);
12888  }
12889 
12890  if ((link_info->num_items > 0) && (link_info->promo_text_array != NULL))
12891  {
12892  for (i = 0; i < link_info->num_items; i++)
12893  {
12894  STB_SIReleaseStringDesc(link_info->promo_text_array[i].string);
12895  }
12896 
12897  STB_FreeMemory(link_info->promo_text_array);
12898  }
12899 
12900  if (link_info->event_desc != NULL)
12901  {
12902  STB_SIReleaseShortEventDescArray(link_info->event_desc, 1);
12903  }
12904 
12905  STB_SIReleaseImageIconDescArray(link_info->icon_array, link_info->num_icons);
12906  }
12907 
12908  FUNCTION_FINISH(STB_SIReleaseRctLinkInfo);
12909 }
12910 
12911 /*!**************************************************************************
12912  * @brief Frees memory used by an SI_FREESAT_LINKAGE_DESC structure
12913  * @param desc - pointer to the SI_FREESAT_LINKAGE_DESC
12914  ****************************************************************************/
12916 {
12918 
12919  FUNCTION_START(STB_SIReleaseFreesatLinkageDesc);
12920 
12921  while (desc != NULL)
12922  {
12923  next = desc->next;
12924 
12925  if (desc->data_types != NULL)
12926  {
12927  STB_FreeMemory(desc->data_types);
12928  }
12929 
12930  STB_FreeMemory(desc);
12931 
12932  desc = next;
12933  }
12934 
12935  FUNCTION_FINISH(STB_SIReleaseFreesatLinkageDesc);
12936 }
12937 
12938 /*!**************************************************************************
12939  * @brief Frees memory used by an SI_FREESAT_PREFIX_DESC structure
12940  * @param list - pointer to the SI_FREESAT_PREFIX_DESC
12941  ****************************************************************************/
12943 {
12944  SI_FREESAT_PREFIX_DESC *next;
12945 
12946  FUNCTION_START(STB_SIReleaseFreesatPrefixList);
12947 
12948  while (list != NULL)
12949  {
12950  next = list->next;
12951 
12952  if (list->uri_prefix != NULL)
12953  {
12954  STB_SIReleaseStringDesc(list->uri_prefix);
12955  }
12956 
12957  STB_FreeMemory(list);
12958 
12959  list = next;
12960  }
12961 
12962  FUNCTION_FINISH(STB_SIReleaseFreesatPrefixList);
12963 }
12964 
12965 /*!**************************************************************************
12966  * @brief Frees a CI+ service list
12967  * @param service_list - pointer to the start of the CI+ service list
12968  ****************************************************************************/
12970 {
12971  SI_CIPLUS_SERVICE *next_service;
12972 
12973  FUNCTION_START(STB_SIReleaseCIPlusServiceList);
12974 
12975  while (service_list != NULL)
12976  {
12977  next_service = service_list->next;
12978 
12979  if (service_list->provider_str != NULL)
12980  {
12981  STB_SIReleaseStringDesc(service_list->provider_str);
12982  }
12983 
12984  if (service_list->name_str != NULL)
12985  {
12986  STB_SIReleaseStringDesc(service_list->name_str);
12987  }
12988 
12989  STB_FreeMemory(service_list);
12990  service_list = next_service;
12991  }
12992 
12993  FUNCTION_FINISH(STB_SIReleaseCIPlusServiceList);
12994 }
12995 
13001 {
13002  SI_URI_LINKAGE_DESC *next;
13003 
13004  FUNCTION_START(STB_SIReleaseURILinkageList);
13005 
13006  while (list != NULL)
13007  {
13008  next = list->next;
13009 
13010  if (list->uri != NULL)
13011  {
13012  STB_SIReleaseStringDesc(list->uri);
13013  }
13014 
13015  if (list->private_data != NULL)
13016  {
13017  STB_FreeMemory(list->private_data);
13018  }
13019 
13020  STB_FreeMemory(list);
13021 
13022  list = next;
13023  }
13024 
13025  FUNCTION_FINISH(STB_SIReleaseURILinkageList);
13026 }
13027 
13028 /*!**************************************************************************
13029  * @brief Parses the given PMT to produce an array of the CA system IDs required
13030  * by the service or streams on the service. The array of IDs will be
13031  * allocated by this function and should be freed using STB_SIReleaseCAIds.
13032  * @param pmt_data - raw PMT section data
13033  * @param pmt_ca_ids - pointer to an array that will be allocated containing
13034  * the CA IDs found in the PMT
13035  * @return Number of CA IDs found in the PMT and returned in the array,
13036  * 0 if none are found.
13037  ****************************************************************************/
13038 U16BIT STB_SIGetPmtCaIdDescArray(U8BIT *pmt_data, U16BIT **pmt_ca_ids)
13039 {
13040  U8BIT *data_ptr;
13041  U16BIT sec_len;
13042  U8BIT *data_end;
13043  U16BIT dloop_len;
13044  U8BIT *dloop_end;
13045  U8BIT dtag;
13046  U16BIT i, num_ca_entries;
13047  SI_CA_DESC *ca_desc_array;
13048 
13049  FUNCTION_START(STB_SIGetPmtCaIdDescArray);
13050 
13051  /* Get pointer to section data and end of section */
13052  data_ptr = pmt_data;
13053  sec_len = (((data_ptr[1] & 0x0f) << 8) | data_ptr[2]) + 3;
13054  data_end = data_ptr + sec_len - 4; // -4 for crc
13055 
13056  /* Skip section header */
13057  data_ptr += 8;
13058 
13059  /* Get descriptor loop length */
13060  dloop_len = ((data_ptr[2] & 0x0f) << 8) | data_ptr[3];
13061  data_ptr += 4;
13062 
13063  num_ca_entries = 0;
13064  ca_desc_array = NULL;
13065 
13066  /* Process first descriptor loop */
13067  dloop_end = data_ptr + dloop_len;
13068  while (data_ptr < dloop_end)
13069  {
13070  dtag = data_ptr[0];
13071  data_ptr++;
13072 
13073  switch (dtag)
13074  {
13075  case CA_DTAG:
13076  {
13077  data_ptr = ParseCaDescriptor(data_ptr, &num_ca_entries, &ca_desc_array, FALSE);
13078  break;
13079  }
13080 
13081  default:
13082  {
13083  /* Skip the descriptor */
13084  data_ptr += (*data_ptr + 1);
13085  break;
13086  }
13087  }
13088  }
13089 
13090  /* Read entry for each stream */
13091  while (data_ptr < data_end)
13092  {
13093  dloop_len = ((data_ptr[3] & 0x0f) << 8) | data_ptr[4];
13094  data_ptr += 5;
13095 
13096  /* Process stream descriptor loop */
13097  dloop_end = data_ptr + dloop_len;
13098  while ((data_ptr < dloop_end) && (data_ptr < data_end))
13099  {
13100  dtag = data_ptr[0];
13101  data_ptr++;
13102 
13103  switch (dtag)
13104  {
13105  case CA_DTAG:
13106  {
13107  data_ptr = ParseCaDescriptor(data_ptr, &num_ca_entries, &ca_desc_array, FALSE);
13108  break;
13109  }
13110 
13111  default:
13112  {
13113  /* Skip the descriptor */
13114  data_ptr += (*data_ptr + 1);
13115  break;
13116  }
13117  }
13118  }
13119  }
13120 
13121  if (num_ca_entries > 0)
13122  {
13123  /* Allocate an array to just pass back the CA system IDs found */
13124  *pmt_ca_ids = (U16BIT *)STB_GetMemory(num_ca_entries * sizeof(U16BIT));
13125  if (*pmt_ca_ids != NULL)
13126  {
13127  for (i = 0; i < num_ca_entries; i++)
13128  {
13129  (*pmt_ca_ids)[i] = ca_desc_array[i].ca_id;
13130  }
13131  }
13132  else
13133  {
13134  num_ca_entries = 0;
13135  }
13136 
13137  STB_SIReleaseCaDescArray(ca_desc_array, num_ca_entries);
13138  }
13139  else
13140  {
13141  *pmt_ca_ids = NULL;
13142  }
13143 
13144  FUNCTION_FINISH(STB_SIGetPmtCaIdDescArray);
13145 
13146  return(num_ca_entries);
13147 }
13148 
13158 void* STB_SIRequestAit(U8BIT path, E_SI_REQUEST_TYPE req_type, U16BIT ait_pid,
13159  void (*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
13160 {
13161  void *filter_ptr;
13162 
13163  FUNCTION_START(STB_SIRequestAit);
13164 
13165  #ifdef DEBUG_SI_RCT_REQUEST
13166  STB_SI_PRINT(("STB_SIRequestRct: path %d pid 0x%04x", path, rct_pid));
13167  #endif
13168  filter_ptr = STB_SIRequestTable(path, ait_pid, SI_AIT_TID, 0xff, MULTI_SECT, 1,
13169  SI_XTID_MATCH_DONT_CARE, SI_XTID_MASK_DONT_CARE, req_type,
13170  SI_BUFFER_4K, TRUE, FALSE, callback, ret_param);
13171 
13172  FUNCTION_FINISH(STB_SIRequestAit);
13173 
13174  return((void *)filter_ptr);
13175 }
13176 
13177 /****************************************************************************
13178 ** End of file
13179 *****************************************************************************/
13180 
void STB_SIReleaseComponentDescArray(SI_COMPONENT_DESC *desc_array, U8BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12116
void STB_SIModifyTableRequest(void *filter_handle, U8BIT tid_match, U8BIT tid_mask, U16BIT xtid_match, U16BIT xtid_mask, U16BIT expected_tables)
modifies the section filtering on an existing filter
Definition: stbsiflt.c:2378
void * STB_SIRequestTot(U8BIT path, E_SI_REQUEST_TYPE req_type, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for TOT.
Definition: stbsitab.c:8475
void STB_SIReleasePatStreamEntry(SI_PAT_SERVICE_ENTRY *entry_ptr)
Frees the memory used by the table entry specified.
Definition: stbsitab.c:11640
void STB_SIReleaseCRIDList(SI_CRID_DESC *crid_list)
Frees the memory used by the descriptor list specified.
Definition: stbsitab.c:12856
void * STB_SIRequestNitFromPid(U8BIT path, U16BIT pid, BOOLEAN actual, E_SI_REQUEST_TYPE req_type, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Create an SI filter for an NIT table.
Definition: stbsitab.c:7899
void STB_SIReleasePmtStreamEntry(SI_PMT_STREAM_ENTRY *entry_ptr)
Frees the memory used by the table entry specified.
Definition: stbsitab.c:11660
void * STB_GetMemory(U32BIT bytes)
Attempts to allocate memory from the heap.
Definition: stbheap.c:221
void STB_SIReleaseCaIdDescArray(U16BIT *desc_array, U8BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12090
void STB_SIReleasePmtTable(SI_PMT_TABLE *pmt_table)
Frees the memory used by the pmt table.
Definition: stbsitab.c:11258
void * STB_SIRequestPmt(U8BIT path, E_SI_REQUEST_TYPE req_type, U16BIT pmt_pid, U16BIT sid_match, U16BIT sid_mask, U16BIT table_count, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for PMT.
Definition: stbsitab.c:7810
void STB_SIReleaseIsoLangDescArray(SI_ISO_LANG_DESC *desc_array, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12273
void STB_SIReleaseRctTable(SI_RCT_TABLE *rct_table)
Frees memory used by an RCT table.
Definition: stbsitab.c:11596
void STB_SIReleaseServListDescArray(SI_SERV_LIST_DESC *desc_array, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12500
Function prototypes for HW control.
void * STB_SIRequestSched(U8BIT path, E_SI_REQUEST_TYPE req_type, E_SI_SCHED_TABLE_REQ reqd_eit_tables, U16BIT sid_match, U16BIT sid_mask, U16BIT table_count, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for EIT schedule table.
Definition: stbsitab.c:8329
Definition: stbsitab.h:789
Definition: stbsitab.h:830
void STB_SIReleaseBatTable(SI_BAT_TABLE *bat_table)
Frees the memory used by the bat table.
Definition: stbsitab.c:11427
SI_EIT_TABLE * STB_SIParseEitTable(SI_TABLE_RECORD *table_rec)
Parses the Eit table supplied in TABLE_RECORD format to create a EIT_TABLE structure. Returns a pointer to the table. Application must call STB_SIReleaseEitTable to free the data.
Definition: stbsitab.c:10355
void STB_SIReleaseRctSubtableData(SI_RCT_SUBTABLE_DATA *data_ptr)
Frees memory used by an SI_RCT_SUBTABLE_DATA structure.
Definition: stbsitab.c:11943
void STB_SIReleaseURILinkageList(SI_URI_LINKAGE_DESC *list)
Frees a list of URI linkage descriptors.
Definition: stbsitab.c:13000
Header file - macros and function prototypes for public use.
void * STB_SIRequestTdt(U8BIT path, E_SI_REQUEST_TYPE req_type, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for TDT.
Definition: stbsitab.c:8408
void STB_SISetUserDefinedDescriptorFunction(U8BIT dtag, STB_SI_USER_DEF_DESCRIP_FUNCTION func)
Sets the function allocated to the user defined descriptor.
Definition: stbsitab.c:7717
void STB_SIReleaseBatTransportEntry(SI_BAT_TRANSPORT_ENTRY *entry_ptr)
Frees the memory used by the table entry specified.
Definition: stbsitab.c:11767
void * STB_SIRequestNitWithId(U8BIT path, U16BIT network_id, E_SI_REQUEST_TYPE req_type, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for NITactual and NITother for the given network ID.
Definition: stbsitab.c:7938
void STB_SIReleaseSubtitleDescArray(SI_SUBTITLE_DESC *desc_array, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12606
void STB_SIReleaseDelSysDesc(SI_DELIVERY_SYS_DESC *desc, SI_DELIVERY_SYS_DESC_TYPE type)
Frees the memory used by the descriptor specified.
Definition: stbsitab.c:11989
void STB_SIReleaseLinkageDescList(SI_LINKAGE_DESC_ENTRY *list_ptr, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12298
void STB_SIReleaseLcnDescArray(SI_LCN_DESC *desc_array, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12766
void STB_SIReleaseShortEventDescArray(SI_SHORT_EVENT_DESC *desc_array, U8BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12525
void STB_SIReleaseMultilingNetNameDescArray(SI_MULTILING_NET_NAME_DESC *desc_array, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12387
void STB_SISetCiplusPrivateDataSpecifierMode(BOOLEAN mode)
Enables or disables use of the CI+ private data specifier when parsing SI tables. ...
Definition: stbsitab.c:7657
Definition: stbsitab.h:732
SI_NIT_TABLE * STB_SIParseNitTable(SI_TABLE_RECORD *table_rec)
Parses the Nit table supplied in TABLE_RECORD format to create a NIT_TABLE structure. Returns a pointer to the table. Application must call STB_SIReleaseNitTable to free the data.
Definition: stbsitab.c:9155
void STB_SIReleaseNordigLcn2DescArray(SI_NORDIG_LCN_DESC *desc_array, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12791
void STB_SIReleaseMultilingComponentDescArray(SI_MULTILING_COMPONENT_DESC *desc_array, U8BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12354
void STB_SIReleaseTeletextDescArray(SI_TELETEXT_DESC *desc_array, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12741
void * STB_SIRequestPat(U8BIT path, E_SI_REQUEST_TYPE req_type, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for PAT.
Definition: stbsitab.c:7773
void STB_SIReleaseRctLinkInfo(SI_RCT_LINK_INFO *link_info)
Frees memory used by an SI_RCT_LINK_INFO structure.
Definition: stbsitab.c:12877
void * STB_SIRequestEitFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type, E_SI_EIT_TABLE_REQ reqd_eit_tables, U16BIT sid_match, U16BIT sid_mask, U16BIT table_count, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for EIT.
Definition: stbsitab.c:8256
void * STB_ResizeMemory(void *ptr, U32BIT new_num_bytes)
Re-allocates a given memory area to the new size, ensuring data contained within the original memory ...
Definition: stbheap.c:550
void * STB_SIRequestCat(U8BIT path, E_SI_REQUEST_TYPE req_type, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for CAT.
Definition: stbsitab.c:8541
Definition: stbsitab.h:560
void STB_SIReleaseTargetRegionList(SI_TARGET_REGION_DESC *desc_list)
Frees the memory used by the descriptor list specified.
Definition: stbsitab.c:12669
void STB_SISetNordigPrivateDataSpecifierMode(BOOLEAN mode)
Enables or disables use of the Nordig private data specifier when parsing SI tables.
Definition: stbsitab.c:7696
SI_PMT_TABLE * STB_SIParsePmtTable(SI_TABLE_RECORD *table_rec)
Parses the Pmt table supplied in TABLE_RECORD format to create a PMT_TABLE structure. Returns a pointer to the table. Application must call STB_SIReleasePmtTable to free the data.
Definition: stbsitab.c:8738
void STB_SIReleasePrefNameDescArray(SI_PREFERRED_NAME_DESC *desc_array, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12826
void STB_SIReleaseFreqListDescArray(SI_NIT_FREQUENCY_LIST_DESC *freq_list)
Frees the memory used by the frequency list descriptor.
Definition: stbsitab.c:12163
BOOLEAN STB_SIParseServiceDescriptor(U8BIT *data, U8BIT *type, SI_STRING_DESC **provider, SI_STRING_DESC **name)
Parses a service descriptor, tag 0x48, allocating SI strings that must be freed using STB_SIReleaseSt...
Definition: stbsitab.c:11148
void STB_SIReleaseStringDesc(SI_STRING_DESC *desc)
Frees the memory used by the descriptor specified.
Definition: stbsitab.c:12040
void STB_SIReleaseTimeTable(SI_TIME_TABLE *time_table)
Frees the memory used by the time table (tdt or tot)
Definition: stbsitab.c:11576
void * STB_SIRequestEit(U8BIT path, E_SI_REQUEST_TYPE req_type, E_SI_EIT_TABLE_REQ reqd_eit_tables, U16BIT sid_match, U16BIT sid_mask, U16BIT table_count, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for EIT.
Definition: stbsitab.c:8214
void STB_SIReleaseExtendedEventDescArray(SI_EXTENDED_EVENT_DESC *desc_array, U8BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12558
SI_SDT_TABLE * STB_SIParseSdtTable(SI_TABLE_RECORD *table_rec)
Parses the Sdt table supplied in TABLE_RECORD format to create a SDT_TABLE structure. Returns a pointer to the table. Application must call STB_SIReleaseSdtTable to free the data.
Definition: stbsitab.c:9623
void STB_SIReleaseCIPlusServiceList(SI_CIPLUS_SERVICE *service_list)
Frees a CI+ service list.
Definition: stbsitab.c:12969
Definition: stbsitab.h:612
void STB_FreeMemory(void *addr)
Releases previously allocated heap memory.
Definition: stbheap.c:336
void STB_SISetEacemPrivateDataSpecifierMode(BOOLEAN mode)
Enables or disables use of the EACEM private data specifier when parsing SI tables.
Definition: stbsitab.c:7670
Definition: stbsitab.h:947
void STB_SIReleaseEitTable(SI_EIT_TABLE *eit_table)
Frees the memory used by the eit table.
Definition: stbsitab.c:11539
SI_RCT_TABLE * STB_SIParseRctTable(SI_TABLE_RECORD *table_rec)
Parses the related content table (RCT) to create an SI_RCT_TABLE structure.
Definition: stbsitab.c:10720
void STB_SPDebugWrite(const char *format,...)
Write debug string to serial/debug port. <CR><LF> characters will be automatically added to the end o...
Debug functions header file.
Header file - macros and function prototypes for public use.
void STB_SIReleaseSdtTable(SI_SDT_TABLE *sdt_table)
Frees the memory used by the sdt table.
Definition: stbsitab.c:11391
SI_PAT_TABLE * STB_SIParsePatTable(SI_TABLE_RECORD *table_rec)
Parses the Pat table supplied in TABLE_RECORD format to create a PAT_TABLE structure. Returns a pointer to the table. Application must call STB_SIReleasePatTable to free the data.
Definition: stbsitab.c:8611
void STB_SIReleaseLtoDescArray(SI_LTO_DESC *desc_array, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12329
SI_BAT_TABLE * STB_SIParseBatTable(SI_TABLE_RECORD *table_rec)
Parses the BAT table supplied in TABLE_RECORD format to create a SI_BAT_TABLE structure. Returns a pointer to the table. Application must call STB_SIReleaseBatTable to free the data.
Definition: stbsitab.c:9969
void STB_SIReleaseMultilingServNameDescArray(SI_MULTILING_SERV_NAME_DESC *desc_array, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12420
BOOLEAN STB_SIParseShortEventDescriptor(U8BIT *data, SI_SHORT_EVENT_DESC **event_desc)
Parses a short event descriptor, tag 0x4d, that must be released by calling STB_SIReleaseShortEventDe...
Definition: stbsitab.c:11180
void STB_SIReleaseAvailabilityDescriptorList(SI_SERV_AVAIL_DESC *desc_list)
Frees the memory used by the descriptor list specified.
Definition: stbsitab.c:12706
Header for STB unicode string handling routines.
void STB_SIReleaseEitEventEntry(SI_EIT_EVENT_ENTRY *entry_ptr)
Frees the memory used by the table entry specified.
Definition: stbsitab.c:11882
U16BIT STB_SIGetPmtCaIdDescArray(U8BIT *pmt_data, U16BIT **pmt_ca_ids)
Parses the given PMT to produce an array of the CA system IDs required by the service or streams on t...
Definition: stbsitab.c:13038
void STB_SIReleaseCaDescArray(SI_CA_DESC *desc_array, U16BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12064
void STB_SIReleaseRctSubtable(SI_RCT_SUBTABLE *sub_ptr)
Frees memory used by an RCT subtable.
Definition: stbsitab.c:11916
void STB_SIModifyPmtRequest(void *fhandle, U16BIT sid_match, U16BIT sid_mask, U16BIT table_count)
Modifies request for PMT to look for different service on SAME PID.
Definition: stbsitab.c:7844
Definition: stbsitab.h:358
System Wide Global Technical Data Type Definitions.
Definition: stbsitab.h:821
void * STB_SIRequestTotFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for TOT.
Definition: stbsitab.c:8508
void STB_SIReleaseBatLcnEntry(SI_BAT_FREESAT_REGION_LCN_ENTRY *entry_ptr)
Frees the memory used by the table entry specified.
Definition: stbsitab.c:11802
void STB_SIClearUserDefinedDescriptorFunctions(void)
Clear all entries in the user defined SI descriptor table.
Definition: stbsitab.c:7745
BOOLEAN STB_SIParseDelSysDesc(U8BIT *data, SI_DELIVERY_SYS_DESC_TYPE *type, SI_DELIVERY_SYS_DESC **desc)
Parses and allocates a system delivery descriptor which should be freed by calling STB_SIReleaseDelSy...
Definition: stbsitab.c:11071
void * STB_SIRequestNit(U8BIT path, E_SI_REQUEST_TYPE req_type, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for NIT(actual)
Definition: stbsitab.c:7870
void * STB_SIRequestBat(U8BIT path, E_SI_REQUEST_TYPE req_type, U16BIT bouquet_id_match, U16BIT bouquet_id_mask, U16BIT table_count, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for Bat.
Definition: stbsitab.c:8133
void STB_SIModifySdtRequest(void *fhandle, BOOLEAN inc_sdt_actual, BOOLEAN inc_sdt_other, U16BIT tran_id_match, U16BIT tran_id_mask, U16BIT table_count)
Modifies request for SDT to look for different transport on SAME PID.
Definition: stbsitab.c:8086
SI_TIME_TABLE * STB_SIParseTimeTable(SI_TABLE_RECORD *table_rec)
Parses the tdt or tot table supplied in TABLE_RECORD format to create a TIME_TABLE structure...
Definition: stbsitab.c:10631
void STB_SIReleaseFreesatPrefixList(SI_FREESAT_PREFIX_DESC *list)
Frees memory used by an SI_FREESAT_PREFIX_DESC structure.
Definition: stbsitab.c:12942
void STB_SIReleaseFreesatLinkageDesc(SI_FREESAT_LINKAGE_DESC *desc)
Frees memory used by an SI_FREESAT_LINKAGE_DESC structure.
Definition: stbsitab.c:12915
void STB_SIReleaseContentDescArray(SI_CONTENT_DESC *desc_array, U8BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12146
Definition: stbsitab.h:237
void STB_SIReleasePatTable(SI_PAT_TABLE *pat_table)
Frees the memory used by the pat table.
Definition: stbsitab.c:11222
void * STB_SIRequestTable(U8BIT path, U16BIT pid, U8BIT tid_match, U8BIT tid_mask, E_SI_TABLE_FORMAT_TYPE format, U16BIT expected_tables, U16BIT xtid_match, U16BIT xtid_mask, E_SI_REQUEST_TYPE req_type, U16BIT buff_size, BOOLEAN crc, BOOLEAN low_priority, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Sets up filter for SI table.
Definition: stbsiflt.c:2297
void STB_SIModifyEitRequest(void *fhandle, E_SI_EIT_TABLE_REQ reqd_eit_tables, U16BIT sid_match, U16BIT sid_mask, U16BIT table_count)
Modifies request for SDT to look for different transport on SAME PID.
Definition: stbsitab.c:8294
Header file - Function prototypes for heap memory.
void STB_SIReleaseNitTransportEntry(SI_NIT_TRANSPORT_ENTRY *entry_ptr)
Frees the memory used by the table entry specified.
Definition: stbsitab.c:11725
void STB_SISetCountryPrivateDataSpecifier(U32BIT code)
Sets the country specific private data specifier code that will be used when parsing SI tables...
Definition: stbsitab.c:7630
void STB_SIReleaseNitTable(SI_NIT_TABLE *nit_table)
Frees the memory used by the nit table.
Definition: stbsitab.c:11299
void STB_SPDebugNoCnWrite(const char *format,...)
Writes debug string to the serial port without <CR><LF>
void STB_SIReleaseSdtServiceEntry(SI_SDT_SERVICE_ENTRY *entry_ptr)
Frees the memory used by the table entry specified.
Definition: stbsitab.c:11833
Definition: stbsitab.h:638
void STB_SIReleaseParentalRatingDescArray(SI_PARENTAL_RATING_DESC *desc_array, U8BIT num_entries)
Frees the memory used by the descriptor array specified.
Definition: stbsitab.c:12475
void STB_SISetNZSatPrivateDataSpecifierMode(BOOLEAN mode)
Enables or disables use of the New Zealand satellite private data specifier when parsing SI tables...
Definition: stbsitab.c:7683
void STB_SISetFreesatPrivateDataSpecifierMode(BOOLEAN mode)
Enables or disables use of the Freesat private data specifier when parsing SI tables.
Definition: stbsitab.c:7644
void * STB_SIRequestTdtFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for TDT.
Definition: stbsitab.c:8442
void * STB_SIRequestBatFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type, U16BIT bouquet_id_match, U16BIT bouquet_id_mask, U16BIT table_count, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for Bat.
Definition: stbsitab.c:8172
void * STB_SIRequestSdt(U8BIT path, E_SI_REQUEST_TYPE req_type, BOOLEAN inc_sdt_actual, BOOLEAN inc_sdt_other, U16BIT tran_id_match, U16BIT tran_id_mask, U16BIT table_count, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for SDT.
Definition: stbsitab.c:7976
void * STB_SIRequestAit(U8BIT path, E_SI_REQUEST_TYPE req_type, U16BIT ait_pid, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for AIT on given PID.
Definition: stbsitab.c:13158
Definition: stbds.h:126
Definition: stbsitab.h:799
void * STB_SIRequestRct(U8BIT path, E_SI_REQUEST_TYPE req_type, U16BIT rct_pid, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for RCT on given PID.
Definition: stbsitab.c:8575
void STB_SIReleaseTargetRegionNameList(SI_NIT_TARGET_REGION_NAME_DESC *desc_list)
Frees the memory used by the descriptor list specified.
Definition: stbsitab.c:12630
void STB_SIReleaseGuidanceDesc(SI_GUIDANCE_DESC *desc_ptr)
Frees the memory used by the descriptor specified.
Definition: stbsitab.c:12197
void * STB_SIRequestSdtFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type, BOOLEAN inc_sdt_actual, BOOLEAN inc_sdt_other, U16BIT tran_id_match, U16BIT tran_id_mask, U16BIT table_count, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for SDT.
Definition: stbsitab.c:8033
void * STB_SIRequestSchedFromPid(U8BIT path, U16BIT pid, E_SI_REQUEST_TYPE req_type, E_SI_SCHED_TABLE_REQ reqd_eit_tables, U16BIT sid_match, U16BIT sid_mask, U16BIT table_count, void(*callback)(void *, U32BIT, SI_TABLE_RECORD *), U32BIT ret_param)
Generates request for EIT schedule table.
Definition: stbsitab.c:8371
void STB_SIReleaseImageIconDescArray(SI_IMAGE_ICON_DESC *icon_array, U8BIT num_icons)
Frees an array of image icons, including the memory used by each one.
Definition: stbsitab.c:12234
U8BIT * STB_SIReadString(U8BIT nbytes, U8BIT *dptr, SI_STRING_DESC **str_ptr)
Copies a string from a descriptor for the specified length. Converts the number of bytes specified in...
Definition: stbsitab.c:10947
Header file - macros and function prototypes for public use.