34 #define INVALID_NDX 0xFF // must be U8BIT max value
35 #define INVALID_TID 0xFF
36 #define EXACT_MATCH 16
38 #define PRIORITY_SHIFT 5
39 #define PRI_EXACT_MASK ((1 << PRIORITY_SHIFT) - 1)
43 #define TOTAL_DSM_LISTS (HASH_SIZE + 1)
47 typedef struct s_BitCnt
53 typedef struct s_Table
59 typedef struct s_DsmResource
70 typedef struct s_PidTable
72 S_DsmResource *dsmlists[TOTAL_DSM_LISTS];
74 H_CacheTable cachetable;
78 typedef struct s_DmxSecFilter
85 typedef struct s_DmxPidFilter
94 S_DmxSecFilter *dmxSecArray;
105 static U8BIT ExactPriority( U16BIT mask )
107 U8BIT exactness, cnt;
108 FUNCTION_START(ExactPriority)
112 exactness = EXACT_MATCH;
115 exactness = NEAR_MATCH;
120 for (cnt = 16, exactness = 0; cnt--; mask >>= 1)
128 FUNCTION_FINISH(ExactPriority)
132 static U8BIT FindPidFilter( S_DmxPidFilter *pDmxPid, U8BIT max, U16BIT pid )
135 FUNCTION_START(FindPidFilter)
136 for (cnt = max; cnt--; )
138 if (pDmxPid[cnt].pid == pid)
145 U16BIT least = 0xFFFF;
148 if (pDmxPid[max].pfid == INVALID_PIDFILT &&
149 pDmxPid[max].updating == FALSE &&
150 least >= pDmxPid[max].pidcounter)
152 least = pDmxPid[max].pidcounter;
157 FUNCTION_FINISH(FindPidFilter)
161 static S_DmxPidFilter* RetrievePidFilter( S_DmxPidFilter *pDmxPid, U8BIT cnt, PIDFILT pfid )
163 FUNCTION_START(RetrievePidFilter)
166 if (pDmxPid->pfid == pfid)
172 FUNCTION_FINISH(RetrievePidFilter)
176 static
void IncBitcnt( S_BitCnt *bitcnt,
S_TableExt tex )
179 for (mbit = 0x8000; mbit; mbit >>= 1, bitcnt++)
200 static void DecBitcnt( S_BitCnt *bitcnt,
S_TableExt tex )
203 for (mbit = 0x8000; mbit; mbit >>= 1, bitcnt++)
224 static S_TableExt TableExtension( S_BitCnt *bitcnt )
228 for (mbit = 0x8000; mbit; mbit >>= 1, bitcnt++)
234 else if (!bitcnt->zeros)
243 static S_TableExt FindTexIdOne( S_DsmResource **ppDsmRes, U16BIT mbit )
245 S_DsmResource *pDsmRes;
248 for (hcnt = TOTAL_DSM_LISTS; hcnt != 0; hcnt--, ppDsmRes++)
250 for (pDsmRes = *ppDsmRes; pDsmRes != NULL; pDsmRes = pDsmRes->next)
252 if (!pDsmRes->accounted && (pDsmRes->tex.id & mbit) == mbit)
254 pDsmRes->accounted = 1;
263 static
S_TableExt FindTexIdZero( S_DsmResource **ppDsmRes, U16BIT mbit )
265 S_DsmResource *pDsmRes;
268 for (hcnt = TOTAL_DSM_LISTS; hcnt != 0; hcnt--, ppDsmRes++)
270 for (pDsmRes = *ppDsmRes; pDsmRes != NULL; pDsmRes = pDsmRes->next)
272 if (!pDsmRes->accounted && (pDsmRes->tex.id & mbit) == 0)
274 pDsmRes->accounted = 1;
283 void ClearTexIdAccounts( S_DsmResource **ppDsmRes )
285 S_DsmResource *pDsmRes;
287 FUNCTION_START(ClearTexIdAccounts)
288 for (hcnt = TOTAL_DSM_LISTS; hcnt != 0; hcnt--, ppDsmRes++)
290 for (pDsmRes = *ppDsmRes; pDsmRes != NULL; pDsmRes = pDsmRes->next)
292 pDsmRes->accounted = 0;
295 FUNCTION_FINISH(ClearTexIdAccounts)
298 static S_DmxSecFilter* SetupSecArray( S_PidTable *pPidTbl, S_DmxSecFilter *pTmpSec, U16BIT scnt, S_Table tbl )
301 S_BitCnt bitscopy[16];
307 pTmpSec->tex = TableExtension( pPidTbl->bitcnt );
311 memcpy(bitscopy, pPidTbl->bitcnt, 16 *
sizeof(S_BitCnt));
313 for (mbit = 0x8000, bitcnt = bitscopy; mbit; mbit >>= 1, bitcnt++)
315 if (bitcnt->ones == 1)
317 tex = FindTexIdOne( pPidTbl->dsmlists, mbit );
318 DecBitcnt( bitscopy, tex );
328 else if (bitcnt->zeros == 1)
330 tex = FindTexIdZero( pPidTbl->dsmlists, mbit );
331 DecBitcnt( bitscopy, tex );
342 ClearTexIdAccounts( pPidTbl->dsmlists );
343 pTmpSec->tex = TableExtension( bitscopy );
357 static void SetupSecFilterArray( S_DmxPidFilter *pDmxPid, S_DmxSecFilter *pTmpSec, U16BIT scTotal )
359 S_Table tbl = { 0xFF, 0xFF };
360 U16BIT numb, numc, numd, totalbc;
361 FUNCTION_START(SetupSecFilterArray)
363 numb = pDmxPid->pt3B.total;
364 numc = pDmxPid->pt3C.total;
365 numd = pDmxPid->pt3D.total;
374 pTmpSec->tex.mask = 0;
375 pTmpSec->tbl.id = 0x38;
376 pTmpSec->tbl.mask = 0xF8;
381 pTmpSec->tex.mask = 0;
382 pTmpSec->tbl.id = 0x39;
383 pTmpSec->tbl.mask = 0xF9;
387 pTmpSec->tex = TableExtension(pDmxPid->pt3B.bitcnt);
388 pTmpSec->tbl.id = 0x3B;
389 pTmpSec->tbl.mask = 0xFF;
397 pTmpSec->tex.mask = 0;
398 pTmpSec->tbl.id = 0x3C;
399 pTmpSec->tbl.mask = 0xFC;
403 pTmpSec->tex = TableExtension(pDmxPid->pt3C.bitcnt);
404 pTmpSec->tbl.id = 0x3C;
409 pTmpSec->tex = TableExtension(pDmxPid->pt3D.bitcnt);
410 pTmpSec->tbl.id = 0x3D;
411 pTmpSec->tbl.mask = 0xFF;
415 pTmpSec->tbl.id = INVALID_TID;
422 pTmpSec->tex = TableExtension(pDmxPid->pt3B.bitcnt);
423 pTmpSec->tbl.id = 0x3B;
424 pTmpSec->tbl.mask = 0xFF;
432 pTmpSec->tex.mask = 0;
433 pTmpSec->tbl.id = 0x3C;
434 pTmpSec->tbl.mask = 0xFC;
438 pTmpSec->tex = TableExtension(pDmxPid->pt3C.bitcnt);
439 pTmpSec->tbl.id = 0x3C;
440 pTmpSec->tbl.mask = 0xFF;
445 pTmpSec->tex = TableExtension(pDmxPid->pt3D.bitcnt);
446 pTmpSec->tbl.id = 0x3D;
447 pTmpSec->tbl.mask = 0xFF;
451 pTmpSec->tbl.id = INVALID_TID;
458 pTmpSec->tex = TableExtension( pDmxPid->pt3D.bitcnt );
464 totalbc = numb + numc;
465 if (totalbc > scTotal)
477 numb = 1 + ((numb * scTotal) / totalbc);
481 numc = scTotal - numb;
486 scTotal -= numb + numc;
491 pTmpSec = SetupSecArray( &pDmxPid->pt3B, pTmpSec, numb, tbl );
496 pTmpSec = SetupSecArray( &pDmxPid->pt3C, pTmpSec, numc, tbl );
500 pTmpSec->tbl.id = INVALID_TID;
513 static BOOLEAN CompareSecFilters( S_DmxSecFilter *pActive, S_DmxSecFilter *pTmpSec, U16BIT secCount )
515 BOOLEAN result = FALSE;
516 FUNCTION_START(CompareSecFilters)
517 for (; secCount--; pActive++, pTmpSec++)
519 if (pTmpSec->tbl.id != pActive->tbl.id)
524 if (pTmpSec->tbl.id == INVALID_TID)
528 if (pTmpSec->tex.mask != pActive->tex.mask ||
529 pTmpSec->tex.id != pActive->tex.id ||
530 pTmpSec->tbl.mask != pActive->tbl.mask)
536 FUNCTION_FINISH(CompareSecFilters)
549 static
void RemoveOldActives(
H_SfmInstance sfm, S_DmxSecFilter *pDmxSec, U16BIT secCount )
551 S_DmxSecFilter *pTmpSec;
553 FUNCTION_START(RemoveOldActives)
554 for (scnt = secCount; scnt--; pDmxSec++)
556 if (pDmxSec->sfid != INVALID_SECFILT)
558 pTmpSec = sfm->dmxSecArray;
559 for (stmp = secCount; stmp != 0; stmp--, pTmpSec++)
561 if (pTmpSec->tex.mask == pDmxSec->tex.mask &&
562 pTmpSec->tex.id == pDmxSec->tex.id &&
563 pTmpSec->tbl.mask == pDmxSec->tbl.mask &&
564 pTmpSec->tbl.id == pDmxSec->tbl.id)
566 pTmpSec->sfid = pDmxSec->sfid;
572 DBGLOG(DF_FILTER,
"%p", pDmxSec)
573 DBGLOG((DF_FILTER|DF_HWSF), "tid=0x%x tidMask=0x%x tide=0x%x tideMask=0x%x",
574 pDmxSec->tbl.
id, pDmxSec->tbl.mask, pDmxSec->tex.
id, pDmxSec->tex.mask)
576 pDmxSec->sfid = INVALID_SECFILT;
577 pDmxSec->tbl.
id = INVALID_TID;
581 FUNCTION_FINISH(RemoveOldActives)
596 static SECFILT SectionFilterAdd(
H_SfmInstance sfm, PIDFILT pfid, U8BIT tid,
597 U8BIT tidMask, U16BIT tidExt, U16BIT tidExtMask )
599 U8BIT match[SECFILT_MASK_SIZE];
600 U8BIT mmask[SECFILT_MASK_SIZE];
604 if (sfid == INVALID_SECFILT)
606 ERRLOG(
"Failed to grab Section Filter on PFID 0x%x", pfid)
611 match[1] = (U8BIT)(tidExt >> 8);
612 match[2] = (U8BIT)(tidExt & 0x00ff);
614 mmask[1] = (U8BIT)(tidExtMask >> 8);
615 mmask[2] = (U8BIT)(tidExtMask & 0x00ff);
616 for (i = 3; i != SECFILT_MASK_SIZE; i++)
621 DBGLOG((DF_FILTER|DF_HWSF),
"pf=%x tid=%x tidm=%x xid=%x xidm=%x", pfid, tid, tidMask, tidExt, tidExtMask)
635 static
void RequestNewActives(
H_SfmInstance sfm, PIDFILT pfid,
636 S_DmxSecFilter *pDmxSec, U16BIT secCount )
638 FUNCTION_START(RequestNewActives)
639 for (; secCount--; pDmxSec++)
641 if (pDmxSec->sfid == INVALID_SECFILT && pDmxSec->tbl.id != INVALID_TID)
643 DBGLOG(DF_FILTER,
"%p", pDmxSec)
645 SectionFilterAdd( sfm, pfid, pDmxSec->tbl.
id,
646 pDmxSec->tbl.mask, pDmxSec->tex.
id, pDmxSec->tex.mask );
647 DBGLOG(DF_FILTER, "tid=0x%x tidMask=0x%x tide=0x%x tideMask=0x%x", pDmxSec->tbl.
id,
648 pDmxSec->tbl.mask, pDmxSec->tex.
id, pDmxSec->tex.mask)
651 FUNCTION_FINISH(RequestNewActives)
662 static
void RemoveAllActives(
H_SfmInstance sfm, S_DmxSecFilter *pDmxSec, U16BIT secCount )
664 FUNCTION_START(RemoveAllActives)
665 for (; secCount--; pDmxSec++)
667 if (pDmxSec->sfid != INVALID_SECFILT)
669 DBGLOG(DF_FILTER,
"%p", pDmxSec)
670 DBGLOG(DF_FILTER, "tid=0x%x tidMask=0x%x tide=0x%x tideMask=0x%x",
671 pDmxSec->tbl.
id, pDmxSec->tbl.mask, pDmxSec->tex.
id, pDmxSec->tex.mask)
673 pDmxSec->sfid = INVALID_SECFILT;
674 pDmxSec->tbl.
id = INVALID_TID;
677 FUNCTION_FINISH(RemoveAllActives)
687 static
void CopyAndClearTempArray( S_DmxSecFilter *pDmxSec, S_DmxSecFilter *pTmpSec, U16BIT scnt )
689 FUNCTION_START(CopyAndClearTempArray)
690 for (; scnt--; pTmpSec++, pDmxSec++)
693 pTmpSec->sfid = INVALID_SECFILT;
694 pTmpSec->tbl.id = INVALID_TID;
696 FUNCTION_FINISH(CopyAndClearTempArray)
707 static void UpdateDemux(
H_SfmInstance sfm, S_DmxPidFilter *pDmxPid, U16BIT secCount )
709 FUNCTION_START(UpdateDemux)
710 SetupSecFilterArray( pDmxPid, sfm->dmxSecArray, secCount );
711 if (CompareSecFilters(pDmxPid->dmxSecArray, sfm->dmxSecArray, secCount))
714 RemoveOldActives( sfm, pDmxPid->dmxSecArray, secCount );
715 RequestNewActives( sfm, pDmxPid->pfid, sfm->dmxSecArray, secCount );
716 CopyAndClearTempArray( pDmxPid->dmxSecArray, sfm->dmxSecArray, secCount );
719 FUNCTION_FINISH(UpdateDemux)
729 static void InsertDsmResource(
H_SfmInstance sfm, S_PidTable *pPidTbl, S_DsmResource *pDsmRes )
731 H_DsmResource *phDsmRes;
732 FUNCTION_START(InsertDsmResource)
735 ASSERT( sfm->freeList == pDsmRes )
736 sfm->freeList = pDsmRes->next;
738 if (pDsmRes->tex.mask == 0xFFFF)
740 phDsmRes = pPidTbl->dsmlists + (pDsmRes->tex.id % HASH_SIZE);
744 phDsmRes = pPidTbl->dsmlists + HASH_SIZE;
749 IncBitcnt( pPidTbl->bitcnt, pDsmRes->tex );
750 sfm->setup.mutexLock( sfm->setup.sfmMutex );
751 while (*phDsmRes && (*phDsmRes)->priority > pDsmRes->priority)
753 phDsmRes = &(*phDsmRes)->next;
756 pDsmRes->next = *phDsmRes;
758 sfm->setup.mutexUnlock( sfm->setup.sfmMutex );
759 if (pPidTbl->cachetable != NULL)
762 dsmref = pDsmRes - sfm->dmxResFirst;
763 switch (pDsmRes->priority >> PRIORITY_SHIFT)
765 case SF_PRIORITY_LOW:
766 SFMCacheSearch( sfm, pPidTbl->cachetable, pDsmRes->tex, (U16BIT)dsmref, SFM_UPDATE_LOW );
768 case SF_PRIORITY_HIGH:
769 SFMCacheSearch( sfm, pPidTbl->cachetable, pDsmRes->tex, (U16BIT)dsmref, SFM_UPDATE_HIGH );
772 case SF_PRIORITY_DIRECT:
777 FUNCTION_FINISH(InsertDsmResource)
787 static void RemoveDsmResource(
H_SfmInstance sfm, S_PidTable *pPidTbl,
788 S_DsmResource *pDsmRes )
790 H_DsmResource *phDsmRes;
791 FUNCTION_START(RemoveDsmResource)
792 ASSERT( pDsmRes != NULL )
793 if (pDsmRes->tex.mask == 0xFFFF)
795 phDsmRes = pPidTbl->dsmlists + (pDsmRes->tex.id % HASH_SIZE);
799 phDsmRes = pPidTbl->dsmlists + HASH_SIZE;
802 DecBitcnt( pPidTbl->bitcnt, pDsmRes->tex );
803 sfm->setup.mutexLock( sfm->setup.sfmMutex );
806 if (*phDsmRes == pDsmRes)
808 *phDsmRes = pDsmRes->next;
811 phDsmRes = &((*phDsmRes)->next);
813 sfm->setup.mutexUnlock( sfm->setup.sfmMutex );
815 pDsmRes->next = sfm->freeList;
816 pDsmRes->tid = INVALID_TID;
817 sfm->freeList = pDsmRes;
818 FUNCTION_FINISH(RemoveDsmResource)
831 S_DmxPidFilter *pDmxPid;
832 S_DmxSecFilter *pDmxSec;
833 S_DsmResource *pDsmRes;
834 U16BIT dmxCount, dsmCount, secCount, cnt;
839 dmxCount = sfm->setup.maxPidFilters;
840 dsmCount = sfm->setup.maxAvailableSectionFilters;
841 secCount = sfm->setup.maxSecFiltersPerPid;
842 ASSERT( dmxCount != 0 && secCount != 0 );
843 size = secCount *
sizeof(S_DmxSecFilter);
844 size *= dmxCount + 1;
845 size += dmxCount *
sizeof(S_DmxPidFilter);
846 size += (dsmCount *
sizeof(S_DsmResource));
847 pDmxPid = sfm->setup.memAlloc( size );
855 memset(pDmxPid, 0, size);
856 sfm->dmxPidArray = pDmxPid;
857 pDmxSec = (S_DmxSecFilter *)(pDmxPid + dmxCount);
860 sfm->dmxSecArray = pDmxSec;
861 for (cnt = secCount; cnt--; pDmxSec++)
863 pDmxSec->sfid = INVALID_SECFILT;
864 pDmxSec->tbl.id = INVALID_TID;
869 pDmxPid->pid = INVALID_PID;
870 pDmxPid->pfid = INVALID_PIDFILT;
871 pDmxPid->dmxSecArray = pDmxSec;
872 for (cnt = secCount; cnt--; pDmxSec++)
874 pDmxSec->sfid = INVALID_SECFILT;
875 pDmxSec->tbl.id = INVALID_TID;
880 pDsmRes = (S_DsmResource *)pDmxSec;
881 sfm->dmxResFirst = pDsmRes;
882 sfm->freeList = pDsmRes;
885 pDsmRes->next = pDsmRes + 1;
886 pDsmRes->tid = INVALID_TID;
887 pDsmRes->dmxPidIndex = INVALID_NDX;
890 pDsmRes->tid = INVALID_TID;
891 pDsmRes->dmxPidIndex = INVALID_NDX;
892 pDsmRes->next = NULL;
893 sfm->dmxResLast = pDsmRes;
906 S_DmxPidFilter *pDmxPid;
911 pDmxPid = sfm->dmxPidArray;
915 for (dmxCount = sfm->setup.maxPidFilters; dmxCount--; pDmxPid++)
917 pDmxPid->pt3B.cachetable = SFMCacheGetTable( cache );
918 pDmxPid->pt3C.cachetable = SFMCacheGetTable( cache );
931 S_DmxPidFilter *pDmxPid;
934 FUNCTION_START(SFMDestroyDemuxResources)
935 pDmxPid = sfm->dmxPidArray;
936 for (total = sfm->setup.maxPidFilters; total--; pDmxPid++)
938 if (pDmxPid->pfid != INVALID_PIDFILT)
944 sfm->setup.memFree( sfm->dmxPidArray );
945 FUNCTION_FINISH(SFMDestroyDemuxResources)
960 H_DscSFRef dsmSfRef )
962 S_DmxPidFilter *pDmxPid;
963 S_DsmResource *pDsmRes;
967 ASSERT( pFilter->priority < 8 )
968 pDsmRes = sfm->freeList;
971 ERRLOG(
"Eek! Dsmcc filter Resources Gone!")
975 dmxPidIndex = FindPidFilter( sfm->dmxPidArray, sfm->setup.maxPidFilters, pFilter->pid );
976 if (dmxPidIndex == INVALID_NDX)
978 ERRLOG(
"Eek! Demux Pid Filters Gone!")
983 pDmxPid = sfm->dmxPidArray + dmxPidIndex;
984 pDmxPid->pid = pFilter->pid;
985 pDsmRes->dsmSfRef = dsmSfRef;
986 pDsmRes->priority = (pFilter->priority << PRIORITY_SHIFT) |
987 ExactPriority( pFilter->tableIdExtMask );
988 pDsmRes->dmxPidIndex = dmxPidIndex;
989 pDsmRes->tid = pFilter->tableId;
990 pDsmRes->tex.id = pFilter->tableIdExt;
991 pDsmRes->tex.mask = pFilter->tableIdExtMask;
993 DBGLOG(DF_FILTER,
"ndx=%d PID=0x%x PFID=0x%x tid=0x%x tide=0x%x",
994 dmxPidIndex, pFilter->pid, pDmxPid->pfid, pDsmRes->tid, pDsmRes->tex.id)
996 switch (pDsmRes->tid)
998 case 0x3B: InsertDsmResource( sfm, &pDmxPid->pt3B, pDsmRes );
break;
999 case 0x3C: InsertDsmResource( sfm, &pDmxPid->pt3C, pDsmRes );
break;
1000 case 0x3D: InsertDsmResource( sfm, &pDmxPid->pt3D, pDsmRes );
break;
1004 pDmxPid->numDsmRes++;
1005 if (!pDmxPid->updating)
1007 pDmxPid->updating = TRUE;
1008 sfm->setup.updateFilter(sfm, pDmxPid);
1027 H_DscSFRef dsmSfRef )
1029 S_DsmResource *pDsmRes;
1030 S_DmxPidFilter *pDmxPid;
1032 pDsmRes = (S_DsmResource *)filterHandle;
1033 ASSERT( pDsmRes->dmxPidIndex != INVALID_NDX )
1034 ASSERT( pDsmRes->dsmSfRef == dsmSfRef )
1035 if (pDsmRes->dmxPidIndex != INVALID_NDX &&
1036 pDsmRes->dsmSfRef == dsmSfRef)
1038 pDmxPid = sfm->dmxPidArray + pDsmRes->dmxPidIndex;
1039 ASSERT( pDmxPid->numDsmRes != 0 )
1040 if (pDmxPid->numDsmRes == 0)
1042 ERRLOG(
"Eek! already have zero Dsmcc filter resources allocated!")
1046 DBGLOG(DF_FILTER,
"num=%d PID=0x%x PFID=0x%x tid=0x%x tide=0x%x",
1047 pDmxPid->numDsmRes, pDmxPid->pid, pDmxPid->pfid, pDsmRes->tid, pDsmRes->tex.id)
1049 ASSERT( pDmxPid->pid != INVALID_PID )
1050 switch (pDsmRes->tid)
1052 case 0x3B: RemoveDsmResource( sfm, &pDmxPid->pt3B, pDsmRes );
break;
1053 case 0x3C: RemoveDsmResource( sfm, &pDmxPid->pt3C, pDsmRes );
break;
1054 case 0x3D: RemoveDsmResource( sfm, &pDmxPid->pt3D, pDsmRes );
break;
1058 pDmxPid->numDsmRes--;
1059 if (!pDmxPid->updating)
1061 pDmxPid->updating = TRUE;
1062 sfm->setup.updateFilter(sfm, pDmxPid);
1078 ASSERT( pPF->updating != FALSE )
1079 pPF->updating = FALSE;
1080 if (pPF->pfid != INVALID_PIDFILT)
1082 if (pPF->numDsmRes != 0)
1084 UpdateDemux( sfm, pPF, sfm->setup.maxSecFiltersPerPid );
1089 RemoveAllActives( sfm, pPF->dmxSecArray, sfm->setup.maxSecFiltersPerPid );
1091 DBGLOG((DF_FILTER|DF_HWSF),
"DELETE PID=0x%x PFID=0x%x", pPF->pid, pPF->pfid)
1093 pPF->pfid = INVALID_PIDFILT;
1094 pPF->pidcounter = sfm->pidcounter;
1098 else if (pPF->numDsmRes != 0)
1101 if (pPF->pfid == INVALID_PIDFILT)
1103 ERRLOG(
"Demux PID filter failed to be added! (0x%x)", pPF->pid)
1107 DBGLOG((DF_FILTER|DF_HWSF),
"ADDDED PID=0x%x PFID=0x%x", pPF->pid, pPF->pfid)
1108 SetupSecFilterArray( pPF, pPF->dmxSecArray, sfm->setup.maxSecFiltersPerPid );
1109 RequestNewActives( sfm, pPF->pfid, pPF->dmxSecArray, sfm->setup.maxSecFiltersPerPid );
1129 H_DscSFRef dsmSfRef,
1130 E_SFPriority priority )
1132 S_DsmResource *pDsmRes;
1134 pDsmRes = (S_DsmResource *)filterHandle;
1135 ASSERT( pDsmRes->dmxPidIndex != INVALID_NDX )
1136 ASSERT( pDsmRes->dsmSfRef == dsmSfRef )
1137 if (pDsmRes->dmxPidIndex != INVALID_NDX &&
1138 pDsmRes->dsmSfRef == dsmSfRef)
1141 sfm->setup.mutexLock( sfm->setup.sfmMutex );
1142 pDsmRes->priority = (pDsmRes->priority & PRI_EXACT_MASK) |
1143 priority << PRIORITY_SHIFT;
1144 sfm->setup.mutexUnlock( sfm->setup.sfmMutex );
1166 U16BIT teid, U8BIT tid, U8BIT vers,
1169 S_DmxPidFilter *pDmxPid;
1170 S_DsmResource *pDsmRes;
1171 S_PidTable *pPidTbl;
1173 U8BIT priority = 0xFF;
1174 E_SFM_STATUS result;
1175 FUNCTION_START(SFM_FilterRequiresSection)
1176 DBGLOG(DF_HWSF,
"pfid=%x tid=%x xid=%x", pfid, tid, teid)
1177 pDmxPid = RetrievePidFilter( sfm->dmxPidArray, sfm->setup.maxPidFilters, pfid );
1178 if (pDmxPid == NULL)
1183 result = SFM_IGNORE;
1189 case 0x3B: pPidTbl = &pDmxPid->pt3B;
break;
1190 case 0x3C: pPidTbl = &pDmxPid->pt3C;
break;
1191 case 0x3D: pPidTbl = &pDmxPid->pt3D;
break;
1193 ERRLOG(
"Unsupported table id 0x%x", tid) *
1197 hash = teid % HASH_SIZE;
1198 sfm->setup.mutexLock( sfm->setup.sfmMutex );
1200 pDsmRes = pPidTbl->dsmlists[hash];
1201 while (pDsmRes != NULL)
1203 if (pDsmRes->tex.id == teid)
1205 priority = pDsmRes->priority;
1208 pDsmRes = pDsmRes->next;
1210 if (pDsmRes == NULL)
1213 pDsmRes = pPidTbl->dsmlists[HASH_SIZE];
1214 while (pDsmRes != NULL)
1216 if (pDsmRes->tex.id == (teid & pDsmRes->tex.mask))
1218 priority = pDsmRes->priority;
1221 pDsmRes = pDsmRes->next;
1224 sfm->setup.mutexUnlock( sfm->setup.sfmMutex );
1225 if (pDsmRes != NULL)
1227 switch (priority >> PRIORITY_SHIFT)
1229 case SF_PRIORITY_LOW:
1230 case SF_PRIORITY_CLEAR:
1231 *phBuffer = pDsmRes;
1232 result = SFM_UPDATE_LOW;
1233 DBGLOG(DF_MAIN,
"pfid=%x tid=%x xid=%x LOW priority", pfid, tid, teid)
1235 case SF_PRIORITY_HIGH:
1236 case SF_PRIORITY_DIRECT:
1237 *phBuffer = pDsmRes;
1238 result = SFM_UPDATE_HIGH;
1239 DBGLOG(DF_MAIN,
"pfid=%x tid=%x xid=%x HIGH priority", pfid, tid, teid)
1243 ERRLOG(
"Bad priority value 0x%x", priority)
1247 else if (pPidTbl->cachetable != NULL)
1250 result = SFM_UPDATE_CACHE;
1254 DBGLOG(DF_FILTER,
"Drop sec Tid=%x TEid=0x%x ver=%d", tid, teid, vers);
1256 result = SFM_IGNORE;
1259 FUNCTION_FINISH(SFM_FilterRequiresSection)
1276 FUNCTION_START(SFM_FilterProcessSection)
1277 if (pDsmRes->tid == *pSection)
1279 U16BIT txid = (U16BIT)((pSection[3] << 8) | pSection[4]);
1280 if (pDsmRes->tex.id == txid ||
1281 pDsmRes->tex.id == (txid & pDsmRes->tex.mask))
1283 CDSM_SysProcessPrivateSection( sfm->dsmcc, pSection, pDsmRes->dsmSfRef );
1286 FUNCTION_FINISH(SFM_FilterProcessSection)
1289 BOOLEAN SFMFilterValidHandle(
H_SfmInstance sfm,
void *hBuffer )
1291 H_DsmResource pDsmRes;
1294 if (pDsmRes >= sfm->dmxResFirst && pDsmRes <= sfm->dmxResLast)
1305 H_DsmResource SFMFilterDsmResource(
H_SfmInstance sfm, U16BIT dsmref )
1307 return sfm->dmxResFirst + dsmref;
PIDFILT STB_DMXGrabPIDFilter(DMXREF dmx, U16BIT pid, F_FILTER_CALLBACK func)
Get a New PID Filter & Setup Associated Buffer and Callback Function Address.
void STB_DMXSetupSectFilter(DMXREF dmx, SECFILT sfid, U8BIT *match_ptr, U8BIT *mask_ptr, U8BIT not_equal_byte_index, BOOLEAN crc)
Configures a match and mask for a specified section filter.
H_CacheFilter SFMCacheRetrieveFilter(H_SfmInstance sfm, H_CacheTable ctable, U16BIT teid, U8BIT vers)
Search cache for section data.
void SFM_DsmccFilterPriorityChange(H_SfmInstance sfm, void *filterHandle, H_DscSFRef dsmSfRef, E_SFPriority priority)
Change DSM-CC section filter priority Called by DSM-CC component, and given in clDsmSysCreate setup...
void SFM_DsmccFilterDelete(H_SfmInstance sfm, void *filterHandle, H_DscSFRef dsmSfRef)
Delete DSM-CC section filter. Called by DSM-CC component, and given in clDsmSysCreate setup...
void SFMFilterProcessSection(H_SfmInstance sfm, U8BIT *pSection, H_DsmResource pDsmRes)
Get DSM-CC filter request and pass section buffer to DSM-CC with it's filter handle This should only ...
void STB_DMXStopPIDFilter(DMXREF dmx, PIDFILT pfid)
Stop Specified PID Filter Collecting Data.
BOOLEAN SFMFilterCreateResources(H_SfmInstance sfm)
Create Filter resources for Section Filter Manager instance.
Section Filter Manasger (SFM): cache definitions.
Section Filter Manager (SFM): filters.
Section Filter Manager (SFM): main definitions.
E_SFM_STATUS SFMFilterRequiresSection(H_SfmInstance sfm, PIDFILT pfid, U16BIT teid, U8BIT tid, U8BIT vers, void **phBuffer)
This function performs minimal checking of section header data to find out whether SFM requires this ...
void SFM_FilterUpdate(H_SfmInstance sfm, H_DmxPidFilter pPF)
Update SFM PID filter to configure HW for latest requirements.
Main API to DSM-CC core layer (provided functions and required callbacks).
void STB_DMXReleasePIDFilter(DMXREF dmx, PIDFILT pfid)
Releases a previously allocated PID filter.
void SFMCacheSearch(H_SfmInstance sfm, H_CacheTable ctable, S_TableExt tex, U16BIT dsmref, E_SFM_STATUS status)
Search cache for section data.
SECFILT STB_DMXGrabSectFilter(DMXREF dmx, PIDFILT pfid)
Allocated a new section filter on the specified PID filter.
void STB_DMXStartPIDFilter(DMXREF dmx, PIDFILT pfid)
Start Specified PID Filter Collecting Data.
void * SFM_DsmccFilterAdd(H_SfmInstance sfm, P_SecFilter pFilter, H_DscSFRef dsmSfRef)
Add DSM-CC section filter. Called by DSM-CC component. Note for multi-tasking: this function uses mut...
void STB_DMXReleaseSectFilter(DMXREF dmx, SECFILT sfid)
Releases a previously allocated section filter.
void SFMFilterDestroyResources(H_SfmInstance sfm)
Destroy Filter resources for Section Filter Manager instance.
void SFMFilterInitCaching(H_SfmInstance sfm)
Initialise caching references.