DSMCC  17.9.0
 All Data Structures Files Functions Typedefs
rootCarousel.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2015 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  *
4  * This file is part of a DTVKit Software Component
5  * You are permitted to copy, modify or distribute this file subject to the terms
6  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
7  *
8  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
9  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
10  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * If you or your organisation is not a member of DTVKit then you have access
13  * to this source code outside of the terms of the licence agreement
14  * and you are expected to delete this and any associated files immediately.
15  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
16  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 
27 #include "rootCarousel.h"
28 #include "module.h"
29 #include "objectCarousel.h"
30 #include "updateCarousel.h"
31 
32 /*------------------------------- Local Macros -------------------------------*/
33 
34 #define INVALID_DSI_TRANSACTION_ID 0xFFFFFFFF
35 
36 /*------------------------------ Exported Data -----------------------------*/
37 
38 
39 
40 /*--------------------------------Local Types --------------------------------*/
41 
42 
43 /*------------------------------- Local Statics ------------------------------*/
44 
45 /*------------------- local prototypes/forward declarations ------------------*/
46 
47 
48 /*------------------------------ Local Functions -----------------------------*/
49 
50 
51 /*---------------------------- Exported Functions ----------------------------*/
52 
53 E_DscError DSC_RootCrslInitialise( P_DsmCoreInst idp, P_RootCarousel pRC, U16BIT magic, U16BIT serviceId, U32BIT cid )
54 {
55  E_DscError err;
56 
57  dsmAssert((idp != NULL));
58  dsmAssert((pRC != NULL));
59 
60  llLinkInit( pRC->llData, NUM_LISTS_ROOT_CAROUSEL );
61 
62  pRC->magic = magic;
63  pRC->rcid = cid;
64  pRC->serviceId = serviceId;
65  pRC->dsiTransactionId = INVALID_DSI_TRANSACTION_ID;
66  pRC->status = RCS_INITIAL;
67  pRC->pCrslInfo = NULL;
68 
69  /* memset(p,0,s) should have called */
70  dsmAssert((pRC->pDsiSf == NULL));
71  dsmAssert((pRC->pPendingSiQueryRef == NULL));
72  dsmAssert((pRC->llcDataCarousels == NULL));
73  dsmAssert((pRC->llcDiiAcquires == NULL));
74 
75  /* -- Create attached lists */
76  err = LLCreate( idp, pRC, OC_DII_ACQUIRE_LIST, &pRC->llcDiiAcquires );
77  if (err)
78  {
79  pRC->llcDiiAcquires = NULL;
80  }
81  else
82  {
83  err = LLCreate( idp, pRC, OC_DATA_CAROUSEL_LIST, &pRC->llcDataCarousels );
84  if (err)
85  {
86  LLDestroy( idp, &pRC->llcDiiAcquires );
87  }
88  else if (NULL != idp->setup.subscribeSIChangeFunc && serviceId != 0)
89  {
90  err = idp->setup.subscribeSIChangeFunc( idp->setup.siqInstance, serviceId );
91  switch (err)
92  {
93  case CLDSM_DUPLICATE_REQUEST:
94  case CLDSM_PENDING:
95  err = CLDSM_OK; /* Pending and duplicate are not errors*/
96  case CLDSM_OK:
97  break;
98 
99  default:
100  {
101  LLDestroy( idp, &pRC->llcDiiAcquires );
102  LLDestroy( idp, &pRC->llcDataCarousels );
103  }
104  }
105  }
106  }
107  return err;
108 }
109 
110 void DSC_RootCrslFinalise( P_DsmCoreInst idp, P_RootCarousel pRC )
111 {
112  dsmAssert((idp != NULL));
113  dsmAssert((pRC != NULL));
114 
115  dsmAssert((pRC->magic == OC_MAGIC || pRC->magic == UC_MAGIC));
116 
117  /* -- Should not be in any lists */
118  dsmAssert((pRC->llData[ROOT_CAROUSEL_LIST].pLLCtrl == NULL));
119 
120  /* -- Should have a DII acquire list ctrl block */
121  dsmAssert((pRC->llcDiiAcquires != NULL));
122 
123  /* -- Should have a DC list ctrl block */
124  dsmAssert((pRC->llcDataCarousels != NULL));
125 
126  /* -- Should not have a section filter assigned */
127  dsmAssert((pRC->pDsiSf == NULL));
128 
129  /* -- Should not have an active SI query */
130  dsmAssert((pRC->pPendingSiQueryRef == NULL));
131 
132 #ifndef NDEBUG
133  {
134  int listCount;
135  /* -- DC list should be empty */
136  listCount = LLCount( pRC->llcDataCarousels );
137  dsmAssert((listCount == 0));
138  }
139 #endif
140 
141  if (NULL != idp->setup.unsubscribeSIChangeFunc && pRC->serviceId != 0)
142  {
143  idp->setup.unsubscribeSIChangeFunc( idp->setup.siqInstance, pRC->serviceId );
144  }
145 
146  /* -- NULL carousel contents. */
147  pRC->magic = 0;
148  pRC->rcid = INVALID_CAROUSEL_ID;
149  pRC->serviceId = 0;
150  pRC->dsiTransactionId = INVALID_DSI_TRANSACTION_ID;
151  pRC->status = RCS_INITIAL;
152  pRC->dsiAssocTag = 0;
153 
154  while (pRC->pCrslInfo != NULL)
155  {
156  P_CarouselInfo pCrslInfo;
157  pCrslInfo = pRC->pCrslInfo->next;
158  idp->setup.freeFunc(pRC->pCrslInfo);
159  pRC->pCrslInfo = pCrslInfo;
160  }
161 
162  LLDestroy( idp, &(pRC->llcDataCarousels));
163  LLDestroy( idp, &(pRC->llcDiiAcquires));
164 }
165 
166 P_RootCarousel DSC_RootCrslGetParentCarousel( P_DataCarousel pDC )
167 {
168  return LLParent( pDC, OC_DATA_CAROUSEL_LIST );
169 }
170 
171 void DSC_RootCrslAbortLoadRequest( P_DsmCoreInst idp, P_RootCarousel pRC )
172 {
173  P_RootLoadRqst pLoadRqst;
174  pLoadRqst = pRC->pLoadRqst;
175  if (NULL != pLoadRqst)
176  {
177  pLoadRqst->status = LRS_ABORTED_LOAD_ERROR;
178  DSC_LoadRsqtFinalise( idp, pLoadRqst );
179  pRC->pLoadRqst = NULL;
180  }
181 }
182 
187  P_CarouselInfo pCarouselInfo )
188 {
189  S_SfTarget target;
190  P_RootLoadRqst pLoadRqst;
191  E_DscError err;
192 
193  dsmAssert((idp != NULL));
194  dsmAssert((pRC != NULL));
195  dsmAssert((pCarouselInfo != NULL));
196  dsmAssert((pRC->status == RCS_PENDING_BOOTINFO));
197 
198  /* TODO: Implement use of FormatID from carousel_id_descriptor
199  for enhanced boot info and enhanced boot mechanism. */
200  if (pRC->rcid == INVALID_CAROUSEL_ID || pRC->rcid == UNKNOWN_CAROUSEL_ID)
201  {
202  pRC->rcid = pCarouselInfo->carouselId;
203  }
204 
205  /* -- Given component_tag references stream on which DSI is broadcast */
206  pRC->dsiAssocTag = pCarouselInfo->associationTag;
207  pRC->pid = pCarouselInfo->pid;
208  pRC->pCrslInfo = pCarouselInfo->next;
209 
210  dsmAssert((pRC->pLoadRqst != NULL));
211  pLoadRqst = (P_RootLoadRqst)pRC->pLoadRqst;
212  dsmAssert((pLoadRqst->status == LRS_INITIAL));
213 
214  /* Request DSI section filter */
215  target.kind = SFK_DSI;
216  target.id = pRC->rcid;
217  target.associationTag = pRC->dsiAssocTag;
218  target.serviceId =
219  (target.associationTag == INVALID_ASSOCIATION_TAG)? pRC->pid : pRC->serviceId;
220  target.u.pRC = pRC;
221  err = DSC_SectionFilterStart( idp, &target, SF_PRIORITY_HIGH, &pRC->pDsiSf );
222  if (!err)
223  {
224  pLoadRqst->status = LRS_STALLED_DSI;
225  /* -- Carousel is now booting */
226  pRC->status = RCS_BOOTING;
227  }
228  else
229  {
230  ERRLOG(DD_OC, "ERR=%u", err)
231  }
232  return err;
233 }
234 
239 {
240  S_SfTarget target;
241  E_DscError err;
242 
243  dsmAssert((idp != NULL));
244  dsmAssert((pRC != NULL));
245 
246  if (pRC->pDsiSf != NULL)
247  {
248  target = pRC->pDsiSf->target;
249  DSC_SectionFilterStop( idp, &pRC->pDsiSf );
250  }
251  else
252  {
253  /* Request DSI section filter */
254  target.kind = SFK_DSI;
255  target.id = pRC->rcid;
256  target.associationTag = pRC->dsiAssocTag;
257  target.serviceId = (target.associationTag == INVALID_ASSOCIATION_TAG)? pRC->pid : pRC->serviceId;
258  target.u.pRC = pRC;
259  }
260  err = DSC_SectionFilterStart( idp, &target, SF_PRIORITY_HIGH, &pRC->pDsiSf );
261  if (err)
262  {
263  ERRLOG(DD_OC, "ERR=%u", err)
264  }
265  return err;
266 }
267 
271 P_RootCarousel DSC_RootCrslListFindById( P_LLControl plcCarousels, U16BIT serviceId, U32BIT couId )
272 {
273  P_RootCarousel pRC = NULL;
274  ListId_t listId;
275 
276  dsmDP3(("ocListFindById()\n"));
277  dsmAssert((plcCarousels != NULL));
278 
279  /* Get listId and first OC in list from Control block */
280  listId = LListId( plcCarousels );
281  pRC = (P_RootCarousel)LLHead( plcCarousels );
282 
283  /* Go through each OC in list until the one with a matching carouselId
284  is found */
285  while (pRC)
286  {
287  /* -- NB. Both service_id and carouselId must match
288  -- to uniquely identify a carousel */
289  if ((pRC->serviceId == serviceId) &&
290  (pRC->rcid == couId))
291  {
292  /* Found the Carousel */
293  break;
294  }
295  pRC = LLNext( pRC, listId );
296  }
297  return pRC;
298 }
299 
300 U16BIT DSC_RootCrslGetServiceId( P_RootCarousel pRC )
301 {
302  return (pRC) ? pRC->serviceId : 0xFFFF;
303 }
304 
305 U16BIT DSC_RootCrslGetPid( P_RootCarousel pRC )
306 {
307  return (pRC) ? pRC->pid : 0xFFFF;
308 }
309 
310 P_DataCarousel DSC_RootCrslFirstDataCarousel( P_RootCarousel pRC )
311 {
312  return LLHead( pRC->llcDataCarousels );
313 }
314 
315 void DSC_RootCrslAddDataCarousel( P_RootCarousel pRC, P_DataCarousel pDC )
316 {
317  dsmAssert((pRC != NULL));
318  dsmAssert((pDC != NULL));
319  LLInsertTail( pRC->llcDataCarousels, pDC );
320 }
321 
322 /* /////////////////////////////////////////////////////////////////////////////
323 //
324 // Unload all data carousels (and associated modules) in carousel
325 //
327 void DSC_RootCrslUnload( P_DsmCoreInst idp, P_RootCarousel pRC )
328 {
329  P_DataCarousel pDC;
330  P_DataCarousel pPrev;
331  dsmAssert((idp != NULL));
332  dsmAssert((pRC != NULL));
333 
334  LLRemove( pRC, ROOT_CAROUSEL_LIST );
335 
336  pDC = LLTail( pRC->llcDataCarousels );
337  while (pDC)
338  {
339  pPrev = LLPrev( pDC, OC_DATA_CAROUSEL_LIST );
340  DSC_DataCrslDelete( idp, pDC );
341  pDC = pPrev;
342  }
343 }
344 
352 void DSC_RootCrslUnloadModule( P_DsmCoreInst idp, P_RootCarousel pRC,
353  U32BIT moduleRef )
354 {
355  P_DataCarousel pDC;
356  U16BIT dcId, moduleId;
357  dsmAssert((idp != NULL));
358  dsmAssert((pRC != NULL));
359 
360  dcId = moduleRef >> 16;
361  moduleId = moduleRef & 0xFFFF;
362  pDC = LLHead( pRC->llcDataCarousels );
363  while (pDC)
364  {
365  if (pDC->dataCarouselId == dcId)
366  {
367  DSC_DataCrslUnloadModule( idp, pDC, moduleId );
368  break;
369  }
370  pDC = LLNext( pDC, OC_DATA_CAROUSEL_LIST );
371  }
372 }
373 
374 void DSC_RootCrslDestroy( P_DsmCoreInst idp, P_RootCarousel pRC )
375 {
376  switch (pRC->magic)
377  {
378  case OC_MAGIC:
379  DSC_ObjCrslDestroy(idp, (P_ObjectCarousel *)&pRC);
380  break;
381  case UC_MAGIC:
382  DSC_UpdCrslDestroy(idp, (P_UpdateCarousel)pRC);
383  break;
384  default:;
385  }
386 }
387 
388 U16BIT DSC_RootCrslMagic( P_RootCarousel pRC )
389 {
390  return (pRC) ? pRC->magic : 0;
391 }
392 
393 E_DscError DSC_RootCrslSrgObjectReset( P_RootCarousel pRC )
394 {
395  E_DscError err;
396  if (!memValidate(pRC) || pRC->magic != OC_MAGIC)
397  {
398  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
399  }
400  else
401  {
402  err = CLDSM_OK;
403  DSC_ObjCrslSrgObjectReset((P_ObjectCarousel)pRC);
404  }
405  return err;
406 }
407 
408 BOOLEAN DSC_RootCrslCheckCompatibility( P_RootCarousel pRC, U8BIT *pCompatDesc, U16BIT compatLen )
409 {
410  if (pRC->magic != UC_MAGIC)
411  {
412  return FALSE;
413  }
414  return DSC_UpdCrslCheckCompatibility( (P_UpdateCarousel)pRC, pCompatDesc, compatLen );
415 }
416 
417 void DSC_RootCrslLoadRequestFail( P_DsmCoreInst idp, P_RootCarousel pRC )
418 {
419  ERRLOG(DD_OC, "RC status %u", pRC->status)
420  if (pRC->pCrslInfo != NULL)
421  {
422  P_CarouselInfo pCrslInfo = pRC->pCrslInfo;
423 
424  /* restart load request */
425  if (pRC->pDsiSf != NULL)
426  {
427  DSC_SectionFilterStop( idp, &pRC->pDsiSf );
428  }
429  pRC->status = RCS_PENDING_BOOTINFO;
430  dsmAssert((pRC->pLoadRqst != NULL));
431  pRC->pLoadRqst->status = LRS_INITIAL;
432  DSC_RootCrslBootCarousel( idp, pRC, pCrslInfo );
433 
434  /* free up extra carousel info */
435  idp->setup.freeFunc(pCrslInfo);
436  }
437  else
438  {
439  DSC_RootCrslAbortLoadRequest(idp, pRC);
440  }
441 }
Header to the 'module' module - Functions/methods for creating/destroying and managing attributes of ...