DSMCC  17.9.0
 All Data Structures Files Functions Typedefs
siQuery.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  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 #include "clDsmSystem.h"
27 #include "siQuery.h"
28 
29 #include "linkList.h"
30 #include "cacheMgr.h"
31 #include "objectCarousel.h"
32 #include "sectionFilter.h"
33 #include "streamObject.h"
34 #include "loadMgr.h"
35 
36 /*---constant definitions for this file--------------------------------------*/
37 
38 
39 /*---local typedef structs for this file-------------------------------------*/
40 
41 /*---local (static) variable declarations for this file----------------------*/
42 
43 /*---local function prototypes for this file---------------------------------*/
44 
45 static E_DscError siQueryCreate( P_DsmCoreInst idp, P_SiQuery *ppSiQuery );
46 
47 static void siQueryDestroy( P_DsmCoreInst idp, P_SiQuery pSiQuery );
48 
49 static P_SiQuery FindPendingPIDQuery( P_DsmCoreInst idp, U16BIT service_id, U16BIT assoc_tag );
50 
51 
52 /*---global function definitions---------------------------------------------*/
53 
76 E_DscError siQueryStart( P_DsmCoreInst idp,
77  P_SIQueryRequest pQueryData, void *queryTarget,
78  P_SIQueryResult pResult )
79 {
80  E_DscError err;
81  P_SiQuery pSiQueryRef;
82  P_SiQuery pOrigSiQueryRef;
83 
84  dsmDP3(("\nsiQueryStart()\n"));
85  dsmAssert((idp != NULL));
86  dsmAssert((pQueryData != NULL));
87  dsmAssert((pResult != NULL));
88 
89  dsmDP4(("lastPID=%d lpStored=%d, lastAssocTag=%d\n",
90  idp->lastPID, idp->lastPIDResultStored, idp->lastAssociationTag));
91  dsmDP4(("kind=%d stored=%d, AssocTag=%d\n",
92  pQueryData->kind, idp->setup.storeSIQueryResults, pQueryData->data.association_tag));
93 
94  /* -- Check if PID lookup result is already stored and we can use it */
95  if ((idp->setup.storeSIQueryResults) &&
96  (pQueryData->kind == SIQUERY_PID) &&
97  (idp->lastPIDResultStored) &&
98  (pQueryData->serviceId == idp->lastServiceId) &&
99  (pQueryData->associationTag == idp->lastAssociationTag))
100  {
101  /* -- Get stored PID result */
102  pResult->kind = SIQUERY_PID;
103  pResult->data.pid = idp->lastPID;
104  err = CLDSM_OK;
105  }
106  else if (pQueryData->kind == SIQUERY_SSU_PID)
107  {
108  /* Special case of ssu PID being given to DSMCC API (and held in service id field) */
109  pResult->kind = SIQUERY_SSU_PID;
110  pResult->data.carouselInfo.pid = pQueryData->serviceId;
111  pResult->data.carouselInfo.carouselId = INVALID_CAROUSEL_ID;
112  pResult->data.carouselInfo.associationTag = INVALID_ASSOCIATION_TAG;
113  idp->lastServiceId = pQueryData->serviceId;
114  idp->lastAssociationTag = (U16BIT)INVALID_ASSOCIATION_TAG;
115  idp->lastPID = pResult->data.carouselInfo.pid;
116  idp->lastPIDResultStored = TRUE;
117  err = CLDSM_OK;
118  }
119  else
120  {
121  err = siQueryCreate( idp, &pSiQueryRef );
122  if (!err)
123  {
124  dsmDP3(("pSiQueryRef = %p\n", pSiQueryRef));
125  dsmDP4(("pQueryData->kind = %s\n",
126  pQueryData->kind == SIQUERY_PID ? "SIQUERY_PID" :
127  pQueryData->kind == SIQUERY_BOOT_CAROUSEL ? "SIQUERY_BOOT_CAROUSEL" :
128  pQueryData->kind == SIQUERY_FIND_CAROUSEL ? "SIQUERY_FIND_CAROUSEL" :
129  pQueryData->kind == SIQUERY_CAROUSEL_INFO ? "SIQUERY_CAROUSEL_INFO" :
130  pQueryData->kind == SIQUERY_SSU_CAROUSEL ? "SIQUERY_SSU_CAROUSEL" :
131  pQueryData->kind == SIQUERY_SSU_PID ? "SIQUERY_SSU_PID" :
132  pQueryData->kind == SIQUERY_CAROUSEL ? "SIQUERY_CAROUSEL" :
133  pQueryData->kind == SIQUERY_PIDLIST ? "SIQUERY_PIDLIST" :
134  pQueryData->kind == SIQUERY_DEFERRED_SERVICE ? "SIQUERY_DEFERRED_SERVICE" :
135  "UNKNOWN"));
136 
137  if (pQueryData->kind == SIQUERY_PID)
138  {
139  pOrigSiQueryRef = FindPendingPIDQuery( idp, pQueryData->serviceId, pQueryData->associationTag );
140  }
141  else
142  {
143  pOrigSiQueryRef = NULL;
144  }
145 
146  if (pOrigSiQueryRef == NULL)
147  {
148  dsmDP3(("siQueryStart() pSiQueryRef=%p target=%p\n", pSiQueryRef, queryTarget));
149  err = idp->setup.startSIQueryFunc( idp->setup.siqInstance,
150  pQueryData, (H_SIQueryRef) pSiQueryRef,
151  idp->generation.ptr, pResult );
152 
153  switch (err)
154  {
155  case CLDSM_PENDING:
156  dsmDP2(("kind=%d target=%p qhdl=%p\n", pResult->kind, queryTarget, pResult->data.queryHandle));
157  dsmAssert((pResult->kind == SIRESULT_PENDING));
158  /* -- Store details of query in query ref */
159  pSiQueryRef->query = *pQueryData;
160  pSiQueryRef->target = queryTarget;
161  pSiQueryRef->state = SIQS_PENDING;
162  pSiQueryRef->original = TRUE;
163  pSiQueryRef->queryHandle = pResult->data.queryHandle;
164  pResult->data.queryHandle = pSiQueryRef;
165 
166  /* -- Insert SI Query in current active list */
167  LLInsertHead( idp->llcCurrSiQueries, pSiQueryRef );
168  break;
169 
170  case CLDSM_OK:
171  if (pQueryData->kind != pResult->kind)
172  {
173  dsmDP1(("kind=%d %d\n", pQueryData->kind, pResult->kind));
174  }
175  dsmAssert((pQueryData->kind == pResult->kind));
176  dsmDP4(("lastPID=%d lpStored=%d, lastAssocTag=%d\n",
177  idp->lastPID, idp->lastPIDResultStored, idp->lastAssociationTag));
178  switch (pQueryData->kind)
179  {
180  case SIQUERY_PID:
181  /* -- Store association_tag to PID mappings */
182  idp->lastServiceId = pQueryData->serviceId;
183  idp->lastAssociationTag = pQueryData->associationTag;
184  idp->lastPID = pResult->data.pid;
185  idp->lastPIDResultStored = TRUE;
186  dsmDP3(("data.PID = %x\n", pResult->data.pid));
187  break;
188 
189  case SIQUERY_PIDLIST:
190  /* TODO: case SIQUERY_PIDLIST: If/when store of all PIDs
191  in PMT implemented */
192  break;
193 
194  case SIQUERY_CAROUSEL:
195  case SIQUERY_CAROUSEL_INFO:
196  case SIQUERY_FIND_CAROUSEL:
197  case SIQUERY_BOOT_CAROUSEL:
198  case SIQUERY_SSU_CAROUSEL:
199  case SIQUERY_SSU_PID:
200  /*
201  -- Store component_tag to PID to prevent a
202  -- subsequent unnecessary SI query when determining
203  -- the PID for the DSI of this carousel
204  */
205  idp->lastServiceId = pQueryData->serviceId;
206  idp->lastAssociationTag = (U16BIT)pResult->data.carouselInfo.associationTag;
207  idp->lastPID = pResult->data.carouselInfo.pid;
208  idp->lastPIDResultStored = TRUE;
209 
210  dsmDP3(("data.carouselInfo.PID = %x\n", pResult->data.carouselInfo.pid));
211  dsmDP3(("data.carouselInfo.component_tag = %x\n", pResult->data.carouselInfo.associationTag));
212  break;
213 
214  case SIQUERY_DEFERRED_SERVICE:
215  break;
216 
217  default:
218  /* -- No useful PID results in any other queries */
219  dsmAssert((0));
220  break;
221  }
222  dsmDP4(("NEW lastPID=%d lpStored=%d, lastAssocTag=%d\n",
223  idp->lastPID, idp->lastPIDResultStored, idp->lastAssociationTag));
224 
225  /* Fall though to destroy SI Query ref since no longer needed */
226 
227  default: /* ERROR cases */
228  siQueryDestroy( idp, pSiQueryRef );
229  }
230  }
231  else
232  {
233  /* -- This is a duplicate PID Query */
234  pSiQueryRef->query = *pQueryData;
235  pSiQueryRef->target = queryTarget;
236  pSiQueryRef->state = SIQS_PENDING;
237  pSiQueryRef->original = FALSE;
238 
239  pResult->kind = SIRESULT_PENDING;
240  pResult->data.queryHandle = pSiQueryRef;
241 
242  dsmAssert((pOrigSiQueryRef->original == TRUE));
243 
244  if (pOrigSiQueryRef->llcDuplSiQuerys == NULL)
245  {
246  /* -- Create list for duplicate queries */
247  err = LLCreate( idp, pOrigSiQueryRef, DUPLICATE_SI_QUERY_LIST,
248  &pOrigSiQueryRef->llcDuplSiQuerys );
249  if (err)
250  {
251  siQueryDestroy( idp, pSiQueryRef );
252  }
253  else
254  {
255  LLInsertTail( pOrigSiQueryRef->llcDuplSiQuerys, pSiQueryRef );
256  err = CLDSM_PENDING;
257  }
258  }
259  else
260  {
261  LLInsertTail( pOrigSiQueryRef->llcDuplSiQuerys, pSiQueryRef );
262  err = CLDSM_PENDING;
263  }
264  }
265  }
266  }
267 
268  DEBUG_CHK((err == CLDSM_OK || err == CLDSM_PENDING || err == CLDSM_ERR_SI_QUERY_FAILED),
269  dsmDP1(("ERROR: siQueryStart: %u\n", err)));
270  dsmDP3(("exit siQueryStart -> rtn: %u\n", err));
271  return err;
272 }
273 
283 void siQueryStop( P_DsmCoreInst idp, P_SiQuery pSiQueryRef )
284 {
285  dsmDP3(("siQueryStop()\n"));
286  dsmAssert((idp != NULL));
287  dsmAssert((pSiQueryRef != NULL));
288  dsmAssert((pSiQueryRef->magic == SI_QUERY_MAGIC));
289 
290  dsmDP2(("siQueryStop(idp,pSiQueryRef=%p) state=%d target=%p\n", pSiQueryRef, pSiQueryRef->state, pSiQueryRef->target));
291 
292  if (pSiQueryRef->original == TRUE)
293  {
294  switch (pSiQueryRef->state)
295  {
296  case SIQS_EXPIRED:
297  case SIQS_COMPLETED:
298  /*
299  -- In these states, a pending SI query is now completed. If it
300  -- is an original query then stop/ack the external query.
301  */
302 
303  /* -- Any duplicate queries should have already been handled */
304  dsmAssert((pSiQueryRef->llcDuplSiQuerys == NULL));
305 
306  /* -- Stop/ack external query */
307  idp->setup.stopSIQueryFunc( idp->setup.siqInstance, pSiQueryRef->queryHandle,
308  (H_SIQueryRef) pSiQueryRef );
309  break;
310 
311  case SIQS_ABORTED:
312  /*
313  -- In this state, an already aborted SI query is being stopped
314  -- so nothing specific to do.
315  */
316  break;
317 
318  default:
319  /* SI Query Refs that require stopping should not be in any other state.*/
320  dsmDP1(("ERROR: Illegal SI query status = %u\n", pSiQueryRef->state));
321  dsmAssert((0));
322  /* -- Notify an internal error here since can't return one */
323  if (idp->setup.errorFunc)
324  {
325  idp->setup.errorFunc( CLDSM_ERR_INTERNAL, NULL);
326  }
327  break;
328  }
329 
330  /* -- Remove from active query list */
331  LLRemove( pSiQueryRef, CURR_SI_QUERY_LIST );
332  }
333  /* else - this is a duplicate query, so nothing specific to do */
334 
335 
336  /* -- Destroy it (use original handle so it is Nulled) */
337  siQueryDestroy( idp, pSiQueryRef );
338 
339  dsmDP3(("exit siQueryStop\n"));
340 }
341 
351 {
352  P_SiQuery pOrigSiQueryRef;
353  P_SiQuery pExtSiQueryRefToStop;
354  BOOLEAN duplicateQuery;
355  BOOLEAN duplicateListEmpty;
356  void *queryHandle;
357 
358  dsmDP3(("siQueryAbortPending()\n"));
359  dsmAssert((idp != NULL));
360  dsmAssert((pSiQueryRef != NULL));
361  dsmAssert((pSiQueryRef->magic == SI_QUERY_MAGIC));
362 
363  pExtSiQueryRefToStop = NULL;
364 
365  switch (pSiQueryRef->state)
366  {
367  case SIQS_PENDING:
368 
369  /*
370  -- In this state, an active SI query is being aborted. If it
371  -- is an original query or the last duplicate query on an expired
372  -- original then mark the original query ref as aborted and stop
373  -- the external query.
374  -- NB. Only stop/destroy the query here if it is a duplicate since
375  -- original queries will be stopped/destroyed when the external
376  -- query stop is acknowledged via clDsmProcessSIQueryEvent.
377  */
378  pSiQueryRef->state = SIQS_ABORTED;
379 
380  if (pSiQueryRef->original == TRUE)
381  {
382  duplicateQuery = FALSE;
383 
384  if (pSiQueryRef->llcDuplSiQuerys != NULL)
385  {
386  /*
387  -- This original query has duplicates so don't stop
388  -- external query yet but but set state to EXPIRED
389  */
390  pSiQueryRef->state = SIQS_EXPIRED;
391  }
392  else
393  {
394  /* -- No duplicates so stop the external query */
395  pExtSiQueryRefToStop = pSiQueryRef;
396  }
397  }
398  else
399  {
400  /*
401  -- This is a duplicate query so no external query to stop for
402  -- this but do need to check if there is an expired parent
403  -- query that needs stopping.
404  */
405  duplicateQuery = TRUE;
406 
407  pOrigSiQueryRef = LLParent( pSiQueryRef, DUPLICATE_SI_QUERY_LIST );
408 
409  /* -- Should always be a parent */
410  dsmAssert((pOrigSiQueryRef != NULL));
411 
412  duplicateListEmpty = LLRemove( pSiQueryRef, DUPLICATE_SI_QUERY_LIST );
413 
414  if (duplicateListEmpty == TRUE)
415  {
416  /* -- Destroy the parent list */
417  LLDestroy( idp, &pOrigSiQueryRef->llcDuplSiQuerys );
418 
419  if (pOrigSiQueryRef->state == SIQS_EXPIRED)
420  {
421  pExtSiQueryRefToStop = pOrigSiQueryRef;
422  }
423  /* else - parent query is still active */
424  }
425  /* else - still more duplicate queries */
426  }
427 
428  if (duplicateQuery == TRUE)
429  {
430  /* -- Cannot be the same for duplicate queries */
431  dsmAssert((pExtSiQueryRefToStop != pSiQueryRef));
432 
433  /* -- Use passed in handle so it gets Nulled */
434  siQueryStop( idp, pSiQueryRef );
435  }
436 
437  if (pExtSiQueryRefToStop != NULL)
438  {
439  /* -- There is an external query to stop */
440 
441  /* -- Get the correct queryHandle */
442  pSiQueryRef = pExtSiQueryRefToStop;
443  queryHandle = pSiQueryRef->queryHandle;
444 
445  idp->setup.stopSIQueryFunc( idp->setup.siqInstance, queryHandle,
446  (H_SIQueryRef) pExtSiQueryRefToStop );
447  }
448  break;
449 
450 
451  default:
452  /*
453  -- SI Query Refs that are aborted should not be in any other state.
454  */
455 
456  dsmDP1(("ERROR: Illegal SI query status = %u\n",
457  pSiQueryRef->state));
458  dsmAssert((0));
459 
460  /* -- Notify an internal error here since can't return one */
461  if (idp->setup.errorFunc)
462  {
463  idp->setup.errorFunc( CLDSM_ERR_INTERNAL, NULL);
464  }
465 
466  /* -- NB. Since there is probably some internal memory corruption
467  -- it is safest not to do anything else here.
468  -- DSM-CC should be shut down (clDsmDestroy) in response to
469  -- this internal error otherwise this may cause a memory leak
470  -- in the MemMgr */
471  break;
472  }
473 
474  dsmDP3(("exit siQueryAbortPending\n"));
475 }
476 
477 #ifdef GET_PID_LIST
478 E_DscError siQueryGetPIDList( P_DsmCoreInst idp )
479 {
480  E_DscError err;
481  S_SIQueryRequest siQueryData;
482  S_SIQueryResult siQueryResult;
483 
484  siQueryData.kind = SIQUERY_PIDLIST;
485  siQueryData.service_id = idp->curr_service_id;
486 
487  err = siQueryStart( idp, &siQueryData, (void *) 0x91D, &siQueryResult );
488 
489  dsmDP1(("(%d) SI query status = %u\n", err, siQueryStatus));
490  switch (err)
491  {
492  case CLDSM_OK:
493  break;
494 
495  case CLDSM_PENDING:
496  break;
497 
498  default:
499  break;
500  }
501 
502  return err;
503 }
504 
505 #endif /*GET_PID_LIST*/
506 
507 
524  P_SiQuery pSiQueryRef, P_SIQueryResult pResult )
525 {
526  E_DscError err = CLDSM_OK;
527  P_RootCarousel pRC;
528  P_SecFilterInfo pSectionFilter;
529 
530  dsmAssert((idp != NULL));
531  dsmAssert((pSiQueryRef != NULL));
532 
533  dsmDP2(("siQueryProcessResult(idp,pSiQueryRef=%p,kind=%d) target=%p\n", pSiQueryRef, pResult->kind, pSiQueryRef->target));
534 
535  switch (pSiQueryRef->state)
536  {
537  case SIQS_PENDING:
538  dsmAssert((pResult != NULL));
539  if (pSiQueryRef->query.kind == pResult->kind)
540  {
541  /* -- Query is still active (ie. not previously aborted before
542  completion and result is still required) */
543  dsmDP2(("lastPID=%d lpStored=%d, lastAssocTag=%d\n",
544  idp->lastPID, idp->lastPIDResultStored, idp->lastAssociationTag));
545 
546  switch (pSiQueryRef->query.kind)
547  {
548  case SIQUERY_PID:
549 
550  /* -- Store result */
551  idp->lastServiceId = pSiQueryRef->query.serviceId;
552  idp->lastAssociationTag = pSiQueryRef->query.associationTag;
553  idp->lastPID = pResult->data.pid;
554  idp->lastPIDResultStored = TRUE;
555 
556  /* -- Get section filter and store PID in it */
557  pSectionFilter = (P_SecFilterInfo) pSiQueryRef->target;
558  dsmAssert((pSectionFilter != NULL));
559  dsmAssert((pSectionFilter->status == SFA_PENDING));
560  pSectionFilter->filter.pid = pResult->data.pid;
561 
562  err = DSC_SectionFilterCommit( idp, pSectionFilter );
563 
564  if (err)
565  {
566  /* -- Abort (and notify) anything depending on filter
567  -- NB. This will also stop the section filter */
568  DSC_SectionFilterAbortDependants( idp, pSectionFilter );
569  }
570  break;
571 
572  case SIQUERY_CAROUSEL:
573  case SIQUERY_CAROUSEL_INFO:
574  case SIQUERY_FIND_CAROUSEL:
575  case SIQUERY_BOOT_CAROUSEL:
576  case SIQUERY_SSU_CAROUSEL:
577  case SIQUERY_SSU_PID:
578  /* -- Only duplicate PID queries are handled */
579  dsmAssert((pSiQueryRef->llcDuplSiQuerys == NULL));
580 
581  /*
582  -- Store component_tag/association_tag to PID mapping.
583  -- This can prevent a subsequent unnecessary SI query
584  -- when determining the PID for the DSI of this carousel
585  */
586  idp->lastServiceId = pSiQueryRef->query.serviceId;
587  idp->lastAssociationTag =
588  (U16BIT)pResult->data.carouselInfo.associationTag;
589  idp->lastPID = pResult->data.carouselInfo.pid;
590  idp->lastPIDResultStored = TRUE;
591 
592  /* -- Get carousel */
593  pRC = (P_RootCarousel) pSiQueryRef->target;
594  if (pRC != NULL)
595  {
596  #ifdef GET_PID_LIST
597  if (status == SIQUERY_BOOT_CAROUSEL)
598  siQueryGetPIDList( idp );
599  #endif /*GET_PID_LIST*/
600 
601  /* -- Clear Query ref in carousel (finished with) */
602  pRC->pPendingSiQueryRef = NULL;
603  err = DSC_RootCrslBootCarousel( idp, pRC, &(pResult->data.carouselInfo));
604  if (err)
605  {
606  DSC_RootCrslAbortLoadRequest( idp, pRC );
607  }
608  }
609  break;
610 
611  case SIQUERY_PIDLIST:
612  /* do nothing */
613  break;
614 
615  case SIQUERY_DEFERRED_SERVICE:
616 
617  DSC_StrmObjectStoreDeferred( idp, pSiQueryRef->target, pResult->data.deferredService );
618 
619  break;
620 
621  default:
622  dsmDP1(("ERROR: Illegal SI query kind = %u\n",
623  pSiQueryRef->query.kind));
624  dsmAssert((0));
625  err = CLDSM_ERR_INTERNAL;
626  break;
627  }
628  }
629  else if (pResult->kind == SIRESULT_FAILURE)
630  {
631  switch (pSiQueryRef->query.kind)
632  {
633  case SIQUERY_PID:
634  /* -- Get section filter */
635  pSectionFilter = (P_SecFilterInfo) pSiQueryRef->target;
636  dsmAssert((pSectionFilter != NULL));
637 
638  /* -- Clear Query ref in filter (finished with) */
639  pSectionFilter->u.pPendingSiQueryRef = NULL;
640 
641  /* -- Abort (and notify) anything depending on filter */
642  DSC_SectionFilterAbortDependants( idp, pSectionFilter );
643  break;
644 
645  case SIQUERY_CAROUSEL_INFO:
646  case SIQUERY_BOOT_CAROUSEL:
647  case SIQUERY_CAROUSEL:
648  case SIQUERY_SSU_CAROUSEL:
649  case SIQUERY_SSU_PID:
650  /* -- Only duplicate PID queries are handled */
651  dsmAssert((pSiQueryRef->llcDuplSiQuerys == NULL));
652 
653  /* -- Get carousel */
654  pRC = (P_RootCarousel) pSiQueryRef->target;
655  if (pRC != NULL)
656  {
657  /* -- Clear Query ref in carousel (finished with) */
658  pRC->pPendingSiQueryRef = NULL;
659 
660  DSC_RootCrslAbortLoadRequest( idp, pRC );
661  }
662  break;
663 
664  /*
665  case SIQUERY_PIDLIST:
666  TODO: Implement for turbo-caching?
667  break;
668  */
669 
670  case SIQUERY_DEFERRED_SERVICE:
671  DSC_StrmObjectStoreDeferred( idp, pSiQueryRef->target, idp->dvbLocator );
672  break;
673 
674  default:
675  dsmDP1(("ERROR: Illegal SI query kind = %u\n",
676  pSiQueryRef->query.kind));
677  dsmAssert((0));
678  err = CLDSM_ERR_INTERNAL;
679  break;
680  }
681  }
682  else
683  {
684  dsmDP1(("ERROR: Illegal SI query status %u\n", pResult->kind));
685  /*dsmAssert((0));*/
686  err = CLDSM_ERR_INVALID_SIQUERY_STATUS;
687  }
688  dsmDP2(("NEW lastPID=%d lpStored=%d, lastAssocTag=%d\n",
689  idp->lastPID, idp->lastPIDResultStored, idp->lastAssociationTag));
690 
691  /* -- Query is now completed so change state */
692  pSiQueryRef->state = SIQS_COMPLETED;
693  break;
694 
695  case SIQS_ABORTED:
696  /* -- Regardless of supplied status, treat this as acknowledge of
697  -- previous SI Query stop request (ie. abort before completion).
698  -- SI query results no longer required so nothing specific
699  -- to do here. */
700  /* -- Only valid for original SI Queries */
701  dsmAssert((pSiQueryRef->original == TRUE));
702  break;
703 
704  case SIQS_EXPIRED:
705  /* -- This query is no longer required but was kept active because
706  -- it had duplicates. Nothing specific to do here. */
707  /* -- Only valid for original SI Queries */
708  dsmAssert((pSiQueryRef->original == TRUE));
709  break;
710 
711  default:
712  dsmDP1(("ERROR: Illegal SI query ref state = %u\n", pSiQueryRef->state));
713  dsmAssert((0));
714  err = CLDSM_ERR_INTERNAL;
715  }
716 
717  siQueryStop( idp, pSiQueryRef );
718 
719  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: siQueryProcessResult: %u\n", err)));
720  dsmDP3(("exit siQueryProcessResult -> rtn: %u \n", err));
721  return err;
722 }
723 
724 /*---Local function definitions---------------------------------------------*/
725 
726 /* /////////////////////////////////////////////////////////////////////////////
727 // siQueryCreate
728 // Creates an instance of the SI Query struct, and initialises it.
730 static E_DscError siQueryCreate( P_DsmCoreInst idp, P_SiQuery *ppSiQuery )
731 {
732  P_SiQuery pSiQuery = NULL;
733  E_DscError err = CLDSM_OK;
734 
735  dsmDP3(("siQueryCreate()\n"));
736  dsmAssert((idp != NULL));
737  dsmAssert((ppSiQuery != NULL));
738 
739  pSiQuery = (P_SiQuery)DSC_CmMemGet( idp, sizeof(S_SiQuery) );
740  if (!pSiQuery)
741  {
742  err = CLDSM_ERR_MEM_HEAP_FULL;
743  }
744  else
745  {
746  err = CLDSM_OK;
747 
748  llLinkInit( pSiQuery->llData, NUM_LISTS_SI_QUERY );
749 
750  pSiQuery->magic = SI_QUERY_MAGIC;
751  pSiQuery->state = SIQS_INITIAL;
752  pSiQuery->queryHandle = NULL;
753  pSiQuery->target = NULL;
754 
755  pSiQuery->query.serviceId = 0;
756  pSiQuery->query.kind = SIQUERY_PID;
757  pSiQuery->query.associationTag = 0;
758 
759  pSiQuery->original = FALSE;
760  pSiQuery->llcDuplSiQuerys = NULL;
761  }
762  *ppSiQuery = pSiQuery;
763 
764  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: siQueryCreate: %u\n", err)));
765  dsmDP3(("exit siQueryCreate -> rtn: %u\n", err));
766  return err;
767 }
768 
769 /* /////////////////////////////////////////////////////////////////////////////
770 // siQueryDestroy
771 // Destroys an instance of the siQuery struct, and all associated data.
773 static void siQueryDestroy( P_DsmCoreInst idp, P_SiQuery pSiQuery )
774 {
775  dsmAssert((idp != NULL));
776  dsmAssert((pSiQuery != NULL));
777  dsmAssert((pSiQuery->magic == SI_QUERY_MAGIC));
778 
779  /* -- Should not be in any lists */
780  dsmAssert((pSiQuery->llData[CURR_SI_QUERY_LIST].pLLCtrl == NULL));
781  dsmAssert((pSiQuery->llData[DUPLICATE_SI_QUERY_LIST].pLLCtrl == NULL));
782 
783  /* -- NULL pSiQueryRef contents.
784  -- NB. Should allow error to be detected if destroyed SI Query is
785  -- erroneously re-used (not guaranteed since may depend on MemMgr
786  -- implementation) */
787  pSiQuery->magic = 0;
788  pSiQuery->state = SIQS_INITIAL;
789  pSiQuery->queryHandle = NULL;
790  pSiQuery->target = NULL;
791 
792  pSiQuery->query.serviceId = 0;
793  pSiQuery->query.kind = SIQUERY_PID;
794  pSiQuery->query.associationTag = 0;
795 
796  pSiQuery->original = FALSE;
797  dsmAssert((pSiQuery->llcDuplSiQuerys == NULL));
798 
799 
800  /* -- Use original handle so it gets Nulled */
801  DSC_CmMemRelease( idp, pSiQuery );
802 
803  dsmDP3(("exit siQueryDestroy\n"));
804 }
805 
806 /* /////////////////////////////////////////////////////////////////////////////
807 // FindPendingPIDQuery
808 // Searches for a matching pending PID query.
810 static P_SiQuery FindPendingPIDQuery( P_DsmCoreInst idp, U16BIT service_id, U16BIT assoc_tag )
811 {
812  P_SiQuery pQueryFromList;
813  ListId_t listId;
814 
815  /* Get listId and first SI Query in list from Control block */
816  listId = LListId( idp->llcCurrSiQueries );
817  pQueryFromList = LLHead( idp->llcCurrSiQueries );
818 
819  /* Go through each SI Query in list until a pending PID query with a
820  matching service_id and assoc_tag is found */
821  while (pQueryFromList)
822  {
823  if ((pQueryFromList->query.kind == SIQUERY_PID) &&
824  (pQueryFromList->query.serviceId == service_id) &&
825  (pQueryFromList->query.associationTag == assoc_tag) &&
826  (pQueryFromList->state == SIQS_PENDING))
827  {
828  /* Found a matching SI Query */
829  /* -- Must always be an original query */
830  dsmAssert((pQueryFromList->original == TRUE));
831  break;
832  }
833  pQueryFromList = LLNext( pQueryFromList, listId );
834  }
835  return pQueryFromList;
836 }
837 
838 /*----------------------------------------------------------------------------*/
General include file for clDsm library internal definitions.
E_DscError siQueryProcessResult(P_DsmCoreInst idp, P_SiQuery pSiQueryRef, P_SIQueryResult pResult)
Processes and stops the specified SI Query.
Definition: siQuery.c:523
Header to the loadMgr module.
Header to the cacheMgr module.
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
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.
void siQueryStop(P_DsmCoreInst idp, P_SiQuery pSiQueryRef)
Stops the specified SI Query. Removes from any lists it is in and destroys associated memory object...
Definition: siQuery.c:283
DSM-CC stream object.