DSMCC  17.9.0
 All Data Structures Files Functions Typedefs
updateCarousel.c
1 /*******************************************************************************
2  * Copyright © 2014 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  *******************************************************************************/
23 /*---includes for this file--------------------------------------------------*/
24 #include "clDsmSystem.h"
25 #include "updateCarousel.h"
26 #include "sectionTimer.h"
27 
28 #include "cacheMgr.h"
29 
30 /*------------------------------- Local Macros -------------------------------*/
31 
32 #define SSU_GROUP_LIST 0
33 #define NUM_LISTS_SSU_GROUPS 1
34 
35 /*------------------------------ Exported Data -----------------------------*/
36 
37 /*--------------------------------Local Types --------------------------------*/
38 
39 typedef struct s_GroupInfo *P_GroupInfo;
40 typedef struct s_GroupInfoItem *P_GroupInfoItem;
41 
42 typedef struct s_GroupInfo
43 {
44  U32BIT id;
45  U32BIT size;
46  U32BIT oui;
48  U32BIT subgroup;
49  U32BIT nextGroupId;
50  U16BIT associationTag;
51  U8BIT positionType; /* for values see E_PostionType */
52 } S_GroupInfo;
53 
54 typedef struct s_GroupInfoItem
55 {
56  S_LLObject llData[NUM_LISTS_SSU_GROUPS];
57  S_GroupInfo group;
58  P_DataCarousel pDC;
59 } S_GroupInfoItem;
60 
61 /*------------------------------- Local Statics ------------------------------*/
62 
63 
64 /*------------------- local prototypes/forward declarations ------------------*/
65 
66 static void CarouselLoadFinalise( P_DsmCoreInst idp, P_RootLoadRqst pLoadRqst );
67 
68 /*------------------------------ Local Functions -----------------------------*/
69 
75 static E_DscError CreateGroupRequest( P_DsmCoreInst idp, P_UpdateCarousel pUC, S_GroupInfo *pGroup )
76 {
77  E_DscError err;
78  P_DataCarousel pDC;
80  P_GroupInfoItem pGII;
81  P_RootLoadRqst pLoadRqst;
82  pGII = (P_GroupInfoItem)DSC_CmMemGet( idp, sizeof(S_GroupInfoItem) );
83  if (!pGII)
84  {
85  err = CLDSM_ERR_MEM_HEAP_FULL;
86  }
87  else
88  {
89  llLinkInit( pGII->llData, NUM_LISTS_SSU_GROUPS );
90  pGII->group = *pGroup;
91  tap.id = 0;
92  tap.transactionId = pGroup->id;
93  tap.associationTag = pGroup->associationTag;
94  tap.timeout = 0xFFFFFFFF;
95  err = DSC_DataCrslCreate( idp, &pUC->root, &tap, &pDC );
96  if (!err)
97  {
98  err = LLCreate( idp, pDC, MODULE_LOAD_REQUEST_LIST, &pDC->llcLoadRequests );
99  if (!err)
100  {
101  err = DSC_LoadRsqtCreate( idp, sizeof(S_RootLoadRqst), TT_SSU_GROUP, pGII,
102  (F_LoadFinalise)CarouselLoadFinalise, &pLoadRqst );
103  if (!err)
104  {
105  LLInsertHead( pDC->llcLoadRequests, pLoadRqst );
106  err = DSC_DataCrslAcquireStart( idp, pDC, SF_PRIORITY_HIGH );
107  if (!err)
108  {
109  LLInsertTail( pUC->llcGroups, pGII );
110  }
111  else
112  {
113  LLDestroy( idp, &pDC->llcLoadRequests );
114  DSC_LoadRsqtDestroy( idp, pLoadRqst );
115  }
116  }
117  else
118  {
119  LLDestroy( idp, &pDC->llcLoadRequests );
120  }
121  }
122  if (err)
123  {
124  DSC_DataCrslDestroy( idp, pDC );
125  }
126  }
127  if (err)
128  {
129  DSC_CmMemRelease( idp, pGII );
130  }
131  }
132  DBGERRCHK(err)
133  return err;
134 }
135 
136 static void UnloadGroups( P_DsmCoreInst idp, P_LLControl llcGroups )
137 {
138  P_GroupInfoItem item;
139  item = LLRemoveTail( llcGroups );
140  while (item != NULL)
141  {
142  ERRPRINT("release=%p", item)
143  DSC_CmMemRelease(idp, item);
144  item = LLRemoveTail( llcGroups );
145  }
146 }
147 
148 /*----------------------------------------------------------------------------*/
149 
150 /*---------------------------- Exported Functions ----------------------------*/
151 
160 E_DscError DSC_UpdCrslCreate( P_DsmCoreInst idp, U16BIT serviceId,
161  U32BIT oui, P_UpdateCarousel *ppUC )
162 {
163  P_UpdateCarousel pUC;
164  P_RootLoadRqst pLoadRqst;
165  E_DscError err;
166 
167  dsmAssert((idp != NULL));
168  dsmAssert((ppUC != NULL));
169 
170  pUC = (P_UpdateCarousel)DSC_CmMemGet( idp, sizeof(S_UpdateCarousel) );
171  if (!pUC)
172  {
173  err = CLDSM_ERR_MEM_HEAP_FULL;
174  *ppUC = NULL;
175  }
176  else
177  {
178  memset(pUC, 0, sizeof(S_UpdateCarousel));
179  err = DSC_RootCrslInitialise( idp, &pUC->root, UC_MAGIC, serviceId, oui );
180  if (err)
181  {
182  DSC_CmMemRelease(idp, pUC);
183  *ppUC = NULL;
184  }
185  else
186  {
187  err = LLCreate( idp, pUC, SSU_GROUP_LIST, &pUC->llcGroups );
188  if (err)
189  {
190  pUC->llcGroups = NULL;
191  DSC_RootCrslFinalise( idp, &pUC->root );
192  DSC_CmMemRelease(idp, pUC);
193  *ppUC = NULL;
194  }
195  else
196  {
197  err = DSC_LoadRsqtCreate( idp, sizeof(S_RootLoadRqst), TT_CAROUSEL, pUC,
198  CarouselLoadFinalise, &pLoadRqst );
199  if (err)
200  {
201  LLDestroy( idp, &(pUC->llcGroups));
202  DSC_RootCrslFinalise( idp, &pUC->root );
203  DSC_CmMemRelease(idp, pUC);
204  *ppUC = NULL;
205  }
206  else
207  {
208  pUC->root.pLoadRqst = pLoadRqst;
209  *ppUC = pUC;
210  }
211  }
212  }
213  }
214  DEBUG_CHK( err == CLDSM_OK, ERRPRINT("Error %u", err));
215  return err;
216 }
217 
224 {
225  dsmAssert((idp != NULL));
226  dsmAssert((pUC != NULL));
227 
228  /* -- Free up Group list */
229  if (LLCount( pUC->llcGroups ))
230  {
231  UnloadGroups( idp, pUC->llcGroups );
232  }
233 
234  LLDestroy( idp, &(pUC->llcGroups));
235 
236  DSC_RootCrslFinalise( idp, &pUC->root );
237 
238  memset(pUC, 0, sizeof(S_UpdateCarousel));
239  DSC_CmMemRelease( idp, pUC );
240 }
241 
242 static void ParseGroupInfoDescriptors( MemPtr pData, U16BIT length, S_GroupInfo *pGroup )
243 {
244  MemPos currPos, endPos;
245  U8BIT dtag;
246  U8BIT dlen;
247  U8BIT ui8;
248  DBG2(DD_OC,"")
249  GET_POS( pData, currPos );
250  endPos = currPos + length;
251  while (currPos < endPos)
252  {
253  READ_UINT8( pData, dtag );
254  READ_UINT8( pData, dlen );
255  switch (dtag)
256  {
257  case DESCRIPTOR_TYPE_TAG:
258  {
259  break;
260  }
261  case DESCRIPTOR_NAME_TAG:
262  {
263  break;
264  }
265  case DESCRIPTOR_INFO_TAG:
266  {
267  break;
268  }
269  case DESCRIPTOR_LOCATION_TAG:
270  {
271  READ_UINT8( pData, ui8 );
272  pGroup->associationTag = ui8;
273  break;
274  }
275  case DESCRIPTOR_GROUP_LINK_TAG:
276  {
277  READ_UINT8( pData, ui8 );
278  READ_UINT32( pData, pGroup->nextGroupId );
279  pGroup->positionType = ui8 + 1; /* increment so know received desc */
280  break;
281  }
282  case DESCRIPTOR_SSU_SUBGROUP_ASS_TAG:
283  {
284  READ_UINT32( pData, pGroup->subgroup );
285  break;
286  }
287  default:
288  {
289  DBG2(DD_OC,"Unknown descriptor tag: %x", dtag);
290  break;
291  }
292  }
293  SET_POS_ABS( pData, currPos + 2 + dlen );
294  GET_POS( pData, currPos );
295  }
296 }
297 
307  U8BIT *pDsiPrivate, U16BIT dsiPrivateLen )
308 {
309  E_DscError err = CLDSM_ERR_END_OF_DATA;
310  S_GroupInfo group;
311  U8BIT *pData;
312  U16BIT glen, numGroups;
313  P_Compatibility pCompat;
314 
315  dsmAssert((pDsiPrivate != NULL));
316 
317  if (dsiPrivateLen < 2)
318  {
319  ERRLOG(DD_OC, "DATA ERROR: Group short len=%u", dsiPrivateLen )
320  }
321  else
322  {
323  pData = pDsiPrivate;
324  READ_UINT16( pData, numGroups );
325  if (dsiPrivateLen < ((numGroups * 12) + 2))
326  {
327  ERRLOG(DD_OC, "DATA ERROR: Group short len=%u groups=%u", dsiPrivateLen, numGroups )
328  }
329  else
330  {
331  dsmAssert((pUC->root.status == RCS_BOOTING));
332  pUC->root.pLoadRqst->status = LRS_STALLED_SRG_MODULE;
333  pUC->root.status = RCS_BOOTED;
334  DBGLOG(DD_OC, "numGroups %u", numGroups)
335  while (numGroups--)
336  {
337  memset(&group, 0, sizeof(S_GroupInfo));
338  group.oui = OUI_SPECIFIER_TYPE | (pUC->root.rcid & OUI_DATA_MASK);
339  group.associationTag = pUC->root.dsiAssocTag;
340  READ_UINT32( pData, group.id );
341  READ_UINT32( pData, group.size );
342 
343  READ_UINT16( pData, glen ); /*Group Compatibility*/
344  pCompat = DSC_UtilParseCompatibilityDesc( idp, pData, glen, group.oui );
345  SET_POS_REL( pData, glen ); /* Skip */
346 
347  READ_UINT16( pData, glen ); /*group info len*/
348  if (glen)
349  {
350  DBGLOG(DD_OC, "Group(%x) Info length=%d", group.id, glen)
351  ParseGroupInfoDescriptors( pData, glen, &group );
352  SET_POS_REL( pData, glen ); /* Skip */
353  }
354  READ_UINT16( pData, glen ); /*group private data len*/
355  if (glen)
356  {
357  DBGLOG(DD_OC, "Group(%x) Private Data length=%d", group.id, glen)
358  SET_POS_REL( pData, glen ); /* Skip */
359  }
360  if (pCompat == NULL)
361  {
362  ERRLOG(DD_OC, "fail parsing Compatibility Descriptor")
363  }
364  else
365  {
366  U16BIT h,s;
367  DBGLOG(DD_OC, "pCompat->sw_num %u", pCompat->sw_num)
368  for (s = 0; s < pCompat->sw_num; s++)
369  {
370  group.smv.sw_model = pCompat->swlist[s].model;
371  group.smv.sw_version = pCompat->swlist[s].version;
372  DBGLOG(DD_OC, "pCompat->hw_num %u", pCompat->hw_num)
373  for (h = 0; h != pCompat->hw_num; h++)
374  {
375  group.smv.hw_model = pCompat->hwlist[h].model;
376  group.smv.hw_version = pCompat->hwlist[h].version;
377  if (idp->setup.ssuFuncs.wanted(group.id,group.size,&(group.smv)))
378  {
379  err = CreateGroupRequest( idp, pUC, &group );
380  if (err)
381  {
382  err = handleInLoopError( idp, CLDSM_OK, err );
383  }
384  /* confirmed match, so can exit both loops */
385  s = pCompat->sw_num;
386  break;
387  }
388  }
389  }
390  DSC_CmMemRelease( idp, pCompat );
391  }
392  }
393  #ifdef DSI_TIMEOUT_SUPPORT
394  sectionTimerRemove(idp, pUC->root.pDsiSf); /* stop DSI timer */
395  #endif /* DSI_TIMEOUT_SUPPORT */
396  switch (err)
397  {
398  case CLDSM_ERR_END_OF_DATA:
399  {
400  DSC_RootCrslLoadRequestFail( idp, &pUC->root );
401  break;
402  }
403  default:
404  {
405  DSC_LoadRsqtFinalise( idp, pUC->root.pLoadRqst );
406  pUC->root.pLoadRqst = NULL;
407  }
408  case CLDSM_OK:
409  {
410  DBGLOG(DD_OC, "Found update")
411  }
412  }
413  }
414  }
415  return err;
416 }
417 
418 BOOLEAN DSC_UpdCrslCheckCompatibility( P_UpdateCarousel pUC, U8BIT *pCompatDesc,
419  U16BIT compatLen )
420 {
421  P_GroupInfoItem item;
422  item = LLHead(pUC->llcGroups);
423  while (item != NULL)
424  {
425  if (DSC_UtilCheckCompatibility(pCompatDesc, compatLen, item->group.oui, item->group.smv))
426  {
427  break;
428  }
429  item = LLNext( item, SSU_GROUP_LIST );
430  }
431  return (item)? TRUE : FALSE;
432 }
433 
434 static void CarouselLoadFinalise( P_DsmCoreInst idp, P_RootLoadRqst pLoadRqst )
435 {
436  P_UpdateCarousel pCarousel;
437  P_GroupInfoItem pGII;
438  E_UCLoadStatus status;
439  U_StatusRef sr;
440  U32BIT data;
441  data = 0;
442  if (pLoadRqst->targetKind == TT_CAROUSEL)
443  {
444  pCarousel = pLoadRqst->target;
445  }
446  else
447  {
448  dsmAssert((pLoadRqst->targetKind == TT_SSU_GROUP));
449  pGII = pLoadRqst->target;
450  pCarousel = LLParent( pGII, SSU_GROUP_LIST );
451  sr.id = pGII->group.id;
452  }
453  switch (pLoadRqst->status)
454  {
455  case LRS_STALLED_SRG_MODULE:
456  /* No matching Update found */
457  dsmAssert((pCarousel->root.status == RCS_BOOTED));
458  sr.id = pCarousel->root.rcid;
459  status = SSU_NOT_AVAILABLE;
460  break;
461 
462  case LRS_STALLED_MODULE:
463  /* received DII for Group - requesting modules */
464  dsmAssert((pLoadRqst->targetKind == TT_SSU_GROUP));
465  if (pCarousel->root.status == RCS_BOOTED)
466  {
467  pCarousel->root.status = RCS_LOADING;
468  if (pGII->group.size != pLoadRqst->remaining)
469  {
470  ERRLOG(DD_OC, "DATA ERROR: Bad Group size=%u actual=%u", pGII->group.size, pLoadRqst->remaining )
471  }
472  }
473  status = SSU_CRSL_READY;
474  data = pLoadRqst->remaining;
475  break;
476 
477  case LRS_LOADED:
478  /* received all modules for Group */
479  pCarousel->root.status = RCS_LOADED;
480  status = SSU_CRSL_DONE;
481  break;
482 
483  default:
484  dsmAssert((0));
485  case LRS_ABORTED_TIMEOUT:
486  case LRS_ABORTED_PATH_ERROR:
487  case LRS_ABORTED_LOAD_ERROR:
488  case LRS_ABORTED_BY_REQUESTER:
489  pCarousel->root.status = RCS_LOAD_FAILED;
490  sr.id = pCarousel->root.rcid;
491  status = SSU_CRSL_ABORT;
492  break;
493  }
494  if (idp->setup.ssuFuncs.status)
495  {
496  idp->setup.ssuFuncs.status( (H_DsmCarousel)pCarousel, status, sr, data );
497  }
498 }
499 
General include file for clDsm library internal definitions.
Header to the sectionTimer module.
Header to the cacheMgr module.