38 #define SIQ_DEFAULT_PMT_TOTAL 64
39 #define VERSION_CHANGED 0xff
44 typedef struct s_SiqCachePat
46 struct s_SiqCachePat *next;
52 typedef struct s_SiqCachePmt
73 static S_SiqCachePat* FindPat(
S_SiqInstance *siq, U16BIT transId )
75 S_SiqCachePat *pPat = siq->patList;
76 while (pPat != NULL && pPat->transId != transId)
83 static void ClearPmts(
S_SiqInstance *siq, S_SiqCachePmt *pPmt, U16BIT total )
87 if (pPmt->table != NULL)
89 DBGLOG(DS_CACHE,
"pPmt=%p serviceId=%d", pPmt, pPmt->serviceId )
97 static
void RemovePat(
S_SiqInstance *siq, S_SiqCachePat *pPat )
99 S_SiqCachePat **ppPat;
100 ppPat = &(siq->patList);
101 while (*ppPat != NULL)
107 siq->setup.memFree( pPat );
110 ppPat = &((*ppPat)->next);
119 FUNCTION_START(ClearPmtArray)
120 pPmt = siq->pmtArray;
124 ASSERT( siq->pmtTotal == 0 )
126 else if (siq->pmtCount != 0)
128 total = siq->pmtTotal;
131 if (pPmt->table != NULL)
133 DBGLOG(DS_CACHE,
"pPmt=%p serviceId=%d", pPmt, pPmt->serviceId )
137 if (siq->patList == NULL)
142 if (siq->pmtCount == 0)
150 FUNCTION_FINISH(ClearPmtArray)
153 static S_SiqCachePmt* GetCachePmt(
S_SiqInstance *siq, U16BIT serviceId )
155 S_SiqCachePmt *pPmt, *result;
158 FUNCTION_START(GetCachePmt)
160 pPmt = siq->pmtArray;
161 total = siq->pmtTotal;
169 if (pPmt->serviceId == serviceId)
179 pPmt = siq->pmtArray;
180 total = siq->pmtTotal;
183 if (pPmt->serviceId == 0)
186 pPmt->serviceId = serviceId;
192 FUNCTION_FINISH(GetCachePmt)
203 static
void ServiceRemoved(
H_SiqInstance siq, S_SiqCachePmt *pCachePmt )
205 if (pCachePmt->table != NULL)
207 DBGLOG(DS_CACHE,
"pPmt=%p serviceId=%d", pCachePmt, pCachePmt->serviceId )
209 pCachePmt->table = NULL;
212 if (pCachePmt->subscribed)
215 pCachePmt->subscribed = 0;
217 if (pCachePmt->requestId)
219 siq->setup.dvpCancelTable( siq->setup.pmtref, pCachePmt->requestId ) ;
220 pCachePmt->requestId = 0;
221 pCachePmt->refresh = 0;
224 SIQ_DeleteQueriesOnService( siq, pCachePmt->serviceId );
225 pCachePmt->serviceId = 0;
226 pCachePmt->accessed = 0;
233 BOOLEAN result = TRUE;
235 siq->pmtArray = siq->setup.memAlloc( SIQ_DEFAULT_PMT_TOTAL *
sizeof(S_SiqCachePmt));
236 if (siq->pmtArray == NULL)
242 memset( siq->pmtArray, 0, SIQ_DEFAULT_PMT_TOTAL *
sizeof(S_SiqCachePmt));
243 siq->pmtTotal = SIQ_DEFAULT_PMT_TOTAL;
250 S_SiqCachePat *pPat, *pNxt;
254 FUNCTION_START(SIQ_CacheExit)
255 pPmt = siq->pmtArray;
256 total = siq->pmtTotal;
259 if (pPmt->subscribed)
261 ERRLOG(
"Leaked SI change subscribe srv_id=%d", pPmt->serviceId)
265 siq->setup.dvpCancelTable( siq->setup.pmtref, pPmt->requestId );
267 if (pPmt->table != NULL)
279 ClearPmts( siq, (S_SiqCachePmt *)(pPat + 1), pPat->serviceTotal );
281 siq->setup.memFree( pPat );
284 while (pPat != NULL);
286 else if (siq->pmtArray != NULL)
288 siq->setup.memFree(siq->pmtArray);
290 FUNCTION_FINISH(SIQ_CacheExit)
303 S_SiqCachePat *pPat, *pCachePat;
305 S_SiqCachePmt *pCachePmt;
308 len = ((dptr[1] & 0x0F) << 8 | dptr[2]);
311 ERRLOG(
"PAT length too small %d", len)
315 id = dptr[3] << 8 | dptr[4];
316 version = (dptr[5] >> 1) & 0x1f;
317 pCachePat = FindPat( siq,
id );
318 if (pCachePat == NULL || pCachePat->version != version)
323 pPat = siq->setup.memAlloc(
sizeof(S_SiqCachePat) + (len *
sizeof(S_SiqCachePmt)));
327 pPat->version = version;
328 pPat->serviceTotal = 0;
329 pPmt = (S_SiqCachePmt *)(pPat + 1);
330 for (; len--; dptr += 4)
332 id = (dptr[0] << 8) | dptr[1];
335 pPat->serviceTotal++;
336 pCachePmt = GetCachePmt( siq,
id );
340 pCachePmt->table = NULL;
341 pCachePmt->serviceId = 0;
345 pPmt->serviceId = id;
346 pPmt->subscribed = 0;
354 pPmt->pmtpid = ((dptr[2] & 0x1f) << 8) | dptr[3];
358 for (pPmt = siq->pmtArray, len = siq->pmtTotal; len--; pPmt++)
360 if (pPmt->serviceId != 0)
363 ServiceRemoved( siq, pPmt );
366 if (siq->patList == NULL && siq->pmtArray != NULL)
369 siq->setup.memFree( siq->pmtArray );
371 else if (pCachePat != NULL)
373 RemovePat(siq, pCachePat);
375 pPat->next = siq->patList;
377 siq->pmtArray = (H_SiqCachePmt)(pPat + 1);
378 siq->pmtTotal = pPat->serviceTotal;
393 if (siq->origNetworkId != origNetworkId ||
394 siq->transportId != transportId)
396 siq->origNetworkId = origNetworkId;
397 siq->transportId = transportId;
398 SIQ_CacheClear( siq );
411 S_SiqCachePmt *pCachePmt;
412 pCachePmt = GetCachePmt( siq, serviceId );
413 if (pCachePmt == NULL)
415 ERRLOG(
"No Cache slot for serviceId=0x%x", serviceId)
419 ServiceRemoved( siq, pCachePmt );
434 U16BIT *pSid, U8BIT *pVer )
436 S_SiqCachePmt *pCachePmt;
443 ERRLOG(
"NULL PMT data")
446 else if (*pmt != PMT_TID)
448 ERRLOG(
"Bad PMT data! (table id=0x%x)", *pmt )
453 serviceId = pmt[3] << 8 | pmt[4];
454 pCachePmt = GetCachePmt( siq, serviceId );
455 if (pCachePmt == NULL)
457 ERRLOG(
"No Cache slot for serviceId=0x%x", serviceId)
462 if (siq->patList == NULL)
464 DBGLOG(DS_PAT,
"Not received PAT")
466 version = (pmt[5] >> 1) & 0x1f;
467 if (pCachePmt->table != NULL && pCachePmt->version == version)
469 DBGLOG(DS_CACHE,
"Ignore PMT srv_id=0x%x vers=%d", serviceId, version)
474 DBGLOG(DS_CACHE,
"new PMT srv_id=0x%x vers=%d, was v=%d tbl=%p", serviceId, version, pCachePmt->version, pCachePmt->table)
510 U16BIT serviceId, U8BIT version )
512 H_SiqCachePmt pCachePmt;
513 H_SiqPmtTable hOldTable;
515 pCachePmt = GetCachePmt( siq, serviceId );
516 if (pCachePmt == NULL)
518 ERRLOG(
"No Cache PMT!")
522 hOldTable = pCachePmt->table;
523 DBGLOG(DS_CACHE,
"new PMT srv_id=0x%x vers=%d old=%p requestId=%x",
524 serviceId, version, hOldTable, pCachePmt->requestId )
525 DBGLOG(DS_CACHE,
"pPmt=%p newTable=%p", pCachePmt, hNewTable )
526 pCachePmt->table = hNewTable;
527 pCachePmt->version = version;
528 if (hOldTable != NULL)
530 ASSERT( !pCachePmt->querying );
531 if (pCachePmt->subscribed)
540 if (pCachePmt->requestId)
542 ASSERT( hOldTable == NULL );
543 pCachePmt->querying = 0;
545 if (!pCachePmt->subscribed)
547 siq->setup.dvpCancelTable( siq->setup.pmtref, pCachePmt->requestId );
548 pCachePmt->requestId = 0;
555 H_SiqPmtTable SIQ_CacheRetrievePmt(
S_SiqInstance *siq, U16BIT serviceId, U32BIT *gettingPmt )
557 S_SiqCachePmt *pCachePmt;
558 H_SiqPmtTable result;
560 FUNCTION_START(SIQ_CacheRetrievePmt)
561 pCachePmt = GetCachePmt( siq, serviceId );
562 if (pCachePmt == NULL)
569 pCachePmt->accessed = ++(siq->cacheAccess);
570 result = pCachePmt->table;
577 if (!pCachePmt->requestId)
579 pCachePmt->querying = 1;
580 pCachePmt->requestId = siq->setup.dvpRequestTable(siq->setup.pmtref, pCachePmt->pmtpid, serviceId, PMT_TID );
582 *gettingPmt = pCachePmt->requestId;
585 FUNCTION_FINISH(SIQ_CacheRetrievePmt)
601 pPmt = siq->pmtArray;
602 total = siq->pmtTotal;
610 if (pPmt->serviceId == serviceId)
612 DBGLOG(DS_CACHE,
"pPmt=%p serviceId=%d", pPmt, pPmt->serviceId )
617 if (siq->patList == NULL)
631 S_SiqCachePat *pPat = siq->patList;
638 ClearPmts( siq, (S_SiqCachePmt *)(pPat + 1), pPat->serviceTotal );
651 S_SiqCachePmt *pCachePmt;
655 pCachePmt = GetCachePmt( siq, serviceId );
656 if (pCachePmt == NULL)
658 err = CLDSM_ERR_SI_SUBSCRIBE_FAILURE;
662 if (pCachePmt->refresh)
664 pCachePmt->refresh = 0;
665 if (pCachePmt->requestId)
667 siq->setup.dvpCancelTable( siq->setup.pmtref, pCachePmt->requestId );
668 pCachePmt->requestId = 0;
671 if (!pCachePmt->requestId)
673 pCachePmt->requestId = siq->setup.dvpRequestTable( siq->setup.pmtref, pCachePmt->pmtpid, serviceId, PMT_TID );
675 if (pCachePmt->requestId)
678 pCachePmt->subscribed++;
682 err = CLDSM_ERR_SI_SUBSCRIBE_FAILURE;
698 S_SiqCachePmt *pCachePmt;
701 pCachePmt = GetCachePmt( siq, serviceId );
702 if (pCachePmt != NULL && pCachePmt->subscribed)
704 pCachePmt->subscribed--;
705 ASSERT(pCachePmt->requestId != 0)
706 if (!pCachePmt->subscribed && !pCachePmt->querying)
709 siq->setup.dvpCancelTable( siq->setup.pmtref, pCachePmt->requestId );
void SIQ_ServiceInfoChangeUnsubscribe(S_SiqInstance *siq, U16BIT serviceId)
Unsubscribe component to previously subscribed service change or alteration updates.
H_SiqPmtTable SIQ_PmtCreateTable(S_SiqInstance *siq, U8BIT *data)
Create PMT structure for monitoring (life-cycle, NB_Info)
void SIQ_CacheClearPmt(H_SiqInstance siq, U16BIT serviceId)
Clear cached PMT information.
void SIQ_PmtDestroyTable(S_SiqInstance *siq, H_SiqPmtTable table)
Destroy PMT structure created by PMT_CreateTable.
void SIQ_UpdatePat(H_SiqInstance siq, U8BIT *dptr)
Provide SIQ with latest PAT data. Calling this function is optional. However, if not used...
E_SIQ_STATUS SIQ_RequirePmt(H_SiqInstance siq, U8BIT *pmt, U16BIT *pSid, U8BIT *pVer)
Ask SIQ whether PMT section data is required. It assumes CRC has been checked and is passing valid PM...
void SIQ_TransportChanged(H_SiqInstance siq, U16BIT origNetworkId, U16BIT transportId)
Inform SIQ when a demux is tuning to another transport stream. Not required if PAT is supplied to SIQ...
Main API to DSM-CC core layer (provided functions and required callbacks).
H_SiqPmtTable SIQ_ParsePmt(H_SiqInstance siq, U8BIT *pmt)
Provide PMT section data to SIQ. It assumes CRC has been checked and is passing valid PMT sections So...
void SIQ_QueryPmtReceive(S_SiqInstance *siq, U16BIT serviceId, H_SiqPmtTable hpmt)
void SIQ_ProcessPmt(H_SiqInstance siq, H_SiqPmtTable hNewTable, U16BIT serviceId, U8BIT version)
Provide PMT section data to SIQ. It assumes CRC has been checked and is passing valid PMT sections So...
Service Information Query: debug definitions.
void SIQ_PmtCheckTableChange(S_SiqInstance *siq, H_SiqPmtTable pOldTable, H_SiqPmtTable pNewTable, U16BIT serviceId)
For each carousel Id in old table, search through new table to see if it still exists. If not, tell DSM-CC. Then tell DSM-CC that PMT has been updated.
Service Information Query: cache functionality.
E_DscError SIQ_ServiceInfoChangeSubscribe(S_SiqInstance *siq, U16BIT serviceId)
Subscribe a component to receive notification of any changes or alterations to the service informatio...
void SIQ_ServiceRemoved(H_SiqInstance siq, U16BIT serviceId)
Inform SIQ when a service has been removed from PAT. Not required if PAT is supplied to SIQ...
Service Information Query: main definitions.
E_DscError CDSM_SysProcessSIChangeEvent(H_DsmCoreInst instance, E_SIChangeEvent evnt, U16BIT service_id, U32BIT carousel_id)
Notify that the SI for the indicated service has changed Changes should be notified in the following ...