DSMCC  17.9.0
 All Data Structures Files Functions Typedefs
clDsmClientMain.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 © 2002 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 <string.h>
28 #include "clDsmSystem.h"
29 
30 #include "dsmObject.h"
31 #include "module.h"
32 #include "dataCarousel.h"
33 #include "objectCarousel.h"
34 #include "updateCarousel.h"
35 #include "loadMgr.h"
36 #include "sectionFilter.h"
37 #include "siQuery.h"
38 #include "clDsmUtils.h"
39 #include "moduleData.h"
40 
41 /*------------------------------- Local Macros -------------------------------*/
42 
43 #define PATH_SEPARATOR_LIST_STRING "\\/:" /* -- Recognised path seperators */
44 
45 /*------------------------------ Exported Data -----------------------------*/
46 
47 
48 /*--------------------------------Local Types --------------------------------*/
49 
50 typedef struct
51 {
52  U16BIT original_network_id;
53  U16BIT transport_stream_id;
54  U16BIT service_id;
55  U16BIT component_tag;
56  U32BIT carousel_id;
57 } S_CarouselLocator;
58 
59 
60 /*------------------------------- Local Statics ------------------------------*/
61 
62 
63 /*------------------- local prototypes/forward declarations ------------------*/
64 
65 static E_DscError RetrieveCarouselPath( P_DsmCoreInst idp,
66  U8BIT *ipPath, U8BIT *opPath,
67  P_ObjectCarousel *ppOC );
68 
69 
70 /*---------------------------- Exported Functions ----------------------------*/
71 
75 E_DscError CDSM_LoadCarousel( H_DsmCoreInst instance,
76  U16BIT serviceId, U32BIT couId, E_SIQueryKind kind,
77  H_DsmCarousel *pclDsmCarouselHandle )
78 {
79  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
80  E_DscError err;
81  S_SIQueryRequest siQueryData;
82  S_SIQueryResult siQueryResult;
83  P_RootCarousel pRC;
84 
85  dsmDP2(("CDSM_LoadCarousel( %p,srvID: %u, carouselID: %u, %u, %p )\n",
86  instance, serviceId, couId, pclDsmCarouselHandle));
87 
88  if (!instance || !pclDsmCarouselHandle)
89  {
90  dsmDP1(("ERROR: Illegal parameter\n"));
91  err = CLDSM_ERR_INVALID_INSTANCE;
92  }
93  else if (!idp->currentServiceSet)
94  {
95  err = CLDSM_ERR_NO_CURRENT_SERVICE_SET;
96  }
97  else if ((couId == INVALID_CAROUSEL_ID || couId == UNKNOWN_CAROUSEL_ID) &&
98  idp->pBootingCarousel != NULL)
99  {
100  *pclDsmCarouselHandle = (H_DsmCarousel)idp->pBootingCarousel;
101  err = CLDSM_DUPLICATE_REQUEST;
102  }
103  else
104  {
105  /* to see if carousel is already loaded (for multi-carousel).
106  NB. Only one 'anonymous' carousel can be booted per program.
107  */
108  pRC = DSC_RootCrslListFindById( idp->llcRootCarousels, serviceId, couId );
109  if (pRC != NULL)
110  {
111  *pclDsmCarouselHandle = (H_DsmCarousel)pRC;
112 
113  err = CLDSM_DUPLICATE_REQUEST;
114  }
115  else
116  {
117  /* -- Load a new carousel -- */
118  *pclDsmCarouselHandle = NULL;
119  switch (kind)
120  {
121  case SIQUERY_SSU_PID:
122  {
123  err = DSC_UpdCrslCreate( idp, 0, couId, (P_UpdateCarousel*)&pRC );
124  break;
125  }
126  case SIQUERY_SSU_CAROUSEL:
127  {
128  err = DSC_UpdCrslCreate( idp, serviceId, couId, (P_UpdateCarousel*)&pRC );
129  break;
130  }
131  default:
132  {
133  err = DSC_ObjCrslCreate( idp, serviceId, couId, (P_ObjectCarousel*)&pRC );
134  break;
135  }
136  }
137  if (!err)
138  {
139  dsmDP4(("carousel load created\n"));
140  siQueryData.dataId = couId;
141  siQueryData.serviceId = serviceId;
142  siQueryData.kind = kind;
143 
144  pRC->status = RCS_PENDING_BOOTINFO;
145  err = siQueryStart( idp, &siQueryData, (void *)pRC, &siQueryResult );
146  switch (err)
147  {
148  case CLDSM_PENDING:
149  dsmDP2(("Query Handle=%p\n", siQueryResult.data.queryHandle));
150  dsmAssert((siQueryResult.kind == SIRESULT_PENDING));
151  /* -- Store query ref in carousel */
152  pRC->pPendingSiQueryRef = siQueryResult.data.queryHandle;
153  err = CLDSM_OK;
154  break;
155 
156  case CLDSM_OK:
157  dsmDP2(("Crsl PID=%d\n", siQueryResult.data.carouselInfo.pid));
158  err = DSC_RootCrslBootCarousel( idp, pRC, &(siQueryResult.data.carouselInfo));
159  if (!err)
160  {
161  break;
162  } /* else fall through to default error case*/
163 
164  default: /* ERROR */
165  if (kind == SIQUERY_SSU_CAROUSEL || kind == SIQUERY_SSU_PID)
166  {
168  }
169  else
170  {
171  DSC_ObjCrslDestroy( idp, (P_ObjectCarousel*)&pRC );
172  }
173  }
174 
175  if (!err)
176  {
177  *pclDsmCarouselHandle = (H_DsmCarousel)pRC;
178 
179  /* -- Insert Carousel in list */
180  LLInsertTail( idp->llcRootCarousels, pRC );
181 
182  if (idp->pBootingCarousel == NULL)
183  {
184  /* -- Store booting OC handle in instance data */
185  idp->pBootingCarousel = pRC;
186  }
187  if (idp->pCurrentCarousel == NULL)
188  {
189  idp->pCurrentCarousel = pRC;
190  }
191  }
192  }
193  }
194  }
195  switch (err)
196  {
197  case CLDSM_OK:
198  DBGLOG(DD_OC, "ptr=%p", *pclDsmCarouselHandle);
199  break;
200  case CLDSM_ERR_SI_QUERY_FAILED:
201  DBG3(DD_OC, "SI query fail loading carousel")
202  break;
203  default:
204  ERRPRINT("ERROR: clDsmLoadCarousel: %u", err);
205  }
206  return err;
207 }
208 
209 /*******************************************************************************
210 *
211 * Unload (or cancel the requested load of) a DSM-CC Object Carousel (service
212 * domain).
213 *
214 *******************************************************************************/
215 E_DscError CDSM_GetCarouselId( H_DsmCoreInst instance, H_DsmCarousel hCarousel, U32BIT *pCarouselId )
216 {
217  P_ObjectCarousel pOC;
218  E_DscError err;
219 
220  dsmDP2(("CDSM_GetCarouselId( %p, %p )\n", instance, hCarousel));
221  if (instance == NULL)
222  {
223  err = CLDSM_ERR_INVALID_INSTANCE;
224  }
225  else if (!memValidate((MemHandle)hCarousel))
226  {
227  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
228  }
229  else
230  {
231  pOC = (P_ObjectCarousel)hCarousel;
232  if (pOC->root.magic != OC_MAGIC)
233  {
234  ERRPRINT("API ERROR: Invalid Carousel handle (magic)")
235  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
236  }
237  else
238  {
239  dsmDP2(("CDSM_GetCarouselId() is %u\n", pOC->root.rcid));
240  *pCarouselId = pOC->root.rcid;
241  err = CLDSM_OK;
242  }
243  }
244  return err;
245 }
246 
247 H_DsmCarousel CDSM_CurrentCarousel( H_DsmCoreInst instance )
248 {
249  return (H_DsmCarousel)instance->pCurrentCarousel;
250 }
251 
253  /*I*/ H_DsmCarousel hCarousel )
254 {
255  E_DscError err;
256 
257  dsmDP2(("CDSM_GetCarouselId( %p, %p )\n", idp, hCarousel));
258  if (idp == NULL)
259  {
260  err = CLDSM_ERR_INVALID_INSTANCE;
261  }
262  else if (!memValidate((MemHandle)hCarousel))
263  {
264  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
265  }
266  else
267  {
268  if (((P_ObjectCarousel)hCarousel)->root.magic != OC_MAGIC)
269  {
270  dsmDP1(("API ERROR: Invalid Carousel handle (magic)\n"));
271  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
272  }
273  else
274  {
275  idp->pCurrentCarousel = (P_RootCarousel)hCarousel;
276  err = CLDSM_OK;
277  }
278  }
279  return err;
280 }
281 
283  H_DsmCarousel hCarousel, U16BIT *total,
284  S_CarouselInfoFileGroup **pGroups )
285 {
286  P_ObjectCarousel pOC;
287  E_DscError err;
288 
289  dsmDP2(("CDSM_CarouselLoadFileGroups( %p, %p )\n", instance, hCarousel));
290  if (instance == NULL)
291  {
292  err = CLDSM_ERR_INVALID_INSTANCE;
293  }
294  else if (!memValidate((MemHandle)hCarousel))
295  {
296  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
297  }
298  else
299  {
300  pOC = (P_ObjectCarousel)hCarousel;
301  if (pOC->root.magic != OC_MAGIC)
302  {
303  dsmDP1(("API ERROR: Invalid Carousel handle (magic)\n"));
304  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
305  }
306  else
307  {
308  switch (pOC->root.status)
309  {
310  case RCS_BOOTED:
311  case RCS_LOADED:
312  err = DSC_ObjCrslRetrieveFileGroups( pOC, total, pGroups );
313  break;
314 
315  default:
316  err = CLDSM_ERR_CAROUSEL_NOT_BOOTED;
317  }
318  }
319  }
320  return err;
321 }
322 
323 /*******************************************************************************
324 *
325 * Unload DSM-CC Object Carousel File Group List
326 *
327 *******************************************************************************/
329  /*I*/ H_DsmCarousel hCarousel,
330  /*I*/ S_CarouselInfoFileGroup *groups )
331 {
332  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
333  P_ObjectCarousel pOC;
334  E_DscError err;
335 
336  dsmDP2(("CDSM_CarouselUnloadFileGroups( %p, %p, %p )\n", instance, hCarousel, groups));
337  if (instance == NULL)
338  {
339  err = CLDSM_ERR_INVALID_INSTANCE;
340  }
341  else
342  {
343  err = CLDSM_OK;
344  if (!memValidate((MemHandle)hCarousel))
345  {
346  DSC_ObjCrslReleaseFileGroups( idp, NULL, groups );
347  }
348  else
349  {
350  pOC = (P_ObjectCarousel)hCarousel;
351  if (pOC->root.magic != OC_MAGIC)
352  {
353  dsmDP1(("API ERROR: Invalid Carousel handle (magic)\n"));
354  DSC_ObjCrslReleaseFileGroups( idp, NULL, groups );
355  }
356  else
357  {
358  DSC_ObjCrslReleaseFileGroups( idp, pOC, groups );
359  }
360  }
361  }
362  return err;
363 }
364 
365 /*******************************************************************************
366 *
367 * Unload (or cancel the requested load of) a DSM-CC Object Carousel (service
368 * domain).
369 *
370 *******************************************************************************/
371 E_DscError CDSM_UnloadCarousel( H_DsmCoreInst instance,
372  /*I*/ H_DsmCarousel clDsmCarouselHandle, E_DsmRstMode mode )
373 {
374  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
375  P_RootCarousel pRC = (P_RootCarousel)clDsmCarouselHandle;
376  P_LoadRequest pLoadRequest;
377  E_DscError err = CLDSM_OK;
378 
379  dsmDP2(("CDSM_UnloadCarousel( %p, %p, %d )\n", instance, clDsmCarouselHandle, mode));
380 
381  dsmAssert((instance != NULL));
382 
383  if (!RC_VALID( pRC ))
384  {
385  dsmDP1(("API ERROR: Invalid Carousel handle (handle)\n"));
386  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
387  }
388  else if ( (pRC->magic == OC_MAGIC) &&
389  DSC_ObjCrslUnloadObjects(idp,(P_ObjectCarousel)pRC,mode) != CLDSM_OK )
390  {
391  dsmDP1(("ERROR: Objects still loaded in Carousel\n"));
392  err = CLDSM_ERR_OBJECTS_STILL_LOADED;
393  }
394  else
395  {
396  /* -- NULL booting carousel reference in instance data (in case
397  -- it is still set) */
398  idp->pBootingCarousel = NULL;
399  if (idp->pCurrentCarousel == pRC)
400  {
401  idp->pCurrentCarousel = NULL;
402  }
403 
404  switch (pRC->status)
405  {
406  case RCS_PENDING_BOOTINFO:
407  /*
408  -- In this state, the carousel is waiting for an
409  -- pending SI Query to complete so abort the query.
410  */
411  dsmAssert((pRC->pPendingSiQueryRef != NULL));
412  siQueryAbortPending( idp, pRC->pPendingSiQueryRef );
413 
414  /* -- Clear Query ref in carousel (finished with) */
415  pRC->pPendingSiQueryRef = NULL;
416 
417  /* fall through to RCS_BOOTING */
418 
419  case RCS_BOOTING:
420  /* -- OC loadRequest must exist in this state */
421  /* -- No module load will be started in this state so stop
422  -- the carousel load request */
423  pLoadRequest = (P_LoadRequest)pRC->pLoadRqst;
424  pLoadRequest->rlr.status = LRS_ABORTED_BY_REQUESTER;
425  /* -- Ack carousel unload/abort */
426  DSC_LoadRsqtFinalise( idp, (P_RootLoadRqst)pLoadRequest );
427  break;
428 
429  case RCS_BOOTED:
430  if (pRC->magic == OC_MAGIC)
431  {
432  /* -- In this state, SRG module load will be started.
433  -- Set load request status and abort module load. */
434  /* -- OC loadRequest must exist */
435  pLoadRequest = (P_LoadRequest)pRC->pLoadRqst;
436  dsmAssert((pLoadRequest != NULL));
437  pLoadRequest->rlr.status = LRS_ABORTED_BY_REQUESTER;
438  lmStopModuleLoadRequest( idp, pLoadRequest );
439  }
440  break;
441 
442  case RCS_LOADED:
443  case RCS_LOADING:
444  case RCS_LOAD_FAILED:
445  /* -- In these states, carousel load is already finalised so
446  -- nothing specific to do */
447  if (pRC->magic == OC_MAGIC)
448  {
449  if (idp->setup.notifyCarouselLoadEventFunc)
450  {
451  idp->setup.notifyCarouselLoadEventFunc((H_DsmCarousel)pRC, OC_LOAD_ABORTED_UNLOAD, pRC->rcid);
452  }
453  }
454  else
455  {
456  dsmAssert((pRC->magic == UC_MAGIC));
457  if (idp->setup.ssuFuncs.status)
458  {
459  U_StatusRef sr;
460  sr.id = pRC->rcid;
461  idp->setup.ssuFuncs.status((H_DsmCarousel)pRC, SSU_CRSL_UNLOAD, sr, 0 );
462  }
463  }
464  break;
465 
466  default:
467  /* -- Illegal status */
468  dsmDP1(("ERROR: Illegal Carousel status = %u\n", pRC->status));
469  dsmAssert((0));
470 
471  err = CLDSM_ERR_INTERNAL;
472  break;
473  }
474 
475  /*
476  -- In this state, the DSI section filter will have been
477  -- requested, so stop it (also Nulls reference in OC).
478  */
479  if (pRC->pDsiSf)
480  {
481  DSC_SectionFilterStop( idp, &pRC->pDsiSf );
482  }
483 
484  if (!err)
485  {
486  DSC_RootCrslUnload( idp, pRC );
487  DSC_RootCrslDestroy( idp, pRC );
488  }
489 
490  if (idp->pCurrentCarousel == NULL)
491  {
492  /* Just unloaded current carousel -
493  * find next loaded carousel and set it as current carousel */
494  idp->pCurrentCarousel = LLHead( idp->llcRootCarousels );
495  }
496  }
497  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: clDsmUnloadCarousel: %u\n", err)));
498  dsmDP2(("exit clDsmUnloadCarousel -> rtn: %u \n", err));
499  return err;
500 }
501 
511 E_DscError CDSM_UnloadModule( H_DsmCoreInst idp, H_DsmCarousel hCarousel,
512  U32BIT moduleRef )
513 {
514  E_DscError err;
515  P_RootCarousel pRC = (P_RootCarousel)hCarousel;
516  if (!memValidate(pRC) || pRC->magic != UC_MAGIC)
517  {
518  ERRPRINT("not Update Carousel")
519  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
520  }
521  else
522  {
523  DSC_RootCrslUnloadModule( idp, pRC, moduleRef );
524  err = CLDSM_OK;
525  }
526  DBGERRCHK(err)
527  return err;
528 }
529 
530 
531 
532 /*
533 -- Load a DSM-CC object
534 --
535 */
536 E_DscError CDSM_LoadObject( H_DsmCoreInst idp,
537  U8BIT *pathname, U32BIT timeout, E_CacheRules cachingRules,
538  H_ObjUserData pUserData, U32BIT sizeOfUserData,
539  E_ObjLoadStatus *pStatus, H_DsmObject *pclDsmObjectHandle )
540 {
541  U8BIT path[MAX_PATH_NAME_SIZE];
542  P_LoadRequest pLoadRequest;
543  P_DsmObject pDsmObject;
544  E_DscError err;
545  P_ObjectCarousel pOC;
546 
547  dsmDP2(("CDSM_LoadObject( %p, %s, %u, %u, %p, %u, %p, %p )\n",
548  idp, pathname, timeout, cachingRules,
549  pUserData, sizeOfUserData, pStatus, pclDsmObjectHandle));
550 
551  API_PARAM_CHK( idp, dsmDP1(("ERROR: Invalid instance\n")),
552  err = CLDSM_ERR_INVALID_INSTANCE; goto _return );
553  API_PARAM_CHK( pStatus, dsmDP1(("ERROR: Illegal parameter\n")),
554  err = CLDSM_ERR_ILLEGAL_PARAMETER; goto _return );
555  API_PARAM_CHK( pclDsmObjectHandle, dsmDP1(("ERROR: Illegal parameter\n")),
556  err = CLDSM_ERR_ILLEGAL_PARAMETER; goto _return );
557  API_PARAM_CHK( pathname, dsmDP1(("ERROR: Invalid pathname\n")),
558  err = CLDSM_ERR_INVALID_PATHNAME; goto _return );
559 
560  err = RetrieveCarouselPath( idp, pathname, path, &pOC );
561  if (!err)
562  {
563  *pclDsmObjectHandle = NULL;
564  *pStatus = OBJ_LOAD_UNINITIATED;
565 
566  err = objectCreate( idp, &pDsmObject );
567  if (!err)
568  {
569  /* -- NB. Unless an error is encountered in this function, this object
570  -- is held open until it is unloaded and the real memory pointer
571  -- is passed to the client */
572 
573  pDsmObject->pObjCarousel = pOC;
574 
575  /* -- NB. dsmObject is created with default caching rules in-case
576  -- cache prioritising is disabled or none are supplied */
577  #ifndef DSM_DISABLE_CACHE_PRIORITISING
578  pDsmObject->cachingRules = cachingRules;
579  #endif
580  err = lmRequestObjectLoad( idp, pOC, path, timeout, pUserData, sizeOfUserData,
581  pDsmObject, &pLoadRequest );
582 
583  if (!err)
584  {
585  switch (pLoadRequest->rlr.status)
586  {
587  case LRS_LOADED:
588  ERRLOG(DD_MOD,"%s LOADED",pathname)
589  pDsmObject->pObjCarousel = pLoadRequest->pObjCarousel;
590  pDsmObject->pModule = pLoadRequest->pModule;
591  pDsmObject->objectDataOffset =
592  pLoadRequest->targetObjectOffset;
593  pDsmObject->objectInfo = pLoadRequest->targetObjectInfo;
594  pDsmObject->kind =
595  convertObjectKindStr(
596  pLoadRequest->targetObjectInfo.objectKind );
597 
598  lmSetObjectModuleLoaded( idp, pDsmObject->pModule );
599 
600  pDsmObject->status = OBJ_LOAD_COMPLETED;
601 
602  *pStatus = OBJ_LOAD_COMPLETED;
603  *pclDsmObjectHandle = (void *) pDsmObject;
604  break;
605 
606  case LRS_STALLED_MODULE:
607  case LRS_STALLED_SRG_MODULE:
608  pDsmObject->r.pLoadRequest = pLoadRequest;
609  pDsmObject->status = OBJ_LOAD_IN_PROGRESS;
610 
611  *pStatus = OBJ_LOAD_IN_PROGRESS;
612  *pclDsmObjectHandle = (void *) pDsmObject;
613  break;
614 
615  case LRS_LITE_OPTIONS_LOADED:
616  dsmDP2(("LRS_LITE_OPTIONS_LOADED pOC=%p\n", pLoadRequest->pObjCarousel));
617  pDsmObject->pObjCarousel = pLoadRequest->pObjCarousel;
618  pDsmObject->pModule = pLoadRequest->pModule;
619  pDsmObject->objectDataOffset =
620  pLoadRequest->targetObjectOffset;
621  pDsmObject->objectInfo = pLoadRequest->targetObjectInfo;
622  pDsmObject->kind =
623  convertObjectKindStr(
624  pLoadRequest->targetObjectInfo.objectKind );
625 
626  lmSetObjectModuleLoaded( idp, pDsmObject->pModule );
627 
628  pDsmObject->status = OBJ_LOAD_COMPLETED;
629  *pStatus = OBJ_LOAD_COMPLETED;
630  *pclDsmObjectHandle = (void *) pDsmObject;
631  break;
632 
633  case LRS_LITE_OPTIONS_PENDING:
634  dsmDP2(("LRS_LITE_OPTIONS_PENDING pOC=%p\n", pLoadRequest->pObjCarousel));
635  pDsmObject->r.pLoadRequest = pLoadRequest;
636  pDsmObject->pObjCarousel = pLoadRequest->pObjCarousel;
637  pDsmObject->objectDataOffset =
638  pLoadRequest->targetObjectOffset;
639  pDsmObject->objectInfo = pLoadRequest->targetObjectInfo;
640  pDsmObject->kind =
641  convertObjectKindStr(
642  pLoadRequest->targetObjectInfo.objectKind );
643 
644  pDsmObject->status = OBJ_LOAD_IN_PROGRESS;
645  *pStatus = OBJ_LOAD_IN_PROGRESS;
646  *pclDsmObjectHandle = (void *) pDsmObject;
647  break;
648 
649  /*
650  *** PLACEHOLDER - NOT CURRENTLY VALID ***
651  case LRS_STALLED_DSI:
652  TODO: Allow object loads before DSI acquired
653  break;
654  */
655 
656  case LRS_ABORTED_PATH_ERROR:
657  *pStatus = OBJ_LOAD_ABORTED_PATH_ERROR;
658  ERRPRINT("%p", pDsmObject)
659  err = CLDSM_ERR_LOAD_FAILED;
660  break;
661 
662  case LRS_ABORTED_LOAD_ERROR:
663  *pStatus = OBJ_LOAD_ABORTED_ERROR;
664  ERRPRINT("%p", pDsmObject)
665  err = CLDSM_ERR_LOAD_FAILED;
666  break;
667 
668  case LRS_ABORTED_TIMEOUT:
669  *pStatus = OBJ_LOAD_ABORTED_TIMEOUT;
670  /* was OC_LOAD_ABORTED_TIMEOUT which was equivalent to OBJ_LOAD_ABORTED_PATH_ERROR !
671  * As it happens, this was not important to any calling func */
672  ERRPRINT("%p", pDsmObject)
673  err = CLDSM_ERR_LOAD_FAILED;
674  break;
675 
676  default:
677  /* -- Illegal status */
678  dsmDP1(("ERROR: Illegal loadRequest status = %u\n",
679  pLoadRequest->rlr.status));
680  *pStatus = OBJ_LOAD_ABORTED_ERROR;
681  ERRPRINT("%p", pDsmObject)
682  dsmAssert((0));
683  err = CLDSM_ERR_INTERNAL;
684  break;
685  }
686  }
687 
688  if (!err)
689  {
690  /* -- Increment loaded object count on this carousel */
691  if (pLoadRequest->rlr.status == LRS_LITE_OPTIONS_LOADED ||
692  pLoadRequest->rlr.status == LRS_LITE_OPTIONS_PENDING)
693  {
694  P_ObjectCarousel pLiteOC;
695 
696  idp->pCurrentCarousel = (P_RootCarousel)pLoadRequest->pObjCarousel;
697 
698  /* Count the object with the NEW carousel */
699  pLiteOC = pDsmObject->pObjCarousel;
700  pLiteOC->loadedObjectCount++;
701  }
702  else
703  {
704  pOC->loadedObjectCount++;
705  }
706 
707  /* -- Add to list of all loaded objects */
708  LLInsertHead( pOC->llcCurrObjects, pDsmObject );
709  }
710  }
711  if (err)
712  {
713  /* -- Error so destroy/free any allocated memory objects */
714  if (pDsmObject)
715  {
716  if (pLoadRequest)
717  {
718  lmLoadDestroy( idp, pLoadRequest );
719  }
720  objectDestroy( idp, pDsmObject );
721  }
722  }
723  else
724  {
725  if (*pStatus == OBJ_LOAD_COMPLETED)
726  {
727  /* -- Object loaded so destroy loadRequest */
728  lmLoadDestroy( idp, pLoadRequest );
729  }
730  }
731  }
732 _return:
733  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("clDsmLoadObject:%u Path=%s not found\n", err, path)));
734  dsmDP2(("clDsmLoadObject -> rtn: %u, o/p: %u, Hl=%p pLoadRequest = 0x%p path=%s\n",
735  err, *pStatus, *pclDsmObjectHandle, pLoadRequest, path));
736  return err;
737 }
738 
739 /*
740 -- Unload (or cancel the requested load for) a DSM-CC object
741 */
742 E_DscError CDSM_UnloadObject( H_DsmCoreInst instance,
743  /*I*/ H_DsmObject clDsmObjectHandle,
744  E_DsmRstMode mode )
745 {
746  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
747  P_DsmObject pObject = (P_DsmObject) clDsmObjectHandle;
748  P_LoadRequest pLoadRequest;
749  E_DscError err = CLDSM_OK;
750  P_ObjectCarousel pOC;
751 
752  dsmDP2(("CDSM_UnloadObject( %p, Hl=%p )\n", instance, clDsmObjectHandle));
753 
754  API_PARAM_CHK( instance, dsmDP1(("ERROR: Invalid instance\n")),
755  err = CLDSM_ERR_INVALID_INSTANCE; goto _return );
756 
757  if (!memValidate( pObject ))
758  {
759  dsmDP1(("API ERROR: Invalid object handle\n"));
760  err = CLDSM_ERR_INVALID_OBJECT_HANDLE;
761  }
762  else if (!DSM_OBJECT_CORRECT( pObject, idp ))
763  {
764  dsmDP1(("API ERROR: Invalid object handle\n"));
765  err = CLDSM_ERR_INVALID_OBJECT_HANDLE;
766  }
767  else if (pObject->status == OBJ_LOAD_ABORTED_UNLOAD)
768  {
769  dsmDP1(("API ERROR: Invalid object handle (already unloaded)\n"));
770  err = CLDSM_ERR_INVALID_OBJECT_HANDLE;
771  }
772  else if (pObject->objectDataSeq != NULL)
773  {
774  dsmDP1(("API ERROR: Object still open\n"));
775  err = CLDSM_ERR_OBJECT_OPEN;
776  }
777  else
778  {
779  /*
780  -- Remove record of object from carousel and remove object from list
781  -- of loaded objects.
782  -- NB. This ensures that object is no longer 'visible' (ie. appears
783  -- unloaded) to any relevant API functions called from within object
784  -- event notify callback.
785  */
786 
787  pOC = pObject->pObjCarousel;
788  if (pOC != NULL)
789  {
790  /* -- Decrement loaded object count on relevant carousel */
791  pOC->loadedObjectCount--;
792  }
793  else
794  {
795  /* this is case when mode was PENDING, followed by FORCE */
796  DBGLOG(DD_GEN, "Object's Carousel is NULL")
797  }
798 
799  /* -- Remove from list of all loaded objects */
800  LLRemove( pObject, CURR_OBJECT_LIST );
801 
802  switch (pObject->status)
803  {
804  case OBJ_LOAD_IN_PROGRESS:
805  pLoadRequest = pObject->r.pLoadRequest;
806  ASSERT( pLoadRequest != NULL )
807  if (mode == RST_MODE_PENDING)
808  {
809  if (pLoadRequest->rlr.status != LRS_ABORT_PENDING_RELOAD)
810  {
811  DBGLOG(DD_GEN, "Object remains pending a re-load")
812  pLoadRequest->rlr.status = LRS_ABORT_PENDING_RELOAD;
813  lmStopModuleLoadRequest( idp, pLoadRequest );
814  /* Special circumstance where Object remains, while Carousel is unloaded
815  * and later the object is attached to new carousel on another service */
816  pObject->pObjCarousel = NULL;
817  }
818  }
819  else
820  {
821  if (pLoadRequest->rlr.status == LRS_ABORT_PENDING_RELOAD)
822  {
823  pLoadRequest->rlr.status = LRS_ABORTED_BY_REQUESTER;
824  DSC_LoadRsqtFinalise( idp, (P_RootLoadRqst)pLoadRequest );
825  }
826  else
827  {
828  /* -- Set loadRequest status and abort module load */
829  pLoadRequest->rlr.status = LRS_ABORTED_BY_REQUESTER;
830  lmStopModuleLoadRequest( idp, pLoadRequest );
831  }
832  objectDestroy( idp, pObject );
833  }
834  break;
835 
836  case OBJ_LOAD_COMPLETED:
837  lmSetObjectModuleUnloaded( idp, pObject->pModule );
838 
839  /* -- NULL module reference in object (finished with) */
840  pObject->pModule = NULL;
841 
842  case OBJ_LOAD_ABORTED_TIMEOUT:
843  case OBJ_LOAD_ABORTED_PATH_ERROR:
844  case OBJ_LOAD_ABORTED_ERROR:
845  /* -- Nothing to do */
846  objectDestroy( idp, pObject );
847  break;
848 
849  default:
850  /* -- Illegal status */
851  objectDestroy( idp, pObject );
852  dsmDP1(("ERROR: Illegal DSM object status = %u\n",
853  pObject->status));
854  dsmAssert((0));
855  err = CLDSM_ERR_INTERNAL;
856  break;
857  }
858  }
859 _return:
860  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: clDsmUnloadObject: %u\n", err)));
861  dsmDP2(("exit clDsmUnloadObject -> rtn: %u \n", err));
862  return err;
863 }
864 
893 E_DscError CDSM_OpenObject(
894  /*I*/ H_DsmCoreInst instance,
895  /*I*/ H_DsmObject clDsmObjectHandle,
896  /*O*/ E_DsmObjectKind *pKind)
897 {
898  E_DscError err = CLDSM_OK;
899  P_DsmCoreInst idp = (P_DsmCoreInst)instance;
900  P_DsmObject pDsmObject = (P_DsmObject)clDsmObjectHandle;
901  P_Module pModule;
902  U32BIT dataOffset = 0; /* Initialise prevents compiler warnings */
903  U32BIT dataLength = 0; /* Initialise prevents compiler warnings */
904 
905  dsmDP2(("CDSM_OpenObject( %p, %p, %p )\n",
906  instance, clDsmObjectHandle, pKind));
907 
908  API_PARAM_CHK( instance, dsmDP1(("ERROR: Invalid instance\n")),
909  err = CLDSM_ERR_INVALID_INSTANCE; goto _return );
910  API_PARAM_CHK( clDsmObjectHandle, dsmDP1(("ERROR: Invalid object handle\n")),
911  err = CLDSM_ERR_INVALID_OBJECT_HANDLE; goto _return );
912  API_PARAM_CHK( pKind, dsmDP1(("ERROR: Illegal parameter\n")),
913  err = CLDSM_ERR_ILLEGAL_PARAMETER; goto _return );
914 
915  if (!DSM_OBJECT_CORRECT( pDsmObject, idp ))
916  {
917  dsmDP1(("API ERROR: Invalid object handle\n"));
918  err = CLDSM_ERR_INVALID_OBJECT_HANDLE;
919  }
920  else if (pDsmObject->pModule == NULL)
921  {
922  err = CLDSM_ERR_OBJECT_NOT_LOADED;
923  }
924  else if (pDsmObject->objectDataSeq != NULL)
925  {
926  err = CLDSM_ERR_OBJECT_OPEN;
927  }
928  else if (idp->dsmObjectsOpen >= NUM_OPEN_DSM_OBJECTS_MAX)
929  {
930  err = CLDSM_ERR_OPEN_OBJECT_LIMIT;
931  }
932  else
933  {
934  pModule = pDsmObject->pModule;
935  dsmAssert((pModule->hModuleData != NULL));
936  dsmAssert((pModule->moduleInfo.crslMagic == OC_MAGIC));
937 
938  /* Determine offset of object information based on object kind.
939  Obtain and store any other general purpose information */
940  switch (pDsmObject->kind)
941  {
942  case STREAM_OBJ:
943  /* Same code as STREAM_OBJ_WITH_EVENTS, so, no break */
944  case STREAM_OBJ_WITH_EVENTS:
945  /* Offset will point to taps_count field */
946  dataOffset = pDsmObject->objectInfo.messageBodyOffset;
947  dataLength = pDsmObject->objectInfo.messageBodyLength;
948  break;
949  case FILE_OBJ:
950  /* Skip over 32-bit length field - hence the '4'.
951  Offset will point to start of the object body.
952  The length will indicate the number of bytes in body.
953  For example a FILE_OBJ offset would be to start of file
954  content and length would be number of bytes in file. */
955  dataOffset = pDsmObject->objectInfo.messageBodyOffset + 4;
956  dataLength = pDsmObject->objectInfo.messageBodyLength - 4;
957  break;
958  case DIRECTORY_OBJ:
959  case SERVICE_GATEWAY_OBJ:
960  /* SRG objectInfoOffset initially points to the field
961  immediately after objectInfo_length field */
962 
963  /* Calc. dataOffset to point to serviceContextList_count field */
964  dataOffset = pDsmObject->objectInfo.objectInfoOffset +
965  pDsmObject->objectInfo.objectInfoLength;
966 
967  /* Calc. dataLength to cover the serviceContextList_count field
968  to the end of the object */
969  dataLength = pDsmObject->objectInfo.objectLen -
970  pDsmObject->objectInfo.objectInfoOffset -
971  pDsmObject->objectInfo.objectInfoLength;
972 
973 
974  break;
975  default:
976  dsmDP1(("API ERROR: Invalid object kind\n"));
977  err = CLDSM_ERR_INVALID_OBJECT_TYPE;
978  break;
979  }
980 
981  /* Check for zero-length object */
982  if (dataLength == 0)
983  {
984  *pKind = pDsmObject->kind;
985  err = CLDSM_ERR_END_OF_DATA;
986  }
987 
988  if (err == CLDSM_OK)
989  {
990  DBGLOG(DD_OBJ,"Module %p, status %u",pModule,pModule->status)
991  pDsmObject->hModuleData = pModule->hModuleData;
992 
993  /* Open the object to enable future access */
994  CHECK_MEM_ERR(memSeqOpen(MEM_CONTEXT, (MemHandle)moduleDataOpen(pDsmObject->hModuleData),
995  (pDsmObject->objectDataOffset + dataOffset), dataLength,
996  TRUE /*async*/, &(pDsmObject->objectDataSeq)));
997 
998  /*
999  -- NB. Should never generate MEM_SEQ_OPEN_LIMIT error since core stack
1000  -- configures memMgr (via memStart) to support sufficient MemSeqRefs to
1001  -- cover it's worst case internal use plus NUM_OPEN_DSM_OBJECTS_MAX
1002  */
1003 
1004  *pKind = pDsmObject->kind;
1005 
1006  idp->dsmObjectsOpen++;
1007  }
1008  }
1009 
1010  goto _return; /* Prevents compiler warnings */
1011 _return:
1012  DEBUG_CHK( err == CLDSM_OK,
1013  dsmDP1(("ERROR: clDsmOpenObject: %u\n", err)));
1014  dsmDP2(("exit clDsmOpenObject -> rtn: %u, o/p: %u \n", err, *pKind));
1015 
1016  return err;
1017 }
1018 
1019 /*
1020 -- Close a loaded object
1021 --
1022 */
1023 E_DscError CDSM_CloseObject( H_DsmCoreInst instance,
1024  /*I*/ H_DsmObject clDsmObjectHandle )
1025 {
1026  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
1027  P_DsmObject pDsmObject = (P_DsmObject) clDsmObjectHandle;
1028  E_DscError err = CLDSM_OK;
1029 
1030  dsmDP2(("CDSM_CloseObject( %p, %p )\n",
1031  instance, clDsmObjectHandle));
1032 
1033  API_PARAM_CHK( instance, dsmDP1(("ERROR: Invalid instance\n")),
1034  err = CLDSM_ERR_INVALID_INSTANCE; goto _return );
1035  API_PARAM_CHK( clDsmObjectHandle, dsmDP1(("ERROR: Invalid object handle\n")),
1036  err = CLDSM_ERR_INVALID_OBJECT_HANDLE; goto _return );
1037 
1038 
1039  if (!DSM_OBJECT_CORRECT( pDsmObject, idp ))
1040  {
1041  dsmDP1(("API ERROR: Invalid object handle\n"));
1042  err = CLDSM_ERR_INVALID_OBJECT_HANDLE;
1043  }
1044  else if (pDsmObject->pModule == NULL)
1045  {
1046  err = CLDSM_ERR_OBJECT_NOT_LOADED;
1047  }
1048  else if (pDsmObject->objectDataSeq == NULL)
1049  {
1050  err = CLDSM_ERR_OBJECT_NOT_OPEN;
1051  }
1052  else
1053  {
1054  moduleDataClose(idp, pDsmObject->hModuleData);
1055  pDsmObject->hModuleData = NULL;
1056  memSeqClose( pDsmObject->objectDataSeq );
1057  pDsmObject->objectDataSeq = NULL;
1058 
1059  idp->dsmObjectsOpen--;
1060  }
1061 
1062  goto _return; /* -- Prevents compiler warnings when no API checking */
1063 _return:
1064  DEBUG_CHK( err == CLDSM_OK,
1065  dsmDP1(("ERROR: clDsmCloseObject: %u\n", err)));
1066  dsmDP2(("exit clDsmCloseObject -> rtn: %u\n", err));
1067  return err;
1068 }
1069 
1076 {
1077  P_DsmObject pDsmObject = (P_DsmObject) clDsmObjectHandle;
1078 
1079  if (!memValidate( pDsmObject ))
1080  {
1081  return NULL;
1082  }
1083  return pDsmObject->myDsmInst;
1084 }
1085 
1086 /*
1087 -- Set caching rules for a cached object (path).
1088 */
1089 E_DscError CDSM_SetObjectCachingRules( H_DsmCoreInst instance,
1090  U8BIT *pathname, E_CacheRules cachingRules )
1091 {
1092  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
1093  U8BIT path[MAX_PATH_NAME_SIZE];
1094  P_Module pModule;
1095  E_DscError err;
1096  P_ObjectCarousel pOC;
1097 
1098  dsmDP2(("CDSM_SetObjectCachingRules( %p, %s, %u )\n", instance, pathname, cachingRules));
1099 
1100  API_PARAM_CHK( instance, dsmDP1(("ERROR: Invalid instance\n")),
1101  err = CLDSM_ERR_INVALID_INSTANCE; goto _return );
1102  API_PARAM_CHK( pathname, dsmDP1(("ERROR: Invalid pathname\n")),
1103  err = CLDSM_ERR_INVALID_PATHNAME; goto _return );
1104 
1105  err = RetrieveCarouselPath( idp, pathname, path, &pOC );
1106  if (!err)
1107  {
1108  #ifdef DSM_DISABLE_CACHE_PRIORITISING
1109  /* -- Setup default caching rules */
1110  cachingRules = CACHE_RULES_DEFAULT;
1111  #endif
1112 
1113  err = lmGetObjectLoadState( idp, pOC, (U8BIT *)path, &pModule );
1114  if (!err)
1115  {
1116  if (pModule != NULL)
1117  {
1118  /* -- Module must be cached with valid moduleData */
1119  dsmAssert((pModule->status == MS_CACHED));
1120  dsmAssert((pModule->hModuleData != NULL));
1121 
1122  /* -- TODO: Handle prioritisation of all caching rule settings */
1123  /* -- If new caching rules have fromStream set they override any previous
1124  -- caching rules for module */
1125  if (cachingRules == CACHE_RULES_FROM_STREAM)
1126  {
1127  DSC_ModuleDataRefresh( idp, pModule );
1128  }
1129  }
1130  }
1131 
1132  if (err == CLDSM_ERR_LOAD_FAILED)
1133  {
1134  /* -- Do not return this error since client is not interested */
1135  err = CLDSM_OK;
1136  }
1137  }
1138 _return:
1139  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: clDsmSetObjectCachingRules: %u\n", err)));
1140  dsmDP2(("exit clDsmSetObjectCachingRules -> rtn: %u\n", err));
1141  return err;
1142 }
1143 
1144 /*
1145 -- Pre-fetch (into cache) a DSM-CC object
1146 --
1147 */
1148 E_DscError CDSM_PrefetchObject( H_DsmCoreInst instance,
1149  U8BIT *pathname, U32BIT timeout )
1150 {
1151  P_DsmCoreInst idp = (P_DsmCoreInst) instance;
1152  U8BIT path[MAX_PATH_NAME_SIZE];
1153  P_LoadRequest pLoadRequest;
1154  E_DscError err;
1155  P_ObjectCarousel pOC;
1156  E_LRStatus lrStatus;
1157 
1158  dsmDP2(("CDSM_PrefetchObject( %p, %s, %u )\n", instance, pathname, timeout));
1159 
1160  API_PARAM_CHK( instance, dsmDP1(("ERROR: Invalid instance\n")),
1161  err = CLDSM_ERR_INVALID_INSTANCE; goto _return );
1162  API_PARAM_CHK( pathname, dsmDP1(("ERROR: Invalid pathname\n")),
1163  err = CLDSM_ERR_INVALID_PATHNAME; goto _return );
1164 
1165  err = RetrieveCarouselPath( idp, pathname, path, &pOC );
1166  if (!err)
1167  {
1168  err = lmPrefetchObjectLoad( idp, pOC, path, timeout, &pLoadRequest );
1169 
1170  if (!err)
1171  {
1172  lrStatus = pLoadRequest->rlr.status;
1173 
1174  switch (lrStatus)
1175  {
1176  case LRS_LOADED:
1177  case LRS_ABORTED_LOAD_ERROR:
1178  case LRS_ABORTED_PATH_ERROR:
1179  /* -- NB. Do not return load failure errors since client
1180  -- is not interested */
1181  lmLoadDestroy( idp, pLoadRequest );
1182  break;
1183 
1184  /*
1185  *** PLACEHOLDER - NOT CURRENTLY VALID ***
1186  case LRS_STALLED_DSI:
1187  TODO: Allow object pre-fetches before DSI acquired
1188  */
1189  case LRS_STALLED_MODULE:
1190  case LRS_STALLED_SRG_MODULE:
1191  /* -- Do nothing */
1192  break;
1193 
1194  default:
1195  /* -- Illegal status */
1196  dsmDP1(("ERROR: Illegal loadRequest status = %u\n",
1197  lrStatus));
1198  dsmAssert((0));
1199  err = CLDSM_ERR_INTERNAL;
1200  break;
1201  }
1202  }
1203 
1204  if (err)
1205  {
1206  /* -- Error so destroy/free any allocated memory objects */
1207  if (pLoadRequest)
1208  {
1209  lmLoadDestroy( idp, pLoadRequest );
1210  }
1211  }
1212  }
1213 _return:
1214  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: clDsmPrefetchObject: %u\n", err)));
1215  dsmDP2(("exit clDsmPrefetchObject -> rtn: %u\n", err));
1216  return err;
1217 }
1218 
1219 /***************************************/
1220 /* -- Asynchronous Client API Calls -- */
1221 /***************************************/
1222 
1223 /*
1224 -- Get specified object kind
1225 */
1226 E_DscError CDSM_ObjectGetKind(
1227  /*I*/ H_DsmObject object,
1228  /*O*/ E_DsmObjectKind *pKind )
1229 {
1230  P_DsmObject pDsmObject = (P_DsmObject) object;
1231  E_DscError err = CLDSM_OK;
1232 
1233  dsmDP2(("CDSM_ObjectGetKind( %p, %p )\n", object, pKind));
1234 
1235  API_PARAM_CHK( object, dsmDP1(("ERROR: Invalid object handle\n")),
1236  err = CLDSM_ERR_INVALID_OBJECT_HANDLE; goto _return );
1237  API_PARAM_CHK( pKind, dsmDP1(("ERROR: Illegal parameter\n")),
1238  err = CLDSM_ERR_ILLEGAL_PARAMETER; goto _return );
1239 
1240 
1241  if (!DSM_OBJECT_VALIDATE( pDsmObject ))
1242  {
1243  dsmDP1(("API ERROR: Invalid object handle\n"));
1244  err = CLDSM_ERR_INVALID_OBJECT_HANDLE;
1245  }
1246  else if (pDsmObject->status != OBJ_LOAD_COMPLETED)
1247  {
1248  err = CLDSM_ERR_OBJECT_NOT_LOADED;
1249  }
1250  else
1251  {
1252  *pKind = pDsmObject->kind;
1253  }
1254 
1255  goto _return; /* -- Prevents compiler warnings when no API checking */
1256 _return:
1257  DEBUG_CHK( err == CLDSM_OK,
1258  dsmDP1(("ERROR: dsmObjectGetKind: %u\n", err)));
1259  dsmDP2(("exit dsmObjectGetKind -> rtn: %u, o/p: %u \n", err, *pKind));
1260  return err;
1261 }
1262 
1263 /*******************************************************************************
1264 * Get specified object carousel handle.
1265 *
1266 * The object (clDsmObjectHandle) must be LOADED.
1267 *
1268 * NB. This can also be called to poll for when an object is loaded.
1269 *
1270 * RETURNS:
1271 * CLDSM_OK (0)
1272 * CLDSM_ERR_INVALID_OBJECT_HANDLE
1273 * CLDSM_ERR_INVALID_OBJECT_TYPE
1274 * CLDSM_ERR_OBJECT_NOT_LOADED
1275 *
1276 *******************************************************************************/
1277 E_DscError CDSM_ObjectGetCarouselHandle(
1278  /*I*/ H_DsmObject object,
1279  /*O*/ void **hCarouselHandle )
1280 {
1281  P_DsmObject pDsmObject = (P_DsmObject) object;
1282  E_DscError err = CLDSM_OK;
1283 
1284  dsmDP2(("CDSM_ObjectGetCarouselHandle( %p, %p )\n", object, hCarouselHandle));
1285 
1286  API_PARAM_CHK( object, dsmDP1(("ERROR: Invalid object handle\n")),
1287  err = CLDSM_ERR_INVALID_OBJECT_HANDLE; goto _return );
1288  API_PARAM_CHK( hCarouselHandle, dsmDP1(("ERROR: Illegal parameter\n")),
1289  err = CLDSM_ERR_ILLEGAL_PARAMETER; goto _return );
1290 
1291 
1292  if (!DSM_OBJECT_VALIDATE( pDsmObject ))
1293  {
1294  dsmDP1(("API ERROR: Invalid object handle\n"));
1295  err = CLDSM_ERR_INVALID_OBJECT_HANDLE;
1296  }
1297  else if (pDsmObject->status != OBJ_LOAD_COMPLETED)
1298  {
1299  err = CLDSM_ERR_OBJECT_NOT_LOADED;
1300  }
1301  else
1302  {
1303  *hCarouselHandle = pDsmObject->pObjCarousel;
1304  }
1305 
1306  goto _return; /* -- Prevents compiler warnings when no API checking */
1307 _return:
1308  DEBUG_CHK( err == CLDSM_OK,
1309  dsmDP1(("ERROR: dsmObjectGetCarouselHandle: %u\n", err)));
1310  dsmDP2(("exit dsmObjectGetCarouselHandle -> rtn: %u, o/p: %p \n", err, *hCarouselHandle));
1311  return err;
1312 }
1313 
1348  /*I*/ H_DsmObject clDsmObjectHandle,
1349  /*I*/ U32BIT serviceId,
1350  /*O*/ U8BIT **pSrvCtxtData,
1351  /*O*/ U32BIT *pSrvCtxtLen)
1352 {
1353  E_DscError err;
1354  P_DsmObject pObject = (P_DsmObject)clDsmObjectHandle;
1355  U32BIT initialOffset;
1356  MemPtr addr;
1357  U32BIT srvId;
1358  U16BIT application_specific_data_length;
1359  U8BIT serviceIdNum;
1360  U8BIT serviceContextList_count;
1361 
1362  dsmDP3(("CDSM_ObjectGetServiceContext(clDsmObjectHandle=%p, serviceId=0x%x)\n",
1363  clDsmObjectHandle, serviceId));
1364 
1365  if (!DSM_OBJECT_VALIDATE(pObject))
1366  {
1367  dsmDP1(("API ERROR: Invalid SRG Object handle\n"));
1368  err = CLDSM_ERR_INVALID_OBJECT_HANDLE;
1369  }
1370  else if (pObject->status != OBJ_LOAD_COMPLETED)
1371  {
1372  dsmDP1(("API ERROR: SRG Object not loaded\n"));
1373  err = CLDSM_ERR_OBJECT_NOT_LOADED;
1374  }
1375  else if (pObject->objectDataSeq == NULL)
1376  {
1377  dsmDP1(("API ERROR Object not open\n"));
1378  err = CLDSM_ERR_OBJECT_NOT_OPEN;
1379  }
1380  else
1381  {
1382  err = CLDSM_ERR_END_OF_DATA;
1383 
1384  /* Remember the offset, so we can restore position before return */
1385  memSeqReadPos((MemSeqRef)pObject->objectDataSeq, &initialOffset);
1386 
1387  /* Get current location within the SRG object message */
1388  addr = pObject->objectDataSeq;
1389 
1390  /* Read serviceContextList_count */
1391  memSeqReadByte( addr, &serviceContextList_count );
1392 
1393  for (serviceIdNum = 0; serviceIdNum != serviceContextList_count; serviceIdNum++)
1394  {
1395  /* Read ServiceID (4 bytes) - This is a combination (concatanation) of
1396  data_broadcast_id (2 bytes) and application_type_code (2 bytes) */
1397  readUInt32Seq(addr, &srvId);
1398 
1399  /* Read application_specific_data_length */
1400  readUInt16Seq(addr, &application_specific_data_length);
1401 
1402  /* Have we found the required ServiceID ? */
1403  if (srvId == serviceId)
1404  {
1405  *pSrvCtxtLen = application_specific_data_length;
1406  memSeqAccessCurrent( addr, (U8BIT **)pSrvCtxtData, pSrvCtxtLen );
1407  err = CLDSM_OK;
1408  break;
1409  }
1410  /* Skip application_specific_data_byte loop */
1411  memSeqSetPosRel( addr, application_specific_data_length);
1412  }
1413  /* Reset offset to original location in SRG object message */
1414  memSeqSetPosAbs(addr, initialOffset);
1415  }
1416  DEBUG_CHK(err == CLDSM_OK, dsmDP1(("ERROR: clDsmSRGObjectHandle=%u\n", err)));
1417  return err;
1418 }
1419 
1420 /*------------------------------ Local Functions -----------------------------*/
1421 
1422 static U8BIT* GetHexValue16( U8BIT *url, U16BIT *pValue )
1423 {
1424  int i, val;
1425  val = 0;
1426  for (i = 0; i != 4; i++, url++)
1427  {
1428  if (*url >= '0' && *url <= '9')
1429  {
1430  val = (val * 16) + *url - '0';
1431  }
1432  else if (*url >= 'a' && *url <= 'f')
1433  {
1434  val = (val * 16) + 0xa + *url - 'a';
1435  }
1436  else if (*url >= 'A' && *url <= 'F')
1437  {
1438  val = (val * 16) + 0xA + *url - 'A';
1439  }
1440  else
1441  {
1442  break;
1443  }
1444  }
1445  if (i != 0)
1446  {
1447  *pValue = val;
1448  }
1449  return url;
1450 }
1451 
1452 static U8BIT* GetHexValue32( U8BIT *url, U32BIT *pValue )
1453 {
1454  int i, val;
1455  val = 0;
1456  for (i = 0; i != 8; i++, url++)
1457  {
1458  if (*url >= '0' && *url <= '9')
1459  {
1460  val = (val * 16) + *url - '0';
1461  }
1462  else if (*url >= 'a' && *url <= 'f')
1463  {
1464  val = (val * 16) + 0xa + *url - 'a';
1465  }
1466  else if (*url >= 'A' && *url <= 'F')
1467  {
1468  val = (val * 16) + 0xA + *url - 'A';
1469  }
1470  else
1471  {
1472  break;
1473  }
1474  }
1475  *pValue = val;
1476  return url;
1477 }
1478 
1479 static U8BIT* ParseDvbLocator( U8BIT *url, S_CarouselLocator *pLoc )
1480 {
1481  url = GetHexValue16( url, &pLoc->original_network_id );
1482  if (*url == '.')
1483  {
1484  url++;
1485  url = GetHexValue16( url, &pLoc->transport_stream_id );
1486  if (*url == '.')
1487  {
1488  url++;
1489  url = GetHexValue16( url, &pLoc->service_id );
1490  if (*url == '.')
1491  {
1492  url++;
1493  url = GetHexValue16( url, &pLoc->component_tag );
1494  if (*url == '$')
1495  {
1496  url++;
1497  url = GetHexValue32( url, &pLoc->carousel_id );
1498  }
1499  }
1500  }
1501  }
1502  return url;
1503 }
1504 
1505 /* /////////////////////////////////////////////////////////////////////////////
1506 // SanitisePath
1507 // -- Create 'sanitised' output path from supplied input path
1508 // -- opPath must reference an array at least MAX_PATH_NAME_SIZE in length
1510 static E_DscError SanitisePath( U8BIT *ipPath, U8BIT *opPath, S_CarouselLocator *pLoc )
1511 {
1512  E_DscError err = CLDSM_OK;
1513  size_t pathLen;
1514  size_t pathElementLen;
1515 
1516  dsmDP3(("SanitisePath()\n"));
1517  dsmAssert((ipPath != NULL));
1518  dsmAssert((opPath != NULL));
1519 
1520  opPath[0] = '\0';
1521  if (strlen((char *)ipPath ) != 0)
1522  {
1523  pathLen = 0;
1524  if (memcmp(ipPath, "DSM:", 4) == 0)
1525  {
1526  ipPath += 4;
1527  }
1528  else if (memcmp(ipPath, "dvb:", 4) == 0)
1529  {
1530  /* according to "ETSI TS 102 851", url has format:
1531  * "dvb:/d/s/2.png" (for same carousel) or,
1532  * "dvb://233a..1044$1/g/h/2.png" (for possibly a different carousel)
1533  */
1534  ipPath += 4;
1535  if (ipPath[0] == '/' && ipPath[1] == '/')
1536  {
1537  /* Section 6.1 table 1 (BNF), this is 'dvb_net_path' */
1538  ipPath += 2;
1539  if (*ipPath != '/')
1540  {
1541  ipPath = ParseDvbLocator( ipPath, pLoc );
1542  }
1543  }
1544  }
1545 
1546  /* -- Discard any leading path separator chars */
1547  while (*ipPath == '/' || *ipPath == '\\')
1548  ipPath++;
1549 
1550  /* -- Find length of next path element in input */
1551  pathElementLen = strcspn((char *)ipPath, PATH_SEPARATOR_LIST_STRING );
1552 
1553  /* -- Check if there is room for this path element in the output array */
1554  pathLen = pathElementLen;
1555  while (pathLen < (MAX_PATH_NAME_SIZE - 1) && pathElementLen != 0)
1556  {
1557  /* -- Copy path element from input to output */
1558  memcpy( opPath, ipPath, pathElementLen );
1559 
1560  /* -- Step input & output pointers */
1561  ipPath += pathElementLen;
1562  opPath += pathElementLen;
1563 
1564  if (*ipPath == '\0')
1565  {
1566  break;
1567  }
1568  /* -- Add a single seperator char to output */
1569  *opPath++ = PATH_SEPERATOR_CHAR;
1570  pathLen++;
1571 
1572  /* -- Step over/discard any/next seperator chars in input */
1573  ipPath += strspn((char *)ipPath, PATH_SEPARATOR_LIST_STRING );
1574 
1575  /* -- Find length of next path element in input */
1576  pathElementLen = strcspn((char *)ipPath, PATH_SEPARATOR_LIST_STRING );
1577  pathLen += pathElementLen;
1578  }
1579  if (pathLen >= (MAX_PATH_NAME_SIZE - 1))
1580  {
1581  dsmDP1(("API ERROR: Invalid pathname length: %u\n", pathLen));
1582  err = CLDSM_ERR_INVALID_PATHNAME;
1583  }
1584  else
1585  {
1586  *opPath = '\0';
1587  }
1588  }
1589  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: SanitisePath: %u\n", err)));
1590  dsmDP3(("exit SanitisePath -> rtn: %u\n", err));
1591  return err;
1592 }
1593 
1594 static E_DscError RetrieveCarouselPath( P_DsmCoreInst idp,
1595  U8BIT *ipPath, U8BIT *opPath,
1596  P_ObjectCarousel *ppOC )
1597 {
1598  P_ObjectCarousel pOC;
1599  E_DscError err;
1600  S_CarouselLocator locator;
1601 
1602  /* set default values */
1603  locator.original_network_id = idp->dvbLocator.original_network_id;
1604  locator.transport_stream_id = idp->dvbLocator.transport_stream_id;
1605  locator.service_id = 0xFFFF;
1606  locator.component_tag = 0xFFFF;
1607  locator.carousel_id = INVALID_CAROUSEL_ID;
1608  err = SanitisePath( ipPath, opPath, &locator );
1609  if (!err)
1610  {
1611  if (locator.original_network_id != idp->dvbLocator.original_network_id ||
1612  (locator.transport_stream_id != 0 &&
1613  locator.transport_stream_id != idp->dvbLocator.transport_stream_id &&
1614  idp->dvbLocator.transport_stream_id != 0))
1615  {
1616  ERRPRINT("different transport: onet=0x%x trans=0x%x",
1617  locator.original_network_id, locator.transport_stream_id )
1618  err = CLDSM_ERR_CAROUSEL_UNAVAILABLE;
1619  }
1620  else
1621  {
1622  pOC = (P_ObjectCarousel)idp->pCurrentCarousel;
1623  if (locator.service_id == 0xFFFF)
1624  {
1625  if (pOC == NULL || !memValidate( pOC ) || pOC->root.magic != OC_MAGIC)
1626  {
1627  ERRPRINT("ERROR: Invalid Current Carousel %p", pOC)
1628  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
1629  }
1630  else
1631  {
1632  locator.service_id = pOC->root.serviceId;
1633  locator.carousel_id = pOC->root.rcid;
1634  DBGLOG(DD_OC, "cid=%d", locator.carousel_id)
1635  }
1636  }
1637  else if (locator.component_tag == 0xFFFF)
1638  {
1639  if (pOC == NULL || !memValidate( pOC ) || pOC->root.magic != OC_MAGIC)
1640  {
1641  ERRPRINT("ERROR: Current Carousel is invalid")
1642  err = CLDSM_ERR_INVALID_CAROUSEL_HANDLE;
1643  }
1644  else if (locator.service_id != pOC->root.serviceId)
1645  {
1646  ERRPRINT("current carousel on different service: sid=0x%x cc_sid=0x%x",
1647  locator.service_id, pOC->root.serviceId)
1648  err = CLDSM_ERR_CAROUSEL_UNAVAILABLE;
1649  }
1650  else
1651  {
1652  locator.carousel_id = pOC->root.rcid;
1653  DBGLOG(DD_OC, "cid=%d", locator.carousel_id)
1654  }
1655  }
1656  else if (locator.carousel_id == INVALID_CAROUSEL_ID)
1657  {
1658  S_SIQueryRequest siQueryData;
1659  S_SIQueryResult siQueryResult;
1660  DBGLOG(DD_OC, "ctag=%d", locator.component_tag)
1661  siQueryData.kind = SIQUERY_CAROUSEL_INFO;
1662  siQueryData.dataId = (U8BIT)locator.component_tag;
1663  siQueryData.serviceId = locator.service_id;
1664  err = siQueryStart( idp, &siQueryData, NULL, &siQueryResult );
1665  switch (err)
1666  {
1667  case CLDSM_PENDING:
1668  /*ignore result*/
1669  err = CLDSM_OK;
1670  break;
1671  case CLDSM_OK:
1672  locator.carousel_id = siQueryResult.data.carouselInfo.carouselId;
1673  DBGLOG(DD_OC, "cid=%d", locator.carousel_id)
1674  break;
1675  default:
1676  ERRPRINT("err=%d", err);
1677  }
1678  }
1679  if (!err)
1680  {
1681  if (locator.carousel_id != INVALID_CAROUSEL_ID)
1682  {
1683  pOC = (P_ObjectCarousel)DSC_RootCrslListFindById( idp->llcRootCarousels, locator.service_id, locator.carousel_id );
1684  if (pOC != NULL)
1685  {
1686  DBGLOG(DD_OC, "pOC=%p", pOC) *
1687  ppOC = pOC;
1688  }
1689  else
1690  {
1691  DBGLOG(DD_OC, "cid=%d", locator.carousel_id)
1692  err = CDSM_LoadCarousel( idp, locator.service_id, locator.carousel_id,
1693  SIQUERY_CAROUSEL, (H_DsmCarousel *)ppOC );
1694  }
1695  }
1696  else
1697  {
1698  err = CDSM_LoadCarousel( idp, locator.service_id, (U8BIT)locator.component_tag,
1699  SIQUERY_CAROUSEL_INFO, (H_DsmCarousel *)ppOC );
1700  }
1701  }
1702  }
1703  }
1704  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: %s: %u\n", __FUNCTION__, err)));
1705  return err;
1706 }
1707 
1708 /*----------------------------------------------------------------------------*/
E_DscError CDSM_OpenObject(H_DsmCoreInst instance, H_DsmObject clDsmObjectHandle, E_DsmObjectKind *pKind)
Open object data for subsequent access via API functions for given object kind. The object must have ...
E_DscError CDSM_CarouselUnloadFileGroups(H_DsmCoreInst instance, H_DsmCarousel hCarousel, S_CarouselInfoFileGroup *groups)
Release "File Group Info" data allocated by used by CDSM_CarouselLoadFileGroups() ...
E_DscError CDSM_LoadCarousel(H_DsmCoreInst instance, U16BIT serviceId, U32BIT couId, E_SIQueryKind kind, H_DsmCarousel *pclDsmCarouselHandle)
Request load of a DSM-CC Object Carousel (service domain).
General include file for clDsm library internal definitions.
Header to the loadMgr module.
E_DscError CDSM_UnloadObject(H_DsmCoreInst instance, H_DsmObject clDsmObjectHandle, E_DsmRstMode mode)
Unload (or cancel the requested load of) a DSM-CC object The client MUST first close and/or unsubscri...
E_DscError CDSM_GetCarouselId(H_DsmCoreInst instance, H_DsmCarousel hCarousel, U32BIT *pCarouselId)
Retrieve Carousel Id for the loaded DSM-CC Object Carousel.
H_DsmCoreInst CDSM_ObjectGetInstance(H_DsmObject clDsmObjectHandle)
Get DSM instance to which the object belongs.
E_DscError CDSM_CarouselLoadFileGroups(H_DsmCoreInst instance, H_DsmCarousel hCarousel, U16BIT *total, S_CarouselInfoFileGroup **pGroups)
Retrieve from Object Carousel's User Info, the "File Group Info" used by Australia and South Africa M...
E_DscError CDSM_UnloadModule(H_DsmCoreInst idp, H_DsmCarousel hCarousel, U32BIT moduleRef)
Unload SSU module. To be called once the client has finished saving this module data.
Header to dsmObject module - functions for managing DSM object heap.
H_DsmCarousel CDSM_CurrentCarousel(H_DsmCoreInst instance)
Retrieve handle to the current carousel for DSM-CC Instance.
E_DscError CDSM_SetCurrentCarousel(H_DsmCoreInst idp, H_DsmCarousel hCarousel)
Sets current carousel for DSM-CC Instance.
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 siQueryAbortPending(P_DsmCoreInst idp, P_SiQuery pSiQueryRef)
Aborts the specified SI Query before completion. Stops/destroys duplicate queries. For original queries or duplicate queries that have expired parents (and no further duplicates) calls stop SI Query callback on relevant query.
Definition: siQuery.c:350
E_DscError CDSM_ObjectGetServiceContext(H_DsmObject clDsmObjectHandle, U32BIT serviceId, U8BIT **pSrvCtxtData, U32BIT *pSrvCtxtLen)
This function gets service context of DSM object (if available) Need by MHEG5 for specified service g...
Header to the sectionFilter module.
E_DscError siQueryStart(P_DsmCoreInst idp, P_SIQueryRequest pQueryData, void *queryTarget, P_SIQueryResult pResult)
Starts an SI Query. First tests if we have already made this query and the results are stored or stil...
Definition: siQuery.c:76
Header to siQuery module - functions for managing SI queries.
Header to the 'module' module - Functions/methods for creating/destroying and managing attributes of ...
eader to the clDsmUtils module.
Header to the moduleData module.