DSMCC  17.9.0
 All Data Structures Files Functions Typedefs
clDsmMain.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  * Copyright © 2001 Koninklijke Philips Electronics N.V
5  *
6  * This file is part of a DTVKit Software Component
7  * You are permitted to copy, modify or distribute this file subject to the terms
8  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
9  *
10  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
11  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
12  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * If you or your organisation is not a member of DTVKit then you have access
15  * to this source code outside of the terms of the licence agreement
16  * and you are expected to delete this and any associated files immediately.
17  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
18  *******************************************************************************/
28 /*---includes for this file--------------------------------------------------*/
29 #include "cldsmcc.h"
30 #include "clDsmSystem.h"
31 #include "clDsmUtils.h"
32 #include "linkList.h"
33 #include "sectionFilter.h"
34 #include "dsmObject.h"
35 #include "module.h"
36 #include "dataCarousel.h"
37 #include "objectCarousel.h"
38 #include "updateCarousel.h"
39 #include "moduleDecompress.h"
40 #include "loadMgr.h"
41 #include "siQuery.h"
42 #include "cacheMgr.h"
43 
44 #include "defMemUtilsContig.h" /* -- Default mem type for module */
45 #include "pmtUpdate.h"
46 #include "streamEvent.h"
47 
48 #if (!defined(NDEBUG) && !defined(NO_DP))
49 #include <stdio.h> /* -- For debug prints etc. */
50 #endif
51 
52 /*------------------------------- Local Macros -------------------------------*/
53 
54 /* Slightly more debug info for processDSI if debug level >=3 */
55 /*#define DEBUG_PROCESS_DSI*/
56 #define DSI_MSG_ID 0x1006
57 #define DII_MSG_ID 0x1002
58 #define DDB_MSG_ID 0x1003
59 
60 /*------------------------------ Exported Data -----------------------------*/
61 #if (!defined(NDEBUG) && !defined(NO_DP))
62 F_Printf DBG_ErrorPrintfFunc = NULL;
63 F_Printf DBG_WarnPrintfFunc = NULL;
64 F_Printf DBG_DebugPrintfFunc = NULL;
65 F_Printf DBG_InfoPrintfFunc = NULL;
66 U32BIT dsmDbgState = 0;
67 #endif
68 
69 /*--------------------------------Local Types --------------------------------*/
70 
71 typedef struct _accelerate_carousel_loading_struct
72 {
73  U16BIT storeWritePos;
74  U16BIT storeReadPos;
75  U16BIT storedSectionsNB;
76  U16BIT SectionsReinjection;
77  BOOLEAN bLargeDDBFilterSet;
78  U16BIT requestedModidPos;
79  P_SecFilterInfo largeDDBFilter;
80 } accelerateCarouselLoading_t;
81 
82 accelerateCarouselLoading_t accCarouselLoadingInfos;
83 
84 /*------------------------------- Local Statics ------------------------------*/
85 
86 #ifdef ACCELERATE_CAROUSEL_LOADING
87 
88 
89 
90 #define kMAX_PRESTORED_SECTIONS 100
91 
92 #define kMAX_SECTION_SIZE 5000
93 
94 typedef struct
95 {
96  U8BIT sectionSize;
97  U16BIT moduleID;
98  U16BIT blockNum;
99  U8BIT injectionDone;
100  U8BIT moduleVersion;
101  U8BIT section[kMAX_SECTION_SIZE];
102 } tPrestoredSection;
103 
104 tPrestoredSection *prestoredSectionsTable = NULL;
105 
106 
107 #define kMAX_MODULE_ID 0xFFFF
108 #define kNOT_REQUESTED 0
109 #define kDO_INJECT 1
110 U8BIT *requestedModuleIDList = NULL;
111 
112 U16BIT GBL_NewResquetedModuleID = 0;
113 
114 #endif /* ACCELERATE_CAROUSEL_LOADING */
115 
116 /*------------------- Local prototypes/forward declarations ------------------*/
117 
118 static E_DscError processDSI( P_DsmCoreInst idp,
119  /*I*/ U8BIT *pDSISection, P_SecFilterInfo pFilterInfo );
120 
121 static E_DscError processDII( P_DsmCoreInst idp,
122  /*I*/ U8BIT *pDIISection, P_SecFilterInfo pFilterInfo );
123 
124 static E_DscError processDDB( P_DsmCoreInst idp,
125  /*I*/ U8BIT *pDDBSection, P_SecFilterInfo pFilterInfo );
126 
127 #ifdef ACCELERATE_CAROUSEL_LOADING
128 
129 static E_DscError storeSection( P_DsmCoreInst idp,
130  U8BIT *pDDBSection);
131 static E_DscError injectStoredSections( P_DsmCoreInst idp);
132 
133 E_DscError requestedModuleIdSet(U16BIT moduleID);
134 
135 E_DscError requestedModuleIdReset(U16BIT moduleID);
136 
137 #endif /* ACCELERATE_CAROUSEL_LOADING */
138 
139 /*---------------------------- Exported Functions ----------------------------*/
140 
141 /**************************************/
142 /* -- Main (synchronous) API Calls -- */
143 /**************************************/
144 
145 void CDSM_SetPrintFuncs( F_Printf errorFunc, F_Printf warnFunc,
146  F_Printf debugFunc, F_Printf infoFunc )
147 {
148 #if (!defined(NDEBUG) && !defined(NO_DP))
149  DBG_ErrorPrintfFunc = errorFunc;
150  DBG_WarnPrintfFunc = warnFunc;
151  DBG_DebugPrintfFunc = debugFunc;
152  DBG_InfoPrintfFunc = infoFunc;
153 #endif
154 }
155 
156 void CDSM_SetPrintState( U32BIT state )
157 {
158 #if (!defined(NDEBUG) && !defined(NO_DP))
159  dsmDbgState = state;
160 #endif
161 }
162 
169 void CDSM_SetDebugState( H_DsmCoreInst dsm, U32BIT dbgMask )
170 {
171 #ifndef NDEBUG
172  dsm->dbgMask = (U16BIT)dbgMask;
173 #endif
174 }
175 
176 /*
177 -- API CALLS INITIATED IN RESPONSE TO SYSTEM EVENTS
178 */
179 
180 /*
181 -- Create DSM-CC Core Layer instance
182 */
183 E_DscError CDSM_SysCreate(
184  /*I*/ P_DsmSetup pSetup,
185  /*O*/ H_DsmCoreInst *pInstance, void **pMemContext )
186 {
187  P_DsmCoreInst idp = NULL;
188  E_DscError err = CLDSM_OK;
189  E_DsmMemErr memErr = MEM_ERR_ALLOC_FAILED;
190  U32BIT sfHeapSize;
191 
192  dsmDP1(("CDSM_SysCreate( %p, %p, %p )\n", pSetup, pInstance, pMemContext));
193 
194 
195  /* -- memory size & usage info prints/checks */
196  dsmDP3(("\n-----------------------------------------\n"));
197  dsmDP3(("DEBUG CHECKS ON MEMORY SIZES (bytes):\n\n"));
198  dsmDP3(("INFO: LinkList Ctrl block size = %u\n", sizeof(S_LLControl)));
199  dsmAssert((sizeof(S_LLControl) <= MIN_MEM_BLK_SIZE));
200  dsmDP3(("INFO: Object Carousel size = %u\n", sizeof(S_ObjectCarousel)));
201  dsmAssert((sizeof(S_ObjectCarousel) <= MIN_MEM_BLK_SIZE));
202  dsmDP3(("INFO: Data Carousel size = %u\n", sizeof(S_DataCarousel)));
203  dsmAssert((sizeof(S_DataCarousel) <= MIN_MEM_BLK_SIZE));
204  dsmDP3(("INFO: Module size = %u\n", sizeof(S_Module)));
205  dsmAssert((sizeof(S_Module) <= MIN_MEM_BLK_SIZE));
206  dsmDP3(("INFO: Module builder size = %u\n", sizeof(S_ModuleBuilder)));
207  dsmAssert((sizeof(S_ModuleBuilder) <= MIN_MEM_BLK_SIZE));
208  dsmDP3(("INFO: LoadRequest size = %u\n", sizeof(S_LoadRequest)));
209  dsmAssert((sizeof(S_LoadRequest) <= MIN_MEM_BLK_SIZE));
210  dsmDP3(("INFO: DSM Object size = %u\n", sizeof(S_DsmObject)));
211  dsmAssert((sizeof(S_DsmObject) <= MIN_MEM_BLK_SIZE));
212  dsmDP3(("INFO: Max pathname size = %u\n", MAX_PATH_NAME_SIZE));
213  dsmAssert((MAX_PATH_NAME_SIZE <= MIN_MEM_BLK_SIZE));
214 
215  dsmDP3(("INFO: Section filter size = %u\n", sizeof(S_SecFilterInfo)));
216  dsmDP3(("-----------------------------------------\n"));
217 
218  dsmDP3(("\nINFO: Core Instance data size (including zlib heap) = %u bytes\n",
219  sizeof(clDsmInstData_t)));
220 
221  *pInstance = NULL;
222  *pMemContext = NULL;
223 
224  API_PARAM_CHK( pInstance, dsmDP1(("ERROR: Illegal parameter\n")),
225  err = CLDSM_ERR_ILLEGAL_PARAMETER; goto _return );
226  API_PARAM_CHK( pMemContext, dsmDP1(("ERROR: Illegal parameter\n")),
227  err = CLDSM_ERR_ILLEGAL_PARAMETER; goto _return );
228  API_PARAM_CHK( pSetup, dsmDP1(("ERROR: Illegal setup\n")),
229  err = CLDSM_ERR_ILLEGAL_SETUP; goto _return );
230  API_PARAM_CHK( pSetup->allocFunc, dsmDP1(("ERROR: Illegal setup\n")),
231  err = CLDSM_ERR_ILLEGAL_SETUP; goto _return );
232  API_PARAM_CHK( pSetup->freeFunc, dsmDP1(("ERROR: Illegal setup\n")),
233  err = CLDSM_ERR_ILLEGAL_SETUP; goto _return );
234  /* API_PARAM_CHK( pSetup->errorFunc, dsmDP1(("ERROR: Illegal setup\n")),
235  err = CLDSM_ERR_ILLEGAL_SETUP; goto _return ); */
236  API_PARAM_CHK( pSetup->addSectionFilterFunc, dsmDP1(("ERROR: Illegal setup\n")),
237  err = CLDSM_ERR_ILLEGAL_SETUP; goto _return );
238  API_PARAM_CHK( pSetup->delSectionFilterFunc, dsmDP1(("ERROR: Illegal setup\n")),
239  err = CLDSM_ERR_ILLEGAL_SETUP; goto _return );
240  API_PARAM_CHK( pSetup->startSIQueryFunc, dsmDP1(("ERROR: Illegal setup\n")),
241  err = CLDSM_ERR_ILLEGAL_SETUP; goto _return );
242  API_PARAM_CHK( pSetup->stopSIQueryFunc, dsmDP1(("ERROR: Illegal setup\n")),
243  err = CLDSM_ERR_ILLEGAL_SETUP; goto _return );
244  API_PARAM_CHK( pSetup->startTimerFunc, dsmDP1(("ERROR: Illegal setup\n")),
245  err = CLDSM_ERR_ILLEGAL_SETUP; goto _return );
246  API_PARAM_CHK( pSetup->stopTimerFunc, dsmDP1(("ERROR: Illegal setup\n")),
247  err = CLDSM_ERR_ILLEGAL_SETUP; goto _return );
248 
249  /* TODO: error check other setup parameters */
250 
251  /* -- Allocate instance memory */
252  idp = pSetup->allocFunc(sizeof(S_DsmCoreInst));
253 
254  if (!idp)
255  {
256  dsmDP1(("ERROR: Unable to allocate instance memory\n"));
257  err = CLDSM_ERR_ALLOC_FAILED;
258  goto _return;
259  }
260 
261  /* -- Make copy of setup info */
262  idp->setup = *pSetup;
263 
264 
265  /* -- Initialise recursion depth counters */
266  idp->pfdlfCallDepth = 0;
267  idp->pfrdoCallDepth = 0;
268  idp->pfsdndCallDepth = 0;
269 
270 
271  /* -- Check SI query result store and turbo-caching are only active
272  -- if explicitly enabled */
273  if (idp->setup.storeSIQueryResults != TRUE)
274  {
275  idp->setup.storeSIQueryResults = FALSE;
276  }
277 
278  if (idp->setup.turboCaching != TRUE)
279  {
280  idp->setup.turboCaching = FALSE;
281  }
282 
283  /* -- Initialise instance data */
284 
285  /* -- Initialise list handles */
286  idp->llcRootCarousels = NULL;
287  idp->llcLoadedModules = NULL;
288  idp->llcModulePriority = NULL;
289  idp->llcExpiredModules = NULL;
290  idp->llcCurrLoadRequests = NULL;
291  idp->llcCurrSiQueries = NULL;
292 
293  idp->hSubscribedEventList = NULL;
294 
295  /* -- Initialise current service info */
296  idp->dvbLocator.service_id = 0;
297  idp->currentServiceSet = FALSE;
298  idp->cacheFull = FALSE;
299 
300 
301  /* Initialise the stale generation counter for siQueries and Sections */
302  idp->generation.ptr = NULL;
303 
304  /* Initialise cache memory usage */
305  idp->cacheMemoryUsage = 0;
306  idp->cacheMaximumUsage = 0;
307 
308  /* -- NULL booting carousel reference */
309  idp->pBootingCarousel = NULL;
310  idp->pCurrentCarousel = NULL;
311 
312  /* -- Initialise SI query result store */
313  idp->lastPIDResultStored = FALSE;
314  idp->lastServiceId = 0;
315  idp->lastAssociationTag = 0;
316  idp->lastPID = 0;
317 
318  /* -- Set number of open objects to 0 */
319  idp->dsmObjectsOpen = 0;
320 
321  if (pSetup->maxAvailableSectionFilters == 0 ||
322  pSetup->maxAvailableSectionFilters > NUM_SECTION_FILTERS_MAXIMUM)
323  {
324  sfHeapSize = NUM_SECTION_FILTERS_MAXIMUM;
325  }
326  else if (pSetup->maxAvailableSectionFilters < NUM_SECTION_FILTERS_MINIMUM)
327  {
328  sfHeapSize = NUM_SECTION_FILTERS_MINIMUM;
329  }
330  else
331  {
332  sfHeapSize = pSetup->maxAvailableSectionFilters;
333  }
334 
335  if (pSetup->maxMemorySize < DSMCC_MINIMUM_CACHE_SIZE)
336  {
337  dsmDP2(("WARN: setting cache size to minimum %d\n", DSMCC_MINIMUM_CACHE_SIZE));
338  pSetup->maxMemorySize = DSMCC_MINIMUM_CACHE_SIZE;
339  }
340 
341  /* -- Create and initialise section filter heap memory */
342  idp->sectionFilterHeap = NULL;
343  err = DSC_SsectionFilterHeapCreate( idp, &idp->sectionFilterHeap, &sfHeapSize );
344 
345  if (err)
346  {
347  dsmDP1(("ERROR: Unable to create section filter heap\n"));
348  idp->sectionFilterHeap = NULL;
349  goto _return;
350  }
351 
352  /* -- Initialise zlib heap (module decompress) memory */
353  moduleDecompressInit( idp );
354 
355  memErr =
356  memStart( MIN_MEM_BLK_SIZE, pSetup->maxMemorySize - (sizeof(S_DsmCoreInst) + sfHeapSize),
357  (NUM_INTERNAL_MEM_SEQ_MAX + NUM_OPEN_DSM_OBJECTS_MAX),
358  idp->setup.memMgrSetup,
359  &idp->memContext );
360 
361  if (memErr != MEM_NO_ERR)
362  {
363  dsmDP1(("ERROR: Unable to start memory manager\n"));
364  err = CLDSM_ERR_MEMMGR_START_PROBLEM;
365  idp->memContext = NULL;
366  goto _return;
367  }
368 
369 #ifdef ACCELERATE_CAROUSEL_LOADING
370  prestoredSectionsTable =
371  (tPrestoredSection *)pSetup->allocFunc( sizeof(tPrestoredSection) * kMAX_PRESTORED_SECTIONS );
372 
373  accCarouselLoadingInfos.bLargeDDBFilterSet = FALSE;
374  accCarouselLoadingInfos.largeDDBFilter = NULL;
375 
376  requestedModuleIDList =
377  (U8BIT *)pSetup->allocFunc(kMAX_MODULE_ID + 1);
378 #endif
379 
380  /* -- Create default lists etc. */
381  err = LLCreate( idp, NULL, ROOT_CAROUSEL_LIST,
382  &idp->llcRootCarousels );
383  if (err)
384  goto _return; /* EXIT */
385 
386  err = LLCreate( idp, NULL, MODULE_LOADED_LIST,
387  &idp->llcLoadedModules );
388  if (err)
389  goto _return; /* EXIT */
390 
391  err = LLCreate( idp, NULL, MODULE_PRIORITY_LIST,
392  &idp->llcModulePriority );
393  if (err)
394  goto _return; /* EXIT */
395 
396  err = LLCreate( idp, NULL, MODULE_DELETE_LIST,
397  &idp->llcExpiredModules );
398  if (err)
399  goto _return; /* EXIT */
400 
401  err = LLCreate( idp, NULL, CURR_LOAD_REQUEST_LIST,
402  &idp->llcCurrLoadRequests );
403  if (err)
404  goto _return; /* EXIT */
405 
406  err = LLCreate( idp, NULL, CURR_SI_QUERY_LIST,
407  &idp->llcCurrSiQueries );
408  if (err)
409  goto _return; /* EXIT */
410 
411  *pMemContext = idp->memContext;
412  *pInstance = idp;
413 
414 _return:
415  if (idp)
416  {
417  if (err)
418  {
419  /* -- Destroy any allocated memory */
420  if (idp->llcRootCarousels)
421  {
422  LLDestroy( idp, &idp->llcRootCarousels );
423  }
424  if (idp->llcLoadedModules)
425  {
426  LLDestroy( idp, &idp->llcLoadedModules );
427  }
428  if (idp->llcModulePriority)
429  {
430  LLDestroy( idp, &idp->llcModulePriority );
431  }
432  if (idp->llcExpiredModules)
433  {
434  LLDestroy( idp, &idp->llcExpiredModules );
435  }
436  if (idp->llcCurrLoadRequests)
437  {
438  LLDestroy( idp, &idp->llcCurrLoadRequests);
439  }
440  if (idp->llcCurrSiQueries)
441  {
442  LLDestroy( idp, &idp->llcCurrSiQueries );
443  }
444 
445  if (memErr == MEM_NO_ERR)
446  {
447  memStop( MEM_CONTEXT );
448  }
449  if (idp->sectionFilterHeap)
450  {
451  idp->setup.freeFunc( idp->sectionFilterHeap );
452  }
453  idp->setup.freeFunc( idp );
454  }
455  }
456 
457  DEBUG_CHK( err == CLDSM_OK,
458  dsmDP1(("ERROR: clDsmSysCreate: %u\n", err)));
459  dsmDP1(("exit clDsmSysCreate -> rtn: %u, o/p: %p, %p \n",
460  err, *pInstance, *pMemContext));
461  return err;
462 }
463 
464 /*
465 -- Destroy DSM-CC Core Layer instance
466 */
467 E_DscError CDSM_SysDestroy( H_DsmCoreInst instance,
468  H_SiqInstance *pSiqInst, H_SfmInstance *pSfmInst )
469 {
470  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
471  E_DscError err = CLDSM_OK;
472  E_DsmMemErr memErr = MEM_NO_ERR;
473 
474  dsmDP2(("CDSM_SysDestroy( %p )\n", instance));
475 
476  API_PARAM_CHK( instance, dsmDP1(("ERROR: Invalid instance\n")),
477  err = CLDSM_ERR_INVALID_INSTANCE; goto _return );
478 
479  /* -- Current service setting is only reset after clDsmSysCreate or after a
480  -- successful clDsmSysReset call */
481  if (idp->currentServiceSet)
482  {
483  err = CLDSM_ERR_INSTANCE_NOT_RESET;
484  }
485  else
486  {
487  /* -- Only safe to do these if instance is reset */
488  LLDestroy( idp, &idp->llcRootCarousels );
489  LLDestroy( idp, &idp->llcLoadedModules );
490  LLDestroy( idp, &idp->llcModulePriority );
491  LLDestroy( idp, &idp->llcExpiredModules );
492  LLDestroy( idp, &idp->llcCurrLoadRequests );
493  LLDestroy( idp, &idp->llcCurrSiQueries );
494  }
495 
496  /* -- Free section filter heap memory */
497  dsmAssert((idp->sectionFilterHeap != NULL));
498  idp->setup.freeFunc( idp->sectionFilterHeap );
499 
500 #ifdef ACCELERATE_CAROUSEL_LOADING
501  idp->setup.freeFunc((tPrestoredSection *)prestoredSectionsTable );
502  idp->setup.freeFunc((U8BIT *)requestedModuleIDList );
503 #endif
504 
505  /* -- Always stop memory manager regardless of any error conditions
506  -- NB. memStop will return an error if there are any allocated
507  -- memory objects but it still frees it's memory heap */
508  memErr = memStop( MEM_CONTEXT );
509 
510  if ((!err) && memErr)
511  {
512  err = CLDSM_ERR_MEMMGR_STOP_PROBLEM;
513  }
514  *pSiqInst = idp->setup.siqInstance;
515  *pSfmInst = idp->setup.sfmInstance;
516 
517  idp->setup.freeFunc( idp );
518 
519  goto _return; /* -- Prevents compiler warnings when no API checking */
520 _return:
521  DEBUG_CHK( err == CLDSM_OK,
522  dsmDP1(("ERROR: clDsmSysDestroy: %u\n", err)));
523  dsmDP2(("exit clDsmSysDestroy -> rtn: %u \n", err));
524  return err;
525 }
526 
532 H_DsmControl CDSM_SysGetControl( H_DsmCoreInst instance )
533 {
534  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
535  return idp->setup.dsmControl;
536 }
537 
538 E_DscError CDSM_UnloadAllCarousels( P_DsmCoreInst idp, U8BIT mode )
539 {
540  H_DsmCarousel hOC;
541  E_DscError intErr = CLDSM_OK;
542 
543  /* -- Any active carousel loads will still be in the carousel list
544  -- so check if there is anything in it */
545  hOC = LLHead( idp->llcRootCarousels );
546 
547  /* -- Forcibly unload/destroy any active carousel loads */
548 
549  while (hOC && !intErr)
550  {
551  intErr = CDSM_UnloadCarousel( idp, hOC, mode );
552 
553  /* -- Any error is internal since we are internally calling
554  -- an API function) */
555  dsmAssert((intErr == CLDSM_OK));
556 
557  if (!intErr)
558  {
559  /* -- Check if there anything else left in the carousel
560  -- list */
561  hOC = LLHead( idp->llcRootCarousels );
562  }
563  }
564 
565  return intErr;
566 }
567 
568 static void CDSM_UnloadCarouselsOnService( P_DsmCoreInst idp, U16BIT serviceId )
569 {
570  E_DscError err;
571  P_RootCarousel pRC, pNext;
572  ListId_t listId;
573 
574  listId = LListId( idp->llcRootCarousels );
575  pRC = LLHead( idp->llcRootCarousels );
576  while (pRC != NULL)
577  {
578  pNext = LLNext( pRC, listId );
579  if (pRC->serviceId == serviceId)
580  {
581  err = CDSM_UnloadCarousel( idp, (H_DsmCarousel)pRC, RST_MODE_FORCE );
582  if (err)
583  {
584  ERRPRINT("Unload carousel err=%d", err)
585  }
586  }
587  pRC = pNext;
588  }
589 }
590 
591 static void ClearAllQueries( P_DsmCoreInst idp )
592 {
593  P_SiQuery pSiQueryRef;
594  E_SiQueryState queryState;
595 
596  /* -- Any active SI queries will still be in the current SI query
597  -- list so check if there is anything in it */
598  pSiQueryRef = LLHead( idp->llcCurrSiQueries );
599  while (pSiQueryRef)
600  {
601  /* -- Copy internal state since query ref will be destroyed */
602  queryState = pSiQueryRef->state;
603 
604  /* -- If SI Query is not in an ABORTED or EXPIRED state there has
605  -- been an internal error */
606  if ((queryState == SIQS_ABORTED) || (queryState == SIQS_EXPIRED))
607  {
608  dsmDP2(("ClearAllQueries: Stopping SI Query=%p state=%d\n", pSiQueryRef, queryState));
609  /* -- Force stop/destroy the SI Query (ie. without waiting for
610  -- any external abort/ack.)
611  -- NB. This also removes it from the current query list */
612  siQueryStop( idp, pSiQueryRef );
613  }
614  else
615  {
616  /* -- NB. Since there is probably some internal memory
617  -- corruption it is safest not to do anything else here.
618  -- DSM-CC should be shut down (clDsmDestroy) in response to
619  -- to this internal error otherwise this may cause a memory
620  -- leak in the MemMgr */
621  ERRPRINT("Invalid query state")
622  /* should it do:
623  * LLRemove( pSiQueryRef, CURR_SI_QUERY_LIST );
624  */
625  break;
626  }
627  pSiQueryRef = LLHead( idp->llcCurrSiQueries );
628  }
629 }
630 
631 static void UnloadLoadRequests( P_DsmCoreInst idp )
632 {
633  P_LoadRequest pNextRequest;
634  P_LoadRequest pLoadRequest;
635  ListId_t listId;
636 
637  listId = LListId( idp->llcCurrLoadRequests );
638  pLoadRequest = LLHead( idp->llcCurrLoadRequests );
639 
640  do
641  {
642  pNextRequest = LLNext( pLoadRequest, listId );
643  ERRPRINT("Load request status=%d", pLoadRequest->rlr.status)
644  DSC_LoadRsqtDestroy( idp, (P_RootLoadRqst)pLoadRequest );
645  pLoadRequest = pNextRequest;
646  }
647  while (pLoadRequest);
648 }
649 
650 static void UnloadModules( P_DsmCoreInst idp, P_LLControl llc, ListId_t listId )
651 {
652  P_Module pModule;
653  P_Module pNextMod;
654  pModule = LLHead( llc );
655  do
656  {
657  pNextMod = LLNext( pModule, listId );
658  dsmAssert((pModule->loadedCount == 0));
659  dsmAssert((pModule->llcLoadRequests == NULL));
660  DSC_ModuleDeleteDcTidyUp( idp, pModule );
661  pModule = pNextMod;
662  }
663  while (pModule);
664 }
665 
666 /*
667 -- Reset DSM-CC Core Layer instance
668 */
669 E_DscError CDSM_SysReset( H_DsmCoreInst instance, E_DsmRstMode mode )
670 {
671  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
672  E_DscError err = CLDSM_OK;
673  int listCount;
674 
675  dsmDP2(("CDSM_SysReset( %p, %u )\n", instance, mode));
676 
677  if (!idp || !idp->currentServiceSet)
678  {
679  ERRPRINT("ERROR: invalid instance? %p", idp);
680  }
681  else
682  {
683  err = CDSM_UnloadAllCarousels( idp, mode );
684  if (err)
685  {
686  ERRPRINT("Failed to unload all carousels err=%d", err)
687  }
688  else
689  {
690  if (mode != RST_MODE_PENDING)
691  {
692  listCount = LLCount( idp->llcCurrLoadRequests );
693  if (listCount)
694  {
695  ERRPRINT("Load requests still present, count=%d", listCount)
696  UnloadLoadRequests( idp );
697  }
698  }
699  listCount = LLCount( idp->llcModulePriority );
700  if (listCount)
701  {
702  ERRPRINT("Priority Modules still present, count=%d", listCount)
703  UnloadModules( idp, idp->llcModulePriority, MODULE_PRIORITY_LIST );
704  }
705  listCount = LLCount( idp->llcLoadedModules );
706  if (listCount)
707  {
708  ERRPRINT("Loaded Modules still present, count=%d", listCount)
709  UnloadModules( idp, idp->llcLoadedModules, MODULE_LOADED_LIST );
710  }
711  listCount = LLCount( idp->llcExpiredModules );
712  if (listCount)
713  {
714  ERRPRINT("Expired Modules still present count=%d", listCount)
715  UnloadModules( idp, idp->llcExpiredModules, MODULE_DELETE_LIST );
716  }
717 
718  ClearAllQueries( idp );
719 
720  DSC_StrmEventListReset( idp );
721 
722  /* -- Re-initialise instance data (may not all be necessary) */
723  dsmDP3(("lastPID=%d lpStored=%d, lastAssocTag=%d",
724  idp->lastPID, idp->lastPIDResultStored, idp->lastAssociationTag));
725 
726  if (idp->dvbLocator.service_id != 0)
727  {
728  if (idp->setup.unsubscribeSIChangeFunc != NULL)
729  {
730  /* unregister for PMT changes for previous service */
731  idp->setup.unsubscribeSIChangeFunc( idp->setup.siqInstance, idp->dvbLocator.service_id );
732  }
733  }
734 
735  /* -- Initialise current service info */
736  idp->dvbLocator.service_id = 0;
737  idp->currentServiceSet = FALSE;
738  idp->cacheFull = FALSE;
739 
740  /* -- Initialise SI query result store */
741  idp->lastPIDResultStored = FALSE;
742  idp->lastAssociationTag = 0;
743  idp->lastPID = 0;
744 
745  /* -- NULL booting carousel reference */
746  idp->pBootingCarousel = NULL;
747 
748  /* -- Set number of open objects to 0
749  -- nb. should not be any open objects at this point */
750  dsmAssert((idp->dsmObjectsOpen == 0));
751  idp->dsmObjectsOpen = 0;
752 
753  if (mode != RST_MODE_PENDING)
754  {
755  /* -- Reset section filter heap memory */
756  DSC_SsectionFilterHeapReset( idp );
757  }
758  /* -- Initialise zlib heap (module decompress) memory */
759  moduleDecompressInit( idp );
760  }
761  }
762  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: clDsmSysReset: %u\n", err)));
763  dsmDP2(("exit clDsmSysReset -> rtn: %u \n", err));
764  return err;
765 }
766 
772 void CDSM_SysSetMemoryMax( H_DsmCoreInst instance, U32BIT maxMemory )
773 {
774  P_DsmCoreInst idp;
775  if (maxMemory > DSMCC_MINIMUM_CACHE_SIZE)
776  {
777  idp = (P_DsmCoreInst) instance;
778  if (idp->setup.maxMemorySize > maxMemory)
779  {
780  DSC_CmMemPurgeCache( idp, maxMemory );
781  }
782  idp->setup.maxMemorySize = maxMemory;
783  }
784 }
785 
820  /*I*/ U16BIT original_network_id, U16BIT transport_stream_id,
821  U16BIT service_id )
822 {
823  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
824  E_DscError err = CLDSM_OK;
825  MemHandle hOC;
826 
827  dsmDP2(("CDSM_SysSetCurrService( %p, %u, %u, %u )\n", instance,
828  original_network_id, transport_stream_id, service_id));
829 
830  API_PARAM_CHK( instance, dsmDP1(("ERROR: Invalid instance\n")),
831  err = CLDSM_ERR_INVALID_INSTANCE; goto _return );
832 
833  /* -- Any active carousel loads will still be in the carousel list
834  -- so check if there is anything in it */
835  hOC = LLHead( idp->llcRootCarousels );
836 
837  if (hOC)
838  {
839  err = CLDSM_ERR_CAROUSELS_STILL_LOADED;
840  goto _return;
841  }
842 
843  dsmDP4(("lastPID=%d lpStored=%d, lastAssocTag=%d",
844  idp->lastPID, idp->lastPIDResultStored, idp->lastAssociationTag));
845 
846  if (idp->dvbLocator.service_id == service_id &&
847  idp->dvbLocator.original_network_id == original_network_id)
848  {
849  idp->dvbLocator.transport_stream_id = transport_stream_id;
850  idp->currentServiceSet = TRUE;
851  }
852  else
853  {
854  if (idp->dvbLocator.service_id != 0)
855  {
856  if (NULL != idp->setup.unsubscribeSIChangeFunc)
857  {
858  /* unregister for PMT changes for previous service */
859  idp->setup.unsubscribeSIChangeFunc( idp->setup.siqInstance, idp->dvbLocator.service_id );
860  }
861  }
862  idp->dvbLocator.original_network_id = original_network_id;
863  idp->dvbLocator.transport_stream_id = transport_stream_id;
864  idp->dvbLocator.service_id = service_id;
865  idp->currentServiceSet = TRUE;
866  if (service_id != 0)
867  {
868  if (NULL != idp->setup.subscribeSIChangeFunc)
869  {
870  idp->setup.subscribeSIChangeFunc( idp->setup.siqInstance, service_id );
871  }
872  }
873  }
874 
875  /* Increment the generation counter */
876  idp->generation.u32++;
877 
878  /* -- Clear SI query result store for new service */
879  idp->lastPIDResultStored = FALSE;
880  idp->lastAssociationTag = 0;
881  idp->lastPID = 0;
882 
883 #ifdef ACCELERATE_CAROUSEL_LOADING
884  {
885  memset(&requestedModuleIDList[0], 0, kMAX_MODULE_ID);
886 
887  memset(&prestoredSectionsTable[0], 0, sizeof(tPrestoredSection) * kMAX_PRESTORED_SECTIONS);
888 
889 
890  accCarouselLoadingInfos.storeWritePos = 0;
891  accCarouselLoadingInfos.storeReadPos = 0;
892  accCarouselLoadingInfos.storedSectionsNB = 0;
893  accCarouselLoadingInfos.bLargeDDBFilterSet = FALSE;
894  }
895 #endif
896 
897 _return:
898  DEBUG_CHK( err == CLDSM_OK,
899  dsmDP1(("ERROR: clDsmSysSetCurrService: %u\n", err)));
900  dsmDP2(("exit clDsmSysSetCurrService -> rtn: %u \n", err));
901  return err;
902 }
903 
904 U16BIT CDSM_SysCurrServiceId( H_DsmCoreInst instance )
905 {
906  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
907  return idp->dvbLocator.service_id;
908 }
909 
910 /*******************************************************************************
911 *
912 * Notifies that the specified timer has either timed-out (triggered) or
913 * been stopped (aborted) before triggering.
914 *
915 *******************************************************************************/
917  void *clDsmTmrUserData, E_TimerStatus status, void *timerHandle )
918 {
919  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
920  P_SecFilterInfo pFilterInfo = (P_SecFilterInfo)clDsmTmrUserData;
921 
922  dsmDP3(("CDSM_SysProcessTimerEvent( %p, %u, %p, %p )\n", instance,
923  status, clDsmTmrUserData, timerHandle));
924 
925  if (pFilterInfo->tms.mainTimerHandle == timerHandle)
926  {
927  pFilterInfo->tms.mainTimerHandle = NULL;
928  }
929  else if (pFilterInfo->tms.nextTimerHandle == timerHandle)
930  {
931  pFilterInfo->tms.nextTimerHandle = NULL;
932  }
933  switch (status)
934  {
935  case TIMER_TRIGGERED:
936  switch (pFilterInfo->target.kind)
937  {
938  case SFK_DSI:
939  dsmDP2(("TIMER_TRIGGERED: SFK_DSI: pFilterInfo = 0x%p\n", pFilterInfo));
940  if (DSC_RootCrslMagic(pFilterInfo->target.u.pRC) == OC_MAGIC)
941  {
942  lmObjCarouselTimeout(idp, pFilterInfo->target.u.pOC);
943  }
944  DSC_RootCrslLoadRequestFail(idp, pFilterInfo->target.u.pRC);
945  break;
946 
947  case SFK_DII:
948  dsmDP2(("TIMER_TRIGGERED: SFK_DII: pFilterInfo = 0x%p\n", pFilterInfo));
949  DSC_DataCrslDelete(idp, pFilterInfo->target.u.pDC);
950  break;
951 
952  case SFK_DDB:
953  dsmDP2(("TIMER_TRIGGERED: SFK_DDB: pFilterInfo = 0x%p\n", pFilterInfo));
954  lmAbortLoadRequestsOnModuleTimeout(idp, pFilterInfo->target.u.pModule);
955  break;
956 
957  default:
958  break;
959  }
960  break;
961 
962  case TIMER_ABORTED:
963  switch (pFilterInfo->target.kind)
964  {
965  case SFK_DSI:
966  dsmDP3(("TIMER_ABORTED: SFK_DSI: pFilterInfo = 0x%p\n", pFilterInfo));
967  break;
968 
969  case SFK_DII:
970  dsmDP3(("TIMER_ABORTED: SFK_DII: pFilterInfo = 0x%p\n", pFilterInfo));
971  break;
972 
973  case SFK_DDB:
974  dsmDP3(("TIMER_ABORTED: SFK_DDB: pFilterInfo = 0x%p\n", pFilterInfo));
975  break;
976 
977  default:
978  break;
979  }
980  break;
981 
982  default:
983  dsmDP2(("TIMER_STAUTS_???: pFilterInfo = 0x%p\n", pFilterInfo));
984  break;
985  }
986 
987  return CLDSM_OK;
988 }
989 
1035  H_SIQueryRef clDsmSIQueryRef, void *clDsmSIUserData, P_SIQueryResult pResult )
1036 {
1037  E_DscError err = CLDSM_OK;
1038  P_SiQuery pSiQueryRef = (P_SiQuery) clDsmSIQueryRef;
1039  P_SiQuery pDuplSiQueryRef;
1040  E_DscError newErr = CLDSM_OK;
1041 
1042  dsmDP2(("CDSM_SysProcessSIQueryEvent( %p, %p, %p )\n", idp, clDsmSIQueryRef, pResult));
1043 
1044  if (idp == NULL)
1045  {
1046  dsmDP1(("ERROR: Invalid instance\n"));
1047  err = CLDSM_ERR_INVALID_INSTANCE;
1048  }
1049  else if ((idp->currentServiceSet == FALSE) ||
1050  (idp->generation.ptr != clDsmSIUserData))
1051  {
1052  /* Discard siQuery when there is no current service or siQueries
1053  generation count is different to generation count in DSMCC instance */
1054  dsmDP3(("INFO: Stale siQuery discarded (generation)\n"));
1055  }
1056  else if (!memValidate(pSiQueryRef))
1057  {
1058  dsmDP1(("API ERROR: Invalid SI Query ref (handle)\n"));
1059  err = CLDSM_ERR_INVALID_SI_QUERY_REF;
1060  }
1061  else
1062  {
1063  if (pSiQueryRef->magic != SI_QUERY_MAGIC)
1064  {
1065  dsmDP1(("API ERROR: Invalid SI Query ref (magic)\n"));
1066  err = CLDSM_ERR_INVALID_SI_QUERY_REF;
1067  }
1068  else if (pSiQueryRef->state == SIQS_COMPLETED)
1069  {
1070  dsmDP1(("API ERROR: Invalid SI Query ref (already completed)\n"));
1071  err = CLDSM_ERR_INVALID_SI_QUERY_REF;
1072  }
1073  else
1074  {
1075  /* -- Should only be called for original queries */
1076  dsmAssert((pSiQueryRef->original == TRUE));
1077 
1078  if (pSiQueryRef->llcDuplSiQuerys != NULL)
1079  {
1080  /* -- Process the duplicates first */
1081  pDuplSiQueryRef = LLRemoveHead( pSiQueryRef->llcDuplSiQuerys );
1082 
1083  while (pDuplSiQueryRef != NULL)
1084  {
1085  newErr = siQueryProcessResult( idp, pDuplSiQueryRef, pResult );
1086  if (newErr)
1087  {
1088  err = handleInLoopError( idp, err, newErr );
1089  }
1090  pDuplSiQueryRef = LLRemoveHead( pSiQueryRef->llcDuplSiQuerys );
1091  }
1092  /* -- Now destroy the duplicate list */
1093  LLDestroy( idp, &pSiQueryRef->llcDuplSiQuerys );
1094  }
1095  /* -- Now process the original query */
1096  newErr = siQueryProcessResult( idp, pSiQueryRef, pResult );
1097  if (newErr)
1098  {
1099  err = handleInLoopError( idp, err, newErr );
1100  }
1101  }
1102  }
1103  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: clDsmSysProcessSIQueryEvent: %u\n", err)));
1104  dsmDP2(("exit clDsmSysProcessSIQueryEvent -> rtn: %u \n", err));
1105  return err;
1106 }
1107 
1108 /*******************************************************************************
1109 *
1110 * Notify that the SI for the indicated service has changed
1111 *
1112 *******************************************************************************/
1114  E_SIChangeEvent event, U16BIT service_id, U32BIT carousel_id )
1115 {
1116  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
1117  E_DscError err = CLDSM_OK;
1118  H_DsmCarousel pOC = NULL;
1119 
1120  API_PARAM_CHK( instance, dsmDP1(("ERROR: Invalid instance\n")),
1121  err = CLDSM_ERR_INVALID_INSTANCE; goto _return );
1122 
1123  dsmDP2(("CDSM_SysProcessSIChangeEvent( %p, %u, %u )\n", instance,
1124  service_id, event));
1125 
1126  dsmDP4(("lastPID=%d lpStored=%d, lastAssocTag=%d",
1127  idp->lastPID, idp->lastPIDResultStored, idp->lastAssociationTag));
1128 
1129 
1130  switch (event)
1131  {
1132  case SICHANGE_SERVICE_UPDATED:
1133  if (idp->dvbLocator.service_id == service_id)
1134  {
1135  idp->lastPIDResultStored = FALSE;
1136  }
1137  /* refresh filters */
1138  err = pmtUpdtAllSectionFiltersReset(instance, service_id);
1139  break;
1140 
1141  case SICHANGE_CAROUSEL_DELETED:
1142  pOC = (H_DsmCarousel)DSC_RootCrslListFindById( idp->llcRootCarousels, service_id, carousel_id );
1143  if (pOC != NULL)
1144  {
1145  err = CDSM_UnloadCarousel( instance, pOC, RST_MODE_FORCE );
1146  }
1147  break;
1148 
1149  case SICHANGE_SERVICE_DELETED:
1150  CDSM_UnloadCarouselsOnService( instance, service_id );
1151  break;
1152 
1153  default:;
1154  }
1155 
1156 _return:
1157  DEBUG_CHK( err == CLDSM_OK,
1158  dsmDP1(("ERROR: clDsmSysProcessSIChangeEvent: %u\n", err)));
1159  dsmDP2(("exit clDsmSysProcessSIChangeEvent -> rtn: %u \n", err));
1160  return err;
1161 }
1162 
1163 /*
1164 -- API CALLS INITIATED IN RESPONSE TO TRANSPORT STREAM EVENTS:
1165 */
1166 
1167 E_DscError CDSM_SectionPriority( H_DsmCoreInst instance,
1168  H_DscSFRef dsmFilterRef, E_SFPriority *priority )
1169 {
1170  E_DscError err;
1171  P_DsmCoreInst idp;
1172  P_SecFilterInfo pFilterInfo;
1173  if (instance == NULL)
1174  {
1175  err = CLDSM_ERR_INVALID_INSTANCE;
1176  ERRPRINT("ERROR: Invalid instance")
1177  }
1178  else
1179  {
1180  idp = (P_DsmCoreInst) instance;
1181  pFilterInfo = DSC_SectionFilterRetrieve( idp, dsmFilterRef );
1182  if (pFilterInfo == NULL)
1183  {
1184  err = CLDSM_ERR_ABORTED;
1185  DBGLOG(DD_SF, "Stale section discarded")
1186  }
1187  else
1188  {
1189  err = CLDSM_OK;
1190  *priority = pFilterInfo->filter.priority;
1191  }
1192  }
1193  DBGLOG(DD_SF, "rtn: %u", err)
1194  return err;
1195 }
1196 
1197 /*
1198 -- Process DSM-CC private section data
1199 --
1200 -- On entry - pSection points at first byte of section (ie. tableId)
1201 --
1202 */
1203 E_DscError CDSM_SysProcessPrivateSection( H_DsmCoreInst idp,
1204  /*I*/ U8BIT *pSection, H_DscSFRef dsmFilterRef )
1205 {
1206  E_DscError err;
1207  P_SecFilterInfo pFilterInfo;
1208  #ifdef ACCELERATE_CAROUSEL_LOADING
1209  U8BIT *pTempSection = pSection;
1210  #endif /* ACCELERATE_CAROUSEL_LOADING */
1211 
1212  DBG3(DD_SF, "CDSM_SysProcessPrivateSection( %p, %p, %p )", idp, pSection, dsmFilterRef)
1213 
1214  if (idp == NULL)
1215  {
1216  err = CLDSM_ERR_INVALID_INSTANCE;
1217  ERRPRINT("ERROR: Invalid instance")
1218  }
1219  else if (pSection == NULL)
1220  {
1221  err = CLDSM_ERR_ILLEGAL_PARAMETER;
1222  ERRPRINT("ERROR: Invalid section")
1223  }
1224  else
1225  {
1226  dsmDP3(("%s sz=0x%x tid=0x%x tide=0x%x, %d of %d\n", __FUNCTION__,
1227  (((int)(pSection[1] & 0x0f) << 8) | pSection[2]) + 3, *pSection,
1228  ((pSection[3] << 8) | pSection[4]), pSection[6] + 1, pSection[7] + 1));
1229 
1230  pFilterInfo = DSC_SectionFilterRetrieve( idp, dsmFilterRef );
1231  if (pFilterInfo == NULL)
1232  {
1233  err = CLDSM_ERR_ABORTED;
1234  DBGLOG(DD_SF, "Stale section discarded ref=0x%x", dsmFilterRef)
1235  }
1236  else
1237  {
1238  switch (pFilterInfo->target.kind)
1239  {
1240  case SFK_DSI:
1241  err = processDSI( idp, pSection, pFilterInfo );
1242  break;
1243 
1244  case SFK_DII:
1245  #ifdef ACCELERATE_CAROUSEL_LOADING
1246  GBL_NewResquetedModuleID = 0;
1247  #endif
1248  err = processDII( idp, pSection, pFilterInfo );
1249 
1250  #ifdef ACCELERATE_CAROUSEL_LOADING
1251  if (accCarouselLoadingInfos.storedSectionsNB > 0)
1252  {
1253  err = injectStoredSections(idp);
1254  }
1255  #endif
1256  break;
1257 
1258  case SFK_DDB:
1259  #ifdef ACCELERATE_CAROUSEL_LOADING
1260  /* processDDB moves pSection pointer !!*/
1261  pTempSection = pSection;
1262  #endif
1263 
1264  err = processDDB( idp, pSection, pFilterInfo );
1265 
1266  #ifdef ACCELERATE_CAROUSEL_LOADING
1267  if (CLDSM_OK != err)
1268  {
1269  /* store current section */
1270  storeSection(idp, pTempSection);
1271  }
1272  #endif
1273  break;
1274 
1275  case SFK_STREAM_DESCR:
1276  err = DSC_StrmEventUpdate( idp, pSection, pFilterInfo->target.u.pEvent, pFilterInfo->target.id );
1277  break;
1278 
1279  default:
1280  /* -- Discard sections from old filters */
1281  DBGLOG(DD_SF, "WARNING: Stale/invalid section filter handle (targetKind)")
1282  err = CLDSM_ERR_ABORTED;
1283  break;
1284  }
1285  /* -- Filter and only return system or internal (ie. fatal) errors here */
1286  switch (err)
1287  {
1288  case CLDSM_ERR_INTERNAL:
1289  case CLDSM_ERR_SYSTEM_ADD_SECTION_FILTER:
1290  case CLDSM_ERR_SECTION_FILTER_HEAP_FULL:
1291  case CLDSM_ERR_MEM_HEAP_FULL:
1292  DBGLOG(DD_SF, "rtn: %u", err)
1293  break;
1294 
1295  /* -- Do not notify or return any other errors */
1296  default:
1297  err = CLDSM_OK;
1298  break;
1299  }
1300  }
1301  }
1302  return err;
1303 }
1304 
1305 #ifdef ACCELERATE_CAROUSEL_LOADING
1306 E_DscError internalSysProcessPrivateSection( H_DsmCoreInst instance,
1307  /*I*/ U8BIT *pSection, P_SecFilterInfo pFilterInfo )
1308 {
1309  U8BIT tableId;
1310  U16BIT tableIdExtension;
1311  E_DscError err = CLDSM_OK;
1312  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
1313 
1314  /* -- Set DP level to 3 to prevent excessive debug prints at default
1315  -- level (L2) caused by DII monitoring */
1316  /* TODO: Set back to DP2 when 'next DII' monitoring implemented? */
1317  dsmDP3(("internalSysProcessPrivateSection( %p, %p, %x )\n",
1318  instance, pSection, clDsmFilterRef));
1319  API_PARAM_CHK( instance, dsmDP1(("ERROR: Invalid instance\n")),
1320  err = CLDSM_ERR_INVALID_INSTANCE; goto _return );
1321  API_PARAM_CHK( pSection, dsmDP1(("ERROR: Illegal parameter\n")),
1322  err = CLDSM_ERR_ILLEGAL_PARAMETER; goto _return );
1323 
1324  /* Discard Section when there is no current service or Section
1325  generation count is different to generation count in DSMCC instance */
1326  if (idp->currentServiceSet == FALSE)
1327  {
1328  dsmDP3(("INFO: Stale section discarded (generation)\n"));
1329  goto _return; /* EXIT */
1330  }
1331 
1332  if (pFilterInfo)
1333  {
1334  switch (pFilterInfo->target.kind)
1335  {
1336  case SFK_DDB:
1337  err = processDDB( idp, pSection, pFilterInfo );
1338  break;
1339 
1340  default:
1341  /* -- Discard sections from old filters */
1342  dsmDP2(("WARNING: Stale/invalid section filter handle (targetKind)\n"));
1343  break;
1344  }
1345  /* -- Filter and only return system or internal (ie. fatal) errors here */
1346  switch (err)
1347  {
1348  case CLDSM_ERR_INTERNAL:
1349  case CLDSM_ERR_SYSTEM_ADD_SECTION_FILTER:
1350  case CLDSM_ERR_SYSTEM_START_TIMER:
1351  case CLDSM_ERR_SECTION_FILTER_HEAP_FULL:
1352  case CLDSM_ERR_MEM_HEAP_FULL:
1353  break;
1354  /* -- Do not notify or return any other errors */
1355  default:
1356  err = CLDSM_OK;
1357  break;
1358  }
1359  }
1360  else
1361  {
1362  /* -- Cannot determine target Data Carousel */
1363  err = CLDSM_ERR_ILLEGAL_PARAMETER;
1364  dsmDP1(("API ERROR: No section filter reference supplied\n"));
1365  }
1366 
1367 _return:
1368  DEBUG_CHK( err == CLDSM_OK,
1369  dsmDP1(("ERROR: clDsmSysProcessPrivateSection: %u\n", err)));
1370 
1371  /* -- Set DP level to 3 to prevent excessive debug prints at default
1372  -- level (L2) caused by DII monitoring */
1373  /* TODO: Set back to DP2 when 'next DII' monitoring implemented */
1374  dsmDP3(("exit clDsmSysProcessPrivateSection -> rtn: %u \n", err));
1375  return err;
1376 }
1377 
1378 #endif /* ACCELERATE_CAROUSEL_LOADING */
1379 
1380 
1381 /*------------------------------ Local Functions -----------------------------*/
1382 
1383 /* -- SECTION PROCESSING FUNCTIONS */
1384 
1385 static U8BIT* ValidateDSI( U8BIT *pData, U16BIT *pPrivateDataLength, U32BIT *pTransactionId )
1386 {
1387  U16BIT ui16, msglen;
1388  U8BIT ui8, adaptationHdrLen;
1389 
1390  /* -- tableId = 0x3B */
1391  READ_UINT8( pData, ui8 );
1392  if (ui8 != 0x3B)
1393  {
1394  DBG1(DD_OC, "DATA ERROR: DSI tableId = %x", ui8)
1395  return NULL;
1396  }
1397  /* -- dsmcc_section_length */
1398  /* DSMCC specifies:
1399  -- - Maximum DSMCC message length is from last_section_number field to
1400  -- start of CRC_32/checksum field (ie. dsmcc_section_length - 9)
1401  -- - Ref[1] - section 9.2.2.1, pg 287
1402  */
1403  READ_UINT16( pData, ui16 );
1404  if (((ui16 & LSB12_MSK) > MAX_SECTION_LEN) ||
1405  (((ui16 & LSB12_MSK) - 9) < MIN_DSI_MSG_LEN))
1406  {
1407  DBG1(DD_OC, "DATA ERROR: DSI section len = %x", ui16)
1408  return NULL;
1409  }
1410 
1411  /* -- tableIdExtension = 0x0000 or 0x0001 */
1412  READ_UINT16( pData, ui16 );
1413  if (ui16 > 1)
1414  {
1415  DBG1(DD_OC, "DATA ERROR: DSI tableIdExtension = %x", ui16)
1416  return NULL;
1417  }
1418 
1419  /* -- Skip versionNumber, sectionNumber, lastSectionNumber - NOT USED */
1420  SET_POS_REL( pData, 3 );
1421 
1422  /* -- pDSISection -> dsmccMessageHeader */
1423  /* -- protocolDescriminator */
1424  READ_UINT8( pData, ui8 );
1425  if (ui8 != 0x11)
1426  {
1427  DBG1(DD_OC, "DATA ERROR: protocolDescriminator = %x", ui8)
1428  return NULL;
1429  }
1430 
1431  /* -- dsmccType = U-N Download Message */
1432  /* -- L1 check because this should be correct */
1433  READ_UINT8( pData, ui8 );
1434  if (ui8 != 0x03)
1435  {
1436  DBG1(DD_OC, "DATA ERROR: DSI dsmccType = %x", ui8)
1437  return NULL;
1438  }
1439 
1440  /* -- messageID = DownloadServerInitiate */
1441  /* -- L1 check because this should be correct */
1442  READ_UINT16( pData, ui16 );
1443  if (ui16 != DSI_MSG_ID)
1444  {
1445  DBG1(DD_OC, "DATA ERROR: DSI messageID = %x", ui16)
1446  return NULL;
1447  }
1448 
1449  /* -- transactionId: originator bits = 10B (DSM-CC [1]) */
1450  /* -- NK 16/10/01 - L2 check since some transmissions are known to set these wrong */
1451  READ_UINT32( pData, *pTransactionId );
1452  if ((*pTransactionId & TRANSACTION_ID_ORIG_MASK) != 0x80000000)
1453  {
1454  DBG1(DD_OC, "DATA ERROR: DSI transactionId (originator (bits 31-30) != 10B) = %x", *pTransactionId)
1455  return NULL;
1456  }
1457  /* -- transactionId: ID bits = 0x0000 (DVB [2]) */
1458  if ((*pTransactionId & TRANSACTION_ID_IDENT_MASK) != 0x00000000)
1459  {
1460  DBG1(DD_OC, "DATA ERROR: DSI transactionId (ID (bits 15-1) != 0x0000) = %x", *pTransactionId)
1461  return NULL;
1462  }
1463 
1464  /* -- Skip reserved data - NOT USED */
1465  SET_POS_REL( pData, 1 );
1466 
1467  /* -- Read adaptationLength */
1468  READ_UINT8( pData, adaptationHdrLen );
1469 
1470  /* -- Check messageLength */
1471  READ_UINT16( pData, msglen );
1472  if (msglen < (DSI_HDR_LEN+adaptationHdrLen))
1473  {
1474  DBG1(DD_OC, "DATA ERROR: DSI messageLength (< DSI_HDR_LEN) = %u", ui16)
1475  return NULL;
1476  }
1477  if (adaptationHdrLen)
1478  {
1479  /* -- Skip adaptationHeader - NOT USED */
1480  SET_POS_REL( pData, adaptationHdrLen );
1481  msglen -= adaptationHdrLen;
1482  }
1483 
1484  /* -- pDSISection -> DSIMessageBody */
1485 
1486  /* -- Skip serverId field - NOT USED (DVB) */
1487  SET_POS_REL( pData, 20 );
1488 
1489  /* -- compatibilityDescriptorLength == 0 - NOT USED (DVB) */
1490  READ_UINT16( pData, ui16 );
1491  if (ui16 != 0x0000)
1492  {
1493  DBG3(DD_OC, "DSI compatibilityDescriptorLength (!= 0) = %u", ui16)
1494  /* this is error according to MHEG or MHP/HBBTV or SSU spec's and should do:
1495  * return NULL;
1496  * But some streams may have it non-zero (e.g. with length of 'decriptorCount' only - i.e. 2)
1497  * We can just skip over this descriptor, anyway.
1498  */
1499  SET_POS_REL( pData, ui16 );
1500  msglen -= ui16;
1501  }
1502  msglen -= DSI_HDR_LEN;
1503 
1504  /* -- Check privateDataLength (ServiceGatewayInfo or GroupInfoIndication) */
1505  READ_UINT16( pData, *pPrivateDataLength );
1506  if (msglen != *pPrivateDataLength)
1507  {
1508  DBG1(DD_OC, "DATA ERROR: DSI private data len, %u, not matching msgLen = %u", *pPrivateDataLength, msglen)
1509  return NULL;
1510  }
1511 
1512  /* Return pointer to private data */
1513  return pData;
1514 }
1515 
1516 /*
1517 // *** NB. Currently only ONE objectCarousel supported ***
1518 // *** TODO: Do we need to handle DSI updates ? ***
1519 //
1520 // If a carousel boot is in progress
1521 //
1522 // Get SRG info from dsiMessage
1523 //
1524 // Identify target objectCarousel for this DSI section
1525 //
1526 // If target objectCarousel identified
1527 // Delete DSI section filter
1528 // Start load of OC service gateway [lmLoadServiceGateway]
1529 // Else
1530 // Discard DSI section
1531 // Endif
1532 //
1533 // Else
1534 // Discard DSI section
1535 // Endif
1536 //
1537 */
1538 static E_DscError processDSI( P_DsmCoreInst idp,
1539  /*I*/ U8BIT *pDSISection, P_SecFilterInfo pFilterInfo )
1540 {
1541  E_DscError err = CLDSM_OK;
1542  P_RootCarousel pRC;
1543  U32BIT transactionId;
1544  U16BIT dsiPrivateLen;
1545 
1546  dsmAssert((idp != NULL));
1547  dsmAssert((pDSISection != NULL));
1548 
1549 #if defined(DEBUG_PROCESS_DSI) && (DSM_DP_LEVEL >= 3)
1550  /* Dump filter information */
1551  dsmDP3(("processDSI(pFilterInfo = %#p boot %#p)\n", pFilterInfo, idp->pBootingCarousel));
1552  dsmDP3(("filter.PID = %x\n", pFilterInfo->filter.PID));
1553  dsmDP3(("filter.tableId = %x\n", pFilterInfo->filter.tableId));
1554  dsmDP3(("filter.tableIdExt = %x\n", pFilterInfo->filter.tableIdExt));
1555 
1556  /* Dump first 32 bytes of section */
1557  U8BIT *ptr = pDSISection;
1558  U16BIT i;
1559  for (i = 0; i < 32; i++)
1560  {
1561  dsmDP3(("%02x ", *ptr++));
1562  if (((i + 1) % 8 == 0) && i != 31)
1563  dsmDP3(("\n"));
1564  }
1565  dsmDP3(("\n"));
1566 #endif
1567 
1568  /* -- Only process DSIs if currently booting a carousel */
1569  dsmAssert((pFilterInfo != NULL));
1570  pRC = pFilterInfo->target.u.pRC;
1571  if (FALSE == LLIsObjectInList(idp->llcRootCarousels, pRC))
1572  {
1573  ERRLOG(DD_OC, "pRC=%p NOT FOUND", pRC)
1574  }
1575  else if (pFilterInfo != pRC->pDsiSf || pRC->pDsiSf->status != SFA_COMMITTED)
1576  {
1577  ERRLOG(DD_OC, " mis-match filter %p %p", pFilterInfo, pRC->pDsiSf)
1578  }
1579  else if (pRC->rcid != pFilterInfo->target.id)
1580  {
1581  ERRLOG(DD_OC, "DATA ERROR: Mismatch Ids rcid=%d tid=%d",
1582  pRC->rcid, pFilterInfo->target.id )
1583  }
1584  else
1585  {
1586  DBGLOG(DD_OC,"pRC=%p", pRC)
1587 
1588  pDSISection = ValidateDSI( pDSISection, &dsiPrivateLen, &transactionId );
1589  if (pDSISection == NULL || pRC->dsiTransactionId == transactionId)
1590  {
1591  DBG4(DD_OC,"DSI discarded p=%p t=%x",pDSISection,transactionId)
1592  }
1593  else
1594  {
1595  DBGLOG(DD_OC,"dsiTransactionId change: %x, %x", pRC->dsiTransactionId, transactionId)
1596  pRC->dsiTransactionId = transactionId;
1597  switch (pRC->magic)
1598  {
1599  case OC_MAGIC:
1600  {
1601  err = DSC_ObjCrslParseSrgInfo( idp, (P_ObjectCarousel)pRC, pDSISection, dsiPrivateLen );
1602  break;
1603  }
1604 
1605  case UC_MAGIC:
1606  {
1607  err = DSC_UpdCrslParseGroupInfo( idp, (P_UpdateCarousel)pRC, pDSISection, dsiPrivateLen );
1608  break;
1609  }
1610 
1611  default:
1612  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
1613  }
1614  }
1615  }
1616  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: processDSI: %u\n", err)));
1617  return err;
1618 }
1619 
1620 static U8BIT* ValidateDII( U8BIT *pData, U16BIT *pMsgLength, U32BIT *pTransactionId )
1621 {
1622  U16BIT ui16, msglen;
1623  U8BIT ui8, adaptationHdrLen;
1624 
1625  /* -- tableId = 0x3B */
1626  READ_UINT8( pData, ui8 );
1627  if (ui8 != 0x3B)
1628  {
1629  DBG1(DD_OC, "DATA ERROR: DII tableId = %x", ui8)
1630  return NULL;
1631  }
1632  /* -- dsmcc_section_length */
1633  /* DSMCC specifies:
1634  -- - Maximum DSMCC message length is from last_section_number field to
1635  -- start of CRC_32/checksum field (ie. dsmcc_section_length - 9)
1636  -- - Ref[1] - section 9.2.2.1, pg 287
1637  */
1638  READ_UINT16( pData, ui16 );
1639  if (((ui16 & LSB12_MSK) > MAX_SECTION_LEN) ||
1640  (((ui16 & LSB12_MSK) - 9) < MIN_DII_MSG_LEN))
1641  {
1642  DBG1(DD_OC, "DATA ERROR: DII section len = %x", ui16)
1643  return NULL;
1644  }
1645 
1646  /* -- tableIdExtension = 0x0002-0xFFFF */
1647  READ_UINT16( pData, ui16 );
1648  if (ui16 < 2)
1649  {
1650  DBG1(DD_OC, "DATA ERROR: DII tableIdExtension = %x", ui16)
1651  return NULL;
1652  }
1653 
1654  /* -- Skip versionNumber, sectionNumber, lastSectionNumber - NOT USED */
1655  SET_POS_REL( pData, 3 );
1656 
1657  /* -- dsmccMessageHeader */
1658  /* -- protocolDescriminator */
1659  READ_UINT8( pData, ui8 );
1660  if (ui8 != 0x11)
1661  {
1662  DBG1(DD_OC, "DATA ERROR: protocolDescriminator = %x", ui8)
1663  return NULL;
1664  }
1665 
1666  /* -- dsmccType = U-N Download Message */
1667  READ_UINT8( pData, ui8 );
1668  if (ui8 != 0x03)
1669  {
1670  DBG1(DD_OC, "DATA ERROR: dsmccType = %x", ui8)
1671  return NULL;
1672  }
1673 
1674  /* -- messageID = DownloadInfoIndication */
1675  READ_UINT16( pData, ui16 );
1676  if (ui16 != DII_MSG_ID)
1677  {
1678  DBG1(DD_OC, "DATA ERROR: messageID = %x", ui16)
1679  return NULL;
1680  }
1681 
1682  /* -- transactionId: originator bits = 10B (DSM-CC [1]) */
1683  READ_UINT32( pData, *pTransactionId );
1684  if ((*pTransactionId & TRANSACTION_ID_ORIG_MASK) != 0x80000000)
1685  {
1686  DBG1(DD_OC, "DATA ERROR: DSI transactionId (originator (bits 31-30) != 10B) = %x", *pTransactionId)
1687  return NULL;
1688  }
1689 
1690  /* -- Skip reserved data - NOT USED */
1691  SET_POS_REL( pData, 1 );
1692 
1693  /* -- Read adaptationLength */
1694  READ_UINT8( pData, adaptationHdrLen );
1695 
1696  /* -- Check messageLength */
1697  READ_UINT16( pData, msglen );
1698  if (msglen < MIN_DII_MSG_BODY_LEN)
1699  {
1700  DBG1(DD_OC, "DATA ERROR: DSI messageLength (< DSI_HDR_LEN) = %u", ui16)
1701  return NULL;
1702  }
1703 
1704  /* -- Skip adaptationHeader - NOT USED */
1705  SET_POS_REL( pData, adaptationHdrLen );
1706 
1707  *pMsgLength = msglen - adaptationHdrLen;
1708 
1709  /* Return pointer to data */
1710  return pData;
1711 }
1712 
1713 /*
1714 // *** NB. Currently only ONE objectCarousel supported ***
1715 //
1716 // Get carouselId from diiMessage
1717 // Get transactionId from diiMessage
1718 //
1719 // Identify relevant OC and target dataCarousel for this DII section
1720 //
1721 // If target dataCarousel identified
1722 // Update dataCarousel with diiMessage [lmUpdateDataCarousel]
1723 // Else
1724 // Discard DII section
1725 // Endif
1726 //
1727 */
1728 static E_DscError processDII( P_DsmCoreInst idp, U8BIT *pDIISection, P_SecFilterInfo pFilterInfo )
1729 {
1730  E_DscError err = CLDSM_OK;
1731  U16BIT diiMsgDataLen;
1732  P_DataCarousel pDataCarousel = NULL;
1733  U32BIT transactionId;
1734 
1735  dsmDP3(("processDII() pFilterInfo = %p\n", pFilterInfo));
1736  dsmAssert((idp != NULL));
1737  dsmAssert((pDIISection != NULL));
1738 
1739  if (pFilterInfo == NULL)
1740  {
1741  err = CLDSM_ERR_ILLEGAL_PARAMETER;
1742  dsmDP1(("API ERROR: No section filter reference supplied\n"));
1743  }
1744  else
1745  {
1746  dsmAssert((pFilterInfo->target.u.pDC != NULL));
1747  pDataCarousel = pFilterInfo->target.u.pDC;
1748 
1749  pDIISection = ValidateDII( pDIISection, &diiMsgDataLen, &transactionId );
1750  if (pDIISection == NULL)
1751  {
1752  ERRPRINT("")
1753  }
1754  else if (pFilterInfo->target.id != (transactionId & TRANSACTION_ID_IDENT_MASK))
1755  {
1756  /* -- Target ID and section ID do not match */
1757  dsmDP3(("INFO: DII filter target ID != transactionId: %u, %u\n",
1758  pFilterInfo->target.id, (transactionId & TRANSACTION_ID_IDENT_MASK)));
1759  }
1760  else if (pDataCarousel != NULL)
1761  {
1762  #ifndef NDEBUG
1763  /* -- Double-check DC matches filter */
1764  dsmAssert((pFilterInfo == pDataCarousel->pDiiSf));
1765  dsmAssert((pDataCarousel->pDiiSf->status == SFA_COMMITTED));
1766  #endif
1767  /* -- NB. DC may be deleted if emptied */
1768  err = DSC_DataCrslUpdate( idp, pDataCarousel, transactionId, pDIISection, diiMsgDataLen );
1769  }
1770  }
1771  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: processDII: %u\n", err)));
1772  return err;
1773 }
1774 
1775 
1776 static U8BIT* ValidateDDB( U8BIT *pData, U16BIT *pMsgLength, U32BIT *pTransactionId )
1777 {
1778  U16BIT ui16, msglen;
1779  U8BIT ui8, adaptationHdrLen;
1780 
1781  /* -- tableId = 0x3C */
1782  READ_UINT8( pData, ui8 );
1783  if (ui8 != 0x3C)
1784  {
1785  DBG1(DD_OC, "DATA ERROR: TableId = %x", ui8)
1786  return NULL;
1787  }
1788  /* -- dsmcc_section_length */
1789  /* DSMCC specifies:
1790  -- - Maximum DSMCC message length is from last_section_number field to
1791  -- start of CRC_32/checksum field (ie. dsmcc_section_length - 9)
1792  -- - Ref[1] - section 9.2.2.1, pg 287
1793  */
1794  READ_UINT16( pData, ui16 );
1795  if (((ui16 & LSB12_MSK) > MAX_SECTION_LEN) ||
1796  (((ui16 & LSB12_MSK) - 9) < MIN_DDB_MSG_LEN))
1797  {
1798  DBG1(DD_OC, "DATA ERROR: section len = %x", ui16)
1799  return NULL;
1800  }
1801 
1802 
1803  /* -- Skip tableIdExtension, versionNumber, sectionNumber, lastSectionNumber - NOT USED */
1804  SET_POS_REL( pData, 5 );
1805 
1806  /* -- dsmccMessageHeader */
1807  /* -- protocolDescriminator */
1808  READ_UINT8( pData, ui8 );
1809  if (ui8 != 0x11)
1810  {
1811  DBG1(DD_OC, "DATA ERROR: protocolDescriminator = %x", ui8)
1812  return NULL;
1813  }
1814 
1815  /* -- dsmccType = U-N Download Message */
1816  READ_UINT8( pData, ui8 );
1817  if (ui8 != 0x03)
1818  {
1819  DBG1(DD_OC, "DATA ERROR: dsmccType = %x", ui8)
1820  return NULL;
1821  }
1822 
1823  /* -- messageID = DownloadDataBlock */
1824  READ_UINT16( pData, ui16 );
1825  if (ui16 != DDB_MSG_ID)
1826  {
1827  DBG1(DD_OC, "DATA ERROR: messageID = %x", ui16)
1828  return NULL;
1829  }
1830 
1831  /* -- transactionId: originator bits = 10B (DSM-CC [1]) */
1832  READ_UINT32( pData, *pTransactionId );
1833  /* -- NB. According to TDNMHEG group - downloadId/carouselId equivalence
1834  -- is not/cannot be guaranteed by broadcasters for DDB*/
1835 
1836  /* -- Skip reserved data - NOT USED */
1837  SET_POS_REL( pData, 1 );
1838 
1839  /* -- Read adaptationLength */
1840  READ_UINT8( pData, adaptationHdrLen );
1841 
1842  /* -- Check messageLength */
1843  READ_UINT16( pData, msglen );
1844  if (msglen < MIN_DDB_MSG_BODY_LEN)
1845  {
1846  DBG1(DD_OC, "DATA ERROR: DSI messageLength (< DSI_HDR_LEN) = %u", ui16)
1847  return NULL;
1848  }
1849 
1850  /* -- Skip adaptationHeader - NOT USED */
1851  SET_POS_REL( pData, adaptationHdrLen );
1852 
1853  *pMsgLength = msglen - adaptationHdrLen;
1854 
1855  /* Return pointer to data */
1856  return pData;
1857 }
1858 
1859 /*
1860 // **** NB. Currently only ONE objectCarousel supported ****
1861 //
1862 // Get carouselId from ddbMessage
1863 // Get moduleId from ddbMessage
1864 //
1865 // Identify relevant OC and target module for this DDB section
1866 //
1867 // If target module identified
1868 // Build ddbMessage into moduleData [DSC_ModuleUpdate]
1869 // If moduleData completed
1870 // Update loadRequest(s)/monitor(s) for module [lmUpdateModule]
1871 // Endif
1872 // Else
1873 // Discard DDB section
1874 // Endif
1875 //
1876 */
1877 static E_DscError processDDB( P_DsmCoreInst idp, U8BIT *pDDBSection, P_SecFilterInfo pFilterInfo )
1878 {
1879  E_DscError err = CLDSM_OK;
1880  U32BIT transactionId;
1881  U16BIT ddbMsgDataLen;
1882  U16BIT moduleId;
1883 
1884  dsmAssert((idp != NULL));
1885  dsmAssert((pDDBSection != NULL));
1886 
1887  if (pFilterInfo == NULL)
1888  {
1889  err = CLDSM_ERR_ILLEGAL_PARAMETER;
1890  dsmDP1(("API ERROR: No section filter reference supplied\n"));
1891  }
1892  else
1893  {
1894  dsmAssert((pFilterInfo->target.u.pModule != NULL));
1895 
1896  pDDBSection = ValidateDDB( pDDBSection, &ddbMsgDataLen, &transactionId );
1897  if (pDDBSection != NULL)
1898  {
1899  /* -- pDDBSection -> DDBMessageBody/Payload */
1900  /* -- Get moduleId (NB. DO NOT advance 'cursor') */
1901  GET_UINT16( pDDBSection, moduleId );
1902  if (pFilterInfo->target.id != moduleId)
1903  {
1904  /* -- Target ID and section ID do not match */
1905  dsmDP3(("INFO: DDB filter target ID != moduleId: %u, %u\n", pFilterInfo->target.id, moduleId));
1906  }
1907  else
1908  {
1909  P_Module pModule;
1910  pModule = pFilterInfo->target.u.pModule;
1911  if (pModule != NULL && pFilterInfo == pModule->pDdbSf)
1912  {
1913  /* -- Double-check Module matches filter */
1914  dsmAssert((pFilterInfo->status == SFA_COMMITTED));
1915  err = DSC_ModuleUpdate( idp, pModule, pDDBSection, ddbMsgDataLen );
1916  }
1917  else
1918  {
1919  /* -- This was not a DDB we were looking for so discard */
1920  dsmDP3(("INFO: DDB discarded - moduleId: %u\n", moduleId));
1921 
1922  #ifdef ACCELERATE_CAROUSEL_LOADING
1923  err = CLDSM_ERR_MODULE_ACQUISITION_FAILURE;
1924  #endif
1925  }
1926  }
1927  }
1928  }
1929  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: processDDB: %u\n", err)));
1930  return err;
1931 }
1932 
1933 #ifdef ACCELERATE_CAROUSEL_LOADING
1934 
1935 static E_DscError storeSection( P_DsmCoreInst idp,
1936  U8BIT *pDDBSection)
1937 {
1938  U8BIT *pDDBSectionIn = pDDBSection;
1939  E_DscError err = CLDSM_OK;
1940  U8BIT adaptationHdrLen;
1941  U16BIT ddbMsgLen;
1942  U16BIT ddbMsgDataLen;
1943  U16BIT moduleId, blockNum;
1944  U8BIT ui8 = 0;
1945  U16BIT ui16 = 0;
1946  U8BIT moduleVersion;
1947  int i;
1948  BOOLEAN bStoreSection = TRUE;
1949  U16BIT msgLength = 0;
1950  U8BIT iMiddlePos = 0;
1951 
1952 
1953  ui8 += 0; ui16 += 0; /* -- stop compiler warnings when no checking */
1954 
1955 
1956  dsmDP3(("processDDB()\n"));
1957  dsmAssert((idp != NULL));
1958  dsmAssert((pDDBSection != NULL));
1959 
1960  /* TODO: report soft errors in L0, L1 (and L2?) checks? */
1961 
1962  /* -- pDDBSection -> section header (tableId) */
1963 
1964  /* -- NB. Only have L2 checks on section header values since
1965  -- section filter should have already checked these! */
1966 
1967  /* -- tableId = 0x3C */
1968  ADV_UINT8_L2CHK( pDDBSection, ui8, ui8 == 0x3C,
1969  dsmDP2(("DATA ERROR: DDB tableId = %x\n", ui8)),
1970  goto _return /* EXIT */
1971  );
1972 
1973  /* -- dsmcc_section_length */
1974  /*
1975  -- DSMCC specifies:
1976  -- - Maximum DSMCC message length is from last_section_number field to
1977  -- start of CRC_32/checksum field (ie. dsmcc_section_length - 9)
1978  -- - Ref[1] - section 9.2.2.1, pg 287
1979  */
1980  /* ADV_UINT16_L2CHK( pDDBSection, ui16, */
1981  /* ( ((ui16 & LSB12_MSK) <= MAX_SECTION_LEN) && */
1982  /* (((ui16 & LSB12_MSK) - 9) >= MIN_DDB_MSG_LEN) ), */
1983  /* dsmDP2(("DATA ERROR: DDB section len = %u\n", ui16 )), */
1984  /* goto _return */
1985  /* ); */
1986 
1987  READ_UINT16( pDDBSection, msgLength );
1988  msgLength = msgLength & LSB12_MSK;
1989 
1990  /* -- Skip tableIdExtension, versionNumber, sectionNumber,
1991  -- lastSectionNumber - NOT USED HERE */
1992  SET_POS_REL( pDDBSection, 5 );
1993 
1994 
1995  /* -- pDDBSection -> dsmccDownloadDataHeader */
1996 
1997  /* -- protocolDescriminator */
1998  /* -- L1 check because this should be correct */
1999  ADV_UINT8_L1CHK( pDDBSection, ui8, ui8 == 0x11,
2000  dsmDP2(("DATA ERROR: DDB protocolDescriminator = %x\n", ui8)),
2001  goto _return );
2002 
2003  /* -- dsmccType = U-N Download Message */
2004  /* -- L1 check because this should be correct */
2005  ADV_UINT8_L1CHK( pDDBSection, ui8, ui8 == 0x03,
2006  dsmDP2(("DATA ERROR: DDB dsmccType = %x\n", ui8)),
2007  goto _return );
2008 
2009  /* -- messageID = DownloadDataBlock */
2010  /* -- L1 check because this should be correct */
2011  ADV_UINT16_L1CHK( pDDBSection, ui16, ui16 == 0x1003,
2012  dsmDP2(("DATA ERROR: DDB messageID = %x\n", ui16)),
2013  goto _return );
2014 
2015  /* -- Skip downloadId - NOT USED */
2016  /* -- NB. According to TDNMHEG group - downloadId/carouselId equivalence
2017  -- is not/cannot be guaranteed by broadcasters */
2018  SET_POS_REL( pDDBSection, 4 );
2019 
2020  /* -- Skip reserved data - NOT USED */
2021  SET_POS_REL( pDDBSection, 1 );
2022 
2023  /* -- Read adaptationLength */
2024  READ_UINT8( pDDBSection, adaptationHdrLen );
2025 
2026  /* -- Read messageLength */
2027  READ_UINT16( pDDBSection, ddbMsgLen );
2028 
2029  /* -- Calculate DDB message payload/data length */
2030  ddbMsgDataLen = (U16BIT)(ddbMsgLen - adaptationHdrLen);
2031 
2032  /* -- Check message data size */
2033  L2_DATA_CHK( ddbMsgDataLen >= MIN_DDB_MSG_BODY_LEN,
2034  dsmDP2(("DATA ERROR: DDB messageLength (< MIN_DDB_MSG_BODY_LEN) = %x\n",
2035  ddbMsgDataLen)),
2036  goto _return );
2037 
2038  /* -- Skip adaptationHeader - NOT USED */
2039  SET_POS_REL( pDDBSection, adaptationHdrLen );
2040 
2041 
2042  /* -- pDDBSection -> DDBMessageBody/Payload */
2043 
2044  /* -- Get moduleId (NB. DO NOT advance 'cursor') */
2045  GET_UINT16( pDDBSection, moduleId );
2046 
2047  /* -- Skip moduleId */
2048  SET_POS_REL( pDDBSection, 2 );
2049 
2050  /* -- Read moduleVersion */
2051  READ_UINT8(pDDBSection, moduleVersion );
2052 
2053  /* -- Skip reserved data */
2054  SET_POS_REL(pDDBSection, 1 );
2055 
2056  /* -- Read blockNumber */
2057  READ_UINT16( pDDBSection, blockNum );
2058 
2059 
2060  iMiddlePos = accCarouselLoadingInfos.storedSectionsNB / 2;
2061 
2062  if (iMiddlePos > 0)
2063  {
2064  for (i = 0; i < iMiddlePos; i++)
2065  {
2066  if ((prestoredSectionsTable[i].moduleID == moduleId) &&
2067  (prestoredSectionsTable[i].blockNum == blockNum))
2068  {
2069  bStoreSection = FALSE;
2070  break;
2071  }
2072 
2073  if ((prestoredSectionsTable[iMiddlePos + i].moduleID == moduleId) &&
2074  (prestoredSectionsTable[iMiddlePos + i].blockNum == blockNum))
2075  {
2076  bStoreSection = FALSE;
2077  break;
2078  }
2079  }
2080 
2081  if ((prestoredSectionsTable[accCarouselLoadingInfos.storedSectionsNB - 1].moduleID == moduleId) &&
2082  (prestoredSectionsTable[accCarouselLoadingInfos.storedSectionsNB - 1].blockNum == blockNum))
2083  {
2084  bStoreSection = FALSE;
2085  }
2086  }
2087  else
2088  {
2089  for (i = 0; i < accCarouselLoadingInfos.storedSectionsNB; i++)
2090  {
2091  if ((prestoredSectionsTable[i].moduleID == moduleId) &&
2092  (prestoredSectionsTable[i].blockNum == blockNum))
2093  {
2094  bStoreSection = FALSE;
2095  break;
2096  }
2097  }
2098  }
2099 
2100  if (bStoreSection == TRUE)
2101  {
2102  if (accCarouselLoadingInfos.storeWritePos >= kMAX_PRESTORED_SECTIONS)
2103  {
2104  accCarouselLoadingInfos.storeWritePos = 0;
2105  }
2106 
2107  prestoredSectionsTable[accCarouselLoadingInfos.storeWritePos].moduleID = moduleId;
2108  prestoredSectionsTable[accCarouselLoadingInfos.storeWritePos].blockNum = blockNum;
2109 
2110 
2111  prestoredSectionsTable[accCarouselLoadingInfos.storeWritePos].sectionSize = msgLength;
2112  memcpy(&prestoredSectionsTable[accCarouselLoadingInfos.storeWritePos].section[0], pDDBSectionIn, msgLength);
2113 
2114  accCarouselLoadingInfos.storeWritePos++;
2115 
2116  if (accCarouselLoadingInfos.storedSectionsNB < kMAX_PRESTORED_SECTIONS)
2117  {
2118  accCarouselLoadingInfos.storedSectionsNB++;
2119  }
2120  }
2121 
2122  goto _return; /* -- stop compiler warnings when no checking */
2123 _return:
2124  DEBUG_CHK( err == CLDSM_OK,
2125  dsmDP1(("ERROR: storeSection: %u\n", err)));
2126  dsmDP3(("exit storeSection -> rtn: %u\n", err));
2127  return err;
2128 } /* storeSection */
2129 
2130 static E_DscError injectStoredSections( P_DsmCoreInst idp)
2131 {
2132  U8BIT *pDDBSection;
2133  E_DscError err = CLDSM_OK;
2134  H_DscSFRef clDsmFilterRef;
2135  S_SecFilterInfo filterInfo;
2136  P_ObjectCarousel pOC;
2137  pModule pModule = NULL;
2138  U16BIT moduleId;
2139  U16BIT moduleCounter = 0;
2140 
2141  memset(&filterInfo, 0, sizeof(S_SecFilterInfo));
2142 
2143  accCarouselLoadingInfos.storeReadPos = 0;
2144  accCarouselLoadingInfos.SectionsReinjection++;
2145 
2146  while (moduleCounter < accCarouselLoadingInfos.storedSectionsNB)
2147  {
2148  moduleCounter++;
2149 
2150  if (accCarouselLoadingInfos.storeReadPos >= kMAX_PRESTORED_SECTIONS)
2151  {
2152  accCarouselLoadingInfos.storeReadPos = 0;
2153  }
2154 
2155  moduleId = prestoredSectionsTable[accCarouselLoadingInfos.storeReadPos].moduleID;
2156 
2157  if ((prestoredSectionsTable[accCarouselLoadingInfos.storeReadPos].injectionDone != 1) &&
2158  (requestedModuleIDList[moduleId] == kDO_INJECT))
2159  {
2160  pDDBSection = &prestoredSectionsTable[accCarouselLoadingInfos.storeReadPos].section[0];
2161 
2162  pOC = LLHead( idp->llcRootCarousels );
2163 
2164  if (pOC != NULL)
2165  {
2166  pModule = DSC_ModuleListFindById( pOC->llcOcModuleAcquires, moduleId );
2167  if (pModule != NULL)
2168  {
2169  filterInfo.hCarousel = (MemHandle)pOC;
2170  filterInfo.target.u.pModule = pModule;
2171  filterInfo.target.id = prestoredSectionsTable[accCarouselLoadingInfos.storeReadPos].moduleID;
2172  filterInfo.target.kind = SFK_DDB;
2173  err = internalSysProcessPrivateSection( idp, pDDBSection, (void *)&filterInfo);
2174  prestoredSectionsTable[accCarouselLoadingInfos.storeReadPos].injectionDone = 1;
2175  }
2176  }
2177  }
2178  accCarouselLoadingInfos.storeReadPos++;
2179  }
2180 }
2181 
2182 E_DscError requestedModuleIdSet(U16BIT moduleID)
2183 {
2184  if (moduleID < kMAX_MODULE_ID)
2185  {
2186  if (requestedModuleIDList[moduleID] != kDO_INJECT)
2187  {
2188  requestedModuleIDList[moduleID] = kDO_INJECT;
2189  GBL_NewResquetedModuleID++;
2190  }
2191  }
2192 }
2193 
2194 E_DscError requestedModuleIdReset(U16BIT moduleID)
2195 {
2196  if (moduleID < kMAX_MODULE_ID)
2197  {
2198  requestedModuleIDList[moduleID] = kNOT_REQUESTED;
2199  }
2200 }
2201 
2202 #endif /* ACCELERATE_CAROUSEL_LOADING */
2203 
2204 
E_DscError CDSM_SysSetCurrService(H_DsmCoreInst instance, U16BIT original_network_id, U16BIT transport_stream_id, U16BIT service_id)
Set/notify the current service (initially and when changing it). This MUST be called initially (ie...
Definition: clDsmMain.c:819
General include file for clDsm library internal definitions.
E_DscError CDSM_SysReset(H_DsmCoreInst instance, E_DsmRstMode mode)
Reset DSM-CC Core Layer instance. Resets conditions to the same state as after CDSM_SysCreate(ie. keeps setup parameters). In normal operation the client MUST first unsubscribe all events, close and and unload all objects and unload all carousels before calling this function. This will have also stopped/deleted all associated system resources (ie. SI queries, timers, SI change monitors, section filters). If any client transactions or system transactions are still active when clDsmReset is called the reset will not be executed and an error returned. NB. The calling environment (system side) must acknowledge stop commands for SI Queries and timers (via processSIQueryEvent, processTimerEvent) and that these may occur asynchronously (ie. after a delay). This means that there may still be some active system transactions for some time after all objects and carousels are unloaded. FORCING RESET IN ERROR CONDITIONS: If all client and system transactions are apparently completed but still returns an error (eg. because handles are unknown/lost or system resource stop requests are not acknowledged) then clDsmReset can be called with appropriate force switches to clear the error condition. Any client transaction errors must first be cleared before system transaction errors can be cleared and both force switches cannot be set at the same time. NB. Only use force switches in known error conditions. It is potentially fatal (may cause illegal memory access) to call the functions: streamEventUnsubscribe, unloadObject, unloadCarousel, processSIQueryEvent, processTimerEvent with old/stale handles after clDsmReset has been forced. CALLBACKS THAT MAY BE INITIATED DURING THIS CALL: deleteSectionFilter stopTimer stopSIQuery unsubscribeSIChange.
Definition: clDsmMain.c:669
E_DscError siQueryProcessResult(P_DsmCoreInst idp, P_SiQuery pSiQueryRef, P_SIQueryResult pResult)
Processes and stops the specified SI Query.
Definition: siQuery.c:523
Header to the loadMgr module.
Defines memory access utils to work with contiguous memory.
E_DscError CDSM_SysProcessSIQueryEvent(H_DsmCoreInst idp, H_SIQueryRef clDsmSIQueryRef, void *clDsmSIUserData, P_SIQueryResult pResult)
Notifies the result of the specified SI query (ie. a callback to startSIQueryFunc that returned SIQUE...
Definition: clDsmMain.c:1034
void CDSM_SetPrintFuncs(F_Printf errorFunc, F_Printf warnFunc, F_Printf debugFunc, F_Printf infoFunc)
Sets debug print functions for four different levels of detail. Any of these parameters can be set to...
Definition: clDsmMain.c:145
DSM-CC functions related to PMT update (header)
E_DscError CDSM_SysProcessSIChangeEvent(H_DsmCoreInst instance, E_SIChangeEvent event, U16BIT service_id, U32BIT carousel_id)
Notify that the SI for the indicated service has changed Changes should be notified in the following ...
Definition: clDsmMain.c:1113
Header to the cacheMgr module.
void CDSM_SysSetMemoryMax(H_DsmCoreInst instance, U32BIT maxMemory)
Set maximum memory usage.
Definition: clDsmMain.c:772
Header to the moduleDecompress module.
Header to dsmObject module - functions for managing DSM object heap.
Main API to DSM-CC core layer (provided functions and required callbacks).
E_DscError CDSM_SysProcessTimerEvent(H_DsmCoreInst instance, void *clDsmTmrUserData, E_TimerStatus status, void *timerHandle)
Definition: clDsmMain.c:916
void CDSM_SetPrintState(U32BIT state)
Sets debug print state to select areas of debug.
Definition: clDsmMain.c:156
E_DscError CDSM_UnloadCarousel(H_DsmCoreInst instance, H_DsmCarousel clDsmCarouselHandle, E_DsmRstMode mode)
Unload (or cancel the requested load of) a DSM-CC Object Carousel (service domain). The client MUST first unload all objects before calling this function (which implies it must also have previously closed and/or unsubscribed any events on any loaded objects). If there are any active object loads in the carousel when clDsmUnloadCarousel is called then the unload will not be executed and an error returned. If the carousel is in the process of loading and/or booting the load operation will be aborted (and the notifyCarouselLoadEventFunc callback made with status OC_LOAD_ABORTED_UNLOAD). Any carousel load request that returned a valid CDSM_CarouselHandle(ie. did not generate an error at clDsmLoadCarousel call time), must be explicitly unloaded via clDsmUnloadCarousel. This is necessary, whether the carousel was successfully loaded or the load was aborted due to timeout or error. Once unload is called for a carousel, the clDsmCarouselHandle is no longer valid and must not be used by the client/calling env. If it needs to access the carousel subsequently it must re-load it and get a new clDsmCarouselHandle value. To forcefully destroy loaded objects and/or carousels (eg. where the handles may be unknown/lost) then clDsmReset can be used with force switches. Note that this physically deletes them from the cache whereas unloading (objects or carousels) does not. CALLBACKS THAT MAY BE INITIATED DURING THIS CALL: delSectionFilterFunc stopTimerFunc stopSIQueryFunc unsubscribeSIChange notifyCarouselLoadEventFunc.
void CDSM_SetDebugState(H_DsmCoreInst dsm, U32BIT dbgMask)
Set Debug mask for core DSM.
Definition: clDsmMain.c:169
void DSC_ModuleDeleteDcTidyUp(P_DsmCoreInst idp, P_Module pModule)
Delete module and destroy parent DC if now empty.
Definition: module.c:388
E_DscError CDSM_SysDestroy(H_DsmCoreInst instance, H_SiqInstance *pSiqInst, H_SfmInstance *pSfmInst)
Destroy DSM-CC Core Layer instance. De-allocates all 'static' memory used by the instance (via freeFu...
Definition: clDsmMain.c:467
Header to dsmStreamEvent module - functions for managing DSM streamEvent.
Header to the sectionFilter module.
Header to siQuery module - functions for managing SI queries.
void siQueryStop(P_DsmCoreInst idp, P_SiQuery pSiQueryRef)
Stops the specified SI Query. Removes from any lists it is in and destroys associated memory object...
Definition: siQuery.c:283
H_DsmControl CDSM_SysGetControl(H_DsmCoreInst instance)
Get control handle from DSM instance .
Definition: clDsmMain.c:532
Header to the 'module' module - Functions/methods for creating/destroying and managing attributes of ...
eader to the clDsmUtils module.