source: svn/zas_dstar/hal/common/dsthalPsiSectGather.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

File size: 47.8 KB
Line 
1/****************************************************************************
2 * Copyright (c) 2004 DST Technologies Inc.  All Rights Reserved.
3 *
4 * file name:      ddPsiSectGather.c
5 * Author:          jina
6 * Description: PSI Section Gathering.
7 *             
8 *
9 * update info**************************************************************
10 * 2004.08.09. malloc/free debugging À§ÇØ macro·Î ¹Ù·Î »ç¿ë ÇÏ´ø °ÍÀ»
11 *             ÇÔ¼ö·Î º¯È¯ ¶Ç´Â º¯¼ö¿¡ ´ëÀÔÇØ¼­ »ç¿ë.*/
12 /****************************************************************************/
13
14#include "dsthalcommon.h"
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19
20#ifdef DMALLOC
21#include <dmalloc.h>
22#endif
23
24#include "dsthalPsiSectGather.h"
25
26/******************************************************************************
27 * Global variable declaration
28 ******************************************************************************/
29DS_U32 gdhlPsiDbgLvl = 2;
30
31/******************************************************************************
32 * Imported variable declaration
33 ******************************************************************************/
34extern int g_Demux_Debug;
35
36/******************************************************************************
37 * Imported function declaration
38 ******************************************************************************/
39
40/******************************************************************************
41 * Local definitions
42 ******************************************************************************/
43
44/******************************************************************************
45 * Local typedefs
46 ******************************************************************************/
47
48/******************************************************************************
49 * Local variables declaration
50 ******************************************************************************/
51
52/******************************************************************************
53 * Local function prototypes
54 ******************************************************************************/
55
56extern DHL_RESULT DD_PSI_ResetSectMask ( void *pParent , PSIMask_t *prefList );
57
58#define PSICTX_CNT 12
59
60typedef struct PSICtxManager_t {
61        DS_U32  freeCount;
62        DS_U32  filterManagerLock;
63        PSIContext_t *psiCtxPtrList[PSICTX_CNT];
64        OS_SEMAPHORE_ID lockSema;
65       
66} PSICtxManager_t;
67
68PSICtxManager_t *gpPsiCtxManager = NULL;
69
70#ifndef DMALLOC
71void * PSI_Malloc( int iSize )
72{
73
74        if( iSize < 0 )
75                return NULL;
76               
77        if(iSize > 4096*100  )
78        {
79                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_Malloc() : warning. it maybe error. iSize = %d. \r\n", iSize );
80                //return NULL;
81        }
82
83        return (OS_malloc((size_t)iSize));
84}
85
86void PSI_Free( void *memBlock )
87{
88        if(!memBlock)
89                return;
90
91        OS_free(memBlock);
92}
93#else
94#define PSI_Free        free
95#define PSI_Malloc      malloc
96#endif
97
98
99
100void DD_PSI_PrintRegisteredPsiCtx()
101{
102        #ifdef PSI_DBG
103        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "\n\n");
104        #endif
105       
106        if(gpPsiCtxManager && gpPsiCtxManager->lockSema)
107        {
108                int i;
109               
110        //      DD_PSI_LockPsiCtxMng();
111                for( i = 0 ; i < PSICTX_CNT ; i++ )
112                {
113                        if ( gpPsiCtxManager->psiCtxPtrList[i])
114                        {
115                                #ifdef PSI_DBG
116                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "R_PSICtx : index[%d] : pid = %d.\r\n", i ,   gpPsiCtxManager->psiCtxPtrList[i]->pid );                               
117                                #endif
118                        }
119                }
120        //      DD_PSI_UnlockPsiCtxMng();
121        }
122        else
123                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_PrintRegisteredPsiCtx : no registered ctx.\r\n");
124}
125
126void DD_PSI_LockPsiCtxMng()
127{
128        if(gpPsiCtxManager && gpPsiCtxManager->lockSema)
129        {
130                //AtiCore_SemLock( gpPsiCtxManager->lockSema , OS_WAIT_FOREVER /*infinite*/);
131                OS_TakeSemaphore( gpPsiCtxManager->lockSema );
132        }
133        else
134                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_LockPsiCtxMng : lock error.\r\n");
135}
136
137void DD_PSI_UnlockPsiCtxMng()
138{
139        if( gpPsiCtxManager && gpPsiCtxManager->lockSema )
140        {
141                //AtiCore_SemUnlock( gpPsiCtxManager->lockSema );
142                OS_GiveSemaphore( gpPsiCtxManager->lockSema );
143        }
144        else
145                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_UnlockPsiCtxMng : unlock error.\r\n");
146}
147
148
149/*PSIContext_t pointer¸¦ °ü¸®ÇÏ´Â global manager¿¡ µî·Ïµµ ÇÑ´Ù.*/
150PSIContext_t * DD_PSI_AllocPSIContextWRegister() 
151{
152        int i;
153        PSIContext_t *pRetPsiCtx = NULL;
154       
155        #ifdef PSI_DBG
156        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the DD_PSI_AllocPSIContextWRegister.\r\n");
157        #endif
158       
159        if(!gpPsiCtxManager)
160        {
161                gpPsiCtxManager = (PSICtxManager_t *)PSI_Malloc( sizeof(PSICtxManager_t) );
162                memset( gpPsiCtxManager , 0 , sizeof(PSICtxManager_t));
163                gpPsiCtxManager->lockSema = OS_CreateCountingSemaphore( "PSICtxSema4", 0/*Option*/,1/*count*/);
164               
165                #ifdef PSI_CTX_MNG_DBG
166                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_AllocPSIContextWRegister : Create PsiCtxManager\r\n");
167                #endif         
168        }
169               
170        if(!gpPsiCtxManager || !(gpPsiCtxManager->lockSema))
171        {
172                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_AllocPSIContextWRegister : alloc psiMng fail.\r\n");
173                return NULL;
174        }
175       
176       
177        DD_PSI_LockPsiCtxMng();
178        for( i = 0 ; i < PSICTX_CNT ; i++ )
179        {
180                /*to find a empty slot.*/
181                if ( gpPsiCtxManager->psiCtxPtrList[i] == NULL )
182                {
183                        gpPsiCtxManager->psiCtxPtrList[i] = DD_PSI_AllocPSIContext();
184                        if( gpPsiCtxManager->psiCtxPtrList[i] == NULL )
185                        {
186                                pRetPsiCtx = NULL;
187                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_AllocPSIContextWRegister : MEM ERROR\r\n");
188                        }                                                       
189                        else
190                        {
191                                pRetPsiCtx = gpPsiCtxManager->psiCtxPtrList[i];
192                                pRetPsiCtx->bRegistered = _TRUE_;
193                                pRetPsiCtx->selfIndex = i;
194                        }
195                       
196                        goto GOOUT;
197                }               
198        }
199
200GOOUT: 
201
202        DD_PSI_UnlockPsiCtxMng();
203        return pRetPsiCtx;
204       
205}
206
207
208
209void    DD_PSI_FreePSIContextWUnregister( PSIContext_t *pPsiContext )
210{
211        int i;
212       
213        if(!gpPsiCtxManager || !pPsiContext)
214                return;
215               
216        DD_PSI_LockPsiCtxMng();
217        i = pPsiContext->selfIndex;
218        if( i >= PSICTX_CNT )
219                return;
220
221//      for( i = 0 ; i < PSICTX_CNT ; i++ )
222        {
223                /*to find a same pointer*/
224                if ( gpPsiCtxManager->psiCtxPtrList[i] == pPsiContext )
225                {
226                        DD_PSI_FreePSIContext(pPsiContext);
227                        gpPsiCtxManager->psiCtxPtrList[i] = NULL;
228                //      break;
229                       
230                }/*if*/         
231        }/*for( i = 0 */
232       
233       
234        #ifdef PSI_CTX_MNG_DBG
235        DD_PSI_PrintRegisteredPsiCtx();
236        #endif
237       
238        DD_PSI_UnlockPsiCtxMng();
239}       
240
241
242PSIContext_t *DD_PSI_AllocPSIContext()
243{
244        PSIContext_t *pPsiContext = NULL;
245       
246        #ifdef PSI_DBG
247        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the DD_PSI_AllocPSIContext.\r\n");
248        #endif
249               
250        pPsiContext = (PSIContext_t *)PSI_Malloc( sizeof(PSIContext_t) );
251        if(pPsiContext == NULL)
252        {
253                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_AllocPSIContext : Error: PSI_Malloc fails\r\n");
254        }
255        else
256                memset( pPsiContext , 0 , sizeof(PSIContext_t) );
257       
258        return pPsiContext;
259}
260
261
262void    DD_PSI_FreePSIContext( PSIContext_t *pPsiContext )
263{
264        PSIDataArray_t *pDataArrayToDelete = NULL;
265       
266        #ifdef PSI_DBG
267        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_FreePSIContext : pid = 0x%x \r\n", pPsiContext->pid);
268        #endif
269       
270        if(!pPsiContext)
271                return;
272
273               
274        if( pPsiContext->psiMask )
275                PSI_Free( pPsiContext->psiMask );
276
277               
278        if( pPsiContext->curDataArray )
279                pDataArrayToDelete = pPsiContext->curDataArray;
280        else
281                pDataArrayToDelete = pPsiContext->nextDataArray;
282       
283        if(pDataArrayToDelete) 
284        {
285                DD_PSI_FreePSIArray(pDataArrayToDelete);
286                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_FreePSIContext : call PSI_FreeData ; 0x%lx\r\n", (DS_U32)pDataArrayToDelete);
287        }
288
289        PSI_Free( (void *)pPsiContext );
290       
291}
292
293
294/*
295 * PSI_GetEmptyPSIMask is used to allocate and initialize a PSIMask.
296 */ 
297DHL_RESULT DD_PSI_GetEmptyPSIMask( DS_S32 numEntries, PSIMask_t **ppMask )
298{
299        int iMaskSize     =     PSIMaskSize(numEntries);
300        PSIMask_t *ptMask =         NULL;
301        *ppMask = NULL;
302
303
304        if( numEntries == 0 || ppMask == NULL)
305                return DHL_FAIL_INVALID_PARAM;
306
307        #ifdef PSI_DBG 
308        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the PSI_GetEmptyMask.\r\n");
309        #endif
310
311       
312        ptMask = (PSIMask_t *)PSI_Malloc(iMaskSize);
313        if( ptMask == NULL)
314                return  DHL_FAIL_OUT_OF_RESOURCE;
315       
316        memset( ptMask , 0 , iMaskSize );
317        ptMask->numEntries = numEntries;
318        *ppMask = ptMask;
319       
320        return(DHL_OK);
321}
322
323
324
325/*
326 * PSI_GetTIDPSIMask creates a psiMask which accepts anything with a particular Table ID
327 * current_next_indicator should be _TRUE_ to get current data or _FALSE_ for the next
328 * applicable data
329 */
330DHL_RESULT DD_PSI_GetTIDPSIMask(PSIMask_t **ppMask, DS_U8 TID, DS_BOOL current_next_indicator)
331{
332        DHL_RESULT err;
333        PSIMask_t *pMask = NULL;
334       
335        #ifdef PSI_DBG         
336        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the PSI_GetTIDPSIMask.\r\n");
337        #endif
338       
339       
340        *ppMask = NULL;
341        if( TID == 0xFF )
342        {
343                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_GetTIDPSIMask : BAD TID\r\n");
344                return DHL_FAIL_INVALID_PARAM;
345        }
346
347        err = DD_PSI_GetEmptyPSIMask(6,&pMask);
348       
349        if( err != DHL_OK )
350        {
351                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_GetTIDPSIMask : PSI_GetEmptyPSIMask return error(0x%x)\r\n" , err );
352                return(err);
353        }
354       
355        pMask->entries[0].value = TID;
356        pMask->entries[0].matchMask = 0xFF;
357       
358        pMask->entries[5].value = current_next_indicator;
359        pMask->entries[5].matchMask = 1;
360       
361       
362        *ppMask = pMask;
363        return(DHL_OK);
364}
365
366/*
367 * PSI_GetTIDPSIMask creates a psiMask which accepts anything with a particular Table ID
368 * current_next_indicator should be _TRUE_ to get current data or _FALSE_ for the next
369 * applicable data
370 */
371DHL_RESULT DD_PSI_GetTIDPSISimpleMask(PSIMask_t **ppMask, DS_U8 TID )
372{
373        DHL_RESULT err;
374        PSIMask_t *pMask = NULL;
375       
376        #ifdef PSI_DBG         
377        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the DD_PSI_GetTIDPSISimpleMask.\r\n");
378        #endif
379       
380       
381        *ppMask = NULL;
382        if( TID == 0xFF )
383        {
384                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_GetTIDPSISimpleMask : BAD TID\r\n");
385                return DHL_FAIL_INVALID_PARAM;
386        }
387
388        err = DD_PSI_GetEmptyPSIMask(1,&pMask);
389       
390        if( err != DHL_OK )
391        {
392                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_GetTIDPSISimpleMask : PSI_GetEmptyPSIMask return error(0x%x)\r\n" , err );
393                return(err);
394        }
395               
396        pMask->entries[0].value = TID;
397        pMask->entries[0].matchMask = 0xFF;
398       
399       
400        *ppMask = pMask;
401        return(DHL_OK);
402}
403
404
405/*
406 * PSI_GetExTIDPSIMask creates a psiMask which accepts anything with a particular Table ID
407 * as well as a particular table_id_externsion. The table_id_extension is a 16 bit field
408 * at byte offset 3 and 4 from the start of a section header. It is used for a variety of
409 * purposes depending on the type of table.
410 * current_next_indicator should be _TRUE_ to get current data or _FALSE_ for the next
411 * applicable data
412 */
413DHL_RESULT DD_PSI_GetExTIDPSIMask(      PSIMask_t **ppMask, 
414                                                                DS_U8 TID, 
415                                                                DS_U16 TIDExtension, 
416                                                                DS_BOOL current_next_indicator)
417{
418        DHL_RESULT err;
419        PSIMask_t *pMask = NULL;
420       
421        #ifdef PSI_DBG         
422        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the PSI_GetExTIDPSIMask.\n");
423        #endif
424       
425       
426        *ppMask = NULL;
427        if( TID == 0xFF )
428        {
429                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_GetExTIDPSIMask : BAD TID\n");
430                return DHL_FAIL_INVALID_PARAM;
431        }
432
433        err = DD_PSI_GetEmptyPSIMask(6,&pMask);
434       
435        if( err != DHL_OK )
436        {
437                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_GetExTIDPSIMask : PSI_GetEmptyPSIMask return error(0x%x)\n" , err );
438                return(err);
439        }
440       
441        pMask->numEntries = 6;
442        pMask->entries[0].value = TID;
443        pMask->entries[0].matchMask = 0xFF;
444
445        if (TIDExtension == 0xFFFF)
446        {
447                pMask->entries[3].value = 0;
448                pMask->entries[3].matchMask = 0;
449
450                pMask->entries[4].value = 0;
451                pMask->entries[4].matchMask = 0;
452        }
453        else
454        {
455        pMask->entries[3].value = TIDExtension >> 8;
456        pMask->entries[3].matchMask = 0xFF;
457       
458        pMask->entries[4].value = TIDExtension & 0xFF;
459        pMask->entries[4].matchMask = 0xFF;
460        }
461        pMask->entries[5].value = current_next_indicator;
462        pMask->entries[5].matchMask = 1;
463       
464        *ppMask = pMask;
465        return(DHL_OK);
466}
467
468DHL_RESULT DD_PSI_GetDvbEitMask(        PSIMask_t **ppMask, 
469                                                                DS_U8 TID, 
470                                                                DS_U16 TIDExtension, 
471                                                                DS_U8  segment_number,
472                                                                DS_BOOL current_next_indicator)
473{
474        DHL_RESULT err;
475        PSIMask_t *pMask = NULL;
476       
477        #ifdef PSI_DBG         
478        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the PSI_GetExTIDPSIMask.\n");
479        #endif
480       
481       
482        *ppMask = NULL;
483        if( TID == 0xFF )
484        {
485                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_GetExTIDPSIMask : BAD TID\n");
486                return DHL_FAIL_INVALID_PARAM;
487        }
488
489        err = DD_PSI_GetEmptyPSIMask(6,&pMask);
490       
491        if( err != DHL_OK )
492        {
493                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_GetExTIDPSIMask : PSI_GetEmptyPSIMask return error(0x%x)\n" , err );
494                return(err);
495        }
496       
497        pMask->numEntries = 7;
498        pMask->entries[0].value = TID;
499        pMask->entries[0].matchMask = 0xFF;
500
501        pMask->entries[3].value = TIDExtension >> 8;
502        pMask->entries[3].matchMask = 0xFF;
503       
504        pMask->entries[4].value = TIDExtension & 0xFF;
505        pMask->entries[4].matchMask = 0xFF;
506       
507        pMask->entries[5].value = current_next_indicator;
508        pMask->entries[5].matchMask = 1;
509       
510        pMask->entries[6].value = segment_number<<3;
511        pMask->entries[6].matchMask = 0xF8;
512       
513        *ppMask = pMask;
514        return(DHL_OK);
515}
516
517/*
518 * GetExTIDFieldPSIFilter creates a psiFilter which accepts anything with a particular Table ID
519 * as well as a either or both bytes of a particular table_id_externsion.
520 * The table_id_extension is either a 16 bit field at byte offset 3 and 4 (whicField==
521 * BOTH_FIELDS) or an 8 bit field at offet 3 (whicField = TOP_FIELD) or
522 * 4 (whicField == BOTTOM_FIELD) from the start of a section header.
523 * Sepecifying BOTH_FIELDS in whicField is equivalent to calling GetExTIDPSIFilter.
524 * It is used for a variety of purposes depending on the type of table.
525 * current_next_indicator should be _TRUE_ to get current data or _FALSE_ for the next
526 * applicable data
527 */
528DHL_RESULT DD_PSI_GetExTIDFieldPSIMask(         PSIMask_t **ppMask, 
529                                                                                        DS_U8 TID, 
530                                                                                        DS_U16 TIDExtension,
531                                                                                        PSIFieldSelect_k whichField, 
532                                                                                        DS_BOOL current_next_indicator)
533{
534        DHL_RESULT err;
535        PSIMask_t *pMask = NULL;
536       
537        *ppMask = NULL;
538       
539        if(TID == 0xFF)
540                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_GetExTIDFieldPSIMask: Bad TID");
541
542        if ((err = DD_PSI_GetEmptyPSIMask(6,&pMask))) {
543               
544                return(err);
545        }
546       
547       
548        pMask->numEntries = 6; 
549        pMask->entries[0].value = TID;
550        pMask->entries[0].matchMask = 0xFF;
551
552        switch(whichField) 
553        {
554                case TOP_FIELD:
555                        pMask->entries[3].value = TIDExtension & 0xFF;
556                        pMask->entries[3].matchMask = 0xFF;
557                        break;
558                case BOTTOM_FIELD:
559                        pMask->entries[4].value = TIDExtension & 0xFF;
560                        pMask->entries[4].matchMask = 0xFF;
561                        break;
562                case BOTH_FIELDS:
563                        pMask->entries[3].value = TIDExtension >> 8;
564                        pMask->entries[3].matchMask = 0xFF;
565                        pMask->entries[4].value = TIDExtension & 0xFF;
566                        pMask->entries[4].matchMask = 0xFF;
567                        break;
568                default:
569                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_GetExTIDFieldPSIMask: bad field");
570        }
571       
572//      pMask->entries[5].value = current_next_indicator;
573//      pMask->entries[5].matchMask = 1;
574
575
576        *ppMask = pMask;
577        return(DHL_OK);
578}
579
580
581/*filter °Ë»ö Á¶°Ç : table ID , ƯÁ¤ 4bits°¡ ÁÖ¾îÁø °ª°ú °°ÀºÁö È®ÀÎ ÇÑ´Ù.*/
582DHL_RESULT DD_PSI_GetTIDPrivateSubtypePSIMask( PSIMask_t **ppMask, 
583                                                                                           DS_U8 TID, 
584                                                                                           DS_U8 byteToSee,
585                                                                                           DS_U8 byteValue,
586                                                                                           PSIFieldSelect_k whichField)
587{
588        DHL_RESULT err;
589        PSIMask_t *pMask = NULL;
590        int filterSize = 0;
591       
592        *ppMask = NULL;
593       
594       
595        if( TID == 0xFF )
596        {
597                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_GetTIDPrivateSubtypeFilter: Bad TID\n");
598                return DHL_FAIL_INVALID_PARAM;
599        }
600
601        if( byteToSee < 1 )
602                filterSize = 1;
603        else
604                filterSize = byteToSee;         /*limit the maximum size...*/
605               
606        if ((err = DD_PSI_GetEmptyPSIMask(filterSize,&pMask))) {
607                return(err);
608        }
609       
610               
611        pMask->numEntries = filterSize; 
612        pMask->entries[0].value = TID;
613        pMask->entries[0].matchMask = 0xFF;
614
615
616        if( filterSize == 1 )
617                return(DHL_OK);
618
619        switch(whichField) {
620                case TOP_FIELD:
621                        pMask->entries[filterSize-1].value = (byteValue<<4) & 0xF0;
622                        pMask->entries[filterSize-1].matchMask = 0xF0;
623                        break;
624                case BOTTOM_FIELD:
625                        pMask->entries[filterSize-1].value = byteValue & 0x0F;
626                        pMask->entries[filterSize-1].matchMask = 0x0F;
627                        break;
628                case BOTH_FIELDS:
629                        pMask->entries[filterSize-1].value = byteValue & 0xff;
630                        pMask->entries[filterSize-1].matchMask = 0xFF;
631                        break;
632        }
633       
634#ifdef PSI_DBG 
635        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_GetTIDPrivateSubtypePSIMask : pMask->value %d , pMask->matchMask %d \n" , pMask->entries[filterSize-1].value , pMask->entries[filterSize-1].matchMask ); 
636#endif
637       
638        *ppMask = pMask;
639        return DHL_OK;
640}
641
642
643
644/*
645 * GetETTPSIFilter creates a psiFilter which is specifically designed to filter
646 * an ATSC PSIP Extended Text Table (ETT) with a specific Extended Text Message ID.
647 * current_next_indicator should be _TRUE_ to get current data or _FALSE_ for the next
648 * applicable data
649 */
650DHL_RESULT DD_PSI_GetETTPSIMask(                PSIMask_t **ppMask, 
651                                                                        DS_U8 TID, 
652                                                                        DS_U32 ETM_id, 
653                                                                        DS_BOOL current_next_indicator)
654{
655        DHL_RESULT err;
656        PSIMask_t *pMask = NULL;
657       
658        *ppMask = NULL;
659       
660
661        if ((err = DD_PSI_GetEmptyPSIMask(13,&pMask))) {
662       
663                return(err);
664        }
665
666       
667        pMask->numEntries = 13;
668        pMask->entries[0].value = TID;
669        pMask->entries[0].matchMask = 0xFF;
670       
671        pMask->entries[5].value = current_next_indicator;
672        pMask->entries[5].matchMask = 1;
673
674        pMask->entries[9].value = ETM_id >> 24;
675        pMask->entries[9].matchMask = 0xFF;
676        pMask->entries[10].value = (ETM_id >> 16) & 0xFF;
677        pMask->entries[10].matchMask = 0xFF;
678        pMask->entries[11].value = (ETM_id >> 8) & 0xFF;
679        pMask->entries[11].matchMask = 0xFF;
680        pMask->entries[12].value = ETM_id & 0xFF;
681        pMask->entries[12].matchMask = 0xFF;
682       
683        *ppMask = pMask;
684       
685        return(DHL_OK);
686}
687
688/*
689 * GetETTPSIFilter creates a psiFilter which is specifically designed to filter
690 * an ATSC PSIP Extended Text Table (ETT) with a specific Extended Text Message ID.
691 * current_next_indicator should be _TRUE_ to get current data or _FALSE_ for the next
692 * applicable data
693 */
694DHL_RESULT DD_PSI_GetDsmccPSIMask(              PSIMask_t **ppMask, 
695                                                                        DS_U8 TID, 
696                                                                        DS_U32 DsmccMessageId, 
697                                                                        DS_BOOL current_next_indicator)
698{
699        DHL_RESULT err;
700        PSIMask_t *pMask = NULL;
701       
702        *ppMask = NULL;
703       
704
705        if ((err = DD_PSI_GetEmptyPSIMask(12,&pMask))) {
706       
707                return(err);
708        }
709
710       
711        pMask->numEntries = 12;
712        pMask->entries[0].value = TID;
713        pMask->entries[0].matchMask = 0xFF;
714       
715        pMask->entries[5].value = current_next_indicator;
716        pMask->entries[5].matchMask = 1;
717       
718        pMask->entries[8].value = DsmccMessageId >> 24;
719        pMask->entries[8].matchMask = 0xFF;
720        pMask->entries[9].value = (DsmccMessageId >> 16) & 0xFF;
721        pMask->entries[9].matchMask = 0xFF;
722        pMask->entries[10].value = (DsmccMessageId >> 8) & 0xFF;
723        pMask->entries[10].matchMask = 0xFF;
724        pMask->entries[11].value = DsmccMessageId & 0xFF;
725        pMask->entries[11].matchMask = 0xFF;
726       
727        *ppMask = pMask;
728       
729        return(DHL_OK);
730}
731
732/*
733 * Call ReadPSIData in response to a PSIDataReceived event. The caller then owns
734 * the data and it is up to the caller to delete the data when it is finished
735 * processing the data.
736 */
737DHL_RESULT DD_PSI_ReadPSIArray( PSIContext_t *psi , PSIDataArray_t **returnArray)
738{
739        int i;
740        DS_BOOL eager = _FALSE_;
741        PSIDataArray_t *desc;
742
743        if(!psi)
744                return DHL_FAIL_NULL_POINTER;
745       
746        *returnArray = NULL;
747       
748        #ifdef PSI_DBG 
749        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the DD_PSI_ReadPSIArray.\r\n");
750        #endif 
751
752    eager = (psi->psiMode == eagerTableMode || psi->psiMode == segmentEagerMode);//(((int)master->psiMode) & PSIMODE_EAGER_FLAG)!= 0;
753//      eager = (((int)psi->psiMode) & PSIMODE_EAGER_FLAG)!= 0;
754
755        if (psi->curDataArray) {
756                *returnArray = desc = psi->curDataArray;
757                if (eager) {
758                        /*
759                         * If this is an eager client, then there may be some
760                         * detached placeholders. Make these NULL to not confuse
761                         * the issue. The -1 placeholders are there to make sure
762                         * that we don't get the same section twice even after
763                         * it has been detached.
764                         */
765                        for (i = 0; i < desc->maxSections; ++i) {
766                                if (desc->sectPtr[i] == (DS_U8 *)-1) {
767                                        desc->sectPtr[i] = NULL;
768                                }
769                        }
770                }
771                psi->curDataArray = NULL;
772               
773                       
774                return DHL_OK;
775        } else {
776                *returnArray = NULL;
777               
778       
779                return DHL_FAIL_OUT_OF_RESOURCE;
780        }
781}
782 
783
784
785
786/*
787 * FreePSIData deletes a PSIDataArray that was obtained by calling ReadPSIData
788 */
789void DD_PSI_FreePSIArray(PSIDataArray_t *psi)
790{
791        int i;
792       
793        #ifdef PSI_DBG 
794//      DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the PSI_FreeArray. psi = 0x%x\n" , psi);
795        #endif
796       
797        if( !psi )
798                return;
799       
800        if (psi) {
801                for (i = 0; i < psi->maxSections; ++i) {
802                        if (psi->sectPtr[i] != NULL &&
803                                psi->sectPtr[i] != (DS_U8 *)-1) {
804                                PSI_Free(psi->sectPtr[i]);
805                        }
806                }
807                PSI_Free(psi);
808        }
809
810}
811
812DHL_RESULT DD_PSI_GetLastReceivedSection(       PSIContext_t *psiCtl,
813                                                                DS_BOOL detach,
814                                                                DS_S32 *returnSectionNumber,
815                                                                DS_S32 *returnLastSectionNumber,
816                                                                DS_U8 **returnSectionData)
817{
818        DS_BOOL eager;
819   
820    if (!psiCtl)
821        return DHL_FAIL_NULL_POINTER;
822       
823        eager = (psiCtl->psiMode == eagerTableMode || psiCtl->psiMode == segmentEagerMode); //(((int)psiCtl->psiMode) & PSIMODE_EAGER_FLAG)!= 0;
824        if (!eager)
825    {
826        printf("|%s| This is not eagerTableMode (%d)\n", __FUNCTION__, psiCtl->psiMode);
827            return DHL_FAIL;
828    }
829   
830        if (psiCtl->curSection < 0 || 
831                psiCtl->nextDataArray == NULL ||
832                psiCtl->nextDataArray->maxSections <= psiCtl->curSection ||
833                psiCtl->nextDataArray->sectPtr[psiCtl->curSection] == NULL ||
834                psiCtl->nextDataArray->sectPtr[psiCtl->curSection] == (DS_U8 *)-1) {
835               
836                return(DHL_FAIL_NOT_FOUND);
837        }
838
839        if (returnSectionNumber) {
840                *returnSectionNumber = psiCtl->curSection;
841        }
842
843        if (returnLastSectionNumber) {
844                *returnLastSectionNumber = psiCtl->nextDataArray->maxSections-1;
845        }
846
847        if (returnSectionData) {
848                *returnSectionData = psiCtl->nextDataArray->sectPtr[psiCtl->curSection];
849                if (detach) {
850                        psiCtl->nextDataArray->sectPtr[psiCtl->curSection] = (DS_U8 *)-1;
851                }
852        }
853
854        return (DHL_OK);
855}
856
857DHL_RESULT DD_PSI_GetLastReceivedSegment(       PSIContext_t *psiCtl,
858                                                                DS_BOOL detach,
859                                                                DS_S32 *returnSegmentNumber,
860                                                                DS_S32 *returnSegmentCount,
861                                                                P_DS_U8 returnSectionData[])
862{
863        DS_BOOL eager;
864    int segment_count=0;
865    int end_segment=-1;
866   
867    if (!psiCtl)
868        return DHL_FAIL_NULL_POINTER;
869       
870        eager = (psiCtl->psiMode == segmentEagerMode); //(((int)psiCtl->psiMode) & PSIMODE_EAGER_FLAG)!= 0;
871        if (!eager)
872    {
873        printf("|%s| This is not eagerTableMode (%d)\n", __FUNCTION__, psiCtl->psiMode);
874            return DHL_FAIL;
875    }
876   
877        if (psiCtl->curSection < 0 || 
878                psiCtl->nextDataArray == NULL ||
879                psiCtl->nextDataArray->maxSections <= psiCtl->curSection ||
880                psiCtl->nextDataArray->sectPtr[psiCtl->curSection] == NULL ||
881                psiCtl->nextDataArray->sectPtr[psiCtl->curSection] == (DS_U8 *)-1) {
882               
883                return(DHL_FAIL_NOT_FOUND);
884        }
885
886        if (returnSegmentNumber) 
887        {
888                *returnSegmentNumber = (psiCtl->curSection>>3);
889        }
890
891        if (returnSegmentCount) 
892        {
893            if (psiCtl->nextDataArray->sectPtr[psiCtl->curSection])
894            {
895                segment_count = psiCtl->nextDataArray->sectPtr[psiCtl->curSection][SECTION_NUM_LAST];
896                    end_segment = psiCtl->nextDataArray->sectPtr[psiCtl->curSection][SECTION_NUM_LAST+5];
897                    *returnSegmentCount = ((segment_count+8)>>3);
898                }
899                else
900                {
901                    printf("|%s| ERROR, sectionPtr is NULL!\n", __FUNCTION__);
902                    return DHL_FAIL_NULL_POINTER;
903                }
904        }
905
906        if (returnSectionData) 
907        {
908            int i, j;
909           
910            for (j=0, i=(psiCtl->curSection & (~0x07)); i<=end_segment; i++, j++)
911            {
912                    returnSectionData[j] = psiCtl->nextDataArray->sectPtr[i];
913                if (detach) {
914                        psiCtl->nextDataArray->sectPtr[i] = (DS_U8 *)-1;
915                }
916        }
917        }
918
919        return (DHL_OK);
920}
921
922unsigned long DD_PSI_CalculateCRC( unsigned char *pTargetData , int iByteCount )
923{
924
925#if 1
926
927        unsigned long crc = 0xFFFFFFFF;
928        unsigned char *byte = pTargetData;
929        unsigned short index;
930        int len = 0;
931
932        while (len++ < iByteCount) {
933                crc ^= *byte++ << 24;
934                for(index = 0; index <= 7; index++)
935            {
936            crc = crc & 0x80000000 ? (crc << 1) ^ 0x04C11DB7 : crc << 1;
937            }
938        }
939       
940        return crc;
941
942
943#else
944        int bit_count = 0;
945        int bit_in_byte = 0;
946        unsigned short int data_bit;
947        unsigned short int shift_reg[32];
948        int i,nr_bits;
949        unsigned char *data;
950        int crc;
951        unsigned short int g[33] = { 
952                1,1,1,0,  1,1,0,1,  1,0,1,1,  1,0,0,0,
953                1,0,0,0,  0,0,1,1,  0,0,1,0,  0,0,0,0,  1 };
954
955        // Initialize shift register's to '1'
956        for(i=0; i<32; i++) shift_reg[i] = 1;
957
958        // Calculate nr of data bits
959        if(iByteCount <= 0)
960                return -1;
961
962//      nr_bits = ((int) (last - first)) * 8;
963        nr_bits = (int)iByteCount*8;
964        data = pTargetData;
965
966        while (bit_count < nr_bits) {
967                // Fetch bit from bitstream
968                data_bit = (short int) (*data  & (0x80 >> bit_in_byte));
969                data_bit = data_bit >> (7 - bit_in_byte);
970                bit_in_byte++; bit_count++;
971                if (bit_in_byte == 8) {
972                        bit_in_byte = 0;
973                        data++;
974                }
975     
976                // Perform the shift and modula 2 addition
977                data_bit ^= shift_reg[31];
978                i = 31;
979                while (i != 0) {
980                        if (g[i])
981                                shift_reg[i] = shift_reg[i-1] ^ data_bit;
982                        else
983                                shift_reg[i] = shift_reg[i-1];
984                        i--;
985                }
986                shift_reg[0] = data_bit;
987        }
988 
989        // make CRC an int
990        crc = 0x00000000;
991        for (i= 0; i<32; i++)
992                crc = (crc << 1) | ((int) shift_reg[31-i]);
993        return crc;     
994
995#endif //#if 1
996
997}
998
999
1000
1001/*
1002 * GetDataCRC retrieves the CRC field from the PSI data
1003 */
1004DS_U32 DD_PSI_GetDataCRC(DS_U8 *data, DS_U32 len)
1005{
1006        DS_U32 crc;
1007        if(len < 4 )
1008                return 0;
1009               
1010        data += (len - 4);
1011        crc = ((*data) << 24) | ((*(data+1)) << 16) | ((*(data+2)) << 8) | *(data+3);
1012        return(crc);
1013}
1014
1015
1016
1017                                                                       
1018void DD_PSI_DataReceived( PSIContext_t *master , DS_U8 *data, int len)
1019{
1020       
1021
1022        int siLength;
1023        PSIDataArray_t *desc;
1024        DS_BOOL useCRC;
1025        PSIEvent event = psiNoEvent;
1026        int maxSections;
1027        DS_BOOL eager = _FALSE_;       
1028        DS_U8   *realData = NULL;
1029        DS_U32 crc = 0;
1030        DS_U32 givenCRC = 0;
1031        int  iDescSize = 0;
1032
1033        DHL_RESULT err = DHL_OK;
1034        DS_U8   sectionNumber = 0;
1035                       
1036        DS_U16 pid = 0;
1037       
1038        if(!master || !data || len == 0 )
1039                return;
1040       
1041        pid = master->pid;
1042        /* Check to make sure the section is not longer than we asked for. */
1043       
1044        siLength = (((data[SECTION_LEN_HI]&0x0F)<<8) | data[SECTION_LEN_LO]) + 3;
1045
1046        #ifdef PSI_DBG 
1047        /*DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the DD_PSI_DataReceived : pisLength = %d \n", siLength );*/
1048        #endif
1049       
1050        if (siLength > master->maxData) {
1051                event = psiSectionTooBig;
1052                goto done;
1053        }
1054
1055        eager = (master->psiMode == eagerTableMode) || (master->psiMode == segmentEagerMode);//(((int)master->psiMode) & PSIMODE_EAGER_FLAG)!= 0;
1056
1057        switch(master->psiMode) {
1058                case privateMode:
1059                case sectionMode:
1060                        /*
1061                         * In private mode, we simply pass the data along. We check CRC if
1062                         * the section_syntax_indicator is set.
1063                         * Section mode is like private mode except that we assume section
1064                         * syntax and force a CRC check regardless of the section_syntax_indicator
1065                         * bit.
1066                         */
1067                        iDescSize = PSIDescriptorSize(1);
1068                        desc = (PSIDataArray_t *)(PSI_Malloc(iDescSize));
1069     
1070                if (!desc) {
1071                                event = psiMemoryError;                         
1072                                goto done;
1073                        }
1074                       
1075                        memset( desc , 0 , iDescSize );
1076                        desc->pid = pid;
1077                        desc->context = master;
1078                        desc->numSections = 1;
1079                        desc->maxSections = 1;
1080
1081                        useCRC =( (master->psiMode == sectionMode) || (data[SECTION_LEN_HI]&0x80 ) ) ;
1082
1083                       
1084                        /*crc check.....*/
1085                        if( useCRC )
1086                        {
1087                                crc = DD_PSI_CalculateCRC(data , siLength-4);
1088                                givenCRC = DD_PSI_GetDataCRC(data, siLength);
1089                               
1090                                if ( g_Demux_Debug >= 2 )
1091                                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_DataReceived : given crc : 0x%x , calculated crc : 0x%x, len = %d\n", (unsigned int)givenCRC , (unsigned int)crc, siLength );
1092                               
1093                                if (crc != givenCRC ) {                                 
1094                                        PSI_Free(desc);
1095                                        event = psiCRCError;
1096                                        goto done; 
1097                                }
1098                        }       
1099       
1100               
1101                        if (master->updateMode == psiCRCChange && useCRC) {
1102                                master->runningCRC = DD_PSI_GetDataCRC(data, siLength);
1103                                if (master->lastCRCValid && master->runningCRC == master->lastCRC) {
1104                                        master->runningCRC = 0;
1105                                       
1106                                        if ( g_Demux_Debug >= 2 )
1107                                            DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "SIDataReceived-secion mode : no changne in CRC...so, free this table.\n");
1108                                   
1109                                    PSI_Free(desc);
1110                                        goto done; 
1111                                }
1112                        }/*to fix.*/
1113                        else if( master->updateMode == psiVersionChange )
1114                        {
1115                                int version =  data[SECTION_VERSION]&SECTION_VERSION_MASK;
1116                                if( master->lastVersion == version )
1117                                {
1118                                       
1119                                        if ( g_Demux_Debug >= 2 )
1120                                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "SIDataReceived-secion mode: no changne in version...so, free this table.\n");
1121                                       
1122                                        PSI_Free(desc);                                                                                 
1123                                        goto done;
1124                                }
1125                                else
1126                                        master->lastVersion = version ;
1127                        }
1128                       
1129                        /*allocate the buffer which will be used by user...*/
1130                        realData = (DS_U8 *)PSI_Malloc( siLength );
1131                        if( !realData )
1132                        {
1133                                err = DHL_FAIL_OUT_OF_RESOURCE;
1134                                goto done;
1135                        }
1136                       
1137                        memset( realData , 0 , siLength );
1138                        memcpy(realData , data , siLength );
1139                        desc->sectPtr[0] = realData;
1140                        if (master->curDataArray) {
1141                                DD_PSI_FreePSIArray(master->curDataArray);
1142                               
1143                        }
1144                       
1145                        master->curDataArray = desc;
1146                        event = psiDataReceived;                       
1147                       
1148                        if ( g_Demux_Debug >= 2 ) {
1149                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSIDataReceived : master->curDataArray is set with 0x%x\n", (unsigned int)desc);
1150                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "testprint : desc->sectPtr[0][0] = 0x%x\n", (unsigned int)desc->sectPtr[0][0]);
1151                        }
1152                                               
1153                        break;
1154                       
1155                case tableMode:
1156                case eagerTableMode:
1157                case segmentTableMode:
1158                case segmentOnlyMode:
1159                case segmentEagerMode:
1160                        desc = master->nextDataArray;
1161                        if (desc &&
1162                                (master->version != (data[SECTION_VERSION]&SECTION_VERSION_MASK) ||
1163                                (master->psiMode != segmentOnlyMode && desc->maxSections != data[SECTION_NUM_LAST]+1))) {
1164                                /*
1165                                 * The version number changed or else something weird happened because
1166                                 * last_section_number changed. In any case, throw away what we had
1167                                 */
1168                                DD_PSI_FreePSIArray(master->nextDataArray);
1169                                master->nextDataArray = desc = NULL;
1170                                master->runningCRC = 0;
1171                                if (eager) {
1172                                        master->eventProc( psiVersionChanged , master, master->userParam);
1173                                }
1174                        }
1175                        sectionNumber = data[SECTION_NUM];
1176                       
1177                        if ( g_Demux_Debug >= 2 )
1178                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSIDataReceived : sectionNumber = %d\n", sectionNumber);
1179
1180                        if (desc) {
1181                                /*
1182                                 * This is a second or subsequent section in the table. Take it if
1183                                 * we haven't seen it yet. Else, discard it.
1184                                 */
1185                                if (sectionNumber >= desc->maxSections) {
1186                                        event = psiMaxSectionOverflow;
1187                                        goto done;
1188                                }
1189                                else if (desc->sectPtr[sectionNumber] != NULL) {
1190                                        /*
1191                                         * This section is beyond maxSections, but we have already informed
1192                                         * the client that this has happened, or else we have already received
1193                                         * this section, so discard this one quietly.
1194                                         */
1195                                       
1196                                        if ( g_Demux_Debug >= 2 )
1197                                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSIDataReceived : it is already received...so, ignored.\n");
1198                                       
1199                                        goto done;
1200                                }
1201                        } else {
1202                                /*
1203                                 * We are getting the first section of a new table
1204                                 */
1205                                if (data[SECTION_NUM_LAST]+1 > master->maxSections) {
1206                                        event = psiMaxSectionOverflow;
1207                                        maxSections = master->maxSections;
1208                                } else {
1209                                        maxSections = data[SECTION_NUM_LAST]+1;
1210                                }
1211                               
1212                                //printf("master->segment_number: %d\n", master->segment_number);
1213                               
1214                                if ( master->psiMode == segmentOnlyMode )
1215                {
1216                            if ( (master->segment_number << 3) != (sectionNumber & 0xF8) )
1217                            {
1218                                printf("PSIDataReceived: Invalid segment number in segmentOnlyMode. (%d, %d)\n", master->segment_number, sectionNumber );
1219                                goto done;
1220                            }
1221                            maxSections = 8;
1222                        }
1223                else
1224                {
1225                                if (sectionNumber >= maxSections) {
1226                                        event = psiLastSectionOverflow;                                 
1227                                        goto done;
1228                                }
1229                        }
1230                               
1231                                if ( g_Demux_Debug >= 2 )
1232                                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the SIDataReceived : decision of maxSections = %d\n", maxSections );
1233                               
1234                                iDescSize = sizeof(PSIDataArray_t);//PSIDescriptorSize(maxSections);
1235                            desc = (PSIDataArray_t *)(PSI_Malloc(iDescSize));
1236
1237                                if (!desc) {
1238                                        event = psiMemoryError;
1239                                        goto done;
1240                                }
1241                               
1242                                memset(desc, 0 , iDescSize );
1243                                desc->pid = pid;
1244                                desc->context = master;
1245                                desc->numSections = 0;
1246                                if ( master->psiMode == segmentOnlyMode )
1247                                    desc->maxSections = 8;
1248                                else
1249                                    desc->maxSections = maxSections;
1250                                master->version = data[SECTION_VERSION]&SECTION_VERSION_MASK;
1251                                master->nextDataArray = desc;
1252                        }
1253                        /*
1254                         * At this point, we have the descriptor and we know that we want the
1255                         * data
1256                         */
1257
1258                        /*crc check...*/
1259
1260                        crc = DD_PSI_CalculateCRC(data , siLength-4);
1261                        givenCRC = DD_PSI_GetDataCRC(data, siLength);
1262                       
1263                        if ( g_Demux_Debug >= 2 )
1264                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in TableMode : given crc : 0x%x , calculated crc : 0x%x, len = %d \n", (unsigned int)givenCRC ,(unsigned int)crc, siLength );
1265                       
1266                        if (crc != givenCRC ) {
1267                                event = psiCRCError;
1268                                goto done; 
1269                        }
1270
1271                       
1272                        /*allocate the buffer which will be used by user...*/
1273                        realData = (DS_U8 *)PSI_Malloc( siLength );
1274                        if( !realData )
1275                        {
1276                                err = DHL_FAIL_OUT_OF_RESOURCE;
1277                                goto done;
1278                        }
1279                       
1280                        memset( realData , 0 , siLength );
1281                        memcpy(realData , data , siLength );
1282                        desc->sectPtr[sectionNumber] = realData;
1283                        if (master->updateMode == psiCRCChange) {
1284                                master->runningCRC ^= DD_PSI_GetDataCRC(data, siLength);
1285                        }
1286                        master->curSection = sectionNumber;
1287                        desc->numSections++;
1288
1289            /*
1290             * If segmentTableMode, we have to count numSections here.
1291             */
1292            if ( master->psiMode == segmentTableMode || 
1293                 master->psiMode == segmentOnlyMode  || 
1294                 master->psiMode == segmentEagerMode )
1295            {
1296                int subtable_start, subtable_end;
1297                int segment_last_section_number;
1298                DS_BOOL bSegmentCompleted;
1299                int i;
1300               
1301                segment_last_section_number = data[SECTION_NUM_LAST+5];
1302                subtable_start = sectionNumber & (~0x07);
1303                subtable_end   = segment_last_section_number;
1304               
1305                bSegmentCompleted = DS_TRUE;
1306                for (i=subtable_start; i<=subtable_end; i++)
1307                {
1308                    if (desc->sectPtr[i] == NULL)
1309                    {
1310                        bSegmentCompleted = DS_FALSE;
1311                        break;
1312                    }
1313                }
1314               
1315                        if ( g_Demux_Debug >= 2 )
1316                    printf("We found segment: subtable %d(%d~%d)\n", sectionNumber, subtable_start, subtable_end);
1317
1318                if ( bSegmentCompleted == DS_TRUE )
1319                {
1320                    int increment;
1321                   
1322                    if ( (subtable_start+8) > desc->maxSections && 
1323                         (master->psiMode == segmentTableMode || master->psiMode == segmentEagerMode) )
1324                        increment = (desc->maxSections-(subtable_end-subtable_start)-subtable_start-1);
1325                    else
1326                        increment = 8-(subtable_end-subtable_start)-1;
1327                   
1328                                if ( g_Demux_Debug >= 2 )
1329                        printf("Increase section counts: %ld -> %ld (max: %ld)\n", desc->numSections, desc->numSections + increment, desc->maxSections);
1330
1331                                if (eager) 
1332                                {
1333                                    master->eventProc(psiSectionReceived, master, master->userParam);
1334                                }
1335
1336                    desc->numSections += increment;
1337                }
1338               
1339                /*
1340                 * TO DO: Have to check whether segment_last_section_number is changed for same segment.
1341                 */
1342                for (i=subtable_start; i<=subtable_end; i++)
1343                {
1344                   
1345                   
1346                }
1347            }
1348           
1349                        if ( g_Demux_Debug >= 2 )
1350                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the SIDataReceived : numSections = %d.\n" , (int)desc->numSections );
1351                       
1352                        if (eager) 
1353                        {
1354                            if (master->psiMode != segmentEagerMode)
1355                                    master->eventProc(psiSectionReceived, master, master->userParam);
1356                        }
1357                        if (desc->numSections >= desc->maxSections) {
1358                                /*
1359                                 * We have the whole table, so we can now feed it to the client
1360                                 */
1361                                 
1362                                if ( g_Demux_Debug >= 2 )
1363                                         DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the SIDataReceived : we have the whole table...\n");
1364                                 
1365                                if (master->updateMode == psiCRCChange) {
1366                                        if (master->lastCRCValid && master->runningCRC == master->lastCRC) {
1367                                                master->runningCRC = 0;
1368                                                master->nextDataArray = NULL;
1369                                                DD_PSI_FreePSIArray(desc);
1370                                               
1371                                               
1372                                                if ( g_Demux_Debug >= 2 )
1373                                                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the SIDataReceived : no changne in CRC...so, free this table.\n");
1374                                               
1375                                                if (eager) {
1376                                                        master->eventProc(psiCRCUnchanged, master, master->userParam);
1377                                                }
1378                                                goto done; 
1379                                        }
1380                                }
1381                                #if 1/*to fix.*/
1382                                else if( master->updateMode == psiVersionChange )
1383                                {
1384                                        int version =  data[SECTION_VERSION]&SECTION_VERSION_MASK;
1385                                        if( master->lastVersion == version )
1386                                        {
1387                                                DD_PSI_FreePSIArray(desc);
1388                                                master->nextDataArray = NULL;
1389                                               
1390                                                if ( g_Demux_Debug >= 2 )
1391                                                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "SIDataReceived : no changne in version...so, free this table.\n");
1392                                               
1393                                                goto done;
1394                                        }
1395                                        else
1396                                                master->lastVersion = version ;
1397                                }
1398                               
1399                                #endif
1400                                /**************/
1401
1402                                if (master->curDataArray) {
1403                                        DD_PSI_FreePSIArray(master->curDataArray);
1404                                }
1405                               
1406                                if ( g_Demux_Debug >= 2 ) {
1407                                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSIDataReceived : master->curDataArray is set with 0x%x\n",(unsigned int)desc);
1408                                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "testprint : desc->sectPtr[0][0] = 0x%x\n", (desc->sectPtr[0] == (DS_U8 *)0 || desc->sectPtr[0] == (DS_U8 *)-1) ? '0' : (unsigned int)desc->sectPtr[0][0]);
1409                                }
1410                                                               
1411                                master->curDataArray = desc;
1412                                master->nextDataArray = NULL;
1413                                event = psiDataReceived;
1414                        } else {
1415                                if ( g_Demux_Debug >= 2 ) {
1416                                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "Don't inform to upper layer.\n");
1417                                }
1418                        }                               
1419                       
1420                        break;
1421                       
1422                default:
1423                        break;
1424        } /*switch(master->psiMode)*/
1425               
1426               
1427                if (event == psiDataReceived) {
1428               
1429                if ( g_Demux_Debug >= 2 )
1430                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "SIDataReceived : we'll send a siDataReceived event to an user.\n");
1431               
1432                if (master->updateMode == psiOneShot) 
1433                {
1434                        if ( g_Demux_Debug >= 2 )
1435                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "SIDataReceived : psiOneShot\r\n");
1436                       
1437                        if(master->stopProc)
1438                        {
1439                                master->stopProc( (DS_U32)(master->pParent) , master->userParamStop);
1440                        }
1441                        else
1442                        {
1443                                if ( g_Demux_Debug >= 2 )
1444                                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the SIDataReceived : no call stopFunction\r\n"); 
1445                        }
1446                                                       
1447                }
1448                else if (master->updateMode == psiVersionChange) {
1449                        /*
1450                         * Here, we modify the siFilter to only fire on a version different
1451                         * from the one we just received.
1452                         */
1453                        #if 0 /*to fix.*/
1454                       
1455                        int version = data[SECTION_VERSION]&SECTION_VERSION_MASK;
1456                       
1457                       
1458                        PSIMask_t *filt = master->psiMask;
1459                                               
1460                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "data[SECTION_VERSION] = 0x%x , version = %d\r\n", data[SECTION_VERSION] , version );
1461                        filt->entries[5].matchMask   &= ~SECTION_VERSION_MASK;
1462                        filt->entries[5].noMatchMask |=  SECTION_VERSION_MASK;
1463                        filt->entries[5].value =
1464                                (filt->entries[5].value & ~SECTION_VERSION_MASK) | version;
1465                               
1466                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "matchMask = 0x%x , noMatchMask = 0x%x , value = %d \r\n", filt->entries[5].matchMask ,
1467                                                                                                                                                                    filt->entries[5].noMatchMask,
1468                                                                                                                                                                    filt->entries[5].value );
1469                        DD_PSI_ResetSectMask ( master->pParent , filt );
1470                        #endif
1471       
1472                }
1473                else if (master->updateMode == psiCRCChange) {
1474                       
1475                        if ( g_Demux_Debug >= 2 )
1476                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "PSI_DataReceived : currCRC = 0x%x , lastCRC = 0x%x\n" , (unsigned int)master->runningCRC , (unsigned int)master->lastCRC );
1477                       
1478                        master->lastCRC = master->runningCRC;
1479                        master->lastCRCValid = _TRUE_;
1480                        master->runningCRC = 0;
1481                }
1482        }
1483                       
1484done:
1485        /*
1486         * Send an event if we have something to tell the client.
1487         */
1488
1489        if (event != psiNoEvent && master->eventProc) {
1490                master->eventProc(event, master->pParent, master->userParam);
1491        }
1492               
1493}
1494
1495
1496DHL_RESULT      DD_PSI_RegisterPSICtx( void       *pParent,
1497                                                                   DS_U16         pid,                                         
1498                                                                   PSIMode    psiMode,
1499                                                                   PSIUpdateMode        updateMode,
1500                                                                   PSIMask_t            *prefList,
1501                                                                   DS_U16         maxData,
1502                                                                   DS_U16         maxSections,
1503                                                                   PSIEventProc_f       eventProc,
1504                                                                   DS_U32               userParam ,
1505                                                                   PSIRegisterProc_f stopFuncPtr,
1506                                                                   DS_U32               usrParamStop,
1507                                                                   DS_BOOL                      bRegister,
1508                                                                   void **returnPSIControl )
1509{
1510       
1511        PSIContext_t    *pPsiContext = NULL;
1512        *returnPSIControl = NULL;
1513       
1514        /*
1515         * If we will be monitoring version changes, then we should only look for current,
1516         * or next versions. The client can monitor both by calling MonitorPSIPid twice with
1517         * two different prefilters.
1518         */
1519         
1520        #ifdef PSI_DBG
1521        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_RegisterPSICtx : prefList->numEntries = 0x%x\r\n", prefList->numEntries  );
1522        #endif
1523       
1524        if (updateMode == psiVersionChange) {
1525               
1526                if( !(prefList->numEntries >= 6 && (prefList->entries[5].matchMask&1) != 0 ) )
1527                {
1528                   DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_RegisterPSICtx : current_next_indicator must be matched for version change. %d.\r\n" , prefList->entries[5].matchMask&1);
1529                   return DHL_FAIL_INVALID_PARAM;
1530                }
1531        }       
1532       
1533        if( bRegister == _TRUE_ )
1534                pPsiContext = DD_PSI_AllocPSIContextWRegister();
1535        else
1536                pPsiContext = DD_PSI_AllocPSIContext();
1537
1538        if( pPsiContext == NULL )
1539        {
1540                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_RegisterPSICtx : DD_PSI_AllocPSIContext() fail.\r\n");
1541                return DHL_FAIL_OUT_OF_RESOURCE;
1542        }
1543
1544       
1545        pPsiContext->pParent   = pParent;
1546       
1547        /*»ç¿ëÀÚ°¡ ÁöÁ¤ÇÑ parent°¡ ¾ø°í, register°¡ enableµÈ °æ¿ì.*/
1548        if( pParent == NULL && bRegister == _TRUE_ )
1549                pPsiContext->pParent = pPsiContext; // gpPsiCtxManager;
1550                       
1551        pPsiContext->psiMask      = prefList;
1552               
1553        pPsiContext->pid = pid;
1554        pPsiContext->psiMode = psiMode;
1555        pPsiContext->updateMode = updateMode;
1556        pPsiContext->maxData = maxData;
1557        pPsiContext->maxSections = maxSections;
1558        pPsiContext->curSection = -1;
1559        pPsiContext->version = -1;
1560        pPsiContext->eventProc = eventProc;
1561        pPsiContext->userParam = userParam;
1562        pPsiContext->lastCRC = 0;
1563        pPsiContext->runningCRC = 0;
1564        pPsiContext->lastCRCValid = _FALSE_;
1565        pPsiContext->curDataArray = NULL;
1566        pPsiContext->nextDataArray = NULL;
1567       
1568        pPsiContext->lastVersion = 0xff;
1569        pPsiContext->stopProc    = stopFuncPtr;
1570        pPsiContext->userParamStop = usrParamStop;
1571       
1572        pPsiContext->oneShot = (updateMode == psiOneShot  /*|| updateMode == psiVersionChange */ ) &&
1573                                                (psiMode != tableMode &&
1574                                                 psiMode != eagerTableMode &&
1575                                                 psiMode != segmentTableMode &&
1576                                                 psiMode != segmentOnlyMode &&
1577                                                 psiMode != segmentEagerMode ); 
1578                                                 
1579               
1580        *returnPSIControl = (void *)pPsiContext;       
1581       
1582        #ifdef PSI_CTX_MNG_DBG
1583        DD_PSI_PrintRegisteredPsiCtx();
1584        #endif
1585       
1586        return DHL_OK;           
1587}
1588                               
1589                               
1590void    DD_PSI_ReleasePSICtx( void * pPSICtx  )
1591{
1592        #ifdef PSI_DBG
1593        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "in the DD_PSI_ReleasePSICtx.\r\n");
1594        #endif
1595       
1596        if(pPSICtx)
1597        {
1598                if( ((PSIContext_t*) pPSICtx)->bRegistered == _TRUE_ )
1599                        DD_PSI_FreePSIContextWUnregister( pPSICtx );
1600                else
1601                        DD_PSI_FreePSIContext( pPSICtx );
1602        }
1603}
1604
1605       
1606DS_BOOL DD_PSI_IsInterestingSection( PSIMask_t  *pSectMask , DS_U8 *pData , int iLen )
1607{
1608       
1609        DS_BOOL noMatchSucceeded        = _FALSE_;
1610        DS_BOOL noMatchUsed             = _FALSE_;
1611        int i;
1612        PSIMaskByte_t *entry;
1613        int len = 0;
1614       
1615        if( !pSectMask || !pData || !iLen )
1616                return _FALSE_;
1617
1618
1619        len = (iLen < pSectMask->numEntries )?iLen:pSectMask->numEntries; 
1620
1621#ifdef PSI_DBG
1622       
1623        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "IsInterestingSection : len = %d , filter->entries : \r\n" , len );
1624       
1625        for( i = 0 ; i < len  ; i++ )
1626        {
1627                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "0x%x ", (pSectMask->entries)[i].value );
1628        }
1629       
1630        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "\nIsInterestingSection : len = %d , section : \r\n" , len );
1631       
1632        for( i = 0 ; i < len  ; i++ )
1633        {
1634                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "0x%x ", pData[i] );
1635                //if( !(i%16) ) DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "\r\n");
1636        }
1637        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "\n");
1638       
1639#endif
1640       
1641        for (i = 0, entry = pSectMask->entries; i < len; ++i,++pData,++entry) {
1642                if ((*pData & entry->matchMask) != (entry->value & entry->matchMask)) {
1643                        return(_FALSE_);
1644                }
1645                if (entry->noMatchMask != 0) {
1646                        noMatchUsed = _TRUE_;
1647                        if ((*pData & entry->noMatchMask) != (entry->value & entry->noMatchMask)) {
1648                                noMatchSucceeded = _TRUE_;
1649                        }
1650                }
1651               
1652                /*
1653                if (i == 0) {
1654                        pData += 2;
1655                }
1656                */
1657        }
1658       
1659        #ifdef PSI_DBG
1660       
1661        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "noMatchSucceeded = %d : noMatchUsed = %d \r\n" , noMatchSucceeded ,noMatchUsed  );
1662       
1663        #endif
1664        return(noMatchSucceeded || !noMatchUsed);
1665               
1666}                       
1667       
1668/*return it's PSIContext if it is the section you want to gather.*/
1669/*gpPsiCtxManagerÀÇ monitoring list¸¦ checkÇÑ´Ù. table monitoring ½ÃÀÛÇÒ¶§
1670register°¡ ¾ø¾úÀ¸¸é ÇØ´ç ¾øÀ½.*/
1671PSIContext_t    *DD_PSI_DoSWSectionFiltering( DS_U16 pid , DS_U8 *pData , int iLen )
1672{
1673        int i;
1674        PSIContext_t *pRetData = NULL;
1675       
1676        if( !pData || !iLen )
1677                return NULL;
1678                       
1679        if(!gpPsiCtxManager)   
1680                return NULL;
1681               
1682        DD_PSI_LockPsiCtxMng();
1683       
1684       
1685        DD_PSI_PrintRegisteredPsiCtx();
1686       
1687        for( i = 0 ; i < PSICTX_CNT ; i++ )
1688        {
1689                /*to find a PsiCtx with same pid & SectinMask.*/
1690                if ( gpPsiCtxManager->psiCtxPtrList[i] && gpPsiCtxManager->psiCtxPtrList[i]->pid == pid && \
1691                         DD_PSI_IsInterestingSection( gpPsiCtxManager->psiCtxPtrList[i]->psiMask , pData , iLen ) == _TRUE_ )
1692                {
1693                        pRetData = gpPsiCtxManager->psiCtxPtrList[i];
1694                       
1695                        #ifdef PSI_DBG
1696                        DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_DoSWSectionFiltering : find one.\n");
1697                        #endif
1698                       
1699                        break;
1700                }               
1701        }
1702       
1703       
1704        DD_PSI_UnlockPsiCtxMng();
1705       
1706        return pRetData;
1707}
1708
1709
1710void DD_PSI_ResetRegisteredMonitorFiltersExcludingOne( DS_U8 tid , DS_U8 byteIndex , DS_U8 byteMask , DS_U8 byteValue)
1711{
1712        int i = 0;
1713        PSIContext_t *pPsiCtx = NULL;
1714
1715        DD_PSI_LockPsiCtxMng();
1716        for( i = 0 ; i < PSICTX_CNT ; i++ )
1717        {
1718                /*to find a empty slot.*/
1719                pPsiCtx = gpPsiCtxManager->psiCtxPtrList[i]; 
1720                if ( pPsiCtx )
1721                {
1722                        if(     pPsiCtx->psiMask->entries[0].value == tid &&
1723                                ((pPsiCtx->psiMask->entries[byteIndex].value) & byteMask) == byteValue )
1724                        {
1725                                #ifdef PSI_DBG
1726                                DHL_DbgPrintf( gdhlPsiDbgLvl, DHLDBG_PSI, "DD_PSI_ResetRegisteredMonitorFiltersExcludingDCM : skip DCM section filter resetting.\n");
1727                                #endif
1728                                continue;
1729                        }
1730                       
1731                        pPsiCtx->lastCRC = 0;
1732                        pPsiCtx->version = 0xff;
1733            }
1734        }
1735       
1736        DD_PSI_UnlockPsiCtxMng();
1737}
1738
1739
1740
1741void DD_PSI_ResetRegisteredMonitorFilters()
1742{
1743        int i = 0;
1744        PSIContext_t *pPsiCtx = NULL;
1745
1746        DD_PSI_LockPsiCtxMng();
1747        for( i = 0 ; i < PSICTX_CNT ; i++ )
1748        {
1749                /*to find a empty slot.*/
1750                pPsiCtx = gpPsiCtxManager->psiCtxPtrList[i]; 
1751                if (pPsiCtx )
1752                {
1753                //      memset( pPsiCtx , 0 , sizeof(PSIContext_t) );
1754                //      pPsiCtx->bRegistered = _TRUE_;
1755                //      pPsiCtx->selfIndex = i;
1756                        pPsiCtx->lastCRC = 0;
1757                        pPsiCtx->version = 0xff;
1758            }
1759        }
1760       
1761        DD_PSI_UnlockPsiCtxMng();
1762}
1763
1764
1765
1766
1767
1768/*2003.12.13. added by jina*/
1769void DD_PSI_ClearRegisteredMonitorFilters()
1770{
1771        int i = 0;
1772        PSIContext_t *pPsiCtx = NULL;
1773
1774        DD_PSI_LockPsiCtxMng();
1775        for( i = 0 ; i < PSICTX_CNT ; i++ )
1776        {
1777                /*to find a empty slot.*/
1778                pPsiCtx = gpPsiCtxManager->psiCtxPtrList[i]; 
1779                if (pPsiCtx )
1780                {
1781                        DD_PSI_FreePSIContext(pPsiCtx);
1782                        gpPsiCtxManager->psiCtxPtrList[i] = NULL;
1783            }
1784        }
1785       
1786        DD_PSI_UnlockPsiCtxMng();
1787}
1788
1789
1790
1791
1792/*when using software section filtering...it is independent from hardware.*/
1793DHL_RESULT DHL_PSI_ReadPSIDataSw( void *hTblHandle , struct PSIDataArray_t **returnPsi )
1794{
1795        DHL_RESULT dhlResult;
1796       
1797        if( !hTblHandle || !returnPsi )
1798                return DHL_FAIL_NULL_POINTER;
1799               
1800        dhlResult = DD_PSI_ReadPSIArray(  hTblHandle , returnPsi);
1801       
1802        return dhlResult;
1803}
1804
1805
1806
1807       
1808DHL_RESULT DHL_PSI_MonitorPSIPidSw(  DS_U16       pid,                                         
1809                                                                   PSIMode    psiMode,
1810                                                                   PSIUpdateMode        updateMode,
1811                                                                   PSIMask_t            *prefList,
1812                                                                   DS_U16         maxData,
1813                                                                   DS_U16         maxSections,
1814                                                                   PSIEventProc_f       eventProc,
1815                                                                   DS_U32               userParam,
1816                                                                   void **returnPSIControl )
1817                                                 
1818{
1819        DHL_RESULT dhlResult = DHL_OK;
1820       
1821        /*»õ·Î ¹Þ±â¸¦ ½Ãµµ ÇÑ´Ù.*/             
1822        dhlResult = DD_PSI_RegisterPSICtx(NULL,
1823                                                                   pid,                                         
1824                                                                   psiMode,
1825                                                                   updateMode,
1826                                                                   prefList,
1827                                                                   maxData,
1828                                                                   maxSections,
1829                                                                   eventProc,
1830                                                                   userParam ,
1831                                                                   NULL,        /*no stop function*/
1832                                                                   0,           /*no param*/ 
1833                                                                   _TRUE_,      /*with register*/
1834                                                                   returnPSIControl );
1835
1836       
1837        return dhlResult;
1838 
1839}
1840
1841
1842DHL_RESULT DHL_PSI_CancelMonitorSw( void * hPsiCtl )
1843{
1844        if(!hPsiCtl)
1845                return DHL_FAIL_INVALID_PARAM;
1846               
1847        DD_PSI_ReleasePSICtx( hPsiCtl );
1848       
1849        return DHL_OK;
1850}
1851
1852
1853void DHL_PSI_FreePSIArray(  PSIDataArray_t *psi )
1854{       
1855        return (DD_PSI_FreePSIArray(psi));
1856}
Note: See TracBrowser for help on using the repository browser.