DSMCC  17.9.0
 All Data Structures Files Functions Typedefs
dataCarousel.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  *******************************************************************************/
26 /*---includes for this file--------------------------------------------------*/
27 #include "clDsmSystem.h"
28 #include "dataCarousel.h"
29 
30 #include "module.h"
31 #include "cacheMgr.h"
32 #include "clDsmUtils.h"
33 #include "sectionFilter.h"
34 #include "sectionTimer.h"
35 #include "rootCarousel.h"
36 
37 /*------------------------------- Local Macros -------------------------------*/
38 
39 
40 
41 /*------------------------------ Exported Data -----------------------------*/
42 
43 
44 
45 /*--------------------------------Local Types --------------------------------*/
46 
47 
48 
49 /*------------------------------- Local Statics ------------------------------*/
50 
51 
52 
53 /*------------------- local prototypes/forward declarations ------------------*/
54 
55 static E_DscError UpdateDiiModules( P_DsmCoreInst idp, P_DataCarousel pDC );
56 static E_DscError FetchDiiModules( P_DsmCoreInst idp, P_DataCarousel pDC );
57 static E_DscError FetchSsuModules( P_DsmCoreInst idp, P_DataCarousel pDC );
58 static E_DscError StartNextSsuDownload( P_DsmCoreInst idp, P_DataCarousel pDC );
59 static void AbortSsuDownload( P_DsmCoreInst idp, P_DataCarousel pDC );
60 static void LoadFinalise( P_DsmCoreInst idp, P_RootLoadRqst pLoadRqst );
61 
62 /* -- CONTIGUOUS MEMORY DATA ACCESS FUNCTIONS */
63 static BOOLEAN GetDiiMsgInfoContig( P_DataCarousel pDC, const U8BIT *pDiiMsg );
64 static BOOLEAN dcFindModuleInDiiMsgContig( const MemPtr pDiiMsg, U32BIT dataLength,
65  U16BIT moduleId, MemPtr *pModuleInfoDescStart );
66 static BOOLEAN dcGetModuleInfoContig( const MemPtr pModuleInfoDescStart,
67  S_ModuleInfo *pModuleInfo );
68 static void dcGetFirstModuleDescContig( const MemPtr mpDiiMsg, MemPtr *mpModuleInfoDescStart );
69 static void dcGetNextModuleDescContig( const MemPtr mpCurrModuleDescStart, MemPtr *mpNextModuleDescStart );
70 
71 #ifdef MEM_CONTIGUOUS
72 
73 #define dcFindModuleInDiiMsgSeq dcFindModuleInDiiMsgContig
74 #define dcGetModuleInfoSeq dcGetModuleInfoContig
75 
76 #else
77 
78 /* -- MANAGED MEMORY DATA ACCESS FUNCTIONS */
79 static BOOLEAN dcFindModuleInDiiMsgSeq( const MemPtr mpDiiMsg, U32BIT dataLength,
80  U16BIT moduleId, MemPtr *mpModuleInfoDescStart );
81 static BOOLEAN dcGetModuleInfoSeq( const MemPtr mpModuleInfoDescStart, S_ModuleInfo *pModuleInfo );
82 
83 #endif
84 
85 /*---------------------------- Exported Functions ----------------------------*/
86 
87 /* /////////////////////////////////////////////////////////////////////////////
88 // DSC_DataCrslCreate
89 // Creates an instance of the DataCarousel struct and initialises it.
91 E_DscError DSC_DataCrslCreate( P_DsmCoreInst idp, P_RootCarousel pRC,
92  P_DeliveryParaTap pTap, P_DataCarousel *ppDataCarousel )
93 {
94  P_DataCarousel pDC = NULL;
95  E_DscError err;
96 
97  dsmDP3(("DSC_DataCrslCreate()\n"));
98  dsmAssert((idp != NULL));
99  dsmAssert((pTap != NULL));
100  dsmAssert((ppDataCarousel != NULL));
101 
102  pDC = (P_DataCarousel)DSC_CmMemGet( idp, sizeof(S_DataCarousel) );
103  if (!pDC)
104  {
105  err = CLDSM_ERR_MEM_HEAP_FULL;
106  }
107  else
108  {
109  err = CLDSM_OK;
110  llLinkInit( pDC->llData, NUM_LISTS_DATA_CAROUSEL );
111 
112  pDC->dataCarouselId =
113  (U16BIT)(pTap->transactionId & TRANSACTION_ID_IDENT_MASK);
114 
115  pDC->transIdver = INVALID_TRANSIDVER;
116  pDC->diiCrc = 0;
117  pDC->tap = *pTap;
118  pDC->pDiiSf = NULL;
119  pDC->diiRequestCount = 0;
120  pDC->diiMonitorCount = 0;
121 
122  pDC->diiInfo.blockSize = 0;
123  pDC->diiInfo.numberOfModules = 0;
124 
125  pDC->diiMsgDataLen = 0;
126  pDC->hDiiMsgData = NULL;
127  pDC->llcLoadRequests = NULL;
128 
129  /* -- Create the module list header block */
130  err = LLCreate( idp, pDC, DC_MODULE_LIST, &pDC->llcDcModules );
131  dsmDP4(("%x pDiiSf=%x\n", err, pDC->pDiiSf));
132 
133  if (err)
134  {
135  DSC_CmMemRelease( idp, pDC );
136  *ppDataCarousel = NULL;
137  }
138  else
139  {
140  err = LLCreate( idp, pDC, MODULE_ACQUIRE_LIST, &pDC->llcModuleAcquires );
141  if (err)
142  {
143  LLDestroy( idp, &(pDC->llcDcModules));
144  DSC_CmMemRelease( idp, pDC );
145  *ppDataCarousel = NULL;
146  }
147  else
148  {
149  DSC_RootCrslAddDataCarousel( pRC, pDC );
150  *ppDataCarousel = pDC;
151  }
152  }
153  }
154 
155  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: DSC_DataCrslCreate: %u\n", err)));
156  dsmDP3(("exit DSC_DataCrslCreate -> rtn: %u\n", err));
157  return err;
158 }
159 
160 /* /////////////////////////////////////////////////////////////////////////////
161 // DSC_DataCrslDestroy
162 // Destroys an instance of the DataCarousel struct, and all associated data.
164 void DSC_DataCrslDestroy( P_DsmCoreInst idp, P_DataCarousel pDC )
165 {
166  dsmAssert((idp != NULL));
167  dsmAssert((pDC != NULL));
168 
169  /* -- Should not be in acquire list */
170  dsmAssert((pDC->llData[OC_DII_ACQUIRE_LIST].pLLCtrl == NULL));
171 
172  /* -- Remove from object carousel DC list */
173  LLRemove( pDC, OC_DATA_CAROUSEL_LIST );
174 
175  /* -- Should not have a load request */
176  dsmAssert((pDC->llcLoadRequests == NULL));
177  /* -- Should not have a section filter assigned */
178  dsmAssert((pDC->pDiiSf == NULL));
179  /* -- Should still have a module list ctrl block */
180  dsmAssert((pDC->llcDcModules != NULL));
181  /* -- Should still have a module list ctrl block */
182  dsmAssert((pDC->llcModuleAcquires != NULL));
183 
184  #ifndef NDEBUG
185  {
186  int listCount;
187  /* -- module list should be empty */
188  listCount = LLCount( pDC->llcDcModules );
189  dsmAssert((listCount == 0));
190  }
191  #endif
192 
193  LLDestroy( idp, &(pDC->llcDcModules));
194  LLDestroy( idp, &(pDC->llcModuleAcquires));
195 
196  if (pDC->hDiiMsgData)
197  {
198  DSC_CmMemRelease( idp, pDC->hDiiMsgData );
199  pDC->hDiiMsgData = NULL;
200  }
201 
202  DSC_CmMemRelease( idp, pDC );
203 
204  dsmDP3(("exit DSC_DataCrslDestroy\n"));
205 }
206 
207 /* /////////////////////////////////////////////////////////////////////////////
208 // DSC_DataCrslDelete
209 //
211 void DSC_DataCrslDelete( P_DsmCoreInst idp, P_DataCarousel pDC )
212 {
213  P_Module pModule;
214  P_Module pPrev;
215  P_RootLoadRqst pLR;
216 
217  dsmDP3(("DSC_DataCrslDelete()\n"));
218  dsmAssert((idp != NULL));
219  dsmAssert((pDC != NULL));
220 
221  DBGLOG(DD_DC, "aqc %d,%d", pDC->diiRequestCount, pDC->diiMonitorCount)
222 
223  while (pDC->llcLoadRequests != NULL)
224  {
225  pLR = LLRemoveTail( pDC->llcLoadRequests );
226  if (pLR == NULL)
227  {
228  LLDestroy( idp, &pDC->llcLoadRequests );
229  break;
230  }
231  dsmAssert((pLR->status != LRS_ABORT_PENDING_RELOAD));
232  DSC_LoadRsqtAbort( idp, pLR );
233  /* When finalise function is LoadFinalise, DSC_LoadRsqtAbort() ends up
234  * calling DSC_DataCrslCheckSsuStatus(), and if it is the only remaining
235  * load request for the data carousel, then pDC->llcLoadRequests will
236  * have been destroyed and set to NULL
237  */
238  }
239 
240  /* -- Delete the attached module(s) */
241  pModule = LLTail( pDC->llcDcModules );
242  /* -- Should be at-least one module */
243  // dsmAssert(( pModule != NULL ));
244  while (pModule != NULL)
245  {
246  pPrev = LLPrev( pModule, DC_MODULE_LIST );
247  DSC_ModuleDelete( idp, pModule );
248  pModule = pPrev;
249  }
250 
251  /* -- Clear any existing DII acquisition requests */
252  if ((pDC->diiRequestCount != 0) || (pDC->diiMonitorCount != 0))
253  {
254  LLRemove( pDC, OC_DII_ACQUIRE_LIST );
255  if (pDC->pDiiSf != NULL)
256  {
257  DBGLOG(DD_SF, "pDiiSf=%x", pDC->pDiiSf)
258  DSC_SectionFilterStop( idp, &pDC->pDiiSf );
259  }
260  }
261 
262  DSC_DataCrslDestroy( idp, pDC );
263 
264  dsmDP3(("exit DSC_DataCrslDelete\n"));
265 }
266 
267 E_DscError DSC_DataCrslAcquireStart( P_DsmCoreInst idp, P_DataCarousel pDC, E_SFPriority sfPriority )
268 {
269  S_SfTarget target;
270  E_DscError err;
271  P_RootCarousel pRC;
272  pRC = (P_RootCarousel)LLParent(pDC, OC_DATA_CAROUSEL_LIST);
273  if (LLInsertHead( pRC->llcDiiAcquires, pDC ))
274  {
275  target.kind = SFK_DII;
276  target.id = pDC->dataCarouselId;
277  target.associationTag = pDC->tap.associationTag;
278  target.serviceId = (target.associationTag == INVALID_ASSOCIATION_TAG) ?
279  DSC_RootCrslGetPid(pRC) : DSC_RootCrslGetServiceId(pRC);
280  target.u.pDC = pDC;
281  dsmDP3(("INFO: Load Data Carousel (DII) Id: %u\n", (pDC->dataCarouselId >> 1)));
282  /* -- DC/DII not already being acquired, so start section filter */
283  err = DSC_SectionFilterStart( idp, &target, sfPriority, &pDC->pDiiSf );
284  if (err == CLDSM_ERR_SI_QUERY_FAILED)
285  {
286  DBGLOG((DD_SF|DD_DC), " Treating query failure as OK")
287  err = CLDSM_OK;
288  }
289  }
290  else
291  {
292  dsmAssert((pDC->pDiiSf));
293  /* -- DC/DII already being acquired so update filter priority */
294  err = DSC_SsectionFilterUpdatePriority( idp, pDC->pDiiSf, sfPriority, /*latchHighest*/ FALSE );
295  }
296  if (err)
297  {
298  ERRPRINT(" err=%d", err)
299  LLRemove( pDC, OC_DII_ACQUIRE_LIST );
300  }
301  else if (sfPriority == SF_PRIORITY_HIGH)
302  {
303  pDC->diiRequestCount++;
304  DBGLOG((DD_SF|DD_DC), "HIGH priority cnt %d sf %p",pDC->diiRequestCount,pDC->pDiiSf)
305  }
306  else
307  {
308  pDC->diiMonitorCount++;
309  DBGLOG((DD_SF|DD_DC), "LOW priority cnt %d sf %p",pDC->diiMonitorCount,pDC->pDiiSf)
310  }
311  return err;
312 }
313 
314 E_DscError DSC_DataCrslAcquireRestart( P_DsmCoreInst idp, P_DataCarousel pDC )
315 {
316  S_SfTarget target;
317  E_DscError err;
318  E_SFPriority sfPriority;
319 
320  if (pDC->pDiiSf != NULL)
321  {
322  target = pDC->pDiiSf->target;
323  sfPriority = pDC->pDiiSf->filter.priority;
324  DSC_SectionFilterStop( idp, &pDC->pDiiSf );
325  }
326  else
327  {
328  P_RootCarousel pRC = (P_RootCarousel)LLParent(pDC, OC_DATA_CAROUSEL_LIST);
329  target.kind = SFK_DII;
330  target.id = pDC->dataCarouselId;
331  target.associationTag = pDC->tap.associationTag;
332  target.serviceId = (target.associationTag == INVALID_ASSOCIATION_TAG) ?
333  DSC_RootCrslGetPid(pRC) : DSC_RootCrslGetServiceId(pRC);
334  target.u.pDC = pDC;
335  sfPriority = (pDC->diiRequestCount)? SF_PRIORITY_HIGH : SF_PRIORITY_LOW;
336  }
337  err = DSC_SectionFilterStart( idp, &target, sfPriority, &pDC->pDiiSf );
338  DBGLOG((DD_SF|DD_DC), " err=%d pDC->pDiiSf=%x", err, pDC->pDiiSf)
339  return err;
340 }
341 
342 void DSC_DataCrslAcquireStop( P_DsmCoreInst idp, P_DataCarousel pDC, E_SFPriority sfPriority )
343 {
344  if (sfPriority == SF_PRIORITY_HIGH)
345  {
346  if (pDC->diiRequestCount > 0)
347  pDC->diiRequestCount--;
348  }
349  else
350  {
351  if (pDC->diiMonitorCount > 0)
352  pDC->diiMonitorCount--;
353  }
354  if ((pDC->diiRequestCount == 0) && (pDC->diiMonitorCount == 0))
355  {
356  LLRemove( pDC, OC_DII_ACQUIRE_LIST );
357  if (pDC->pDiiSf != NULL)
358  {
359  DBGLOG(DD_SF, "pDiiSf=%x", pDC->pDiiSf)
360  DSC_SectionFilterStop( idp, &pDC->pDiiSf );
361  }
362  }
363 }
364 
365 /* /////////////////////////////////////////////////////////////////////////////
366 // DSC_DataCrslListFindById
367 // Find a dataCarousel in a dataCarouselList by it's transactionId (ID part)
368 // Returns NULL in phDataCarousel if not found.
370 P_DataCarousel DSC_DataCrslListFindById( P_LLControl pDcList, U32BIT transactionId )
371 {
372  U16BIT searchDcId = (U16BIT)(transactionId & TRANSACTION_ID_IDENT_MASK);
373  P_DataCarousel pDcFromList = NULL;
374  ListId_t listId;
375 
376  dsmDP3(("DSC_DataCrslListFindById()\n"));
377 
378  /* Get listId and first DC in list from Control block */
379  listId = LListId( pDcList );
380  pDcFromList = (P_DataCarousel)LLHead( pDcList );
381 
382  /* Go through each DC in list until the one with a matching transactionId
383  is found */
384  while (pDcFromList)
385  {
386  /* Is this the DC we want? */
387  if (pDcFromList->dataCarouselId == searchDcId)
388  {
389  /* Found the DC */
390  break;
391  }
392  pDcFromList = LLNext( pDcFromList, listId );
393  }
394  dsmDP3(("exit DSC_DataCrslListFindById: %p\n", pDcFromList));
395  return pDcFromList;
396 }
397 
398 U16BIT DSC_DataCrslGetServiceId( P_DataCarousel pDC )
399 {
400  return DSC_RootCrslGetServiceId( LLParent(pDC, OC_DATA_CAROUSEL_LIST));
401 }
402 
403 U16BIT DSC_DataCrslGetPid( P_DataCarousel pDC )
404 {
405  return DSC_RootCrslGetPid( LLParent(pDC, OC_DATA_CAROUSEL_LIST));
406 }
407 
408 P_Module DSC_DataCrslFirstModule( P_DataCarousel pDC )
409 {
410  return LLHead( pDC->llcDcModules );
411 }
412 
413 void DSC_DataCrslUnloadModule( P_DsmCoreInst idp, P_DataCarousel pDC,
414  U16BIT moduleId )
415 {
416  P_Module pModule;
417  pModule = LLHead( pDC->llcDcModules );
418  while ( pModule != NULL )
419  {
420  if (pModule->moduleInfo.moduleId == moduleId)
421  {
422  dsmAssert((pModule->status == MS_CACHED));
423  dsmAssert((pModule->hModuleData != NULL));
424  /* finished with module - delete it */
425  DSC_ModuleDelete( idp, pModule );
426  break;
427  }
428  pModule = LLNext( pModule, DC_MODULE_LIST );
429  }
430 }
431 
432 
433 E_DscError DSC_DataCrslNewModuleLoad( P_DsmCoreInst idp, P_DataCarousel pDC, P_Module pModule )
434 {
435  E_DscError err;
436  MemPtr mpDiiMsg;
437  MemPtr mpStart;
438 
439  dsmAssert((pModule->status == MS_INITIAL));
440  if (pDC->hDiiMsgData != NULL)
441  {
442  MEMPTR_SEQ_OPEN( MEM_CONTEXT, pDC->hDiiMsgData, 0, pDC->diiMsgDataLen, FALSE, mpDiiMsg );
443  MEMPTR_OPEN( mpDiiMsg, mpStart );
444 
445  pModule->moduleInfo.crslMagic = DSC_RootCrslMagic(LLParent(pDC, OC_DATA_CAROUSEL_LIST));
446 
447  if ( dcFindModuleInDiiMsgSeq( mpDiiMsg, pDC->diiMsgDataLen, pModule->moduleInfo.moduleId, &mpStart ) &&
448  dcGetModuleInfoSeq( mpStart, &pModule->moduleInfo ) )
449  {
450  /* -- Add monitor on DII in-case version change occurs */
451  err = DSC_DataCrslAcquireStart( idp, pDC, SF_PRIORITY_LOW );
452  if (!err)
453  {
454  pModule->moduleInfo.blockSize = pDC->diiInfo.blockSize;
455  pModule->status = MS_PENDING_DDB;
456  }
457  else
458  {
459  /* -- First request for new module so abort module on failure */
460  DSC_ModuleDeleteDcTidyUp( idp, pModule );
461  }
462  MEMPTR_CLOSE( mpStart );
463  MEMPTR_SEQ_CLOSE( MEM_CONTEXT, pDC->hDiiMsgData, mpDiiMsg );
464  }
465  else
466  {
467  DBGLOG(DD_DC," ModuleId %u not found in STORED DII", pModule->moduleInfo.moduleId)
468  /* This may be an erroneous load (broadcast error) or
469  -- it may be a request for a new module for which
470  -- the updated DII has not yet arrived.
471  -- In-case it is the latter, force DII to be
472  -- re-acquired by destroying 'erroneous' DII message
473  -- data store.
474  -- Module stays at status MS_INITIAL so DII is
475  -- re-fetched (see below).
476  -- NB. DII is only re-fetched once. If module still
477  -- cannot be found when new DII arrives the load will
478  -- be aborted
479  */
480  MEMPTR_CLOSE( mpStart );
481  MEMPTR_SEQ_CLOSE( MEM_CONTEXT, pDC->hDiiMsgData, mpDiiMsg );
482  DSC_CmMemRelease( idp, pDC->hDiiMsgData );
483  pDC->hDiiMsgData = NULL;
484  pDC->diiMsgDataLen = 0;
485  pDC->transIdver = INVALID_TRANSIDVER;
486  pDC->diiCrc = 0;
487  err = DSC_DataCrslAcquireStart( idp, pDC, SF_PRIORITY_HIGH );
488  if (!err)
489  {
490  pModule->status = MS_PENDING_INFO;
491  }
492  else
493  {
494  DSC_ModuleDeleteDcTidyUp( idp, pModule );
495  }
496  }
497  }
498  else /* if (pDC->hDiiMsgData == NULL) So no DII message data store */
499  {
500  /* First request for new module so request DII */
501  err = DSC_DataCrslAcquireStart( idp, pDC, SF_PRIORITY_HIGH );
502  if (!err)
503  {
504  pModule->status = MS_PENDING_INFO;
505  }
506  else
507  {
508  DSC_ModuleDeleteDcTidyUp( idp, pModule );
509  }
510  }
511  return err;
512 }
513 
514 /* /////////////////////////////////////////////////////////////////////////////
515 //
516 // Called when a new DII message arrives to supply info for new module
517 // builds and check current modules for version updates.
518 //
519 // If turboCaching enabled, also creates and requests (loads) any modules
520 // not already in the cache.
521 //
523 E_DscError DSC_DataCrslUpdate( P_DsmCoreInst idp, P_DataCarousel pDC, U32BIT transactionId,
524  U8BIT *pDiiMsg, U16BIT diiMsgDataLen )
525 {
526  E_DscError err = CLDSM_OK;
527  U32BIT diiCrc;
528  MemPtr mpDiiMsgData;
529  U16BIT transIdver;
530 
531  dsmAssert((idp != NULL));
532  dsmAssert((pDC != NULL));
533  dsmAssert((pDiiMsg != NULL));
534 
535  sectionTimerRemove(idp, pDC->pDiiSf);
536 
537  diiCrc = CDSM_UtilCalculateCRC(pDiiMsg, diiMsgDataLen);
538  transIdver = (transactionId & TRANSACTION_ID_VERSION_MASK) >> 16;
539 
540  if (pDC->diiRequestCount ||
541  (pDC->diiMonitorCount && (transIdver != pDC->transIdver || pDC->diiCrc != diiCrc)))
542  {
543  if (pDC->hDiiMsgData != NULL)
544  {
545  DSC_CmMemRelease( idp, pDC->hDiiMsgData );
546  pDC->hDiiMsgData = NULL;
547  }
548  if (GetDiiMsgInfoContig( pDC, pDiiMsg ))
549  {
550  if (pDC->diiInfo.numberOfModules == 0)
551  {
552  DSC_DataCrslDelete( idp, pDC );
553  }
554  else
555  {
556  pDC->hDiiMsgData = DSC_CmMemGet( idp, diiMsgDataLen );
557  if (pDC->hDiiMsgData == NULL)
558  {
559  err = CLDSM_ERR_MEM_HEAP_FULL;
560  }
561  else
562  {
563  /* -- Store new DII message data and info store */
564  MEMPTR_SEQ_OPEN( MEM_CONTEXT, pDC->hDiiMsgData, 0,
565  diiMsgDataLen, FALSE, mpDiiMsgData );
566  MEMPTR_WRITE( pDiiMsg, mpDiiMsgData, diiMsgDataLen );
567  MEMPTR_SEQ_CLOSE( MEM_CONTEXT, pDC->hDiiMsgData, mpDiiMsgData );
568  pDC->diiMsgDataLen = diiMsgDataLen;
569 
570  if (DSC_RootCrslMagic(LLParent(pDC, OC_DATA_CAROUSEL_LIST)) == UC_MAGIC)
571  {
572  if (pDC->diiCrc != diiCrc || transIdver != pDC->transIdver)
573  {
574  if (pDC->diiCrc != 0)
575  {
576  /* This should never happen with SSU
577  - a DII change while downloading modules */
578  AbortSsuDownload( idp, pDC );
579  }
580  err = FetchSsuModules( idp, pDC );
581  }
582  }
583  else
584  {
585  err = UpdateDiiModules( idp, pDC );
586  if (!err && idp->setup.turboCaching && !idp->cacheFull)
587  {
588  err = FetchDiiModules( idp, pDC );
589  }
590  }
591  pDC->transIdver = transIdver;
592  pDC->diiCrc = diiCrc;
593  }
594  }
595  }
596  }
597  DBGERRCHK(err)
598  return err;
599 }
600 
601 /* /////////////////////////////////////////////////////////////////////////////
602 // updateCachedModuleVersion
603 //
605 static E_DscError UpdateCachedModuleVersion( P_DsmCoreInst idp,
606  P_DataCarousel pDC, P_Module pModule, S_ModuleInfo *pModuleInfo )
607 {
608  P_Module pNewModule;
609  E_DscError err;
610 
611  dsmAssert((idp != NULL));
612  dsmAssert((pModule != NULL));
613  dsmAssert((pModuleInfo != NULL));
614  dsmAssert(((pModule->status == MS_CACHED) ||
615  (pModule->status == MS_ACQ_ABORTED)));
616 
617  if (pModule->loadedCount > 0)
618  {
619  if (DSC_DataCrslFirstModule(pDC) == pModule)
620  {
621  DSC_RootCrslSrgObjectReset(LLParent(pDC, OC_DATA_CAROUSEL_LIST));
622  }
623 
624  /* -- Remove old module from loaded list */
625  LLRemove( pModule, MODULE_LOADED_LIST );
626 
627  /* -- Create new module version */
628  err = DSC_ModuleCreate( idp, pModule->moduleInfo.moduleId, &pNewModule );
629  if (!err)
630  {
631  /* -- Set new module version info */
632  pNewModule->moduleInfo = *pModuleInfo;
633  pNewModule->status = MS_PENDING_DDB;
634 
635  /* -- Insert new module in place of old module in all lists
636  -- of which it is a member */
637  LLReplaceAll( pModule, pNewModule, NUM_LISTS_MODULE );
638 
639  err = DSC_ModuleAcquireStart( idp, pNewModule, SF_PRIORITY_DIRECT );
640  if (err)
641  {
642  DSC_ModuleDelete( idp, pNewModule );
643  }
644  }
645  /* -- Add old module to delete list */
646  pModule->status = MS_EXPIRED;
647  LLInsertHead( idp->llcExpiredModules, pModule );
648  }
649  else /* -- Module not loaded (ie. not in use) */
650  { /* -- Reset module state and update with new version info */
651  DSC_ModuleResetState( idp, pModule, MS_PENDING_INFO );
652  pModule->moduleInfo = *pModuleInfo;
653  pModule->status = MS_PENDING_DDB;
654 
655  if (DSC_DataCrslFirstModule(pDC) == pModule &&
656  DSC_RootCrslSrgObjectReset(LLParent(pDC, OC_DATA_CAROUSEL_LIST)) == CLDSM_OK)
657  {
658  err = DSC_ModuleAcquireStart( idp, pModule, SF_PRIORITY_DIRECT );
659  }
660  else
661  {
662  err = DSC_ModuleAcquireStart( idp, pModule, SF_PRIORITY_CLEAR );
663  }
664  if (err)
665  {
666  DSC_ModuleDelete( idp, pModule );
667  }
668  }
669  return err;
670 }
671 
672 /*
673 -- Update a Data Carousel module with new module info
674 */
675 static E_DscError UpdateDiiModule( P_DsmCoreInst idp,
676  P_DataCarousel pDC, P_ModuleInfo pModuleInfo, P_Module pModule )
677 {
678  E_DscError err = CLDSM_OK;
679 
680  dsmAssert((idp != NULL));
681  dsmAssert((pDC != NULL));
682  dsmAssert((pModuleInfo != NULL));
683  dsmAssert((pModule != NULL));
684 
685  if (pModule->status == MS_PENDING_INFO)
686  {
687  pModule->moduleInfo = *pModuleInfo;
688  pModule->status = MS_PENDING_DDB;
689 
690  /* -- Add monitor on DII in-case version change occurs (and remove
691  -- request for DII) */
692  /* -- NB. Call in this order to prevent unneccessary delete/add of
693  -- sectionFilter (nb. add call cannot fail since DII section filter
694  -- must already be requested so can ignore returns) */
695  err = DSC_DataCrslAcquireStart( idp, pDC, SF_PRIORITY_LOW );
696  dsmAssert((err == CLDSM_OK));
697  DSC_DataCrslAcquireStop( idp, pDC, SF_PRIORITY_HIGH );
698 
699  /* -- Now ready to acquire module data. */
700  /* -- Set high SF priority if this module has client load requests
701  -- otherwise set low SF priority (ie. it is an internal module
702  -- pre-fetch) */
703  err = DSC_ModuleAcquireStart( idp, pModule, DSC_ModulePriority(pModule));
704  if (err)
705  {
706  DSC_ModuleDelete( idp, pModule );
707  }
708  }
709  else /* -- Module status != MS_PENDING_INFO */
710  {
711  dsmAssert((pModule->status != MS_INITIAL));
712  dsmAssert((pModule->status != MS_EXPIRED));
713 
714  if (pModule->moduleInfo.version != pModuleInfo->version ||
715  pModule->moduleInfo.moduleSize != pModuleInfo->moduleSize)
716  {
717  dsmDP4(("Module Id: %u version %u,%u status=%x",
718  pModule->moduleInfo.moduleId, pModule->moduleInfo.version, pModuleInfo->version, pModule->status));
719 
720  switch (pModule->status)
721  {
722  case MS_PENDING_DDB:
723  case MS_BUILDING:
724  {
725  dsmDP4(("(acquiring)\n"));
726  /* -- Module acquisition is in progress so reset and
727  -- continue with new module info */
728  DSC_ModuleResetState( idp, pModule, MS_PENDING_INFO );
729  pModule->moduleInfo = *pModuleInfo;
730  pModule->status = MS_PENDING_DDB;
731  break;
732  }
733  case MS_ACQ_ABORTED:
734  {
735  dsmDP4(("(acquiring)\n"));
736  /*
737  -- This module was previously aborted due to decompression
738  -- failures. Module is now updated so abort or re-acquire
739  -- (depending on whether turbo-caching enabled).
740  */
741  /*fall thro*/
742  }
743  case MS_CACHED:
744  {
745  if (idp->setup.turboCaching == TRUE)
746  {
747  /* -- Update out-of-date module */
748  /* -- NB. ppModule value may get changed */
749  err = UpdateCachedModuleVersion( idp, pDC, pModule, pModuleInfo );
750  }
751  else
752  {
753  DSC_ModuleDelete( idp, pModule );
754  }
755  break;
756  }
757  default:
758  {
759  /* -- Illegal status */
760  dsmDP1(("ERROR: Illegal module status = %u\n", pModule->status));
761  dsmAssert((0));
762  /* -- Set flag to force module abort */
763  err = CLDSM_ERR_INTERNAL;
764  DSC_ModuleDelete( idp, pModule );
765  break;
766  }
767  }
768  }
769  }
770  DBGERRCHK(err)
771  return err;
772 }
773 
774 /* /////////////////////////////////////////////////////////////////////////////
775 //
776 // Called when a new DII message arrives to supply info for new module
777 // builds and check current modules for version updates.
778 //
779 // If turboCaching enabled, also creates and requests (loads) any modules
780 // not already in the cache.
781 //
783 static E_DscError UpdateDiiModules( P_DsmCoreInst idp, P_DataCarousel pDC )
784 {
785  P_Module pModule;
786  P_Module pNextModule;
787  U8BIT *pModuleDescStart;
788  S_ModuleInfo moduleInfo;
789  E_DscError err = CLDSM_OK;
790  E_DscError newErr;
791 
792  dsmAssert((idp != NULL));
793  dsmAssert((pDC != NULL));
794 
795  /* -- Module list should always be present */
796  dsmAssert((pDC->llcDcModules != NULL));
797 
798  moduleInfo.crslMagic = DSC_RootCrslMagic(LLParent(pDC, OC_DATA_CAROUSEL_LIST));
799 
800  /* -- Get first module in dataCarousel */
801  pModule = LLHead( pDC->llcDcModules );
802 
803  /* -- Update all relevant modules in dataCarousel */
804  while (pModule != NULL)
805  {
806  /* -- Determine next module in list before handling module
807  -- update since a version update may change the pModule
808  -- value (actually should be OK because 'new'
809  -- module should be in same position in all lists) */
810  pNextModule = LLNext( pModule, DC_MODULE_LIST );
811 
812  dsmAssert((pModule->status != MS_INITIAL));
813  dsmAssert((pModule->status != MS_EXPIRED));
814 
815  moduleInfo.blockSize = pDC->diiInfo.blockSize;
816  moduleInfo.associationTag = pDC->tap.associationTag;
817 
818  /* -- NB. Use contiguous memory copy of DII here for speed */
819  if (dcFindModuleInDiiMsgContig( pDC->hDiiMsgData, pDC->diiMsgDataLen,
820  pModule->moduleInfo.moduleId, &pModuleDescStart ) &&
821  dcGetModuleInfoContig( pModuleDescStart, &moduleInfo ))
822  {
823  /* -- NB. pModule value may get changed */
824  newErr = UpdateDiiModule( idp, pDC, &moduleInfo, pModule );
825  if (newErr)
826  {
827  err = handleInLoopError( idp, err, newErr );
828  }
829  }
830  else
831  {
832  dsmDP3(("INFO: Module Id: %u not found or not valid in RECEIVED DII\n", pModule->moduleInfo.moduleId));
833  DSC_ModuleDelete( idp, pModule );
834  }
835  pModule = pNextModule;
836  }
837  DBGERRCHK(err)
838  return err;
839 }
840 
841 /*
842 -- Internally prefetch a module into a Data Carousel using DII info
843 --
844 -- NB. This does nothing if the cache is full
845 --
846 */
847 static E_DscError FetchModule( P_DsmCoreInst idp,
848  P_DataCarousel pDC, P_ModuleInfo pModuleInfo )
849 {
850  P_Module pModule;
851  E_DscError err = CLDSM_OK;
852 
853  DBGLOG(DD_DC, " Id: %u", pModuleInfo->moduleId)
854  dsmAssert((idp != NULL));
855  dsmAssert((pDC != NULL));
856  dsmAssert((pModuleInfo != NULL));
857 
858  dsmAssert((idp->cacheFull == FALSE));
859 
860  /* -- Create and request module */
861  err = DSC_ModuleCreate( idp, pModuleInfo->moduleId, &pModule );
862  if (!err)
863  {
864  LLInsertTail( pDC->llcDcModules, pModule );
865  pModule->moduleInfo = *pModuleInfo;
866  pModule->status = MS_PENDING_DDB;
867 
868  /* -- Add monitor on DII in-case version change occurs */
869  err = DSC_DataCrslAcquireStart( idp, pDC, SF_PRIORITY_LOW );
870  if (!err)
871  {
872  /* -- Now ready to acquire module data */
873  err = DSC_ModuleAcquireStart( idp, pModule, SF_PRIORITY_LOW );
874  }
875  if (err)
876  {
877  DSC_ModuleDelete( idp, pModule );
878  }
879  }
880  DBGERRCHK(err)
881  return err;
882 }
883 
884 /* /////////////////////////////////////////////////////////////////////////////
885 //
886 // Creates and requests (loads) any modules not already in the cache.
887 //
889 static E_DscError FetchDiiModules( P_DsmCoreInst idp, P_DataCarousel pDC )
890 {
891  U8BIT *pModuleDescStart;
892  S_ModuleInfo moduleInfo;
893  E_DscError err = CLDSM_OK;
894  E_DscError newErr;
895  U16BIT numModules;
896 
897  dsmDP3(("lmUpdateDataCarousel()\n"));
898  dsmAssert((idp != NULL));
899  dsmAssert((pDC != NULL));
900 
901  /* -- Module list should always be present */
902  dsmAssert((pDC->llcDcModules != NULL));
903  dsmAssert((pDC->diiInfo.numberOfModules != 0));
904 
905  /* -- Loop round all modules in DII message to see if there
906  -- are new ones that need creating/requesting */
907  /* -- NB. Use contiguous memory copy of DII here for speed */
908  numModules = pDC->diiInfo.numberOfModules;
909  /* -- Get first module descriptor in DII */
910  dcGetFirstModuleDescContig( pDC->hDiiMsgData, &pModuleDescStart );
911 
912  memset( &moduleInfo, 0, sizeof(S_ModuleInfo) );
913  moduleInfo.blockSize = pDC->diiInfo.blockSize;
914  moduleInfo.crslMagic = OC_MAGIC;
915 
916  while (numModules--)
917  {
918  if (dcGetModuleInfoContig( pModuleDescStart, &moduleInfo ))
919  {
920  /* -- Check if this module already exists */
921  if (DSC_ModuleListFindById( pDC->llcDcModules, moduleInfo.moduleId ) == NULL)
922  {
923  newErr = FetchModule( idp, pDC, &moduleInfo );
924  if (newErr)
925  {
926  err = handleInLoopError( idp, err, newErr );
927  }
928  }
929  }
930  /* -- Get next module descriptor in DII */
931  dcGetNextModuleDescContig( pModuleDescStart, &pModuleDescStart );
932  }
933  DBGERRCHK(err)
934  return err;
935 }
936 
937 static void DeleteModulesOnLoadRqst( P_DsmCoreInst idp, P_DataCarousel pDC, P_RootLoadRqst pLoadRqst )
938 {
939  P_Module pModule, pPrev;
940  pModule = LLTail( pDC->llcDcModules );
941  while (pModule != NULL)
942  {
943  pPrev = LLPrev( pModule, DC_MODULE_LIST );
944  if (pModule->pLoadRqst == pLoadRqst)
945  {
946  DSC_ModuleDelete( idp, pModule );
947  }
948  pModule = pPrev;
949  }
950 }
951 
952 static void LoadFinalise( P_DsmCoreInst idp, P_RootLoadRqst pLoadRqst )
953 {
954  P_DataCarousel pDC;
955  E_UCLoadStatus status;
956  switch (pLoadRqst->status)
957  {
958  case LRS_INITIAL:
959  {
960  pDC = LLParent((P_Module)pLoadRqst->target, DC_MODULE_LIST);
961  status = SSU_LOAD_ABORTED;
962  break;
963  }
964  case LRS_STALLED_MODULE:
965  {
966  pDC = (P_DataCarousel)pLoadRqst->target;
967  status = SSU_LOAD_STARTING;
968  break;
969  }
970  case LRS_LOADED:
971  {
972  pDC = (P_DataCarousel)pLoadRqst->target;
973  status = SSU_LOAD_COMPLETE;
974  dsmAssert((pLoadRqst->remaining == 0));
975  if (!idp->setup.multipleSsuDownloads)
976  {
977  StartNextSsuDownload( idp, pDC );
978  }
979  pLoadRqst->target = NULL;
980  break;
981  }
982  default:
983  case LRS_ABORTED_LOAD_ERROR:
984  {
985  pDC = (P_DataCarousel)pLoadRqst->target;
986  status = SSU_LOAD_ABORTED;
987  pLoadRqst->target = NULL;
988  DeleteModulesOnLoadRqst( idp, pDC, pLoadRqst );
989  }
990  }
991  if (idp->setup.ssuFuncs.status)
992  {
993  U_StatusRef sr;
994  sr.ur = pLoadRqst->usrRef;
995  idp->setup.ssuFuncs.status( (H_DsmCarousel)LLParent(pDC, OC_DATA_CAROUSEL_LIST), status,
996  sr, pLoadRqst->remaining );
997  }
998  DSC_DataCrslCheckSsuStatus( idp, pDC );
999 }
1000 
1001 /* /////////////////////////////////////////////////////////////////////////////
1002 //
1003 // Creates and requests (loads) all ssu modules
1004 //
1006 static E_DscError FetchSsuModules( P_DsmCoreInst idp, P_DataCarousel pDC )
1007 {
1008  P_Module pModule;
1009  U8BIT *pModuleDescStart;
1010  S_ModuleInfo moduleInfo;
1011  S_LLControl llcModules;
1012  P_RootLoadRqst pLoadRqst;
1013  E_DscError err;
1014  U16BIT numModules;
1015 
1016  dsmAssert((idp != NULL));
1017  dsmAssert((pDC != NULL));
1018 
1019  /* -- Module list should always be present */
1020  dsmAssert((pDC->llcDcModules != NULL));
1021  dsmAssert((pDC->diiInfo.numberOfModules != 0));
1022  dsmAssert((DSC_RootCrslMagic(LLParent(pDC, OC_DATA_CAROUSEL_LIST)) == UC_MAGIC));
1023  dsmAssert((LLHead(pDC->llcDcModules) == NULL));
1024  /* First load request is for Group */
1025  dsmAssert((LLHead(pDC->llcLoadRequests) != NULL));
1026 
1027  LLCtrlBlockInit( &llcModules, DC_MODULE_LIST, pDC );
1028  pLoadRqst = LLHead(pDC->llcLoadRequests);
1029  if (pLoadRqst == NULL)
1030  {
1031  err = CLDSM_ERR_INTERNAL;
1032  }
1033  else
1034  {
1035  err = CLDSM_OK;
1036  /* -- Loop round all modules in DII message to see if there
1037  -- are new ones that need creating/requesting */
1038  /* -- NB. Use contiguous memory copy of DII here for speed */
1039  numModules = pDC->diiInfo.numberOfModules;
1040 
1041  /* -- Get first module descriptor in DII */
1042  dcGetFirstModuleDescContig( pDC->hDiiMsgData, &pModuleDescStart );
1043 
1044  memset( &moduleInfo, 0, sizeof(S_ModuleInfo) );
1045  moduleInfo.blockSize = pDC->diiInfo.blockSize;
1046  moduleInfo.crslMagic = UC_MAGIC;
1047  moduleInfo.associationTag = pDC->tap.associationTag;
1048 
1049  while (numModules--)
1050  {
1051  if (dcGetModuleInfoContig( pModuleDescStart, &moduleInfo ))
1052  {
1053  /* this module should not already exist */
1054  dsmAssert((DSC_ModuleListFindById(pDC->llcDcModules, moduleInfo.moduleId) == NULL));
1055  err = DSC_ModuleCreate( idp, moduleInfo.moduleId, &pModule );
1056  if (err)
1057  {
1058  pModule = LLRemoveTail(&llcModules);
1059  while (pModule != NULL)
1060  {
1061  DSC_ModuleDestroy( idp, pModule );
1062  pModule = LLRemoveTail(&llcModules);
1063  }
1064  break;
1065  }
1066  LLInsertTail( &llcModules, pModule );
1067  pModule->moduleInfo = moduleInfo;
1068  moduleInfo.u.ssup.offset += moduleInfo.originalSize;
1069  }
1070  dcGetNextModuleDescContig( pModuleDescStart, &pModuleDescStart );
1071  }
1072  pLoadRqst->remaining = moduleInfo.u.ssup.offset;
1073  }
1074  if (!err)
1075  {
1076  pModule = LLHead(&llcModules);
1077  while (pModule != NULL && !err)
1078  {
1079  switch ( pModule->moduleInfo.u.ssup.positionType )
1080  {
1081  case PTYP_INIT:
1082  {
1083  LLRemove( pModule, DC_MODULE_LIST );
1084  LLInsertTail( pDC->llcDcModules, pModule );
1085  err = DSC_LoadRsqtCreate( idp, sizeof(S_RootLoadRqst), TT_SSU_MODULE, pModule,
1086  LoadFinalise, &pLoadRqst );
1087  if (!err)
1088  {
1089  LLInsertTail( pDC->llcLoadRequests, pLoadRqst );
1090  pModule->moduleInfo.u.ssup.offset = 0;
1091  pModule->pLoadRqst = pLoadRqst;
1092  pLoadRqst->remaining = pModule->moduleInfo.originalSize;
1093  }
1094  pModule = LLHead(&llcModules);
1095  break;
1096  }
1097  case PTYP_FIRST:
1098  {
1099  LLRemove( pModule, DC_MODULE_LIST );
1100  LLInsertTail( pDC->llcDcModules, pModule );
1101  err = DSC_LoadRsqtCreate( idp, sizeof(S_RootLoadRqst), TT_SSU_MODULE, pModule,
1102  LoadFinalise, &pLoadRqst );
1103  if (!err)
1104  {
1105  LLInsertTail( pDC->llcLoadRequests, pLoadRqst );
1106  pModule->moduleInfo.u.ssup.offset = 0;
1107  pModule->pLoadRqst = pLoadRqst;
1108  moduleInfo.u.ssup.offset = pModule->moduleInfo.originalSize;
1109  pModule = DSC_ModuleListFindById(&llcModules, pModule->moduleInfo.u.ssup.nextModuleId);
1110  while (pModule != NULL && (pModule->moduleInfo.u.ssup.positionType & PTYP_INTER))
1111  {
1112  LLRemove( pModule, DC_MODULE_LIST );
1113  LLInsertTail( pDC->llcDcModules, pModule );
1114  pModule->pLoadRqst = pLoadRqst;
1115  pModule->moduleInfo.u.ssup.offset = moduleInfo.u.ssup.offset;
1116  moduleInfo.u.ssup.offset += pModule->moduleInfo.originalSize;
1117  if (pModule->moduleInfo.u.ssup.positionType == PTYP_LAST)
1118  {
1119  break;
1120  }
1121  pModule = DSC_ModuleListFindById(&llcModules, pModule->moduleInfo.u.ssup.nextModuleId);
1122  }
1123  if (pModule == NULL || pModule->moduleInfo.u.ssup.positionType != PTYP_LAST)
1124  {
1125  ERRLOG(DD_DC,"Invalid end of module link %p",pModule)
1126  err = CLDSM_ERR_END_OF_DATA;
1127  }
1128  else
1129  {
1130  pLoadRqst->remaining = moduleInfo.u.ssup.offset;
1131  }
1132  }
1133  pModule = LLHead(&llcModules);
1134  break;
1135  }
1136  default:
1137  {
1138  ERRLOG(DD_DC,"Unknown position type %d",pModule->moduleInfo.u.ssup.positionType)
1139  err = CLDSM_ERR_END_OF_DATA;
1140  break;
1141  }
1142  case PTYP_LAST:
1143  case PTYP_INTER:
1144  {
1145  pModule = LLNext(pModule,DC_MODULE_LIST);
1146  }
1147  }
1148  }
1149  if (LLCount(&llcModules))
1150  {
1151  ERRLOG(DD_DC,"unassigned modules %d",LLCount(&llcModules))
1152  if (!err)
1153  {
1154  err = CLDSM_ERR_END_OF_DATA;
1155  }
1156  }
1157  if (err)
1158  {
1159  pModule = LLRemoveTail(&llcModules);
1160  while (pModule != NULL)
1161  {
1162  DSC_ModuleDestroy( idp, pModule );
1163  pModule = LLRemoveTail(&llcModules);
1164  }
1165  pModule = LLRemoveTail(pDC->llcDcModules);
1166  while (pModule != NULL)
1167  {
1168  DSC_ModuleDestroy( idp, pModule );
1169  pModule = LLRemoveTail(pDC->llcDcModules);
1170  }
1171  while (LLCount(pDC->llcLoadRequests) > 1)
1172  {
1173  DSC_LoadRsqtDestroy(idp, LLRemoveTail(pDC->llcLoadRequests));
1174  }
1175  }
1176  else
1177  {
1178  DSC_LoadRsqtNotify( idp, LLHead(pDC->llcLoadRequests), LRS_STALLED_MODULE );
1179  DSC_DataCrslAcquireStop( idp, pDC, SF_PRIORITY_HIGH );
1180  err = StartNextSsuDownload( idp, pDC );
1181  DSC_DataCrslCheckSsuStatus( idp, pDC );
1182  }
1183  }
1184  DBGERRCHK(err)
1185  return err;
1186 }
1187 
1188 static H_UsrRef SsuStartModule( P_DsmCoreInst idp, P_Module pModule )
1189 {
1190  H_UsrRef usrRef;
1191  U8BIT *chptr,chsav;
1192  chptr = pModule->moduleInfo.u.ssup.mpName;
1193  if (chptr)
1194  {
1195  chptr += pModule->moduleInfo.u.ssup.nameLen;
1196  chsav = *chptr;
1197  *chptr = 0;
1198  }
1199  usrRef = idp->setup.ssuFuncs.startModule(pModule->moduleInfo.u.ssup.moduleType,
1200  pModule->moduleInfo.u.ssup.mpName);
1201  if (chptr)
1202  {
1203  *chptr = chsav;
1204  }
1205  return usrRef;
1206 }
1207 
1208 static E_DscError StartNextSsuDownload( P_DsmCoreInst idp, P_DataCarousel pDC )
1209 {
1210  E_DscError err = CLDSM_OK;
1211  P_RootLoadRqst pLoadRqst;
1212  P_Module pModule;
1213  pLoadRqst = LLHead(pDC->llcLoadRequests);
1214  if (pLoadRqst != NULL)
1215  {
1216  dsmAssert((pLoadRqst->targetKind == TT_SSU_GROUP));
1217  pLoadRqst = LLNext(pLoadRqst,MODULE_LOAD_REQUEST_LIST);
1218  }
1219  while (pLoadRqst != NULL)
1220  {
1221  dsmAssert((pLoadRqst->targetKind == TT_SSU_MODULE));
1222  if (pLoadRqst->target != NULL && pLoadRqst->usrRef == NULL)
1223  {
1224  pModule = (P_Module)pLoadRqst->target;
1225  pLoadRqst->usrRef = SsuStartModule( idp, pModule );
1226  if (pLoadRqst->usrRef == NULL)
1227  {
1228  P_RootLoadRqst pLR = pLoadRqst;
1229  pLoadRqst = LLPrev(pLR,MODULE_LOAD_REQUEST_LIST);
1230  LLRemove( pLR, MODULE_LOAD_REQUEST_LIST );
1231  pLR->target = NULL;
1232  pLR->remaining = 0;
1233  pLR->status = LRS_ABORTED_PATH_ERROR;
1234  DeleteModulesOnLoadRqst( idp, pDC, pLR );
1235  DSC_LoadRsqtDestroy( idp, pLR );
1236  }
1237  else
1238  {
1239  pLoadRqst->target = pDC;
1240  DSC_LoadRsqtNotify( idp, pLoadRqst, LRS_STALLED_MODULE );
1241  if (!idp->setup.ssuFuncs.wantModuleData)
1242  {
1243  while (pModule->pLoadRqst == pLoadRqst)
1244  {
1245  dsmAssert((pModule->status == MS_INITIAL));
1246  DSC_DataCrslAcquireStart( idp, pDC, SF_PRIORITY_LOW );
1247  if (DSC_ModuleAcquireStart( idp, pModule, SF_PRIORITY_LOW ) == CLDSM_OK)
1248  {
1249  pModule->status = MS_PENDING_DDB;
1250  }
1251  pModule = LLNext(pModule,DC_MODULE_LIST);
1252  }
1253  if (!idp->setup.multipleSsuDownloads)
1254  {
1255  break;
1256  }
1257  }
1258  else
1259  {
1260  while (pModule != NULL && pModule->pLoadRqst == pLoadRqst)
1261  {
1262  dsmAssert((pModule->status == MS_INITIAL));
1263  if (idp->setup.ssuFuncs.wantModuleData(pLoadRqst->usrRef, MAKE_MODULE_REF(pDC->dataCarouselId, pModule->moduleInfo.moduleId),
1264  pModule->moduleInfo.u.ssup.offset, pModule->moduleInfo.originalSize, pModule->moduleInfo.u.ssup.moduleCrc))
1265  {
1266  DSC_DataCrslAcquireStart( idp, pDC, SF_PRIORITY_LOW );
1267  if (DSC_ModuleAcquireStart( idp, pModule, SF_PRIORITY_LOW ) == CLDSM_OK)
1268  {
1269  pModule->status = MS_PENDING_DDB;
1270  }
1271  }
1272  else
1273  {
1274  pModule->pLoadRqst = NULL;
1275  pLoadRqst->remaining -= pModule->moduleInfo.originalSize;
1276  }
1277  pModule = LLNext(pModule,DC_MODULE_LIST);
1278  }
1279  if (!pLoadRqst->remaining)
1280  {
1281  P_RootLoadRqst pLR = pLoadRqst;
1282  pLoadRqst = LLPrev(pLR,MODULE_LOAD_REQUEST_LIST);
1283  DSC_LoadRsqtFinalNotify( idp, pLR, LRS_LOADED );
1284  }
1285  else if (!idp->setup.multipleSsuDownloads)
1286  {
1287  break;
1288  }
1289  }
1290  }
1291  }
1292  pLoadRqst = LLNext(pLoadRqst,MODULE_LOAD_REQUEST_LIST);
1293  }
1294  DBGERRCHK(err)
1295  return err;
1296 }
1297 
1298 static void AbortSsuDownload( P_DsmCoreInst idp, P_DataCarousel pDC )
1299 {
1300  P_RootLoadRqst pLoadRqst, pLR;
1301  pLoadRqst = LLHead(pDC->llcLoadRequests);
1302  ASSERT(pLoadRqst != NULL)
1303  if (pLoadRqst != NULL && pLoadRqst->status == LRS_STALLED_MODULE)
1304  {
1305  while (LLCount(pDC->llcLoadRequests) > 1)
1306  {
1307  pLR = LLTail(pDC->llcLoadRequests);
1308  DSC_LoadRsqtAbort( idp, pLR );
1309  }
1310  }
1311 }
1312 
1313 void DSC_DataCrslCheckSsuStatus( P_DsmCoreInst idp, P_DataCarousel pDC )
1314 {
1315  P_RootLoadRqst pLoadRqst;
1316  pLoadRqst = LLHead(pDC->llcLoadRequests);
1317  if (pLoadRqst != NULL && pLoadRqst->status != LRS_LOADED)
1318  {
1319  dsmAssert((pLoadRqst->targetKind == TT_SSU_GROUP));
1320  pLoadRqst = LLNext(pLoadRqst,MODULE_LOAD_REQUEST_LIST);
1321  while (pLoadRqst != NULL && pLoadRqst->target == NULL)
1322  {
1323  dsmAssert((pLoadRqst->targetKind == TT_SSU_MODULE));
1324  pLoadRqst = LLNext(pLoadRqst,MODULE_LOAD_REQUEST_LIST);
1325  }
1326  if (pLoadRqst == NULL)
1327  {
1328  pLoadRqst = LLHead(pDC->llcLoadRequests);
1329  dsmAssert((pLoadRqst->finalise != LoadFinalise));
1330  DSC_LoadRsqtFinalNotify( idp, pLoadRqst, LRS_LOADED );
1331  if (!LLCount(pDC->llcLoadRequests))
1332  {
1333  LLDestroy( idp, &pDC->llcLoadRequests );
1334  }
1335  }
1336  }
1337 }
1338 
1339 /* -- CONTIGUOUS MEMORY DATA ACCESS FUNCTIONS */
1340 
1341 #include "defMemUtilsContig.h" /* -- Default mem type for functions */
1342 
1343 static BOOLEAN GetDiiMsgInfoContig( P_DataCarousel pDC, const U8BIT *pDiiMsg )
1344 {
1345  U8BIT *pDiiMsgInfo = (U8BIT *) pDiiMsg;
1346  BOOLEAN valid;
1347  U16BIT compatLen;
1348 
1349  dsmAssert((pDiiMsg != NULL));
1350  dsmAssert((pDC != NULL));
1351 
1352  /* -- pDiiMsg -> DIIMessageBody */
1353 
1354  /* -- Skip downloadId - not used here */
1355  SET_POS_REL( pDiiMsgInfo, 4 );
1356 
1357  /* -- blockSize <= MAX_DDB_BLOCKSIZE */
1358  /* -- L0 check because if this is too large we cannot process the module */
1359  /* -- NB. This is VERY unlikely since it with the default (UK MHEG)
1360  -- settings it would imply a broadcast module containing one object >3Mb
1361  -- in size or a broadcast module containing multiple objects with a DDB
1362  -- blockSize of only 80 bytes approx. */
1363  READ_UINT16( pDiiMsgInfo, pDC->diiInfo.blockSize );
1364  if ( pDC->diiInfo.blockSize > MAX_DDB_BLOCKSIZE )
1365  {
1366  dsmDP2(("DATA ERROR: DII Info DDB Blocksize (> %u) = %u\n", MAX_DDB_BLOCKSIZE, pDC->diiInfo.blockSize));
1367  valid = FALSE;
1368  }
1369  else
1370  {
1371  /* -- Skip windowSize, ackPeriod, tCDownloadWindow, tCDownloadScenario - unused in DVB OC */
1372  SET_POS_REL( pDiiMsgInfo, 10 );
1373 
1374  /* -- get compatibilityDescriptorLength */
1375  READ_UINT16( pDiiMsgInfo, compatLen );
1376  if (compatLen == 0)
1377  {
1378  valid = TRUE;
1379  }
1380  else
1381  {
1382  dsmDP3(("DATA: DII Info compatibilityDescriptorLength (!= 0) = %u\n", compatLen));
1383  valid = DSC_RootCrslCheckCompatibility(
1384  (P_RootCarousel)LLParent(pDC, OC_DATA_CAROUSEL_LIST), pDiiMsgInfo, compatLen );
1385  SET_POS_REL( pDiiMsgInfo, compatLen );
1386  }
1387  READ_UINT16( pDiiMsgInfo, pDC->diiInfo.numberOfModules );
1388  DBG2(DD_DC, "No of modules = %u", pDC->diiInfo.numberOfModules)
1389  }
1390  return valid;
1391 }
1392 
1393 static BOOLEAN dcFindModuleInDiiMsgContig(
1394  /*I*/ const MemPtr mpDiiMsg, U32BIT dataLength, U16BIT moduleId,
1395  /*O*/ MemPtr *mpModuleInfoDescStart )
1396 {
1397  BOOLEAN found;
1398 
1399  dsmDP3(("dcFindModuleInDiiMsgContig()\n"));
1400 
1402 
1403  dsmDP3(("exit dcFindModuleInDiiMsgContig -> rtn: %u\n", found));
1404  return found;
1405 }
1406 
1407 static BOOLEAN dcGetModuleInfoContig(
1408  const MemPtr mpModuleInfoDescStart, S_ModuleInfo *pModuleInfo )
1409 {
1410  BOOLEAN valid;
1411 
1412  dsmDP3(("dcGetModuleInfoContig()\n"));
1413 
1414  #include "getModuleInfo_include_src.h"
1415 
1416  dsmDP3(("exit dcGetModuleInfoContig -> rtn: %u\n", valid));
1417  return valid;
1418 }
1419 
1420 static void dcGetFirstModuleDescContig(
1421  /*I*/ const MemPtr mpDiiMsg,
1422  /*O*/ MemPtr *mpModuleInfoDescStart )
1423 {
1424  MemPtr mpModuleInfoDesc;
1425  MemPos currPos = 0;
1426  U16BIT compatLen;
1427 
1428  dsmDP3(("dcGetFirstModuleDescContig()\n"));
1429 
1430  dsmAssert((mpDiiMsg != NULL));
1431  dsmAssert((mpModuleInfoDescStart != NULL));
1432 
1433 
1434  /* -- Open MemPtr for accessing module info in DII message */
1435  MEMPTR_OPEN( mpDiiMsg, mpModuleInfoDesc );
1436 
1437  /* -- mpModuleInfoDesc -> DIIMessageBody */
1438 
1439  /* -- Skip downloadId, blockSize - not used here */
1440  SET_POS_REL( mpModuleInfoDesc, 6 );
1441 
1442  /* -- Skip windowSize, ackPeriod, tCDownloadWindow, tCDownloadScenario - unused in DVB */
1443  SET_POS_REL( mpModuleInfoDesc, 10 );
1444 
1445  /* -- get compatibilityDescriptorLength, and skip */
1446  READ_UINT16( mpModuleInfoDesc, compatLen );
1447  if (compatLen != 0)
1448  {
1449  SET_POS_REL( mpModuleInfoDesc, compatLen );
1450  }
1451 
1452  /* -- Skip numberOfModules - not used here */
1453  SET_POS_REL( mpModuleInfoDesc, 2 );
1454 
1455  /* -- mpModuleInfoDesc -> start of first module descriptor */
1456 
1457  GET_POS( mpModuleInfoDesc, currPos );
1458  SET_POS_ABS( *mpModuleInfoDescStart, currPos );
1459 
1460  MEMPTR_CLOSE( mpModuleInfoDesc );
1461 
1462  dsmDP3(("exit dcGetFirstModuleDescContig\n"));
1463 }
1464 
1465 static void dcGetNextModuleDescContig(
1466  /*I*/ const MemPtr mpCurrModuleDescStart,
1467  /*O*/ MemPtr *mpNextModuleDescStart )
1468 {
1469  MemPtr mpModuleInfoDesc;
1470  MemPos currPos = 0;
1471  U8BIT moduleInfoLength;
1472 
1473  dsmDP3(("dcGetNextModuleDescContig()\n"));
1474 
1475  dsmAssert((mpCurrModuleDescStart != NULL));
1476  dsmAssert((mpNextModuleDescStart != NULL));
1477 
1478  /* -- Open MemPtr for accessing module info in DII message */
1479  MEMPTR_OPEN( mpCurrModuleDescStart, mpModuleInfoDesc );
1480 
1481  /* -- mpModuleInfoDesc -> start of current module descriptor */
1482 
1483  /* -- Skip moduleId - not used here */
1484  SET_POS_REL( mpModuleInfoDesc, 2 );
1485 
1486  /* -- Skip moduleSize, moduleVersion */
1487  SET_POS_REL( mpModuleInfoDesc, 5 );
1488 
1489  /* -- Read moduleInfoLength */
1490  READ_UINT8( mpModuleInfoDesc, moduleInfoLength );
1491 
1492  /* -- Skip objectInfo */
1493  SET_POS_REL( mpModuleInfoDesc, (S32BIT)moduleInfoLength );
1494 
1495  /* -- mpModuleInfoDesc -> start of next module descriptor */
1496 
1497  GET_POS( mpModuleInfoDesc, currPos );
1498  SET_POS_ABS( *mpNextModuleDescStart, currPos );
1499 
1500  MEMPTR_CLOSE( mpModuleInfoDesc );
1501 
1502  dsmDP3(("exit dcGetNextModuleDescContig\n"));
1503 }
1504 
1505 #ifndef MEM_CONTIGUOUS
1506 
1507 /* -- MANAGED MEMORY DATA ACCESS FUNCTIONS */
1508 
1509 #include "defMemUtilsMgd.h" /* -- Default mem type for functions */
1510 
1511 static BOOLEAN dcFindModuleInDiiMsgSeq(
1512  /*I*/ const MemPtr mpDiiMsg, U32BIT dataLength, U16BIT moduleId,
1513  /*O*/ MemPtr *mpModuleInfoDescStart )
1514 {
1515  BOOLEAN found;
1516 
1517  dsmDP3(("dcFindModuleInDiiMsgSeq()\n"));
1518 
1520 
1521  dsmDP3(("exit dcFindModuleInDiiMsgSeq -> rtn: %u\n", found));
1522  return found;
1523 }
1524 
1525 static BOOLEAN dcGetModuleInfoSeq(
1526  const MemPtr mpModuleInfoDescStart, S_ModuleInfo *pModuleInfo )
1527 {
1528  BOOLEAN valid;
1529 
1530  dsmDP3(("dcGetModuleInfoSeq()\n"));
1531 
1532  #include "getModuleInfo_include_src.h"
1533 
1534  dsmDP3(("exit dcGetModuleInfoSeq -> rtn: %u\n", valid));
1535  return valid;
1536 }
1537 
1538 #endif
1540 /*------------------------------ Local Functions -----------------------------*/
1541 
1542 
1543 /*----------------------------------------------------------------------------*/
General include file for clDsm library internal definitions.
void DSC_LoadRsqtAbort(P_DsmCoreInst idp, P_RootLoadRqst pLoadRqst)
Force abort (on error) any type of load request Finalise the load request (notify client) and destroy...
Definition: loadRqst.c:157
Defines memory access utils to work with contiguous memory.
Header to the sectionTimer module.
Common source code to find module info descriptor in DII. To be included by functions processing data...
Header to the cacheMgr module.
void DSC_ModuleDelete(P_DsmCoreInst idp, P_Module pModule)
Destroy the module and destroy parent DC if now empty.
Definition: module.c:303
void DSC_ModuleDeleteDcTidyUp(P_DsmCoreInst idp, P_Module pModule)
Delete module and destroy parent DC if now empty.
Definition: module.c:388
Header to the sectionFilter module.
E_DscError DSC_ModuleAcquireStart(P_DsmCoreInst idp, P_Module pModule, E_SFPriority sfPriority)
Start aquisition of module.
Definition: module.c:204
Header to the 'module' module - Functions/methods for creating/destroying and managing attributes of ...
Defines memory access utils to work with managed (MemMgr) memory.
eader to the clDsmUtils module.
Common source code to extract module info from module info descriptor in DII. To be included by funct...