source: svn/newcon3bcm2_21bu/dst/dmw/src/Channel/DMW_ChannelDemux.c

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

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

  • Property svn:executable set to *
File size: 129.8 KB
Line 
1/****************************************************
2        DMW_ChannelDemux.c
3       
4        Demux related PSI/PSIP table reception functions.
5
6        Copyright 2003 Digital STREAM Technology, Inc.
7        All Rights Reserved
8
9        $Id: ChannelDemux.c,v 1.23  2004 cafrii Exp $
10       
11*****************************************************/
12
13
14
15#include "DMW_Platform.h"
16
17
18#include "DHL_OSAL.h"
19#include "DHL_DBG.h"
20//#include "DHL_PsiAPI.h"
21#include "DLIB_PSI.h"
22#include "DLIB_PSIP.h"
23#include "DLIB_PSIP_Monitor.h"
24#include "DLIB_PSIP_Parser.h"
25#include "DLIB_PSI_Monitor.h"
26#include "DLIB_PSI_Parser.h"
27
28//#include "DHL_Memchain.h"  // for memChain feature..
29#include "DLIB_BitOp.h"
30
31
32
33#include "DMW_Config.h"
34#include "DMW_Status.h"
35
36
37#include "DMW_DebugUtil.h"
38#include "DMW_ChannelDemux.h"
39
40#include "DMW_Dummy.h"
41
42//#include <string.h>
43
44
45DHL_MODULE("$dmx", 0);
46
47
48//-------------------------------------------------------
49// Configurations..
50
51
52
53#define TEST_CHANNEL_DEMUX 1
54        // include test code of channel demux
55
56       
57
58
59#define PSIP_WAIT_IN_TICK (1000/20)
60        // 1/20 ÃÊ À̸é, 60 tick/sec system¿¡¼­´Â ¾à 3 Á¤µµ µÇ´Â °ªÀÌ´Ù.
61
62
63
64
65int gMaxTableMonitorsAtOneTime = 24; 
66        //
67        // ÀÌ °ªÀº ¹Ýµå½Ã Hardware RestrictionÀ» °í·ÁÇÑ »óÅ¿¡¼­ °áÁ¤µÇ¾î¾ß ÇÑ´Ù.
68        // ZoranÀº 40°³ÀÇ Demux object°¡ »ç¿ë °¡´ÉÇÏ´Ù. (°¢°¢ ´Ù¸¥ PID)
69        // ÀÌ Áß¿¡¼­ Video/Audio, PAT, PMT, MGT, STT, EAS µîÀÇ ¸ð´ÏÅÍ ¿ëµµ·Î »ç¿ëµÇ°í ÀÖÀ» ¼ö ÀÖ´Â °ÍÀ» Á¦¿ÜÇϸé
70        // ´ë·« 32°³ Á¤µµ¸¸ µ¿½Ã monitor°¡ °¡´ÉÇÒ °ÍÀÌ´Ù.
71        //
72        // Beetle 640ÀÇ °æ¿ì¿¡´Â ÃÖ´ë µ¿½Ã¿¡ 32°³ ¹Û¿¡ »ç¿ëÇÒ ¼ö ¾ø´Ù.
73        // µû¶ó¼­ µ¿½Ã ¸ð´ÏÅÍ´Â ¾ÈÀüÇÏ°Ô 24°³ Á¤µµ¸¸ »ç¿ëÇϵµ·Ï Çϰí,
74        // ÇöÀç (2005/5/11) ¼º´É»óÀÇ ¾à°£ÀÇ ¹®Á¦°¡ ÀÖ´Ù.
75
76
77
78
79
80//---------------------------------------------------------------------------
81
82#if COMMENT
83________(){}
84#endif
85
86
87void byteBufInit(byteBufPtr_t bt, UINT8 *buffer, UINT32 bufSize)
88{
89        /* Initialize */
90        bt->buffer = buffer;
91                // buffer°¡ NULLÀ̸é simulation mode ·Î¼­, buffer Å©±â estimation¿¡ »ç¿ëµÊ.
92        bt->bufSize = bufSize;
93        bt->offset = 0;
94        bt->overrunError = 0;
95
96        return;
97}
98
99void byteBufSetBytesBuf(byteBufPtr_t bt, UINT8 *buf, UINT16 nBytes)
100{
101        if (nBytes == 0)
102                return;
103               
104        // check overrun
105        if (bt->offset + nBytes > bt->bufSize) {
106                bt->overrunError = TRUE;
107                DHL_OS_Printf("!! byteBufSetX overrun, offset %d, bytesize %d\n", 
108                                                bt->offset, (int)nBytes);
109                return;
110        }
111       
112        if (bt->buffer) {
113                memcpy(bt->buffer + bt->offset, buf, nBytes);
114        }
115        bt->offset += nBytes;
116}
117
118void byteBufSetBytes(byteBufPtr_t bt, UINT32 data, UINT8 nBytes)
119{
120        // nBytes should be 1, 2, 4
121        if (nBytes == 0 || nBytes > 4) {
122                DHL_OS_Printf("!! byteBufSet invalid bytesize %d\n", (int)nBytes);
123                return;
124        }
125               
126        // check overrun
127        if (bt->offset + nBytes > bt->bufSize) {
128                bt->overrunError = TRUE;
129                DHL_OS_Printf("!! byteBufSet overrun, offset %d, bytesize %d\n", 
130                                                        bt->offset, (int)nBytes);
131                return;
132        }
133       
134        if (bt->buffer) {
135                if (nBytes == 1)
136                        *(bt->buffer + bt->offset)     = data&0xff;
137                else if (nBytes == 2) {
138                        *(bt->buffer + bt->offset)     = (data>>8 )&0xff;
139                        *(bt->buffer + bt->offset + 1) = (data    )&0xff;
140                }
141                else if (nBytes == 3) {
142                        *(bt->buffer + bt->offset)     = (data>>16)&0xff;
143                        *(bt->buffer + bt->offset + 1) = (data>>8 )&0xff;
144                        *(bt->buffer + bt->offset + 2) = (data    )&0xff;
145                }
146                else {
147                        *(bt->buffer + bt->offset)     = (data>>24)&0xff;
148                        *(bt->buffer + bt->offset + 1) = (data>>16)&0xff;
149                        *(bt->buffer + bt->offset + 2) = (data>>8 )&0xff;
150                        *(bt->buffer + bt->offset + 3) = (data    )&0xff;
151                }
152        }
153        bt->offset += nBytes;
154}
155
156STATUS byteBufGetBytesBuf(byteBufPtr_t bt, UINT8 *buf, UINT16 nBytes)
157{
158        if (bt->offset + nBytes > bt->bufSize) {
159                bt->overrunError = TRUE;
160                DHL_OS_Printf("!! byteBufGetX overrun, offset %d, bytesize %d\n", 
161                                                        bt->offset, (int)nBytes);
162                return statusOverflow;
163        }
164       
165        if (nBytes)
166                memcpy(buf, bt->buffer+bt->offset, nBytes);
167       
168        bt->offset += nBytes;
169        return statusOK;
170}
171
172UINT32 byteBufGetBytes(byteBufPtr_t bt, UINT8 nBytes)
173{
174        UINT32 value;
175        UINT8 data[4] = {0, };
176       
177        // bytesize should be 1, 2, 4
178        if (nBytes == 0 || nBytes > 4) {
179                DHL_OS_Printf("!! byteBuf invalid bytesize %d\n", (int)nBytes);
180                return 0;
181        }
182               
183        if (byteBufGetBytesBuf(bt, data, nBytes))
184                return 0; // error
185       
186        if (nBytes == 1)
187                value = data[0];
188        else if (nBytes == 2)
189                value = data[0]<<8U | data[1];
190        else if (nBytes == 3)
191                value = data[0]<<16UL | data[1]<<8UL | data[2];
192        else
193                value = data[0]<<24UL | data[1]<<16UL | data[2]<<8UL | data[3];
194               
195        return value;
196}
197
198void byteBufSkipBytes(byteBufPtr_t bt, UINT8 numberOfBytes)
199{
200        // check overrun
201        if (bt->offset + numberOfBytes > bt->bufSize) {
202                bt->overrunError = TRUE;
203                DHL_OS_Printf("!! byteBuf overrun, offset %d, last skip %d\n", 
204                                                        bt->offset, (int)numberOfBytes);
205                return;
206        }
207        bt->offset += numberOfBytes;
208}
209
210UINT32 byteBufGetOffset(byteBufPtr_t bt)
211{
212        return bt->offset;     
213}
214
215BOOL byteBufCheckError(byteBufPtr_t bt)
216{
217        return (bt->overrunError);
218}
219
220
221
222
223#if COMMENT
224__________(){}
225#endif
226
227// cafrii 070322 change
228//
229//  ¸ðµç getXX ·ùÀÇ ÇÔ¼ö¸¦ ÇϳªÀÇ event data procÀ¸·Î ÅëÀÏ..
230//  ´õÀÌ»ó driver/halÀÇ proc data¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù.
231
232typedef struct PSIMultiEventProcData_t {
233        tDHL_PSI_DataArray              *desc;
234        DHL_RESULT                              err;
235        DHL_OS_SEMA_ID          sema4;
236       
237        UINT32 id;   // cafrii 040331 add this for debugging
238                // ¿©·¯°³ÀÇ PSI monitor¸¦ µ¿½Ã¿¡ ½ÃÀÛÇÏ´Â °æ¿ì, ¹ß»ýµÈ PSI Event°¡ ¾î´À monitor·ÎºÎÅÍ
239                // ¿Â °ÍÀÎÁö¸¦ ¾Ë¾Æ³»´Âµ¥ µµ¿òÀ̵ȴÙ.
240                // event procedure¿¡¼­´Â id ÀÇ ¼ö½Å flag¸¦ set ½ÃÅ´À¸·Î½á event°¡ ¹ß»ýÇß´Ù´Â »ç½ÇÀ»
241                //
242                // Å뺸ÇÑ´Ù. (¹°·Ð sema4¸¦ ÀÌ¿ëÇØ¼­µµ event°¡ Àü´ÞµÈ´Ù.)
243               
244} PSIMultiEventProcData;
245
246
247// LSB 8 bit´Â PSI arrayÀÇ indexÀÌ´Ù.
248
249#define PME_SEND 0x800   // event °¡ SEND µÇ¾úÀ½
250#define PME_CNFM 0x400   // event °¡ ¼ö½Å ¹× Confirm µÇ¾úÀ½
251#define PME_MASK 0xf00
252
253#define PME_EV_SEND_BADPKT   0x010000
254#define PME_EV_SEND_SCRAMBLE 0x020000
255
256#define PME_EV_CNFM_BADPKT   0x100000
257#define PME_EV_CNFM_SCRAMBLE 0x200000
258
259#define PME_EV_MASK 0xff0000
260
261#define PMT_FLAG_SINGLE 0x1000000    // Single ModeÀÎ °æ¿ì
262
263
264
265void _Dmc_MultiEventProc(tDHL_PSI_Event event, tDHL_PSI_ControlHandle psiCtl, UINT32 userParam)
266{
267        PSIMultiEventProcData *procData = (PSIMultiEventProcData *)userParam;
268        tDHL_PSI_DataArray *desc;
269        DHL_RESULT err;
270
271        switch (event) { 
272                case ePSIEVENT_DATARECEIVED:
273                        err = DHL_PSI_ReadPSIData(psiCtl, &desc);
274                        if (err) {
275                                dprint(0, "++++ !! DHL_PSI_ReadPSIData returned %s\n",ErrorString(err));
276                        }
277                        else {
278                                procData->desc = desc;
279                                //dprint(3, "++++ data for table %d received, psiCtl %x\n", procData->id, psiCtl); // id is just for debugging..
280                                //if (procData->id & PME_SEND)
281                                //      dprint(0, "!!!! event already sent!! id: 0x%x\n", procData->id);
282                                       
283                                procData->id |= PME_SEND;  // indicating that this table is received..
284                        }
285                        procData->err = err;
286                        dprint(3, "eventproc: event %d received. give sem %x..\n", event, procData->sema4);
287                        DHL_OS_GiveSemaphore(procData->sema4);
288                        break;
289                case ePSIEVENT_SCRAMBLEDERROR:
290                        if (!(procData->id & PME_EV_SEND_SCRAMBLE)) {
291                                procData->id |= PME_EV_SEND_SCRAMBLE;
292                                procData->err = DHL_FAIL_SCRAMBLED;
293                                dprint(0, "++++ psiScrambledErr [%d] --> send evt\n", (procData->id & 0xff));
294                                DHL_OS_GiveSemaphore(procData->sema4);
295                        }
296                        else
297                                dprint(0, "++++ psiScrambledErr [%d]\n", (procData->id & 0xff));
298                        break;
299
300                case ePSIEVENT_DUP3PACKET:
301                case ePSIEVENT_LOSTPACKET:
302                case ePSIEVENT_DISCONTINUITY:
303                case ePSIEVENT_SYNCERR:
304                case ePSIEVENT_CRCERROR:
305                        if (!(procData->id & PME_EV_SEND_BADPKT)) {
306                                procData->id |= PME_EV_SEND_BADPKT;
307                                dprint(0, "++++ %s [%d] --> send evt\n", DHL_PSIEventString(event), (procData->id & 0xff));
308                                if ((procData->id & PMT_FLAG_SINGLE) == 0) // single RX °¡ ¾Æ´Ñ °æ¿ì¿¡¸¸ event Àü´Þ.
309                                        DHL_OS_GiveSemaphore(procData->sema4);
310                        }
311                        else
312                                dprint(0, "++++ %s [%d]\n", DHL_PSIEventString(event), (procData->id & 0xff));
313                        break;
314               
315                default:
316                        dprint(0, "++++ %s [%d]\n", DHL_PSIEventString(event), (procData->id & 0xff));
317                        break;
318        }
319}
320
321
322
323STATUS Dmc_GetPAT(tDHL_TSD tsd, MPEG_PAT **returnPat, int timeOut, BOOL (*ckfn)())
324{
325        PSIMultiEventProcData procData;
326        tDHL_PSI_ControlHandle returnPSICtl = (tDHL_PSI_ControlHandle)0;
327        DHL_RESULT err;
328        STATUS status = statusOK;
329        int semErr;
330        UINT32 tickStart;
331
332#if 0
333        if (dmc_TaskID != Dmc_GetCurrentTaskID()) {
334                dprint(2, "!! Dmc_GetPAT() should be called only in DmcTask.\n");
335                return statusInvalidState;
336        }
337#endif
338
339        if (returnPat == NULL) return statusInvalidArgument;
340
341        memset(&procData, 0, sizeof(procData));
342        procData.desc = NULL;
343        procData.err = DHL_OK;
344        procData.id = (UINT32)-1; // id·Î Single Mode or Multiple Mode ±¸ºÐ
345        procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcPAT",OS_SEM_PRIO,0);
346        if (!procData.sema4) {
347                return statusOutOfMemory;
348        }
349        if ((err = MonitorPAT(tsd, TRUE, FALSE, // current, not eager
350                                                  ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &returnPSICtl))) {
351                status = statusOutOfResource;
352                goto done;
353        }
354
355        tickStart = DHL_OS_GetMsCount();
356        while (1) {
357                semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK);
358               
359                if (semErr == DHL_OK) 
360                        break;
361
362                if (ckfn && ckfn()) {
363                        status = statusCancelled;
364                        goto done2;
365                }
366               
367                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
368                        status = statusTimeout;
369                        goto done2;
370                }
371        }
372
373        if (procData.err) {
374                // noDataError, ScrambledError
375                status = statusPSIPError;
376                goto done2;
377        }
378
379        err = ParsePAT(procData.desc, returnPat);
380       
381        if (IsError(err)) {
382                // noDataError, badFormatError, outOfCPUMemoryError;
383                status = statusPSIPError;
384                *returnPat = NULL;
385        }
386
387done2:
388        if (returnPSICtl) DHL_PSI_StopMonitor(returnPSICtl);
389        if (procData.desc) DHL_PSI_FreePSIData(procData.desc);
390
391done:
392        if (procData.sema4) DHL_OS_DeleteSemaphore(procData.sema4);
393        return status;
394}
395
396STATUS Dmc_GetPMT(tDHL_TSD tsd, UINT16 pid, UINT16 program_number, MPEG_PMT **returnPmt, int timeOut, BOOL (*ckfn)())
397{
398        // GetPMTÀÇ º¯Çü.
399       
400        PSIMultiEventProcData procData;
401        tDHL_PSI_ControlHandle returnPSICtl = (tDHL_PSI_ControlHandle)0;
402        DHL_RESULT err;
403        STATUS status = statusOK;
404        int semErr;
405        UINT32 tickStart;
406
407#if 0
408        if (dmc_TaskID != Dmc_GetCurrentTaskID()) {
409                dprint(2, "!! Dmc_GetPMT() should be called only in DmcTask.\n");
410                return statusInvalidState;
411        }
412#endif
413
414        if (returnPmt == NULL) return statusInvalidArgument;
415
416        if (pid <= 0 || pid >= 0x1FFF) {  // cafrii 050315 add
417                return statusInvalidArgument;
418        }
419
420        memset(&procData, 0, sizeof(procData));
421        procData.desc = NULL;
422        procData.err = DHL_OK;
423        procData.id = (UINT32)-1;
424        procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcPMT",OS_SEM_PRIO,0);
425        if (!procData.sema4) {
426                return statusOutOfMemory;
427        }
428        if ((err = MonitorPMT(tsd, pid, program_number, TRUE, // current
429                                                ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &returnPSICtl))) {
430                status = statusOutOfResource;
431                goto done;
432        }
433
434        tickStart = DHL_OS_GetMsCount();
435        while (1) {
436                semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK);
437               
438                if (semErr == DHL_OK)
439                        break;
440
441                if (ckfn && ckfn()) {
442                        status = statusCancelled;
443                        goto done2;
444                }
445               
446                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
447                        status = statusTimeout;
448                        goto done2;
449                }
450        }
451
452        if (procData.err) {
453                status = statusPSIPError;
454                goto done2;
455        }
456
457        err = ParsePMT(procData.desc, returnPmt);
458
459        if (IsError(err)) {
460                status = statusPSIPError;
461                *returnPmt = NULL;
462        }
463
464done2:
465        if (returnPSICtl) 
466                DHL_PSI_StopMonitor(returnPSICtl);
467        if (procData.desc) 
468                DHL_PSI_FreePSIData(procData.desc);
469
470done:
471        DHL_OS_DeleteSemaphore(procData.sema4);
472        return status;
473}
474
475STATUS Dmc_GetMgtSection(tDHL_TSD tsd, mgtSectionPtr_t *mgtSectPtr, int timeOut, BOOL (*ckfn)())
476{
477        PSIMultiEventProcData procData;
478        tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0;
479        int     semErr;
480        DHL_RESULT err;
481        STATUS status = statusOK;
482        UINT32 tickStart;
483
484#if 0
485        if (dmc_TaskID != Dmc_GetCurrentTaskID()) {
486                dprint(2, "!! Dmc_GetMgtSection() should be called only in DmcTask.\n");
487                return statusInvalidState;
488        }
489#endif
490        if (mgtSectPtr == NULL) return statusInvalidArgument;
491
492        memset(&procData, 0, sizeof(procData));
493        procData.desc = NULL;
494        procData.err = DHL_OK;
495        procData.id = (UINT32)-1;
496        procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcMgt",OS_SEM_PRIO,0);
497        if (!procData.sema4) {
498                return statusOutOfMemory;
499        }
500       
501        err = MonitorMgt(tsd, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl);
502        if (err) {
503                status = statusOutOfResource;
504                goto GetSectionExit;
505        }
506        tickStart = DHL_OS_GetMsCount();
507        while (1) {
508                semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK);
509               
510                if (semErr == DHL_OK)
511                        break;
512
513                if (ckfn && ckfn()) {
514                        status = statusCancelled;
515                        goto CancelPsiMonitor;
516                }
517               
518                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
519                        status = statusTimeout;
520                        goto CancelPsiMonitor;
521                }
522        }
523        if ((err = procData.err)) {
524                status = statusPSIPError;
525                goto CancelPsiMonitor;
526        }
527
528        err = ParseMgtSection(procData.desc->sectPtr[0], mgtSectPtr);
529
530        if (IsError(err)) {
531                status = statusPSIPError;
532                *mgtSectPtr = NULL;
533        }
534
535CancelPsiMonitor:
536        if (psiCtl) DHL_PSI_StopMonitor(psiCtl);
537        if (procData.desc) DHL_PSI_FreePSIData(procData.desc);
538
539GetSectionExit:
540        DHL_OS_DeleteSemaphore(procData.sema4);
541        return status;
542}
543
544STATUS Dmc_GetSttSection(tDHL_TSD tsd, sttSectionPtr_t *sttSectPtr, int timeOut, BOOL (*ckfn)())
545{
546        PSIMultiEventProcData procData;
547        tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0;
548        int semErr;
549        DHL_RESULT err;
550        STATUS status = statusOK;
551        UINT32 tickStart;
552
553#if 0
554        if (dmc_TaskID != Dmc_GetCurrentTaskID()) {
555                dprint(2, "!! Dmc_GetSttSection() should be called only in DmcTask.\n");
556                return statusInvalidState;
557        }
558#endif
559        if (sttSectPtr == NULL) return statusInvalidArgument;
560
561        memset(&procData, 0, sizeof(procData));
562        procData.desc = NULL;
563        procData.err = DHL_OK;
564        procData.id = (UINT32)-1;
565        procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcStt",OS_SEM_PRIO,0);
566        if (!procData.sema4) {
567                return statusOutOfMemory;
568        }
569       
570        err = MonitorStt(tsd, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl);
571        if (err) {
572                status = statusOutOfResource;
573                goto GetSectionExit;
574        }
575       
576        tickStart = DHL_OS_GetMsCount();
577        while (1) {
578                semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK);
579               
580                if (semErr == DHL_OK)
581                        break;
582
583                if (ckfn && ckfn()) {
584                        status = statusCancelled;
585                        goto CancelPsiMonitor;
586                }
587               
588                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
589                        status = statusTimeout;
590                        goto CancelPsiMonitor;
591                }
592        }
593        if (procData.err) {
594                status = statusPSIPError;
595                goto CancelPsiMonitor;
596        }
597
598        err = ParseSttSection(procData.desc->sectPtr[0], sttSectPtr);
599
600        if (IsError(err)) {
601                status = statusPSIPError;
602                *sttSectPtr = NULL;
603        }
604
605CancelPsiMonitor:
606        if (psiCtl) DHL_PSI_StopMonitor(psiCtl);
607        if (procData.desc) DHL_PSI_FreePSIData(procData.desc);
608
609GetSectionExit:
610        DHL_OS_DeleteSemaphore(procData.sema4);
611        return status;
612}
613
614STATUS Dmc_GetTvct(tDHL_TSD tsd, tvctPtr_t *tvctPtr, int timeOut, BOOL (*ckfn)())
615{
616        PSIMultiEventProcData procData;
617        tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0;
618        int semErr;
619        DHL_RESULT err;
620        STATUS status = statusOK;
621        UINT32 tickStart;
622
623#if 0
624        if (dmc_TaskID != Dmc_GetCurrentTaskID()) {
625                dprint(2, "!! Dmc_GetTvct() should be called only in DmcTask.\n");
626                return statusInvalidState;
627        }
628#endif
629
630        if (tvctPtr == NULL) return statusInvalidArgument;
631
632        memset(&procData, 0, sizeof(procData));
633        procData.desc = NULL;
634        procData.err = DHL_OK;
635        procData.id = (UINT32)-1;
636        procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcTvct",OS_SEM_PRIO,0);
637        if (!procData.sema4) {
638                return statusOutOfMemory;
639        }
640        dprint(3, "created sem %x\n", procData.sema4);
641       
642        err = MonitorTvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl);
643        if (err) {
644                status = statusOutOfResource;
645                goto GetSectionExit;
646        }
647       
648        tickStart = DHL_OS_GetMsCount();
649        while (1) {
650                semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK);
651               
652                if (semErr == DHL_OK)
653                        break;
654
655                if (ckfn && ckfn()) {
656                        status = statusCancelled;
657                        goto CancelPsiMonitor;
658                }
659               
660                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
661                        status = statusTimeout;
662                        goto CancelPsiMonitor;
663                }
664        }
665        if (procData.err) {
666                status = statusPSIPError;
667                goto CancelPsiMonitor;
668        }
669
670        err = ParseTvct(procData.desc->sectPtr, tvctPtr);
671
672        if (IsError(err)) {
673                status = statusPSIPError;
674                *tvctPtr = NULL;
675        }
676
677CancelPsiMonitor:
678        if (psiCtl) DHL_PSI_StopMonitor(psiCtl);
679        if (procData.desc) DHL_PSI_FreePSIData(procData.desc);
680
681GetSectionExit:
682        DHL_OS_DeleteSemaphore(procData.sema4);
683        return status;
684}
685
686STATUS Dmc_GetCvct(tDHL_TSD tsd, cvctPtr_t *cvctPtr, int timeOut, BOOL (*ckfn)())
687{
688        PSIMultiEventProcData procData;
689        tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0;
690        int semErr;
691        DHL_RESULT err;
692        STATUS status = statusOK;
693        UINT32 tickStart;
694
695#if 0
696        if (dmc_TaskID != Dmc_GetCurrentTaskID()) {
697                dprint(2, "!! Dmc_GetCvct() should be called only in DmcTask.\n");
698                return statusInvalidState;
699        }
700#endif
701        if (cvctPtr == NULL) return statusInvalidArgument;
702
703        memset(&procData, 0, sizeof(procData));
704        procData.desc = NULL;
705        procData.err = DHL_OK;
706        procData.id = (UINT32)-1;
707        procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcCvct",OS_SEM_PRIO,0);
708        if (!procData.sema4) {
709                return statusOutOfMemory;
710        }
711       
712        err = MonitorCvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl);
713        if (err) {
714                status = statusOutOfResource;
715                goto GetSectionExit;
716        }
717       
718        tickStart = DHL_OS_GetMsCount();
719        while (1) {
720                semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK);
721               
722                if (semErr == DHL_OK)
723                        break;
724                       
725                if (ckfn && ckfn()) {
726                        status = statusCancelled;
727                        goto CancelPsiMonitor;
728                }
729               
730                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
731                        status = statusTimeout;
732                        goto CancelPsiMonitor;
733                }
734        }
735        if (procData.err) {
736                status = statusPSIPError;
737                goto CancelPsiMonitor;
738        }
739
740        err = ParseCvct(procData.desc->sectPtr, cvctPtr);
741
742        if (IsError(err)) {
743                status = statusPSIPError;
744                *cvctPtr = NULL;
745        }
746
747CancelPsiMonitor:
748        if (psiCtl) DHL_PSI_StopMonitor(psiCtl);
749        if (procData.desc) DHL_PSI_FreePSIData(procData.desc);
750
751GetSectionExit:
752        DHL_OS_DeleteSemaphore(procData.sema4);
753
754        return status;
755}
756
757STATUS Dmc_GetEit(tDHL_TSD tsd, UINT16 PID, UINT16 source_id, eitPtr_t *eitPtr, 
758                                                int timeOut, BOOL (*ckfn)())
759{
760        PSIMultiEventProcData procData;
761        tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0;
762        int     semErr;
763        DHL_RESULT err;
764        STATUS status = statusOK;
765        UINT32 tickStart;
766
767#if 0
768        if (dmc_TaskID != Dmc_GetCurrentTaskID()) {
769                dprint(2, "!! Dmc_GetEit() should be called only in DmcTask.\n");
770                return statusInvalidState;
771        }
772#endif
773
774        if (eitPtr == NULL) return statusInvalidArgument;
775
776        if (PID <= 0 || PID >= 0x1FFF) {  // cafrii 050315 add
777                return statusInvalidArgument;
778        }
779
780        memset(&procData, 0, sizeof(procData));
781        procData.desc = NULL;
782        procData.err = DHL_OK;
783        procData.id = (UINT32)-1;
784        procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcEit",OS_SEM_PRIO,0);
785        if (!procData.sema4) {
786                return statusOutOfMemory;
787        }
788       
789        err = MonitorEit(tsd, PID, source_id, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl);
790        if (err) {
791                status = statusOutOfResource;
792                goto GetSectionExit;
793        }
794       
795        tickStart = DHL_OS_GetMsCount();
796        while (1) {
797                semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK);
798               
799                if (semErr == DHL_OK)
800                        break;
801
802                if (ckfn && ckfn()) {
803                        status = statusCancelled;
804                        goto CancelPsiMonitor;
805                }
806               
807                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
808                        status = statusTimeout;
809                        goto CancelPsiMonitor;
810                }
811        }
812        if (procData.err) {
813                status = statusPSIPError;
814                goto CancelPsiMonitor;
815        }
816
817        err = ParseEit(procData.desc->sectPtr, eitPtr);
818
819        if (IsError(err)) {
820                status = statusPSIPError;
821                *eitPtr = NULL;
822        }
823
824CancelPsiMonitor:
825        if (psiCtl) DHL_PSI_StopMonitor(psiCtl);
826        if (procData.desc) DHL_PSI_FreePSIData(procData.desc);
827
828GetSectionExit:
829        DHL_OS_DeleteSemaphore(procData.sema4);
830        return status;
831}
832
833STATUS Dmc_GetEttSection(tDHL_TSD tsd, UINT16 PID, UINT32 ETM_id, ettSectionPtr_t *ettSectPtr, 
834                                                        int timeOut, BOOL (*ckfn)())
835{
836        PSIMultiEventProcData procData;
837        tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0;
838        int semErr;
839        DHL_RESULT err;
840        STATUS status = statusOK;
841        UINT32 tickStart;
842
843#if 0
844        if (dmc_TaskID != Dmc_GetCurrentTaskID()) {
845                dprint(2, "!! Dmc_GetEttSection() should be called only in DmcTask.\n");
846                return statusInvalidState;
847        }
848#endif
849
850        if (ettSectPtr == NULL) return statusInvalidArgument;
851
852        if (PID <= 0 || PID >= 0x1FFF) {  // cafrii 050315 add
853                return statusInvalidArgument;
854        }
855
856        memset(&procData, 0, sizeof(procData));
857        procData.desc = NULL;
858        procData.err = DHL_OK;
859        procData.id = (UINT32)-1;
860        procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcEtt",OS_SEM_PRIO,0);
861        if (!procData.sema4) {
862                return statusOutOfMemory;
863        }
864       
865        err = MonitorEtt(tsd, PID, ETM_id, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl);
866        if (err) {
867                status = statusOutOfResource;
868                goto GetSectionExit;
869        }
870       
871        tickStart = DHL_OS_GetMsCount();
872        while (1) {
873                semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK);
874               
875                if (semErr == DHL_OK)
876                        break;
877
878                if (ckfn && ckfn()) {
879                        status = statusCancelled;
880                        goto CancelPsiMonitor;
881                }
882               
883                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
884                        status = statusTimeout;
885                        goto CancelPsiMonitor;
886                }
887        }
888        if (procData.err) {
889                status = statusPSIPError;
890                goto CancelPsiMonitor;
891        }
892
893        err = ParseEttSection(procData.desc->sectPtr[0], ettSectPtr);
894
895        if (IsError(err)) {
896                status = statusPSIPError;
897                *ettSectPtr = NULL;
898        }
899
900CancelPsiMonitor:
901        if (psiCtl) DHL_PSI_StopMonitor(psiCtl);
902        if (procData.desc) DHL_PSI_FreePSIData(procData.desc);
903
904GetSectionExit:
905        DHL_OS_DeleteSemaphore(procData.sema4);
906        return status;
907} 
908
909STATUS Dmc_GetRrtSection(tDHL_TSD tsd, UINT8 region, rrtSectionPtr_t *rrtSectPtr, 
910                                                        int timeOut, BOOL (*ckfn)())
911{
912        PSIMultiEventProcData procData;
913        tDHL_PSI_ControlHandle psiCtl = (tDHL_PSI_ControlHandle)0;
914        int semErr;
915        DHL_RESULT err;
916        STATUS status = statusOK;
917        UINT32 tickStart;
918
919#if 0
920        if (dmc_TaskID != Dmc_GetCurrentTaskID()) {
921                dprint(2, "!! Dmc_GetRrtSection() should be called only in DmcTask.\n");
922                return statusInvalidState;
923        }
924#endif
925
926        if (rrtSectPtr == NULL) return statusInvalidArgument;
927
928        memset(&procData, 0, sizeof(procData));
929        procData.desc = NULL;
930        procData.err = DHL_OK;
931        procData.id = (UINT32)-1;
932        procData.sema4 = DHL_OS_CreateCountingSemaphore("DmcRrt",OS_SEM_PRIO,0);
933        if (!procData.sema4) {
934                return statusOutOfMemory;
935        }
936       
937        err = MonitorRrt(tsd, region, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&procData, &psiCtl);
938        if (err) {
939                status = statusOutOfResource;
940                goto GetSectionExit;
941        }
942        tickStart = DHL_OS_GetMsCount();
943        while (1) {
944                semErr = DHL_OS_TakeSemaphore(procData.sema4, PSIP_WAIT_IN_TICK);
945               
946                if (semErr == DHL_OK)
947                        break;
948
949                if (ckfn && ckfn()) {
950                        status = statusCancelled;
951                        goto CancelPsiMonitor;
952                }
953               
954                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
955                        status = statusTimeout;
956                        goto CancelPsiMonitor;
957                }
958        }
959        if (procData.err) {
960                status = statusPSIPError;
961                goto CancelPsiMonitor;
962        }
963
964        err = ParseRrtSection(procData.desc->sectPtr[0], rrtSectPtr);
965
966        if (IsError(err)) {
967                status = statusPSIPError;
968                *rrtSectPtr = NULL;
969        }
970
971CancelPsiMonitor:
972        if (psiCtl) DHL_PSI_StopMonitor(psiCtl);
973        if (procData.desc) DHL_PSI_FreePSIData(procData.desc);
974
975GetSectionExit:
976        DHL_OS_DeleteSemaphore(procData.sema4);
977        return status;
978}
979
980void Dmc_FreeAtscTable(void *tablePtrPtr)
981{
982        // ÀÚµ¿ÀûÀ¸·Î Null setting±îÁö ÇÏ´Â Free API..
983        //
984        //  ex:  Dmc_FreeAtscTable(&mgt);
985        //
986        if (tablePtrPtr == NULL || *(void **)tablePtrPtr == NULL) return; // cafrii 040420
987        FreeAtscTable(*(void **)tablePtrPtr);
988        *(void **)tablePtrPtr = NULL;
989}
990
991
992
993
994// DHL_RESULT MonitorRrt (tDHL_TSD tsd, UINT8 region, tDHL_PSI_Update updateMode, tDHL_PSI_EventProc eventProc,
995//                              UINT32 userParam, tDHL_PSI_ControlHandle *psiCtl)
996
997// ƯÁ¤ regionÀ» ÁöÁ¤ÇÏÁö ¾Ê°í ¸ðµç RRT¸¦ ´Ù monitorÇÏ´Â ÇÔ¼ö·Î¼­
998// ¿©·¯ regionÀÇ rrt¸¦ ´Ù ÇÔ²² ¼ö½ÅÇÒ ¶§ »ç¿ëÇÔ.
999//
1000STATUS Dmc_MonitorRrt(tDHL_TSD tsd, tDHL_PSI_Update updateMode, tDHL_PSI_EventProc eventProc, 
1001                                                UINT32 userParam, tDHL_PSI_ControlHandle *psiCtl)
1002{
1003        tDHL_PSI_Filter *pref;
1004
1005        // Set up the Table ID filter, table id 0xCA
1006        if (DHL_PSI_AllocFilterWithTid(&pref, tid_rating_region_table, TRUE)) {
1007                return statusOutOfResource;
1008        }
1009
1010        // Set up PID Filter
1011        if (DHL_PSI_StartMonitor(tsd,
1012                                                PSIP_BASE_PID,
1013                                                ePSIMODE_SECTION,  // RRT´Â ÇѰ³ÀÇ sectionÀ¸·Î¸¸ ±¸¼ºµÈ´Ù.
1014                                                updateMode,
1015                                                pref,
1016                                                4096,
1017                                                1,
1018                                                eventProc,
1019                                                userParam,
1020                                                psiCtl)) {
1021                DHL_OS_Free((void**)&pref);
1022                return statusOutOfResource;
1023        }
1024
1025        return statusOK;
1026}
1027
1028
1029
1030// cafrii 060306 add
1031
1032#undef MEM_LIMIT
1033#define MEM_LIMIT       0x00004000      // 16K
1034
1035#undef checkMemoryError
1036#define checkMemoryError(p) if (p == NULL) {status = statusOutOfMemory; goto ParseExit;}
1037
1038STATUS Dmc_RestoreRrt(UINT8 *buffer, rrtSectionPtr_t *rrtSectionPtr)
1039{
1040        rrtSectionPtr_t  rrt = NULL;
1041        memChainSetup_t  memSetup = {MEM_LIMIT,NULL,NULL};
1042        memId_t          memId = NULL;
1043        bitBuffer_t      tBits, *bits = &tBits;
1044        INT32            i,j,k;
1045        INT32            count_i,count_j,count_k;
1046        INT32            section_length;
1047        DHL_RESULT          err;
1048        STATUS           status = statusOK;
1049
1050#if 0 // cafrii 080303 avoid using assert
1051        DHL_ASSERT((buffer != NULL), "Dmc_RestoreRrt():bad parameter");
1052#else
1053        if (buffer == NULL)
1054                return statusInvalidArgument;
1055#endif
1056
1057        if (buffer[0] != tid_rating_region_table) {
1058                dprint(0, "!! RRT: invalid marker 0x%x\n", buffer[0]);
1059                status = statusInvalidArgument;
1060                goto ParseExit;
1061        }
1062
1063        section_length = ((buffer[1] & 0x0F) << 8) | buffer[2];
1064
1065        /* initialize the bitBuffer */
1066        bitBufferInitialize(bits, buffer+3, section_length);
1067
1068        /* create the memChain */
1069        err = memChainCreate(&memId,&memSetup);
1070        if (err) {
1071                status = statusOutOfMemory;
1072                goto ParseExit;
1073        }
1074        /* allocate memory for rrtSection */
1075        rrt = (rrtSectionPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(rrtSection_t)+sizeof(memId_t))) + 1);
1076        checkMemoryError(rrt);
1077
1078        /* parse section */
1079        rrt->rating_region  = (rating_region_k) bitBufferGetBits(bits,8);
1080        rrt->version_number = bitBufferGetBits(bits,8);
1081
1082        count_i = rrt->rating_region_name_length = bitBufferGetBits(bits,8);
1083        rrt->rating_region_name = (UINT8 *)memChainAlloc(memId, count_i*sizeof(UINT8));
1084        checkMemoryError(rrt->rating_region_name);
1085        for (i=0; i<count_i; i++) {
1086                rrt->rating_region_name[i] = bitBufferGetBits(bits,8);
1087        }
1088
1089        count_i = rrt->dimensions_defined = bitBufferGetBits(bits,8);
1090        // max 255
1091        rrt->dimension = (rrtDimensionPtr_t)memChainAlloc(memId,count_i*sizeof(rrtDimension_t));
1092        checkMemoryError(rrt->dimension);
1093
1094        for (i=0; i<count_i; i++) 
1095        {
1096                rrtDimensionPtr_t dim = &rrt->dimension[i];
1097                count_j = dim->dimension_name_length    = bitBufferGetBits(bits,8);
1098                dim->dimension_name = (UINT8 *)memChainAlloc(memId, count_j*sizeof(UINT8));
1099                checkMemoryError(dim->dimension_name);
1100                for (j=0; j<count_j; j++) {
1101                        dim->dimension_name[j]          = bitBufferGetBits(bits,8);
1102                }
1103               
1104                dim->graduated_scale                    = bitBufferGetBits(bits,1);
1105                dim->first_value_empty                  = bitBufferGetBits(bits,1);
1106                bitBufferSkipBits(bits,2);      /* reserved */
1107                count_j = dim->values_defined   = bitBufferGetBits(bits,4);
1108                // max 15
1109                dim->value = (rrtValuePtr_t)memChainAlloc(memId,count_j*sizeof(rrtValue_t));
1110                checkMemoryError(dim->value);
1111
1112                for (j=0; j<count_j; j++) 
1113                {
1114                        rrtValuePtr_t value = &dim->value[j];
1115                        value->block_on  = bitBufferGetBits(bits,1);
1116                        bitBufferSkipBits(bits,7);      /* reserved */
1117                       
1118                        count_k = value->abbrev_rating_value_length     = bitBufferGetBits(bits,8);
1119                        value->abbrev_rating_value = (UINT8 *)memChainAlloc(memId, count_k*sizeof(UINT8));
1120                        checkMemoryError(value->abbrev_rating_value);
1121                        for (k=0; k<count_k; k++) {
1122                                value->abbrev_rating_value[k] = bitBufferGetBits(bits,8);
1123                        }
1124
1125                        count_k = value->rating_value_length = bitBufferGetBits(bits,8);
1126                        value->rating_value = (UINT8 *)memChainAlloc(memId, count_k*sizeof(UINT8));
1127                        checkMemoryError(value->rating_value);
1128                        for (k=0; k<count_k; k++) {
1129                                value->rating_value[k] = bitBufferGetBits(bits,8);
1130                        }
1131                }
1132        }
1133
1134        /* parsing complete */
1135        *(((memId_t *)rrt)-1) = memId;
1136        memId = NULL;           /* so memChain not deleted */
1137
1138ParseExit:
1139       
1140        if (memId) {
1141                /* delete the cvctSection memory */
1142                memChainDestroy(memId);
1143        }
1144       
1145        if (bitBufferCheckError(bits))
1146                dprint(0, "!! RestoreRRT bitbuffer overrun, bufsize %d, bit offset %d\n",
1147                                        bits->bufSize, bits->bitOffset);
1148
1149        *rrtSectionPtr = rrt;
1150
1151        return (status);
1152}
1153
1154
1155int Dmc_FlattenRrt(UINT8 *buffer, int bufsize, rrtSectionPtr_t rrt)
1156{
1157        int i, k;
1158        byteBuf_t bt0, *bt = &bt0;
1159        UINT16 length;
1160        UINT8 data;
1161       
1162        if (rrt == NULL)
1163                return 0;
1164               
1165        if (buffer)
1166                byteBufInit(bt, buffer, bufsize);
1167        else
1168                byteBufInit(bt, NULL, 0xFFFF);
1169       
1170        byteBufSet1Byte(bt, 0); // marker´Â ¸Ç ¸¶Áö¸·¿¡..
1171        byteBufSet2Byte(bt, 0); // section_length
1172       
1173        byteBufSet1Byte(bt, rrt->rating_region);
1174        byteBufSet1Byte(bt, rrt->version_number);
1175        byteBufSet1Byte(bt, rrt->rating_region_name_length);
1176        byteBufSetBytesBuf(bt, rrt->rating_region_name, rrt->rating_region_name_length);
1177        byteBufSet1Byte(bt, rrt->dimensions_defined);
1178       
1179        for (i=0; i<rrt->dimensions_defined; i++)
1180        {
1181                rrtDimensionPtr_t dim = &rrt->dimension[i];
1182               
1183                byteBufSet1Byte(bt, dim->dimension_name_length);
1184                byteBufSetBytesBuf(bt, dim->dimension_name, dim->dimension_name_length);
1185                data = 
1186                                (dim->graduated_scale ? 0x80 : 0) |
1187                                (dim->first_value_empty ? 0x40 : 0) |
1188                                (dim->values_defined & 0x0f);
1189                byteBufSet1Byte(bt, data);
1190               
1191                for (k=0; k<dim->values_defined; k++) 
1192                {
1193                        rrtValuePtr_t value = &dim->value[k];
1194                       
1195                        byteBufSet1Byte(bt, value->block_on ? 0x80 : 0);
1196                        byteBufSet1Byte(bt, value->abbrev_rating_value_length);
1197                        byteBufSetBytesBuf(bt, value->abbrev_rating_value, value->abbrev_rating_value_length);
1198                        byteBufSet1Byte(bt, value->rating_value_length);
1199                        byteBufSetBytesBuf(bt, value->rating_value, value->rating_value_length);
1200                }
1201        }
1202       
1203        length = byteBufGetOffset(bt);
1204       
1205        if (buffer) {
1206                byteBufInit(bt, buffer, bufsize);
1207                byteBufSet1Byte(bt, tid_rating_region_table); // marker
1208                byteBufSet2Byte(bt, length); // section_length
1209        }
1210               
1211        return (int)length;
1212}
1213
1214
1215
1216//-------------------------------------------------------------------------
1217
1218#if 0
1219___________()
1220#endif
1221
1222
1223
1224
1225#if 0
1226___________()
1227#endif
1228
1229STATUS Dmc_GetVctAndPat(tDHL_TSD tsd, tvctPtr_t *tvctPtr, cvctPtr_t *cvctPtr, MPEG_PAT **patPtr, 
1230                                                int timeOut, BOOL (*ckfn)(UINT32))
1231{
1232        PSIMultiEventProcData *aProcData;
1233        tDHL_PSI_ControlHandle *aPsiCtl;
1234        DHL_OS_SEMA_ID sema4;
1235        int i, nReceivedTable;
1236        UINT32 tickStart;
1237        //BOOL bDownloadCancelled = FALSE;
1238        DHL_RESULT err;
1239        STATUS status = statusOK;
1240        int timeoutOrg = timeOut; // caller's original timeout
1241        int timeoutAdd = timeoutOrg/2;  // additional time in case of bad signal.
1242       
1243        dprint(1, "Dmc_GetVctAndPat()\n");
1244
1245        if (tvctPtr == NULL && cvctPtr == NULL && patPtr == NULL) {
1246                return statusInvalidArgument;
1247        }
1248
1249        aPsiCtl = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(3 * sizeof(tDHL_PSI_ControlHandle));
1250        if (aPsiCtl == NULL) {
1251                dprint(0, "!! out of memory for PsiCtls..\n");
1252                return statusOutOfMemory;
1253        }
1254        memset (aPsiCtl, 0, 3 * sizeof(tDHL_PSI_ControlHandle));
1255
1256        aProcData = (PSIMultiEventProcData *) DHL_OS_Malloc(3 * sizeof(PSIMultiEventProcData));
1257        if (aProcData == NULL) {
1258                dprint(0, "!! out of memory for ProcData..\n");
1259                DHL_OS_Free((void**)&aPsiCtl);
1260                return statusOutOfMemory;
1261        }
1262        memset (aProcData, 0, 3 * sizeof(PSIMultiEventProcData));
1263       
1264        // semaphoreÀº Çϳª¸¸ ¸¸µé¾î¼­ ¸ðµç ProcData¿¡ ¶È°°ÀÌ ³Ö¾îÁÖÀÚ.
1265        sema4 = DHL_OS_CreateCountingSemaphore("GetVctPat", OS_SEM_FIFO, 0);
1266        if (!sema4) {
1267                DHL_OS_Free((void**)&aPsiCtl);
1268                DHL_OS_Free((void**)&aProcData);
1269                return statusOutOfMemory;
1270        }
1271       
1272        // Event report¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ÁغñÇÑ´Ù.
1273        for (i=0; i<3; i++) {
1274                aProcData[i].err = DHL_OK; // it will be initialized at EventProc..
1275                aProcData[i].sema4 = sema4; // it will be used in EventProc to notify Data arrival
1276                aProcData[i].id = i;        // id for just debugging..
1277        }
1278
1279        // Psi Monitor¸¦ ½ÃÀÛÇÑ´Ù. ¼ö½ÅÇϰíÀÚ ÇÏ´Â Table °¹¼ö¸¸Å­ PsiCtlÀ» »ý¼º ÇØ¾ß ÇÑ´Ù.
1280        err = MonitorTvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[0], &aPsiCtl[0]);
1281        if (err) {
1282                dprint(0, "\t !! MonitorTvct err %d %s\n", err, ErrorString((DHL_RESULT)err));
1283                status = statusOutOfResource;
1284                goto CancelPsiMonitor;
1285        }
1286        err = MonitorCvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[1], &aPsiCtl[1]);
1287        if (err) {
1288                dprint(0, "\t !! MonitorCvct err %d %s\n", err, ErrorString((DHL_RESULT)err));
1289                status = statusOutOfResource;
1290                goto CancelPsiMonitor;
1291        }
1292        if ((err = MonitorPAT(tsd, TRUE /* current */, FALSE /* not eager */,
1293                                                  ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, (UINT32)&aProcData[2], &aPsiCtl[2]))) {
1294                dprint(0, "\t !! MonitorPAT err %d %s\n", err, ErrorString((DHL_RESULT)err));
1295                status = statusOutOfResource;
1296                goto CancelPsiMonitor;
1297        }
1298
1299        tickStart = DHL_OS_GetMsCount();
1300        nReceivedTable = 0;
1301        while (1) {
1302                // ÃÑ nEit °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù.
1303                //
1304                err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK);
1305               
1306                if (err == DHL_OK) {
1307                        int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000;  // unit: 0.01 sec
1308                        //nReceivedTable++; // cafrii 070117 change policy!!
1309
1310                        // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù.
1311                        //
1312                        if ((aProcData[0].id & PME_MASK) == PME_SEND) {  // TVCT
1313                                nReceivedTable++; // cafrii 070117 change policy!!
1314                                aProcData[0].id |= PME_CNFM;             //  ¿¡·¯¿¡ »ó°ü¾øÀÌ download flag¸¦ set.
1315                                if (aProcData[0].err == DHL_OK) {
1316                                        if (tvctPtr) {
1317                                                err = ParseTvct(aProcData[0].desc->sectPtr, tvctPtr);
1318                                                if (IsError(err))
1319                                                        *tvctPtr = NULL; // cafrii 050315 add
1320                                        }
1321                                        dprint(2, "\t TVCT received (err %d) %d.%02d sec -> %x\n", 
1322                                                        aProcData[0].err, elapsedTime/100, elapsedTime%100, tvctPtr);
1323                                        DHL_PSI_FreePSIData(aProcData[0].desc);
1324                                }
1325                        }
1326                        else if ((aProcData[1].id & PME_MASK) == PME_SEND) {  // CVCT
1327                                nReceivedTable++; // cafrii 070117 change policy!!
1328                                aProcData[1].id |= PME_CNFM;
1329                                if (aProcData[1].err == DHL_OK) {
1330                                        if (cvctPtr) {
1331                                                err = ParseCvct(aProcData[1].desc->sectPtr, cvctPtr);
1332                                                if (IsError(err))
1333                                                        *cvctPtr = NULL; // cafrii 050315 add
1334                                        }
1335                                        dprint(2, "\t CVCT received (err %d) %d.%02d sec -> %x\n", 
1336                                                        aProcData[1].err, elapsedTime/100, elapsedTime%100, cvctPtr);
1337                                        DHL_PSI_FreePSIData(aProcData[1].desc);
1338                                }
1339                        }
1340                        else if ((aProcData[2].id & PME_MASK) == PME_SEND) {  // PAT
1341                                nReceivedTable++; // cafrii 070117 change policy!!
1342                                aProcData[2].id |= PME_CNFM;
1343                                if (aProcData[2].err == DHL_OK) {
1344                                        if (patPtr) {
1345                                                err = ParsePAT(aProcData[2].desc, patPtr);
1346                                                if (IsError(err))
1347                                                        *patPtr = NULL; // cafrii 050315 add
1348                                        }
1349                                        dprint(2, "\t PAT received (err %d) %d.%02d sec -> %x\n", 
1350                                                        aProcData[2].err, elapsedTime/100, elapsedTime%100, patPtr);
1351                                        DHL_PSI_FreePSIData(aProcData[2].desc);
1352                                }
1353                        }
1354                        // cafrii 070117 add
1355                        else {
1356                                for (i=0; i<3; i++) {  // TVCT, CVCT, PAT¿¡ ´ëÇØ¼­ bad packet ó¸®.
1357                                        if ((aProcData[i].id & PME_EV_SEND_BADPKT) &&
1358                                                (aProcData[i].id & PME_EV_CNFM_BADPKT) == 0) {
1359                                                aProcData[i].id |= PME_EV_CNFM_BADPKT;
1360                                                if (timeOut < timeoutOrg + timeoutAdd) {
1361                                                        timeOut = timeoutOrg + timeoutAdd;
1362                                                        dprint(2, "\t  timeout increased by badpkt\n");
1363                                                }
1364                                        }
1365                                }
1366                        }
1367                       
1368                }
1369                // ·çÇÁ Á¾·á Á¶°Ç.. tvct/cvct µÑ Áß¿¡ Çϳª¶û, pat°¡ ¼ö½ÅµÇ¸é Á¾·á..
1370                // ¸¸¾à ÇÔ¼ö ÀÎÀÚ·Î NULLÀ» ÁöÁ¤Çß´Ù¸é ¼ö½ÅÀÇ Àǻ簡 ¾ø´Â °ÍÀ̹ǷΠ±× tableÀº üũÇÏÁö ¾Ê´Â´Ù.
1371                //
1372                if (patPtr && (aProcData[2].id & PME_CNFM) == 0) {
1373                        // pat should be downloaded, but not yet..
1374                        // patPtrÀ» non-Null·Î ÁöÁ¤Çϸé PAT´Â ²À ¹Þ¾Æ¾ß ÇÑ´Ù. ´õ ±â´Ù¸®ÀÚ..
1375                }
1376                else { 
1377                        // pat´Â ¼ö½ÅÀÌ µÇ¾ú°Å³ª ¼ö½ÅÇÒ Çʿ䰡 ¾ø´Â °æ¿ì.. ÀÌÁ¦ vctµéÀ» üũÇÑ´Ù.
1378                        //
1379                        if ((aProcData[0].id & PME_CNFM) || (aProcData[1].id & PME_CNFM)) {
1380                                // VCT µÑ Áß Çϳª°¡ ¼ö½ÅµÇ¾úÀ¸¹Ç·Î OK..
1381                                // ÁÖÀÇ! pat´Â ¼ö½ÅÀÌ ¾ÈµÇ¾úÀ» ¼öµµ ÀÖ´Ù.. ±×·± °æ¿ì¶ó¸é patPtrÀÌ NULLÀÎ °æ¿ìÀÌ´Ù.
1382                                dprint(2, "xVCT and PAT, %d tables received OK\n", nReceivedTable);
1383                                break;
1384                        }
1385                        // vct µÑ´Ù ¾ÆÁ÷ ¼ö½ÅÀÌ ¾ÈµÈ °æ¿ì..
1386                        // ±×·¯³ª ¸¸¾à caller°¡ tvctPtr, cvctPtrÀ» NULL·Î ÁöÁ¤ÇÑ °æ¿ì¶ó¸é ¹ÞÀ» Àǻ簡 ¾ø´Â
1387                        // °ÍÀ̹ǷΠ´õ ±â´Ù¸± Çʿ䰡 ¾ø´Ù.
1388                        if (cvctPtr == NULL && tvctPtr == NULL) {
1389                                dprint(2, "VCT no need to download.. OK\n");
1390                                break;
1391                        }
1392                }
1393               
1394                if (ckfn && ckfn(0)) {
1395                        // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù.
1396                        dprint(2, "!! download cancelled\n");
1397                        status = statusCancelled;
1398                        break;
1399                }
1400               
1401                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
1402                        // ¿©·¯°³ÀÇ tableÀ» ¹Þ°í ÀÖÀ¸¹Ç·Î °³°³ tableÀÇ timeoutÀº ¹«ÀǹÌ
1403                        //status = statusTimeout;
1404                        dprint(2, "!! timeout (%ds) err, only %d/%d tables received..\n", timeOut/1000, 
1405                                                nReceivedTable, 3);
1406                        break;
1407                }
1408        } // while
1409       
1410       
1411CancelPsiMonitor:
1412        for (i=0; i<3; i++) {
1413                if (aPsiCtl[i])
1414                        DHL_PSI_StopMonitor(aPsiCtl[i]); 
1415        }
1416        if (aPsiCtl) DHL_OS_Free((void**)&aPsiCtl);
1417        if (aProcData) DHL_OS_Free((void**)&aProcData);
1418
1419        if (sema4)
1420                DHL_OS_DeleteSemaphore(sema4);
1421       
1422        //
1423        // caller´Â °¢ table pointerµéÀ» °Ë»çÇØ¼­ ¿¡·¯ À¯¹«¸¦ Ã¼Å©ÇØ¾ß ÇÑ´Ù.
1424        // ÀϺΠtableµé¿¡¼­ timeout error°¡ ¹ß»ýÇß´õ¶óµµ, ¸î°³¸¸ ¹ÞÀ¸¸é °è¼Ó ÁøÇàÇÒ ¼ö´Â ÀÖ´Ù.
1425        // (¿¹: VCT°¡ ¾ø¾îµµ PAT·Î ÁøÇà °¡´É)
1426        //
1427        return status;
1428}
1429
1430
1431//
1432// Tvct¿Í Cvct µÑ Áß Çϳª ¸ÕÀú ¿À´Â °ÍÀ» ¹Þ¾Æ¼­ Xvct·Î ¸®ÅÏÇÏ´Â ÇÔ¼ö
1433//
1434STATUS Dmc_GetXvct(tDHL_TSD tsd, xvctPtr_t *xvctPtr, int timeOut, BOOL (*ckfn)(UINT32))
1435{
1436        PSIMultiEventProcData *aProcData;
1437        tDHL_PSI_ControlHandle *aPsiCtl;
1438        DHL_OS_SEMA_ID sema4;
1439        int i, nReceivedTable;
1440        UINT32 tickStart;
1441        DHL_RESULT err;
1442        STATUS status = statusOK;
1443       
1444        tvctPtr_t tvct = NULL;
1445        cvctPtr_t cvct = NULL;
1446       
1447        dprint(1, "Dmc_GetXvct()\n");
1448        if (xvctPtr == NULL) {
1449                return statusInvalidArgument;
1450        }
1451
1452        aPsiCtl = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(2 * sizeof(tDHL_PSI_ControlHandle));
1453        if (aPsiCtl == NULL) {
1454                dprint(0, "!! out of memory for PsiCtls..\n");
1455                return statusOutOfMemory;
1456        }
1457        memset (aPsiCtl, 0, 2 * sizeof(tDHL_PSI_ControlHandle));
1458
1459        aProcData = (PSIMultiEventProcData *) DHL_OS_Malloc(2 * sizeof(PSIMultiEventProcData));
1460        if (aProcData == NULL) {
1461                dprint(0, "!! out of memory for ProcData..\n");
1462                DHL_OS_Free((void**)&aPsiCtl);
1463                return statusOutOfMemory;
1464        }
1465        memset (aProcData, 0, 2 * sizeof(PSIMultiEventProcData));
1466       
1467        // semaphoreÀº Çϳª¸¸ ¸¸µé¾î¼­ ¸ðµç ProcData¿¡ ¶È°°ÀÌ ³Ö¾îÁÖÀÚ.
1468        sema4 = DHL_OS_CreateCountingSemaphore("GetXVct", OS_SEM_FIFO, 0);
1469        if (!sema4) {
1470                DHL_OS_Free((void**)&aPsiCtl);
1471                DHL_OS_Free((void**)&aProcData);
1472                return statusOutOfMemory;
1473        }
1474       
1475        // Event report¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ÁغñÇÑ´Ù.
1476        for (i=0; i<2; i++) {
1477                aProcData[i].err = DHL_OK; // it will be initialized at EventProc..
1478                aProcData[i].sema4 = sema4; // it will be used in EventProc to notify Data arrival
1479                aProcData[i].id = i;        // id for just debugging..
1480        }
1481
1482        // Psi Monitor¸¦ ½ÃÀÛÇÑ´Ù. ¼ö½ÅÇϰíÀÚ ÇÏ´Â Table °¹¼ö¸¸Å­ PsiCtlÀ» »ý¼º ÇØ¾ß ÇÑ´Ù.
1483        err = MonitorTvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc,
1484                                                (UINT32)&aProcData[0], &aPsiCtl[0]);
1485        if (err) {
1486                dprint(0, "\t !! MonitorTvct err %d %s\n", err, ErrorString(err));
1487                status = statusOutOfResource;
1488                goto CancelPsiMonitor;
1489        }
1490        err = MonitorCvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, 
1491                                                (UINT32)&aProcData[1], &aPsiCtl[1]);
1492        if (err) {
1493                dprint(0, "\t !! MonitorCvct err %d %s\n", err, ErrorString(err));
1494                status = statusOutOfResource;
1495                goto CancelPsiMonitor;
1496        }
1497
1498        tickStart = DHL_OS_GetMsCount();
1499        nReceivedTable = 0;
1500        while (1) {
1501                // ÃÑ 2 °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù.
1502                //
1503                err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK);
1504               
1505                if (err == DHL_OK) 
1506                {
1507                        int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000;  // unit: 0.01 sec
1508                        //nReceivedTable++; // cafrii 070117 change policy!!
1509                       
1510                        // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù.
1511                        //
1512                        if ((aProcData[0].id & PME_MASK) == PME_SEND) {  // TVCT
1513                                nReceivedTable++; // cafrii 070117 change policy!!
1514                                aProcData[0].id |= PME_CNFM;             //  ¿¡·¯¿¡ »ó°ü¾øÀÌ download flag¸¦ set.
1515                                if (aProcData[0].err == DHL_OK) {
1516                                        err = ParseTvct(aProcData[0].desc->sectPtr, &tvct);
1517                                        if (IsError(err)) {
1518                                                tvct = NULL; // cafrii 050315 add
1519                                                status = statusPSIPError;
1520                                        }
1521                                        dprint(2, "\t TVCT received (err %d) %d.%02d sec -> %x\n", 
1522                                                        aProcData[0].err, elapsedTime/100, elapsedTime%100, tvct);
1523                                        DHL_PSI_FreePSIData(aProcData[0].desc);
1524                                }
1525                                else
1526                                        status = statusPSIPError;
1527                        }
1528                        else if ((aProcData[1].id & PME_MASK) == PME_SEND) {  // CVCT
1529                                nReceivedTable++; // cafrii 070117 change policy!!
1530                                aProcData[1].id |= PME_CNFM;
1531                                if (aProcData[1].err == DHL_OK) {
1532                                        err = ParseCvct(aProcData[1].desc->sectPtr, &cvct);
1533                                        if (IsError(err)) {
1534                                                cvct = NULL; // cafrii 050315 add
1535                                                status = statusPSIPError;
1536                                        }
1537                                        dprint(2, "\t CVCT received (err %d) %d.%02d sec -> %x\n", 
1538                                                        aProcData[1].err, elapsedTime/100, elapsedTime%100, cvct);
1539                                        DHL_PSI_FreePSIData(aProcData[1].desc);
1540                                }
1541                                else
1542                                        status = statusPSIPError;
1543                        }
1544                }
1545                // ·çÇÁ Á¾·á Á¶°Ç.. tvct/cvct µÑ Áß¿¡ Çϳª°¡ ¼ö½ÅµÇ¸é Á¾·á..
1546                // ¸¸¾à ÇÔ¼ö ÀÎÀÚ·Î NULLÀ» ÁöÁ¤Çß´Ù¸é ¼ö½ÅÀÇ Àǻ簡 ¾ø´Â °ÍÀ̹ǷΠ±× tableÀº üũÇÏÁö ¾Ê´Â´Ù.
1547                //
1548                // µÎ tableÀÌ µ¿½Ã¿¡ ¼ö½ÅµÉ °æ¿ì CVCT¿¡ ¿ì¼±±ÇÀ» ÁÖ±â À§ÇØ ¼ø¼­ º¯°æ
1549                //
1550                if (aProcData[1].id & PME_CNFM) {  // CVCT ¼ö½Å
1551                        dprint(2, "CVCT received OK, total %d\n", nReceivedTable);
1552                        if (cvct) {
1553                                status = Dmc_TranslateCvct(cvct, xvctPtr);
1554                                if (status)
1555                                        *xvctPtr = NULL;
1556                        }
1557                        else
1558                                *xvctPtr = NULL;
1559                        break;  // ´õÀÌ»ó üũÇÏÁö ¾Ê°í ¿©±â¼­ loop-out
1560                }
1561                if (aProcData[0].id & PME_CNFM) {  // TVCT ¼ö½Å
1562                        dprint(2, "TVCT received OK, total %d\n", nReceivedTable);
1563                        if (tvct) {
1564                                status = Dmc_TranslateTvct(tvct, xvctPtr);
1565                                if (status)
1566                                        *xvctPtr = NULL;
1567                        }
1568                        else
1569                                *xvctPtr = NULL;
1570                        break; 
1571                }
1572               
1573                if (ckfn && ckfn(0)) {
1574                        // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù.
1575                        dprint(2, "!! download cancelled\n");
1576                        status = statusCancelled;
1577                        break;
1578                }
1579               
1580                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
1581                        // TVCT/CVCT µÑ Áß¿¡ Çϳª´Â ²À ¹Þ¾ÆÁ®¾ß ÇÑ´Ù.
1582                        status = statusTimeout;
1583                        dprint(2, "!! timeout (%ds) err, only %d/%d tables received..\n", timeOut/1000, 
1584                                                nReceivedTable, 2);
1585                        break;
1586                }
1587        } // while
1588       
1589       
1590CancelPsiMonitor:
1591        for (i=0; i<2; i++) {
1592                if (aPsiCtl[i])
1593                        DHL_PSI_StopMonitor(aPsiCtl[i]); 
1594        }
1595        DHL_OS_Free((void**)&aPsiCtl);
1596        DHL_OS_Free((void**)&aProcData);
1597
1598        if (sema4)
1599                DHL_OS_DeleteSemaphore(sema4);
1600       
1601        Dmc_FreeAtscTable(&tvct);
1602        Dmc_FreeAtscTable(&cvct);
1603       
1604        // cafrii 050713 add
1605        if (*xvctPtr == NULL && status == statusOK)
1606                status = statusPSIPError;  // Ưº°ÇÑ ÀÌÀ¯µµ ¾ø´Âµ¥ vct¸¦ ¸ø¹ÞÀº °æ¿ì??
1607       
1608        return status;
1609}
1610
1611
1612
1613
1614#if 0
1615___________()
1616#endif
1617
1618
1619//------------------------------------
1620// MainChannelTable °ü·Ã ±â´É
1621//
1622// MainChannelTable À̶õ TVCT, CVCT, PAT, PMTµéÀ» ¸»ÇÏ´Â °ÍÀ¸·Î
1623// Autoscan °úÁ¤¿¡¼­ ÀÌ Å×À̺íÀ» ÇѲ¨¹ø¿¡ ¼ö½ÅÇÏ´Â ±â´ÉÀ» ¼öÇàÇÑ´Ù.
1624//
1625// cafrii 041129 add
1626//
1627
1628void Dmc_FreeMainChannelTables(DmcMainTables *tbls)
1629{
1630        int i;
1631       
1632        if (tbls == NULL) return;
1633       
1634        Dmc_FreeAtscTable(&tbls->tvct);
1635        Dmc_FreeAtscTable(&tbls->cvct);
1636       
1637        Dmc_FreeAtscTable(&tbls->pat);
1638
1639        for (i=0; tbls->pmtList && i<tbls->num_programs; i++) {
1640                Dmc_FreeAtscTable(&tbls->pmtList[i]);
1641        }
1642        DHL_OS_Free((void**)&tbls->pmtList);
1643       
1644}
1645
1646
1647#define  MCTID_TVCT  0
1648#define  MCTID_CVCT  1
1649#define  MCTID_PAT   2
1650
1651STATUS Dmc_GetMainChannelTables(tDHL_TSD tsd, DmcMainTables *tbls, int timeOut, BOOL (*ckfn)(UINT32))
1652{
1653        PSIMultiEventProcData *aProcData;
1654        tDHL_PSI_ControlHandle *aPsiCtl;
1655
1656        PSIMultiEventProcData *aProcDataPmt = NULL;
1657        tDHL_PSI_ControlHandle *aPsiCtlPmt = NULL;
1658       
1659        DHL_OS_SEMA_ID        sema4;
1660       
1661        DHL_RESULT err;
1662        STATUS status = statusOK;
1663       
1664        int i, k, nReceivedTable;
1665        UINT32 tickStart;
1666       
1667        int  elapsedTime;
1668        BOOL bPsiCompleted;
1669       
1670        int nMonitors = 0; // cafrii 060119 add
1671        int idxPmt = 0;  // cafrii 060726 add, pmt ¸ð´ÏÅÍ index
1672        UINT16 pid;
1673
1674        int timeoutOrg = timeOut;
1675        int timeoutAdd = timeOut/2; // additional time in case of bad signal
1676
1677        BOOL bNewMonitorStarted = FALSE; // cafrii 070117 add
1678        BOOL bProcessed;
1679       
1680        dprint(1, "Dmc_GetMainChannelTables()\n");
1681        if (tbls == NULL) {
1682                return statusInvalidArgument;
1683        }
1684       
1685        memset(tbls, 0, sizeof(DmcMainTables));
1686
1687        aPsiCtl = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(3 * sizeof(tDHL_PSI_ControlHandle));
1688        if (aPsiCtl == NULL) {
1689                dprint(0, "!! out of memory for PsiCtls..\n");
1690                return statusOutOfMemory;
1691        }
1692        memset (aPsiCtl, 0, 3 * sizeof(tDHL_PSI_ControlHandle));
1693
1694        aProcData = (PSIMultiEventProcData *) DHL_OS_Malloc(3 * sizeof(PSIMultiEventProcData));
1695        if (aProcData == NULL) {
1696                dprint(0, "!! out of memory for ProcData..\n");
1697                DHL_OS_Free((void**)&aPsiCtl);
1698                return statusOutOfMemory;
1699        }
1700        memset (aProcData, 0, 3 * sizeof(PSIMultiEventProcData));
1701       
1702        // semaphoreÀº Çϳª¸¸ ¸¸µé¾î¼­ ¸ðµç ProcData¿¡ ¶È°°ÀÌ ³Ö¾îÁÖÀÚ.
1703        sema4 = DHL_OS_CreateCountingSemaphore("GetMainTbls", OS_SEM_FIFO, 0);
1704        if (!sema4) {
1705                DHL_OS_Free((void**)&aPsiCtl);
1706                DHL_OS_Free((void**)&aProcData);
1707                return statusOutOfMemory;
1708        }
1709       
1710        // Event report¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ÁغñÇÑ´Ù.
1711        for (i=0; i<3; i++) {
1712                aProcData[i].err = DHL_OK; // it will be initialized at EventProc..
1713                aProcData[i].sema4 = sema4; // it will be used in EventProc to notify Data arrival
1714                aProcData[i].id = i;        // id for just debugging..
1715        }
1716
1717        // Psi Monitor¸¦ ½ÃÀÛÇÑ´Ù. ¼ö½ÅÇϰíÀÚ ÇÏ´Â Table °¹¼ö¸¸Å­ PsiCtlÀ» »ý¼º ÇØ¾ß ÇÑ´Ù.
1718        //
1719        // ------- TVCT ----------
1720        // id : 0
1721        err = MonitorTvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, 
1722                                                        (UINT32)&aProcData[MCTID_TVCT], &aPsiCtl[MCTID_TVCT]);
1723        if (err) {
1724                dprint(0, "\t !! MonitorTvct err %d %s\n", err, ErrorString((DHL_RESULT)err));
1725                status = statusOutOfResource;
1726                goto CancelPsiMonitor;
1727        }
1728        nMonitors++;
1729        // ------- CVCT ----------
1730        // id : 1
1731        err = MonitorCvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, 
1732                                                        (UINT32)&aProcData[MCTID_CVCT], &aPsiCtl[MCTID_CVCT]);
1733        if (err) {
1734                dprint(0, "\t !! MonitorCvct err %d %s\n", err, ErrorString((DHL_RESULT)err));
1735                status = statusOutOfResource;
1736                goto CancelPsiMonitor;
1737        }
1738        nMonitors++;
1739        // ------- PAT ----------
1740        // id : 2
1741        if ((err = MonitorPAT(tsd, TRUE /* current */, FALSE /* not eager */,
1742                                                  ePSIUPDATE_ONESHOT, _Dmc_MultiEventProc, 
1743                                                  (UINT32)&aProcData[MCTID_PAT], &aPsiCtl[MCTID_PAT]))) {
1744                dprint(0, "\t !! MonitorPAT err %d %s\n", err, ErrorString((DHL_RESULT)err));
1745                status = statusOutOfResource;
1746                goto CancelPsiMonitor;
1747        }
1748        nMonitors++;
1749       
1750        // ------- PMT ----------
1751        // id 3 ~ 3+pat->numPrograms-1
1752        //
1753        // ÇöÀç´Â ÁøÇà ºÒ°¡.. PMT PID¸¦ ¾Ë¾Æ¾ß Çϱ⠶§¹®..
1754
1755        tickStart = DHL_OS_GetMsCount();
1756        nReceivedTable = 0;
1757        while (1) {
1758                // ÃÑ 3 ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù.
1759                //
1760                err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK);
1761               
1762                if (err) 
1763                        goto label_check;
1764                       
1765                elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000;  // unit: 0.01 sec
1766                bProcessed = FALSE;
1767
1768                // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù.
1769                //
1770                if ((aProcData[MCTID_TVCT].id & PME_MASK) == PME_SEND)   //----------  TVCT
1771                {
1772                        nReceivedTable++;
1773                        aProcData[MCTID_TVCT].id |= PME_CNFM;          //  ¿¡·¯¿¡ »ó°ü¾øÀÌ download flag¸¦ set.
1774                        if (aProcData[MCTID_TVCT].err == DHL_OK) 
1775                        {
1776                                err = ParseTvct(aProcData[MCTID_TVCT].desc->sectPtr, &tbls->tvct);
1777                                if (IsError(err)) {
1778                                        tbls->tvct = NULL; // cafrii 050315 add
1779                                        status = statusPSIPError;
1780                                }
1781                                dprint(2, "\t TVCT received (err %d) %d.%02d sec -> %x\n", 
1782                                                aProcData[MCTID_TVCT].err, elapsedTime/100, elapsedTime%100, tbls->tvct);
1783                                DHL_PSI_FreePSIData(aProcData[MCTID_TVCT].desc);
1784                                bProcessed = TRUE;
1785
1786                                // cafrii 081021 add. if we free monitor asap, performance will improved.
1787                                DHL_PSI_StopMonitor(aPsiCtl[MCTID_TVCT]);
1788                                aPsiCtl[MCTID_TVCT] = 0;
1789                                nMonitors--;
1790                        }
1791                        else
1792                                dprint(0, "!! TVCT received err\n");
1793                }
1794                else if ((aProcData[MCTID_CVCT].id & PME_MASK) == PME_SEND)   //--------- CVCT
1795                {
1796                        nReceivedTable++;
1797                        aProcData[MCTID_CVCT].id |= PME_CNFM;
1798                        if (aProcData[MCTID_CVCT].err == DHL_OK) 
1799                        {
1800                                err = ParseCvct(aProcData[MCTID_CVCT].desc->sectPtr, &tbls->cvct);
1801                                if (IsError(err)) {
1802                                        tbls->cvct = NULL; // cafrii 050315 add
1803                                        status = statusPSIPError;
1804                                }
1805                                dprint(2, "\t CVCT received (err %d) %d.%02d sec -> %x\n", 
1806                                                aProcData[0].err, elapsedTime/100, elapsedTime%100, tbls->cvct);
1807                                DHL_PSI_FreePSIData(aProcData[MCTID_CVCT].desc);
1808                                bProcessed = TRUE;
1809
1810                                // cafrii 081021 add. if we free monitor asap, performance will improved.
1811                                DHL_PSI_StopMonitor(aPsiCtl[MCTID_CVCT]);
1812                                aPsiCtl[MCTID_CVCT] = 0;
1813                                nMonitors--;
1814                        }
1815                        else
1816                                dprint(0, "!! CVCT received err\n");
1817                }
1818                else if ((aProcData[MCTID_PAT].id & PME_MASK) == PME_SEND)   //---------- PAT
1819                {
1820                        nReceivedTable++;
1821                        aProcData[MCTID_PAT].id |= PME_CNFM;
1822                        if (aProcData[MCTID_PAT].err == DHL_OK) 
1823                        {
1824                                err = ParsePAT(aProcData[MCTID_PAT].desc, &tbls->pat);
1825                                if (IsError(err)) {
1826                                        tbls->pat = NULL; // cafrii 050315 add
1827                                        status = statusPSIPError;
1828                                }
1829                                dprint(2, "\t PAT received (err %d) %d.%02d sec -> %x\n", 
1830                                                aProcData[MCTID_PAT].err, elapsedTime/100, elapsedTime%100, tbls->pat);
1831                                DHL_PSI_FreePSIData(aProcData[MCTID_PAT].desc);
1832                               
1833                                if (tbls->pat) {
1834                                        tbls->num_programs = tbls->pat->numPrograms;
1835                                        dprint(2, "\t   num programs in PAT : %d\n", tbls->num_programs);
1836                                       
1837                                        if (dprintable(3))
1838                                                PrintPAT(tbls->pat); // cafrii 050707 add
1839                                }
1840                                bProcessed = TRUE;
1841
1842                                // cafrii 081021 add. if we free monitor asap, performance will improved.
1843                                DHL_PSI_StopMonitor(aPsiCtl[MCTID_PAT]);
1844                                aPsiCtl[MCTID_PAT] = 0;
1845                                nMonitors--;
1846
1847                        }
1848                        else
1849                                dprint(0, "!! PAT received err\n");
1850                               
1851                        // PAT¸¦ ´Ù¿î·Îµå ¹ÞÀº ±× ¼ø°£¿¡¸¸ Çѹø PMT ¸ð´ÏÅ͸¦ ½ÃÀÛÇÑ´Ù.
1852                        //  ¸ð´ÏÅÍ ±¸µ¿ Áß¿¡ ¿¡·¯°¡ ¹ß»ýÇÒ °æ¿ì retry¸¦ ÇÏÁö ¾Ê´Â´Ù.
1853                        //
1854                        if (tbls->num_programs > 0) 
1855                        {
1856                                // »õ·Ó°Ô PMT ¸ð´ÏÅ͸¦ ½ÃÀÛÇÑ´Ù..
1857                                bNewMonitorStarted = FALSE;
1858
1859                                aPsiCtlPmt = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(tbls->num_programs * sizeof(tDHL_PSI_ControlHandle));
1860                                if (aPsiCtlPmt == NULL) {
1861                                        dprint(0, "!! out of memory for aPsiCtlPmt..\n");
1862                                        goto label_check;
1863                                }
1864                                memset (aPsiCtlPmt, 0, tbls->num_programs * sizeof(tDHL_PSI_ControlHandle));
1865
1866                                aProcDataPmt = (PSIMultiEventProcData *) DHL_OS_Malloc(tbls->num_programs * sizeof(PSIMultiEventProcData));
1867                                if (aProcDataPmt == NULL) {
1868                                        dprint(0, "!! out of memory for aProcDataPmt..\n");
1869                                        DHL_OS_Free((void**)&aPsiCtlPmt);
1870                                        goto label_check;
1871                                }
1872                                memset (aProcDataPmt, 0, tbls->num_programs * sizeof(PSIMultiEventProcData));
1873                               
1874                                tbls->pmtList = (MPEG_PMT **) DHL_OS_Malloc(tbls->num_programs * sizeof(MPEG_PMT *));
1875                                if (tbls->pmtList == NULL) {
1876                                        dprint(0, "!! out of memory for pmtList..\n");
1877                                        DHL_OS_Free((void**)&aPsiCtlPmt);
1878                                        DHL_OS_Free((void**)&aProcDataPmt);
1879                                        goto label_check;
1880                                }
1881                                memset (tbls->pmtList, 0, tbls->num_programs * sizeof(MPEG_PMT *));
1882                               
1883                                for (idxPmt=0; idxPmt<tbls->num_programs; idxPmt++) 
1884                                {
1885                                        pid = tbls->pat->programs[idxPmt].program_map_PID;
1886                                       
1887                                        if (pid <= 0 || pid >= 0x1FFF) { // cafrii 050315 add
1888                                                dprint(0, "!! pmt[%d] pid 0x%x invalid\n", idxPmt, pid);
1889                                                continue;
1890                                        }
1891                                       
1892                                        // cafrii 060119 add
1893                                        if (nMonitors >= gMaxTableMonitorsAtOneTime) {
1894                                                dprint(2, "\t max %d tables monitored.\n", nMonitors);
1895                                                break;
1896                                        }
1897                                       
1898                                        aProcDataPmt[idxPmt].err = DHL_OK;
1899                                        aProcDataPmt[idxPmt].sema4 = sema4;
1900                                        aProcDataPmt[idxPmt].id = 0x10 + idxPmt;   // PMTÀÇ id´Â 0x10 + pmt index ÀÌ´Ù.
1901                                       
1902                                        if ((err = MonitorPMT(tsd, 
1903                                                                        pid, 
1904                                                                        tbls->pat->programs[idxPmt].program_number,
1905                                                                        TRUE /* current */, 
1906                                                                        ePSIUPDATE_ONESHOT, 
1907                                                                        _Dmc_MultiEventProc, 
1908                                                                        (UINT32)&aProcDataPmt[idxPmt], 
1909                                                                        &aPsiCtlPmt[idxPmt]))) 
1910                                        {
1911                                                // cafrii 081007 add
1912                                                if (err == DHL_FAIL_OUT_OF_RESOURCE || err == DHL_FAIL_OUT_OF_MEMORY) {
1913                                                        dprint(2, "\t stop monitor pmt, at idx %d\n", idxPmt);
1914                                                        break;
1915                                                }
1916                                                else
1917                                                        dprint(0, "\t !! MonitorPMT[%d] err %d %s\n", idxPmt, err, 
1918                                                                        ErrorString((DHL_RESULT)err));
1919                                        }
1920                                        else {
1921                                                bNewMonitorStarted = TRUE;
1922                                                nMonitors++;
1923                                                dprint(2, "\t  MonitorPMT[%d] pn %d, pid %d success (%d monitors total)\n", 
1924                                                                idxPmt, tbls->pat->programs[idxPmt].program_number,
1925                                                                tbls->pat->programs[idxPmt].program_map_PID, nMonitors);
1926                                        }
1927                                }
1928
1929                                // pat°¡ ¼ö½ÅµÇ´Â ½Ã°£ µ¿¾È pmtµéÀº timeout¿¡¼­ ¼ÕÇØ¸¦ ºÃ±â ¶§¹®¿¡
1930                                // ´Ù½Ã timeoutÀ» Á¶Á¤ÇÑ´Ù. ÇöÀç ½ÃÁ¡À¸·ÎºÎÅÍ ´Ù½Ã timeoutÀ» ¿¬Àå..
1931                                //
1932                                if (bNewMonitorStarted) {
1933                                        timeOut = DHL_OS_GetMsCount() + timeoutOrg - tickStart;
1934                                        dprint(2, "\t  timeout adjusted to %u tick by pat rx\n", timeOut);
1935                                }
1936                        }
1937                }
1938
1939                // Ç×»ó ÀÌ blockÀÌ ½ÇÇà µÉ ¼ö ÀÖµµ·Ï ÇÔ.
1940                //else if (aProcDataPmt)      //---------- PMT
1941                if (aProcDataPmt)
1942                {
1943                        // PAT °¡ ¼ö½ÅÀÌ ÀÌ¹Ì µÇ¾î¼­ Pmt list °¡ ¸¸µé¾îÁ® ÀÖ´Â °æ¿ì¿¡¸¸ üũ °¡´É..
1944                        //
1945                        for (k=0; k<tbls->num_programs; k++)
1946                        {
1947                                if ((aProcDataPmt[k].id & PME_MASK) != PME_SEND)
1948                                        continue;
1949
1950                                nReceivedTable++;
1951                                aProcDataPmt[k].id |= PME_CNFM;
1952                               
1953                                dprint(3, "\t PMT[%d] received\n", k);
1954                               
1955                                if (aProcDataPmt[k].err == DHL_OK) 
1956                                {
1957                                        err = ParsePMT(aProcDataPmt[k].desc, &tbls->pmtList[k]);
1958                                        if (IsError(err)) {
1959                                                tbls->pmtList[k] = NULL; // cafrii 050315 add
1960                                                status = statusPSIPError;
1961                                        }
1962                                        dprint(2, "\t PMT[%d] received (err %d) %d.%02d sec -> %x\n", 
1963                                                        k, aProcDataPmt[k].err, elapsedTime/100, elapsedTime%100, tbls->pmtList[k]);
1964                                                       
1965                                        if (dprintable(3))
1966                                                PrintPMT(tbls->pmtList[k]); // cafrii 050707 add
1967                                       
1968                                        dprint(3, "\t free PSI data 0x%x\n", aProcDataPmt[k].desc);
1969                                        DHL_PSI_FreePSIData(aProcDataPmt[k].desc);
1970                                }
1971                                else
1972                                        dprint(0, "!! PMT[%d] received err\n", k);
1973                               
1974                                bProcessed = TRUE;
1975
1976                                // cafrii 060726 add dynamic delete and re-monitor
1977                                // pmtÇϳª°¡ ¹Þ¾ÆÁö¸é ³²Àº psifilter·Î ´Ù½Ã pmt ¸ð´ÏÅÍ ½ÃÀÛ.
1978                                //
1979
1980                        #if DEVELOPMENT_BUILD // cafrii 080303 avoid using assert
1981                                DHL_ASSERT(aPsiCtlPmt[k], "null pmtpsictl?"); 
1982                        #else
1983                                if (aPsiCtlPmt[k] == (tDHL_PSI_ControlHandle)0)
1984                                        dprint(0, "%s: null pmtpsictl[%d]?\n", __FUNCTION__, k);
1985                        #endif
1986                       
1987                                DHL_PSI_StopMonitor(aPsiCtlPmt[k]);
1988                                aPsiCtlPmt[k] = (tDHL_PSI_ControlHandle)0;
1989                                nMonitors--;
1990
1991                        }
1992
1993                        // cafrii 081021
1994                        // ¼³·É pmt processed °¡ ¾ÈµÈ °æ¿ì¶óµµ (bProcessed FALSE),
1995                        // tvct µîÀÌ ¼ö½Å ¿Ï·á µÇ¾î slotÀÌ available ÇÒ ¼öµµ ÀÖÀ¸¹Ç·Î Ç×»ó üũÇÑ´Ù.
1996                        //
1997                        bNewMonitorStarted = FALSE;
1998                       
1999                        for (; bProcessed && idxPmt<tbls->num_programs; idxPmt++)
2000                        {
2001                                pid = tbls->pat->programs[idxPmt].program_map_PID;
2002                                if (pid <= 0 || pid >= 0x1FFF) {
2003                                        dprint(0, "!! pmt[%d] pid 0x%x invalid\n", idxPmt, pid);
2004                                        continue;
2005                                }
2006                                aProcDataPmt[idxPmt].err = DHL_OK;
2007                                aProcDataPmt[idxPmt].sema4 = sema4;
2008                                aProcDataPmt[idxPmt].id = 0x10 + idxPmt;   // PMTÀÇ id´Â 0x10 + pmt index ÀÌ´Ù.
2009                               
2010                                if ((err = MonitorPMT(tsd, 
2011                                                                pid, 
2012                                                                tbls->pat->programs[idxPmt].program_number,
2013                                                                TRUE /* current */, 
2014                                                                ePSIUPDATE_ONESHOT, 
2015                                                                _Dmc_MultiEventProc, 
2016                                                                (UINT32)&aProcDataPmt[idxPmt], 
2017                                                                &aPsiCtlPmt[idxPmt]))) 
2018                                {
2019                                        // cafrii 081007 add
2020                                        if (err == DHL_FAIL_OUT_OF_RESOURCE || err == DHL_FAIL_OUT_OF_MEMORY) {
2021                                                dprint(2, "\t full. stop monitor pmt, at idx %d\n", idxPmt);
2022                                                break;
2023                                        }
2024                                        else
2025                                                dprint(0, "\t !! MonitorPMT[%d] err %d %s\n", idxPmt, err, 
2026                                                                ErrorString((DHL_RESULT)err));
2027                                }
2028                                else {
2029                                        bNewMonitorStarted = TRUE;
2030                                        nMonitors++;
2031                                        dprint(2, "\t  MonitorPMT[%d] pn %d, pid %d success (%d monitors total)\n", 
2032                                                        idxPmt, tbls->pat->programs[idxPmt].program_number,
2033                                                        tbls->pat->programs[idxPmt].program_map_PID, nMonitors);
2034                                       
2035                                        // cafrii 081021,
2036                                        // pat, tvct ¿ë slotÀÌ available ÇØ Á³À» ¼ö ÀÖÀ½. ³ª°¡Áö ¸»°í °è¼Ó ÁøÇà.
2037                                        //idxPmt++;
2038                                        //break;
2039                                }
2040                        }
2041
2042                        if (bNewMonitorStarted) {
2043                                timeOut = DHL_OS_GetMsCount() + timeoutOrg - tickStart;
2044                                dprint(2, "\t  timeout adjusted to %u tick\n", timeOut);
2045                        }
2046                       
2047                }
2048
2049                else {
2050                        // cafrii 070117 add
2051                        for (i=0; i<3; i++) {  // TVCT, CVCT, PAT¿¡ ´ëÇØ¼­¸¸ bad packet 󸮸¦ ÇÏ¸é µÈ´Ù.
2052                                if ((aProcData[i].id & PME_EV_SEND_BADPKT) &&
2053                                        (aProcData[i].id & PME_EV_CNFM_BADPKT) == 0) {
2054                                        aProcData[i].id |= PME_EV_CNFM_BADPKT;
2055                                        if (timeOut < timeoutOrg + timeoutAdd) {
2056                                                timeOut = timeoutOrg + timeoutAdd;
2057                                                dprint(2, "\t  timeout increased by badpkt [%d]\n", i);
2058                                        }
2059                                }
2060                        }
2061                        //dprint(0, "!! semaphore taken, but no filter matched??\n");
2062                }
2063               
2064                // cafrii 041129 add comment
2065                //
2066                // ¸ðµÎ OneShotÀ¸·Î Monitor¸¦ ÇßÁö¸¸, °æ¿ì¿¡ µû¶ó¼­ event°¡ µÎ¹ø ºÒ¸± ¼öµµ ÀÖ´Ù.
2067                // Áï semaphore ´Â ÁöÁ¤µÈ Ƚ¼ö ÀÌ»óÀ¸·Î take/give µÉ ¼ö ÀÖ´Ù.
2068                // ±×·¡¼­ ÀÌ¹Ì Ã³¸®µÈ data ÀÎÁö ¸ÕÀú üũ¸¦ ÇØ º¸´Â ½À°üÀ» µéÀÌ´Â°Ô ÁÁ´Ù.
2069               
2070               
2071label_check:
2072
2073                //--------------------- Á¾·á Á¶°Ç üũ -------------------------
2074                //
2075                bPsiCompleted = FALSE;
2076               
2077                if (aProcData[MCTID_PAT].id & PME_CNFM) {
2078                        // PAT ¼ö½Å ¿Ï·á.
2079                       
2080                        if (aProcDataPmt == NULL) {
2081                       
2082                                // PAT´Â ¼ö½ÅÀÌ µÇ¾ú´Âµ¥, PMT list °¡ NULL À̶ó¸é pat ¶Ç´Â system ¿¡ ¿¡·¯°¡ ¹ß»ýÇØ¼­
2083                                // PMT¸¦ ´õ ÀÌ»ó ¼ö½ÅÇÒ ¼ö ¾ø´Â »óÅÂÀÓÀ» ¸»ÇÑ´Ù.
2084                                //
2085                                bPsiCompleted = TRUE;  // ¿¡·¯°¡ ¹ß»ýÇßÀ¸¹Ç·Î.. ÁøÇà ºÒ°¡. completed..
2086                                dprint(3, "  pat is completed and pmt cannot be downloaded\n");
2087                        }
2088                        else {
2089                                bPsiCompleted = TRUE;
2090                               
2091                                for (k=0; k<tbls->num_programs; k++) {
2092                                        if (aPsiCtlPmt[k] && (aProcDataPmt[k].id & PME_CNFM) == 0) {
2093                                                //
2094                                                // PMT ¼ö½ÅÀ» À§ÇÑ PsiCtlÀº ½ÃÀ۵Ǿú´Âµ¥, ¾ÆÁ÷ confirme ¾ÈµÈ pmt..
2095                                                // 
2096                                                bPsiCompleted = FALSE;  // Çϳª¶óµµ ¼ö½ÅÀÌ ¾ÈµÈ°ÍÀÌ ÀÖÀ¸¸é FALSE..
2097                                                break;
2098                                        }
2099                                }
2100                                if (bPsiCompleted) {
2101                                        dprint(3, "  pat and all pmt completed..\n");
2102                                }
2103                        }
2104                }
2105               
2106                // ·çÇÁ Á¾·á Á¶°Ç.. tvct/cvct µÑ Áß¿¡ Çϳª¶û, psi°¡ ¼ö½Å(¶Ç´Â ¿¡·¯)µÇ¸é Á¾·á..
2107                //
2108                if (bPsiCompleted &&
2109                        ((aProcData[MCTID_TVCT].id & PME_CNFM) || (aProcData[MCTID_CVCT].id & PME_CNFM))) {
2110                        // VCT µÑ Áß Çϳª°¡ ¼ö½ÅµÇ¾úÀ¸¹Ç·Î OK..
2111                        // ÁÖÀÇ! pat´Â ¼ö½ÅÀÌ ¾ÈµÇ¾úÀ» ¼öµµ ÀÖ´Ù.. ±×·± °æ¿ì¶ó¸é patPtrÀÌ NULLÀÎ °æ¿ìÀÌ´Ù.
2112                        dprint(2, "xVCT and PAT, %d tables received OK\n", nReceivedTable);
2113                        break;
2114                }
2115               
2116                //--------------------- Ãë¼Ò Á¶°Ç üũ -------------------------
2117               
2118                if (ckfn && ckfn(0)) {
2119                        // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù.
2120                        dprint(2, "!! download cancelled\n");
2121                        status = statusCancelled;
2122                        break;
2123                }
2124               
2125                //--------------------- ŸÀÓ ¾Æ¿ô üũ -------------------------
2126
2127                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
2128                        //status = statusTimeout;
2129                        // ¿©·¯°³ÀÇ tableÀ» ¹Þ°í Àֱ⠶§¹®¿¡ °³°³ tableÀÇ timeoutÀº ¹«ÀǹÌ..
2130                        dprint(2, "!! timeout (%ds) err, only %d/%d tables received..\n", timeOut/1000, 
2131                                                nReceivedTable, 3 + tbls->num_programs);
2132                        break;
2133                }
2134        } // while
2135       
2136       
2137CancelPsiMonitor:
2138        for (i=0; i<3; i++) {
2139                if (aPsiCtl[i]) {
2140                        //dprint(3, "  cancel psictl[%d]\n", i);
2141                        DHL_PSI_StopMonitor(aPsiCtl[i]);
2142                        nMonitors--;
2143                }
2144        }
2145       
2146        DHL_OS_Free((void**)&aPsiCtl);
2147        DHL_OS_Free((void**)&aProcData);
2148
2149        for (i=0; aPsiCtlPmt && i<tbls->num_programs; i++) {
2150                if (aPsiCtlPmt[i]) {
2151                        //dprint(3, "  cancel pmt psictl[%d]\n", i);
2152                        DHL_PSI_StopMonitor(aPsiCtlPmt[i]);
2153                        nMonitors--;
2154                }
2155        }
2156       
2157        if (nMonitors != 0)
2158                dprint(0, "!! final monitors number not zero, %d\n", nMonitors);
2159       
2160        if (aPsiCtlPmt)
2161                DHL_OS_Free((void**)&aPsiCtlPmt);
2162        if (aProcDataPmt)
2163                DHL_OS_Free((void**)&aProcDataPmt);
2164
2165        if (sema4)
2166                DHL_OS_DeleteSemaphore(sema4);
2167
2168        // cafrii 081210 add
2169        if (tbls->pmtList == NULL && (tbls->pat || tbls->num_programs)) {
2170                // valid pat while pmtList is null.
2171                // to avoid confusion, delete pat as if pat not received.
2172                dprint(0, "!! valid pat while null pmtlist. delete pat!\n");
2173                if (tbls->pat)
2174                        FreePAT(tbls->pat);
2175                tbls->pat = NULL;
2176                tbls->num_programs = 0;
2177        }
2178
2179        return status; 
2180}
2181
2182
2183
2184
2185#if 0
2186___________()
2187#endif
2188
2189STATUS Dmc_GetMultipleEITsEx(tDHL_TSD tsd, int nEit, UINT16 *aPID, UINT16 *aSourceID, eitPtr_t **aEitPtrPtr, 
2190                                                                int timeOut, BOOL (*chkfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL))
2191{
2192        // source_id´Â µ¿ÀÏÇϰí (°°Àº ÇÁ·Î±×·Ò) PID¸¸ ´Ù¸¥ (EIT-0, EIT-1, EIT-2, ...)À» µ¿½Ã ¼ö½ÅÇÒ ¼öµµ ÀÖ°í,
2193        // PID°¡ µ¿ÀÏÇϰí source_id°¡ ´Ù¸¥ (EIT-0 of multiple program)À» µ¿½Ã ¼ö½ÅÇÒ ¼öµµ ÀÖ´Ù.
2194        // Áï aEitPtr[0]ÀÌ EIT-0, aEitPtr[1]ÀÌ EIT-1À» ÀǹÌÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. ÁÖÀÇ¿ä¸Á..
2195       
2196        // ¿äûÇÑ EIT¸¦ ¸ðµÎ ¹ÞÀ¸¸é success¸¦ ¸®ÅÏÇÑ´Ù.
2197        // Çϳª¶óµµ failÀÌ ³ª¸é (timeoutÀÌ µÇ¾ú°Ç, scramble error°¡ µÇ¾ú°Ç °£¿¡..) statusError¸¦ ¸®ÅÏÇÑ´Ù.
2198        // ÇöÀç ±¸Á¶»ó °¢°¢ÀÇ EIT¿¡ ´ëÇØ¼­ ¸®ÅϰªÀ» ÁÙ ¼ö°¡ ¾ø´Ù.
2199        //
2200        // aPID[x] °¡ 0À̸é request¸¦ ÇÏÁö ¾Ê´Â´Ù.
2201        // Áï nEit °¹¼ö¸¸Å­ÀÇ request°¡ µÇÁö ¾ÊÀ» ¼öµµ ÀÖ´Ù.
2202        //
2203       
2204        PSIMultiEventProcData *aProcData;
2205        tDHL_PSI_ControlHandle *aPsiCtl;
2206        DHL_OS_SEMA_ID sema4;
2207        int i, nReceivedEit, nGoodEit, nEitMonitor;
2208        UINT32 tickStart;
2209        BOOL bDownloadCancelled = FALSE;
2210        DHL_RESULT err = DHL_OK;
2211                // cafrii 060420 add default value,
2212                // in some case, CancelPsiMonitor reached without initializing this variable.
2213        STATUS returnStatus = statusOK;
2214
2215        nGoodEit = nReceivedEit = 0; // cafrii 041105 move to here
2216
2217        dprint(1, "Dmc_GetMultipleEitsEx(%d eit, timeout %d sec)\n", nEit, timeOut/1000);
2218
2219        if (nEit <= 0 || aPID == NULL || aSourceID == NULL || aEitPtrPtr == NULL) {
2220                dprint(0, "!! Invalid Arguments, nEit %d, aPid %x, aSrcId %x, aEitPP %x\n", nEit, aPID, aSourceID, aEitPtrPtr);
2221                return statusInvalidArgument;
2222        }
2223        aPsiCtl = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(nEit * sizeof(tDHL_PSI_ControlHandle));
2224        if (aPsiCtl == NULL) {
2225                dprint(0, "!! out of memory for PsiCtls..\n");
2226                return statusOutOfMemory;
2227        }
2228        memset (aPsiCtl, 0, nEit * sizeof(tDHL_PSI_ControlHandle));
2229
2230        aProcData = (PSIMultiEventProcData *) DHL_OS_Malloc(nEit * sizeof(PSIMultiEventProcData));
2231        if (aProcData == NULL) {
2232                dprint(0, "!! out of memory for ProcData..\n");
2233                DHL_OS_Free((void**)&aPsiCtl);
2234                return statusOutOfMemory;
2235        }
2236        memset (aProcData, 0, nEit * sizeof(PSIMultiEventProcData));
2237
2238        // semaphoreÀº Çϳª¸¸ ¸¸µé¾î¼­ ¸ðµç ProcData¿¡ ¶È°°ÀÌ ³Ö¾îÁÖÀÚ.
2239        sema4 = DHL_OS_CreateCountingSemaphore("GetEITs", OS_SEM_FIFO, 0);
2240        if (!sema4) {
2241                DHL_OS_Free((void**)&aPsiCtl);
2242                DHL_OS_Free((void**)&aProcData);
2243                return statusOutOfMemory;
2244        }
2245       
2246        // Event report¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ÁغñÇÑ´Ù.
2247        for (i=0; i<nEit; i++) {
2248                if (aEitPtrPtr[i]) 
2249                        *(aEitPtrPtr[i]) = NULL;   // it will be initialized inside MonitorEit API..
2250                aProcData[i].err = DHL_OK; // it will be initialized at EventProc..
2251                aProcData[i].sema4 = sema4; // it will be used in EventProc to notify Data arrival
2252                aProcData[i].id = i;        // id for just debugging..
2253        }
2254
2255        // Psi Monitor¸¦ ½ÃÀÛÇÑ´Ù. ¼ö½ÅÇϰíÀÚ ÇÏ´Â Table °¹¼ö¸¸Å­ PsiCtlÀ» »ý¼º ÇØ¾ß ÇÑ´Ù.
2256        for (i=0, nEitMonitor=0; i<nEit; i++) 
2257        {
2258                if (aPID[i] == 0 || aEitPtrPtr[i] == NULL) { 
2259                        dprint(3, "\t Eit[%d] PID 0x%x invalid or output ptr NULL.. skip\n", i, aPID[i]);
2260                        continue;
2261                }
2262               
2263                if (aPID[i] <= 0 || aPID[i] >= 0x1FFF) {  // cafrii 050315 add
2264                        dprint(0, "!! Eit[%d] pid 0x%x invalid\n", i, aPID[i]);
2265                        continue;
2266                }
2267               
2268                err = MonitorEit(tsd, aPID[i], aSourceID[i], ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, 
2269                                                _Dmc_MultiEventProc, (UINT32)&aProcData[i], &aPsiCtl[i]);
2270                if (err) {
2271                        dprint(0, "!! %d-th Eit monitor (pid %d, source %d) failed! err %d %s\n", 
2272                                                i, aPID[i], aSourceID[i], err, ErrorString((DHL_RESULT)err));
2273                        //goto CancelPsiMonitor; // Áß°£¿¡ Monitor¿¡ ¼º°øÇÑ PsiCtlÀÌ ÀÖÀ» °ÍÀ̹ǷΠ±×³É ÇÔ¼ö ExitÇÏ¸é ¾ÈµÈ´Ù.
2274
2275                        if (!returnStatus) returnStatus = statusOutOfResource;
2276
2277                        // cafrii 070321 add comment
2278                        // °£È¤ PSIPÀÌ À߸ø ¸¸µé¾îÁ®¼­ PES PID¿Í PSI PID¸¦ °ãÃļ­ ¸¸µé¾î ³õ´Â °æ¿ì°¡ ÀÖ¾ú´Ù.
2279                        // ÀÌ ¿¡·¯ÀÇ °æ¿ì´Â skipÇÏ°í ´ÙÀ½ Monitor¸¦ ÁøÇàÇÑ´Ù.
2280                        //
2281                        if (err != DHL_FAIL_BUSY) // ÀÌ ¿¡·¯°¡ ³¯ °æ¿ì¿¡´Â ±×³É ´ÙÀ½ ¸ð´ÏÅÍ °è¼Ó ÁøÇà..
2282                                break;
2283                }
2284                else {
2285                        nEitMonitor++;
2286                }
2287        }
2288
2289        if (nEitMonitor == 0) goto CancelPsiMonitor;
2290        dprint(2, "    %d monitor requested..\n", nEitMonitor);
2291       
2292        tickStart = DHL_OS_GetMsCount();
2293       
2294        while (1) {
2295                // ÃÑ nEit °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù.
2296                //
2297                err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK);
2298               
2299                if (err == DHL_OK) {
2300                        int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000;  // unit: 0.01 sec
2301                        //nReceivedEit++;  // cafrii 070117 change policy!!
2302                       
2303                        // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù.
2304                       
2305                        for (i=0; i<nEit; i++) 
2306                        {
2307                                if ((aProcData[i].id & PME_MASK) != PME_SEND)
2308                                        continue; //
2309                               
2310                                // Eit-i is newly received!
2311                                nReceivedEit++; // cafrii 070117 change policy!!
2312                               
2313                                aProcData[i].id |= PME_CNFM;
2314                                if (aProcData[i].err) { // received but error occurred..
2315                                        dprint(0, "!! Eit[%d] err %d, %s\n", i, err, ErrorString((DHL_RESULT)err));
2316                                        if (!returnStatus) returnStatus = statusPSIPError;
2317                                        continue;
2318                                }
2319                                       
2320                                if (aPID[i] == 0 || aEitPtrPtr[i] == NULL) {  // this EIT is not actually requested..
2321                                        dprint(0, "!! event from non-requested Eit-%d ??\n", i);
2322                                        continue;
2323                                }
2324                                if (aProcData[i].desc == NULL) { // ÀÌ tableÀº timeout °É·Á ¼ö½ÅÇÏÁö ¸øÇÏ¿´´Ù. goto ´ÙÀ½ EIT..
2325                                        dprint(0, "!! event from non-received Eit-%d ??\n", i);
2326                                        continue;
2327                                }
2328                               
2329                                // lock eit ptr location
2330                                if (lockfn)
2331                                        lockfn(TRUE);
2332                                       
2333                                dprint(3, "  parse Eit[%d] to loc 0x%x\n", i, aEitPtrPtr[i]);
2334                               
2335                                err = ParseEit(aProcData[i].desc->sectPtr, aEitPtrPtr[i]);
2336                               
2337                                if (IsError(err)) // cafrii 050315 change
2338                                {
2339                                        // Multiple EIT ¼ö½ÅÀÇ °æ¿ì °¢°¢ÀÇ EIT¿¡ ´ëÇØ ¿¡·¯ ¸®ÅÏÀ» ÇÒ ¼ö ¾ø´Ù.
2340                                        // ¿ÀÁ÷ EitPtr·Î¸¸ °á°ú¸¦ ¾Ë·ÁÁÙ ¼ö Àִµ¥, Parsing µµÁß¿¡ ¿¡·¯°¡ ³ªµµ EitPtrÀÌ Non-NullÀÏ ¼ö ÀÖ´Ù.
2341                                        // ÀÌ °æ¿ì ¸®ÅϵǴ EitPtrÀº FreeAtscTableµµ ÇØ¼­´Â ¾ÈµÈ´Ù. ¹Ù·Î NULL·Î ¸®¼ÂÇØ¹ö¸®ÀÚ.
2342                                        //
2343                                        dprint(0, "!! err in ParseEit of Eit-%d, err %d, %s\n", i, err, ErrorString((DHL_RESULT)err));
2344                                        *(aEitPtrPtr[i]) = NULL;
2345                                       
2346                                        if (!returnStatus) returnStatus = statusPSIPError;
2347                                }
2348                                else {
2349                                        nGoodEit++;
2350                                }
2351                                // unlock eit ptr location
2352                                if (lockfn)
2353                                        lockfn(FALSE);
2354                                       
2355                                if (chkfn && chkfn(userparam, (UINT32) aEitPtrPtr[i])) {
2356                                        // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù.
2357                                        dprint(2, "!! download cancelled\n");
2358                                        bDownloadCancelled = TRUE;
2359                                        break;
2360                                }
2361                                break; // Çѹø¿¡ Çϳª¾¿ Ç¥½Ã..
2362                        }
2363                        if (bDownloadCancelled) break;
2364                       
2365                        if (i >= nEit)
2366                                dprint(2, " Eit event received but no related eit!!\n");
2367                        else
2368                                dprint(2, " Eit[%d] received (err %d) total %d, %d.%02d sec\n", 
2369                                        i, aProcData[i].err, nReceivedEit, elapsedTime/100, elapsedTime%100);
2370                }
2371               
2372                if (chkfn && chkfn(userparam, 0)) {
2373                        // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù.
2374                        dprint(2, "!! download cancelled\n");
2375                        bDownloadCancelled = TRUE;
2376                        break;
2377                }
2378
2379                if (nReceivedEit >= nEitMonitor) {
2380                        // ¸ðµç °ÍÀ» ´Ù ¼ö½ÅÇÏ¿´´Ù.
2381                        dprint(2, "all %d tables are received\n", nReceivedEit);
2382                        break;
2383                }
2384               
2385                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
2386                        err = DHL_FAIL_TIMEOUT;
2387                                // cafrii 060420 add
2388                                // informs that timeout is occurred.
2389                        dprint(2, "!! timeout (%ds) err, only %d/%d/%d Eits received..\n", timeOut/1000, 
2390                                                nGoodEit, nReceivedEit, nEitMonitor);
2391                        break;  // ÀϺδ ¹Þ¾ÒÀ» °ÍÀ̹ǷΠ¾Æ·¡ Parsing ÀÛ¾÷À» °ÅÃÄ¾ß ÇÑ´Ù.
2392                }
2393        }
2394
2395CancelPsiMonitor:
2396        for (i=0; i<nEit; i++) {
2397                if (aPsiCtl[i])
2398                        DHL_PSI_StopMonitor(aPsiCtl[i]); 
2399                if (aProcData[i].desc)
2400                        DHL_PSI_FreePSIData(aProcData[i].desc); // parsingÀÌ ³¡³µ±â ¶§¹®¿¡ ÀÌ desc µ¥ÀÌÅÍ´Â ºÒÇÊ¿äÇÏ´Ù.
2401        }
2402        DHL_OS_Free((void**)&aPsiCtl);
2403        DHL_OS_Free((void**)&aProcData);
2404
2405        if (sema4)
2406                DHL_OS_DeleteSemaphore(sema4);
2407       
2408#if 0
2409        dprint(3, " Total %d good/%d recv/%d mon/%d req EITs..\n", nGoodEit, nReceivedEit, nEitMonitor, nEit);
2410        for (i=0; i<nEit; i++)
2411                if (aEitPtrPtr[i]) dprint(3, "   Eit[%d]: 0x%x\n", i, *(aEitPtrPtr[i]));
2412#endif
2413               
2414        // ¿¡·¯´Â Ưº°È÷ ¸®ÅÏÇÏÁö ¾Ê¾Æµµ µÉµí.. ¾îÂ¥ÇÇ caller´Â aEitPtrÀ» °Ë»çÇØ¼­ ¿¡·¯ À¯¹«¸¦ Ã¼Å©ÇØ¾ß ÇÑ´Ù.
2415        //
2416        if (bDownloadCancelled)
2417                return statusCancelled;
2418               
2419        for (i=0; i<nEit; i++) {
2420                // aPID[i]°¡ Non-NullÀ̸é request°¡ µÈ °ÍÀε¥, aEitPtrÀÌ NULLÀÌ¸é ¹º°¡ ¿¡·¯°¡ ¹ß»ýÇÑ °ÍÀÌ´Ù.
2421                if (aPID[i] && aEitPtrPtr[i] && *(aEitPtrPtr[i]) == NULL) {
2422                        if (returnStatus)
2423                                return returnStatus;
2424                               
2425                        //return statusTimeout; 
2426                        return nEitMonitor>0 ? statusTimeout : statusError; // ¼ö½Å ¿Ï·áÇÏÁö ¸øÇß´Ù´Â ÀǹÌÀÇ ¿¡·¯°¡ ¾øÀ½..
2427                        // cafrii 070712 bugfix
2428                        //   Eit monitor¸¦ Çϳªµµ ½ÃÀÛµµ ¸øÇÏ°í ¹Ù·Î Á¾·áÇÏ´Â °æ¿ì¶ó¸é timeout °á°ú¸¦ ÁÖ¸é ¾ÈµÈ´Ù.
2429                        //   ¹Ù·Î ´Ù½Ã Àç½Ãµµ¸¦ Çϱ⠶§¹®.
2430                }
2431        }
2432        return statusOK; // requestµÈ ¸ðµç EIT°¡ ¸ðµÎ Non-NULLÀÌ¸é ¼º°øÀ¸·Î ÇÏÀÚ..
2433}
2434
2435
2436STATUS Dmc_GetMultipleEITs(tDHL_TSD tsd, int nEit, UINT16 *aPID, UINT16 *aSourceID, eitPtr_t *aEitPtr, 
2437                                                        int timeOut, BOOL (*chkfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL))
2438{
2439        // backward compatibile fnction..
2440        //
2441        int i;
2442        STATUS status;
2443        eitPtr_t **eitPtrPtrArry = DHL_OS_Malloc(nEit * sizeof(eitPtr_t *));
2444
2445        if (eitPtrPtrArry == NULL) return statusOutOfMemory;
2446        memset (eitPtrPtrArry, 0, nEit * sizeof(eitPtr_t *));
2447       
2448        for (i=0; i<nEit; i++)
2449                eitPtrPtrArry[i] = &aEitPtr[i];
2450       
2451        status = Dmc_GetMultipleEITsEx(tsd, nEit, aPID, aSourceID, eitPtrPtrArry, timeOut, chkfn, userparam, lockfn);
2452       
2453        DHL_OS_Free((void**)&eitPtrPtrArry);
2454
2455        return status;
2456}
2457
2458
2459
2460
2461STATUS Dmc_GetMultipleETTsEx(tDHL_TSD tsd, int nETT, UINT16 *aEttPID, UINT32 *aETMID, ettSectionPtr_t **aEttPtrPtr,
2462                                                                int timeOut, BOOL (*ckfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL))
2463{
2464        // Dmc_GetMulipleEITs¿Í µ¿ÀÏÇÑ ±¸Á¶¿¡ µ¿ÀÏÇÑ »ç¿ë¹ýÀ» °¡Áö°í ÀÖ´Ù.
2465        //
2466        // aEttPID[x] °¡ 0À̸é request¸¦ ÇÏÁö ¾Ê´Â´Ù.
2467        //
2468        // aETMID[x] °¡ 0 À̸é request¸¦ ÇÏÁö ¾Ê´Â´Ù. <-- »èÁ¦.. aETMID ´ë½Å aEttPID Á¤º¸¸¸À» »ç¿ëÇÏÀÚ..
2469        // Áï nETT °¹¼ö¸¸Å­ÀÇ request°¡ µÇÁö ¾ÊÀ» ¼öµµ ÀÖ´Ù.
2470        // ETM_id ÀÇ ±¸Á¶´Â ¾Æ·¡¿Í °°´Ù.
2471        //
2472        //    bits           31          16  15           2  1  0
2473        //  channel ETM_id      source_id     0 ...       0  0  0
2474        //  event ETM_id        source_id        event_id    1  0
2475        //
2476        // source_id°¡ 0 ÀÎ °æ¿ì ETM_id °ª 0Àº Àǹ̰¡ ÀÖ´Â °ªÀÌ µÇ¹Ç·Î requestÀÇ À¯¹« ÆÇÁ¤ ±âÁØÀ¸·Î 0À» »ç¿ëÇÒ ¼ö ¾ø´Ù.
2477        // ±×·¯³ª source_id 0´Â »ç¿ëÇÏÁö ¸øÇϵµ·Ï reserve µÇ¾î ÀÖ´Â °ªÀ̹ǷΠ¾È½ÉÇϰí requestÀÇ Àǹ̷Π»ç¿ëÇÒ ¼ö ÀÖ´Ù.
2478        //
2479        //   <-- spec »ó ±×·¯ÇÏÁö¸¸ Ȥ source_id 0 ÀÌ »ç¿ëµÉ °æ¿ì¸¦ ´ëºñÇÏ¿© ETMID 0 ÀÇ °ªÀ» Ưº°ÇÑ Àǹ̷Π»ç¿ëÇÏÁö ¾Êµµ·Ï ¼öÁ¤µÊ
2480        //
2481        // aEttPtrPtr[i]´Â i¹øÂ° Ett pointer°¡ ÀúÀåµÉ °ø°£ (ettSectionPtr_t *)ÀÇ ÁÖ¼Ò¸¦ °¡Áö°í ÀÖ´Ù.
2482        //
2483       
2484        PSIMultiEventProcData *aProcData;
2485        tDHL_PSI_ControlHandle *aPsiCtl;
2486        DHL_OS_SEMA_ID sema4;
2487        int i, nReceivedEtt, nGoodEtt, nEttMonitor;
2488        UINT32 tickStart;
2489        BOOL bDownloadCancelled = FALSE;
2490        DHL_RESULT err = DHL_OK;
2491                // cafrii 060420 add default value,
2492                // in some case, CancelPsiMonitor reached without initializing this variable.
2493        STATUS returnStatus = statusOK;
2494       
2495        nGoodEtt = nReceivedEtt = 0; // cafrii 041105 move to here
2496
2497        dprint(1, "Dmc_GetMultipleEttsEx(%d ett, timeout %d sec)\n", nETT, timeOut/1000);
2498
2499        if (nETT <= 0 || aEttPID == NULL || aETMID == NULL || aEttPtrPtr == NULL) {
2500                dprint(0, "!! Invalid Arguments, nEtt %d, aEttPid %x, aETMID %x, aEttSectPtr %x\n", nETT, aEttPID, aETMID, aEttPtrPtr);
2501                return statusInvalidArgument;
2502        }
2503        aPsiCtl = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(nETT * sizeof(tDHL_PSI_ControlHandle));
2504        if (aPsiCtl == NULL) {
2505                dprint(0, "!! out of memory for PsiCtls..\n");
2506                return statusOutOfMemory;
2507        }
2508        memset (aPsiCtl, 0, nETT * sizeof(tDHL_PSI_ControlHandle));
2509       
2510        aProcData = (PSIMultiEventProcData *) DHL_OS_Malloc(nETT * sizeof(PSIMultiEventProcData));
2511        if (aProcData == NULL) {
2512                dprint(0, "!! out of memory for ProcData..\n");
2513                DHL_OS_Free((void**)&aPsiCtl);
2514                return statusOutOfMemory;
2515        }
2516        memset (aProcData, 0, nETT * sizeof(PSIMultiEventProcData));
2517
2518        // semaphoreÀº Çϳª¸¸ ¸¸µé¾î¼­ ¸ðµç ProcData¿¡ ¶È°°ÀÌ ³Ö¾îÁÖÀÚ.
2519        sema4 = DHL_OS_CreateCountingSemaphore("GetETTs", OS_SEM_FIFO, 0);
2520        if (!sema4) {
2521                DHL_OS_Free((void**)&aProcData);
2522                DHL_OS_Free((void**)&aPsiCtl);
2523                return statusOutOfMemory;
2524        }
2525        //
2526        //dprint(3, "  aPsiCtl %x aProcData %x, sema4 %x\n", aPsiCtl, aProcData, sema4);
2527        //
2528        // Event report¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ÁغñÇÑ´Ù.
2529        for (i=0; i<nETT; i++) {
2530                // ettPtrÀÌ ÀúÀåµÉ Æ÷ÀÎÅÍ´Â caller°¡ NULL·Î ÁöÁ¤ÇßÀ» ¼öµµ ÀÖ´Ù. Ç×»ó NULL ¿©ºÎ¸¦ Ã¼Å©ÇØ¾ß ÇÑ´Ù.
2531                if (aEttPtrPtr[i])
2532                        *(aEttPtrPtr[i]) = NULL; // ½ÃÀÛÇϱâ Àü¿¡ ÃʱâÈ­¸¦ ÇÑ´Ù.
2533                aProcData[i].err = DHL_OK; // it will be initialized at EventProc..
2534                aProcData[i].sema4 = sema4; // it will be used in EventProc to notify Data arrival
2535                aProcData[i].id = i;        // id for just debugging..
2536                //dprint(3, "    aEttPtrPtr[%d] = %x, *aEttPtrPtr[%d] = %x\n", i, aEttPtrPtr[i], i, aEttPtrPtr[i] ? *(aEttPtrPtr[i]) : 0);
2537        }
2538
2539        // Psi Monitor¸¦ ½ÃÀÛÇÑ´Ù. ¼ö½ÅÇϰíÀÚ ÇÏ´Â Table °¹¼ö¸¸Å­ PsiCtlÀ» »ý¼º ÇØ¾ß ÇÑ´Ù.
2540        //
2541        for (i=0, nEttMonitor=0; i<nETT; i++) 
2542        {
2543                if (aEttPID[i] == 0 || aEttPtrPtr[i] == NULL) { 
2544                        dprint(3, "\t NULL ett[%d] pid or output ptr NULL.. skip\n", i);
2545                        continue;
2546                }
2547
2548                if (aEttPID[i] <= 0 || aEttPID[i] >= 0x1FFF) {  // cafrii 050315 change
2549                        dprint(0, "!! ett[%d] pid 0x%x invalid..\n", i, aEttPID[i]);
2550                        continue;
2551                }
2552
2553                // ett´Â Ç×»ó SectionMode·Î µ¿ÀÛÇϱ⠶§¹®¿¡ (Table Àüü¸¦ ¹Þ´Â°Ô Àǹ̰¡ ¾ø´Ù) PSIMode ÀÎÀÚ°¡ ¾øÀ½.
2554                err = MonitorEtt(tsd, aEttPID[i], aETMID[i], ePSIUPDATE_ONESHOT, 
2555                                                _Dmc_MultiEventProc, (UINT32)&aProcData[i], &aPsiCtl[i]);
2556                if (err) {
2557                        dprint(0, "!! %d-th Ett monitor (pid %d, etm 0x%x) failed! err %d %s\n", 
2558                                                i, aEttPID[i], aETMID[i], err, ErrorString((DHL_RESULT)err));
2559                                               
2560                        if (!returnStatus) returnStatus = statusOutOfResource;
2561                       
2562                        if (err != DHL_FAIL_BUSY) // cafrii 041105 add condition
2563                                break;
2564                }
2565                else {
2566                        //dprint(3, "   (%d) monitor pid %x etm %x, psiCtl %x\n", i, aEttPID[i], aETMID[i], aPsiCtl[i]);
2567                        nEttMonitor++;
2568                }
2569        }
2570
2571        if (nEttMonitor == 0) goto CancelPsiMonitor;
2572        dprint(2, "    %d monitor requested..\n", nEttMonitor);
2573
2574        tickStart = DHL_OS_GetMsCount();
2575
2576        while (1) {
2577                // ÃÑ nETT °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù.
2578                //
2579                err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK);
2580               
2581                if (err == DHL_OK) {
2582                        int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000;  // unit: 0.01 sec
2583                        //nReceivedEtt++; // cafrii 070117 change policy!!
2584
2585                        // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù.
2586                       
2587                        for (i=0; i<nETT; i++)
2588                        {
2589                                if ((aProcData[i].id & PME_MASK) != PME_SEND)
2590                                        continue;
2591
2592                                // Ett-i is newly received..
2593                                nReceivedEtt++; // cafrii 070117 change policy!!
2594                               
2595                                aProcData[i].id |= PME_CNFM;
2596                                if (aProcData[i].err) {
2597                                        dprint(0, "!! Ett[%d] err %d, %s\n", i, err, ErrorString((DHL_RESULT)err));
2598                                        if (!returnStatus) returnStatus = statusPSIPError;
2599                                        continue; // goto ´ÙÀ½ EIT..
2600                                }
2601                               
2602                                if (aEttPID[i] == 0 || aEttPtrPtr[i] == NULL) {  // this ETT is not actually requested..
2603                                        dprint(0, "!! event from non-requested Ett-%d ??\n", i);
2604                                        continue;
2605                                }
2606                                if (aProcData[i].desc == NULL) { // ÀÌ sectionÀº timeout °É·Á ¼ö½ÅÇÏÁö ¸øÇÏ¿´´Ù. goto ´ÙÀ½ Ett..
2607                                        dprint(0, "!! event from non-received Eit-%d ??\n", i);
2608                                        continue;
2609                                }
2610                       
2611                                // lock eit ptr location
2612                                if (lockfn)
2613                                        lockfn(TRUE);
2614                                       
2615                                dprint(3, "  parse Ett[%d] to loc 0x%x (cur %x)\n", i, aEttPtrPtr[i], (*(aEttPtrPtr[i])));
2616                               
2617                                err = ParseEttSection(aProcData[i].desc->sectPtr[0], aEttPtrPtr[i]);
2618                               
2619                                if (IsError(err)) // cafrii 050315 change
2620                                { 
2621                                        // Multiple ETT ¼ö½ÅÀÇ °æ¿ì °¢°¢ÀÇ ETT¿¡ ´ëÇØ ¿¡·¯ ¸®ÅÏÀ» ÇÒ ¼ö ¾ø´Ù.
2622                                        // ¿ÀÁ÷ EttSectPtr·Î¸¸ °á°ú¸¦ ¾Ë·ÁÁÙ ¼ö Àִµ¥, Parsing µµÁß¿¡ ¿¡·¯°¡ ³ªµµ EttSectPtrÀÌ Non-NullÀÏ ¼ö ÀÖ´Ù.
2623                                        // ÀÌ °æ¿ì ¸®ÅϵǴ EttSectPtrÀº FreeAtscTableµµ ÇØ¼­´Â ¾ÈµÈ´Ù. ¹Ù·Î NULL·Î ¸®¼ÂÇØ¹ö¸®ÀÚ.
2624                                        //
2625                                        dprint(0, "!! err in ParseEttSection, err %d, %s\n", err, ErrorString((DHL_RESULT)err));
2626                                        *(aEttPtrPtr[i]) = NULL;
2627                                       
2628                                        if (!returnStatus) returnStatus = statusPSIPError;
2629                                }
2630                                else {
2631                                        nGoodEtt++;
2632                                        //dprint(3, "      --> ett[%d]: [%x]=%x\n", i, aEttPtrPtr[i], *(aEttPtrPtr[i]));
2633                                }
2634                                // unlock eit ptr location
2635                                if (lockfn)
2636                                        lockfn(FALSE);
2637                                       
2638                                if (ckfn && ckfn(userparam, (UINT32) aEttPtrPtr[i])) {
2639                                        // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù.
2640                                        dprint(2, "!! download cancelled\n");
2641                                        bDownloadCancelled = TRUE;
2642                                        break;
2643                                }
2644                                       
2645                                break; // Çѹø¿¡ Çϳª¾¿ Ç¥½Ã..
2646                        }
2647                       
2648                        if (bDownloadCancelled) break;
2649                       
2650                        if (i >= nETT) 
2651                                dprint(2, " Ett event received but no related ett!!\n");
2652                        else
2653                                dprint(2, " Ett[%d] received (err %d) total %d, %d.%02d sec\n", i, 
2654                                        aProcData[i].err, nReceivedEtt, elapsedTime/100, elapsedTime%100);
2655                }
2656               
2657                if (ckfn && ckfn(userparam, 0)) {
2658                        // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù.
2659                        dprint(2, "!! download cancelled\n");
2660                        bDownloadCancelled = TRUE;
2661                        break;
2662                }
2663
2664                if (nReceivedEtt >= nEttMonitor) {
2665                        // ¸ðµç °ÍÀ» ´Ù ¼ö½ÅÇÏ¿´´Ù.
2666                        dprint(2, "all %d etts are received!!\n", nReceivedEtt);
2667                        break;
2668                }
2669               
2670                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
2671                        // ÀÌ ÇÔ¼ö¿¡¼­ timeout ¸®ÅϰªÀº ¾øÀ½..
2672                        //err = statusTimeout;
2673                        dprint(2, "!! timeout (%ds) err, only %d/%d/%d Etts received..\n", timeOut/1000,
2674                                                nGoodEtt, nReceivedEtt, nEttMonitor);
2675                        break;  // ÀϺδ ¹Þ¾ÒÀ» °ÍÀ̹ǷΠ¾Æ·¡ Parsing ÀÛ¾÷À» °ÅÃÄ¾ß ÇÑ´Ù.
2676                }
2677        }
2678       
2679       
2680CancelPsiMonitor:
2681
2682        for (i=0; i<nETT; i++) {
2683                if (aPsiCtl[i]) {
2684                        //dprint(3, "  cancel PsiCtls [%d] %x\n", i, aPsiCtl[i]);
2685                        DHL_PSI_StopMonitor(aPsiCtl[i]); 
2686                }
2687                if (aProcData[i].desc) {
2688                        //dprint(3, "  DHL_PSI_FreePSIData[%d] %x\n", i, aProcData[i].desc);
2689                        DHL_PSI_FreePSIData(aProcData[i].desc); // parsingÀÌ ³¡³µ±â ¶§¹®¿¡ ÀÌ desc µ¥ÀÌÅÍ´Â ºÒÇÊ¿äÇÏ´Ù.
2690                }
2691        }
2692        //dprint(3, "Free aPsiCtl %x, aProcData %x\n", aPsiCtl, aProcData);
2693        DHL_OS_Free((void**)&aPsiCtl);
2694        DHL_OS_Free((void**)&aProcData);
2695
2696        //dprint(3, "Deleting sema4 %x..\n", sema4);
2697        if (sema4)
2698                DHL_OS_DeleteSemaphore(sema4);
2699       
2700        dprint(3, " Total good %d /recv %d /mon %d /req %d ETTs..\n", nGoodEtt, nReceivedEtt, nEttMonitor, nETT);
2701#if 0
2702        for (i=0; i<nETT; i++)
2703                if (aEttPtrPtr[i]) dprint(3, "   Ett[%d]: 0x%x\n", i, *(aEttPtrPtr[i]));
2704#endif
2705               
2706        //dprint(3, "error processing..\n");
2707        // ¿¡·¯´Â Ưº°È÷ ¸®ÅÏÇÏÁö ¾Ê¾Æµµ µÉµí.. ¾îÂ¥ÇÇ caller´Â ETT section pointer¸¦ °Ë»çÇØ¼­ ¿¡·¯ À¯¹«¸¦ Ã¼Å©ÇØ¾ß ÇÑ´Ù.
2708        //
2709        if (bDownloadCancelled)
2710                return statusCancelled;
2711
2712        for (i=0; i<nETT; i++) {
2713                // aPID[i]°¡ Non-NullÀ̸é request°¡ µÈ °ÍÀε¥, aEttSectPtrÀÌ NULLÀÌ¸é ¹º°¡ ¿¡·¯°¡ ¹ß»ýÇÑ °ÍÀÌ´Ù.
2714                if (aEttPID[i] && aEttPtrPtr[i] && *(aEttPtrPtr[i]) == NULL) {
2715                        if (returnStatus) 
2716                                return returnStatus;
2717
2718                        //return statusTimeout; // ¼ö½Å ¿Ï·áÇÏÁö ¸øÇß´Ù´Â ÀǹÌÀÇ ¿¡·¯°¡ ¾øÀ½..
2719                        return nEttMonitor>0 ? statusTimeout : statusError; // ¼ö½Å ¿Ï·áÇÏÁö ¸øÇß´Ù´Â ÀǹÌÀÇ ¿¡·¯°¡ ¾øÀ½..
2720                        // cafrii 070712 bugfix
2721                        //   Ett monitor¸¦ Çϳªµµ ½ÃÀÛµµ ¸øÇÏ°í ¹Ù·Î Á¾·áÇÏ´Â °æ¿ì¶ó¸é timeout °á°ú¸¦ ÁÖ¸é ¾ÈµÈ´Ù.
2722                        //   ¹Ù·Î ´Ù½Ã Àç½Ãµµ¸¦ Çϱ⠶§¹®.
2723                }
2724        }
2725        return statusOK; // requestµÈ ¸ðµç EIT°¡ ¸ðµÎ Non-NULLÀÌ¸é ¼º°øÀ¸·Î ÇÏÀÚ..
2726}
2727
2728
2729STATUS Dmc_GetMultipleETTs(tDHL_TSD tsd, int nETT, UINT16 *aEttPID, UINT32 *aETMID, ettSectionPtr_t *aEttSectPtr,
2730                                                        int timeOut, BOOL (*ckfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL))
2731{
2732        // backward compatibile fnction..
2733        //
2734        int i;
2735        STATUS status;
2736        ettSectionPtr_t **ettPtrPtrArry = DHL_OS_Malloc(nETT * sizeof(ettSectionPtr_t *));
2737
2738        if (ettPtrPtrArry == NULL) return statusOutOfMemory;
2739        memset (ettPtrPtrArry, 0, nETT * sizeof(ettSectionPtr_t *));
2740       
2741        for (i=0; i<nETT; i++)
2742                ettPtrPtrArry[i] = &aEttSectPtr[i];
2743       
2744        status = Dmc_GetMultipleETTsEx(tsd, nETT, aEttPID, aETMID, ettPtrPtrArry, timeOut, ckfn, userparam, lockfn);
2745       
2746        DHL_OS_Free((void**)&ettPtrPtrArry);
2747
2748        return status;
2749}
2750
2751
2752
2753
2754
2755
2756
2757#if 0
2758_____Relay_Version_____()
2759#endif
2760
2761// TableÀ» ¹ÞÀ¸¸é ¹Ù·Î ´ÙÀ½ table ¸ð´ÏÅ͸¦ ½ÃÀÛÇÏ¿© ¹Þ°íÀÚ ÇÏ´Â Å×À̺íÀ» µ¿½Ã¿¡ ºü¸£°Ô ¹Þ´Â ÇÔ¼ö..
2762// »ç¿ë¹ýÀº GetMultipleXX ·ùÀÇ ÇÔ¼ö¿Í µ¿ÀÏÇÏ´Ù.
2763
2764
2765STATUS Dmc_GetRelayEITsEx(tDHL_TSD tsd, int nEit, UINT16 *aPID, UINT16 *aSourceID, eitPtr_t **aEitPtrPtr, 
2766                                                                int timeOut, BOOL (*chkfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL))
2767{
2768        // source_id´Â µ¿ÀÏÇϰí (°°Àº ÇÁ·Î±×·Ò) PID¸¸ ´Ù¸¥ (EIT-0, EIT-1, EIT-2, ...)À» µ¿½Ã ¼ö½ÅÇÒ ¼öµµ ÀÖ°í,
2769        // PID°¡ µ¿ÀÏÇϰí source_id°¡ ´Ù¸¥ (EIT-0 of multiple program)À» µ¿½Ã ¼ö½ÅÇÒ ¼öµµ ÀÖ´Ù.
2770        // Áï aEitPtr[0]ÀÌ EIT-0, aEitPtr[1]ÀÌ EIT-1À» ÀǹÌÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. ÁÖÀÇ¿ä¸Á..
2771       
2772        // ¿äûÇÑ EIT¸¦ ¸ðµÎ ¹ÞÀ¸¸é success¸¦ ¸®ÅÏÇÑ´Ù.
2773        // Çϳª¶óµµ failÀÌ ³ª¸é (timeoutÀÌ µÇ¾ú°Ç, scramble error°¡ µÇ¾ú°Ç °£¿¡..) statusError¸¦ ¸®ÅÏÇÑ´Ù.
2774        // ÇöÀç ±¸Á¶»ó °¢°¢ÀÇ EIT¿¡ ´ëÇØ¼­ ¸®ÅϰªÀ» ÁÙ ¼ö°¡ ¾ø´Ù.
2775        //
2776        // aPID[x] °¡ 0À̸é request¸¦ ÇÏÁö ¾Ê´Â´Ù.
2777        // Áï nEit °¹¼ö¸¸Å­ÀÇ request°¡ µÇÁö ¾ÊÀ» ¼öµµ ÀÖ´Ù.
2778        //
2779        // GetMultipleEITsEx¿Í ´Ù¸¥Á¡Àº aPID[x]°¡ Non-zero ÀÌ¸é ¹Ýµå½Ã aEitPtrPtr[x]µµ Non-NULL À̾î¾ß ÇÑ´Ù.
2780        // aEitPtrPtr[x]¸¦ skip ¿©ºÎ·Î »ç¿ëÇÒ ¼ö ¾ø´Ù. (skipÈÄ °è¼Ó ÁøÇàÇϱâ´Â ÇÏÁö¸¸ ¿¡·¯ ¸Þ½ÃÁö°¡ Ç¥½ÃµÊ)
2781        //
2782       
2783        PSIMultiEventProcData *aProcData;
2784        tDHL_PSI_ControlHandle *aPsiCtl;
2785        DHL_OS_SEMA_ID sema4;
2786        int i, idxMon, nReceivedEit, nGoodEit, nEitMonitor;
2787        UINT32 tickStart;
2788        BOOL bDownloadCancelled = FALSE;
2789        DHL_RESULT err = DHL_OK;
2790                // cafrii 060420 add default value,
2791                // in some case, CancelPsiMonitor reached without initializing this variable.
2792        STATUS returnStatus = statusOK;
2793       
2794        nGoodEit = nReceivedEit = 0; // cafrii 041105 move to here
2795
2796        dprint(1, "Dmc_GetRelayEITsEx(%d eit, timeout %d sec)\n", nEit, timeOut/1000);
2797
2798        if (nEit <= 0 || aPID == NULL || aSourceID == NULL || aEitPtrPtr == NULL) {
2799                dprint(0, "!! Invalid Arguments, nEit %d, aPid %x, aSrcId %x, aEitPP %x\n", nEit, aPID, aSourceID, aEitPtrPtr);
2800                return statusInvalidArgument;
2801        }
2802        aPsiCtl = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(nEit * sizeof(tDHL_PSI_ControlHandle));
2803        if (aPsiCtl == NULL) {
2804                dprint(0, "!! out of memory for PsiCtls..\n");
2805                return statusOutOfMemory;
2806        }
2807        memset (aPsiCtl, 0, nEit * sizeof(tDHL_PSI_ControlHandle));
2808               
2809        aProcData = (PSIMultiEventProcData *) DHL_OS_Malloc(nEit * sizeof(PSIMultiEventProcData));
2810        if (aProcData == NULL) {
2811                dprint(0, "!! out of memory for ProcData..\n");
2812                DHL_OS_Free((void**)&aPsiCtl);
2813                return statusOutOfMemory;
2814        }
2815        memset (aProcData, 0, nEit * sizeof(PSIMultiEventProcData));
2816
2817        // semaphoreÀº Çϳª¸¸ ¸¸µé¾î¼­ ¸ðµç ProcData¿¡ ¶È°°ÀÌ ³Ö¾îÁÖÀÚ.
2818        // counting semaphore·Î¼­ table Çϳª°¡ ¼ö½Å µÉ ¶§¸¶´Ù Çϳª¾¿ release µÇ´Â sema4ÀÌ´Ù.
2819        sema4 = DHL_OS_CreateCountingSemaphore("GetEITs", OS_SEM_FIFO, 0);
2820        if (!sema4) {
2821                DHL_OS_Free((void**)&aPsiCtl);
2822                DHL_OS_Free((void**)&aProcData);
2823                return statusOutOfMemory;
2824        }
2825       
2826        // Event report¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ÁغñÇÑ´Ù.
2827        for (i=0; i<nEit; i++) {
2828                if (aEitPtrPtr[i]) 
2829                        *(aEitPtrPtr[i]) = NULL;   // it will be initialized inside MonitorEit API..
2830                aProcData[i].err = DHL_OK; // it will be initialized at EventProc..
2831                aProcData[i].sema4 = sema4; // it will be used in EventProc to notify Data arrival
2832                aProcData[i].id = i;        // id for just debugging..
2833                        // id ¿¡´Â ¼ö½Å ¹ÞÀ» Å×À̺íÀÇ index [0~nEit-1] ÀÌ ±â·ÏµÇ¾î Àִµ¥,
2834                        // Å×ÀÌºí ¼ö½ÅÀÌ µÇ¾î¼­ eventProcÀÌ ºÒ·ÈÀ¸¸é PME_SEND ºñÆ®°¡ ¼Â µÈ´Ù.
2835                        // clientÃø¿¡¼­ À̸¦ °¨ÁöÇϰí 󸮸¦ ¸¶¹«¸® ÇßÀ¸¸é PME_CNFM ºñÆ®·Î ¸¶Å©ÇÑ´Ù.
2836        }
2837
2838        // Psi Monitor¸¦ ½ÃÀÛÇÑ´Ù. ¼ö½ÅÇϰíÀÚ ÇÏ´Â Table °¹¼ö¸¸Å­ PsiCtlÀ» »ý¼º ÇØ¾ß ÇÑ´Ù.
2839        for (idxMon=0, nEitMonitor=0; idxMon<nEit; idxMon++)
2840        {
2841                // µ¿½Ã¿¡ ¸ð´ÏÅÍ ÇÒ ¼ö ÀÖ´Â ÃÖ´ë °¹¼ö¸¦ ÃʰúÇÏ¿´À¸¸é ±×¸¸ monitorÇÑ´Ù.
2842                if (nEitMonitor >= gMaxTableMonitorsAtOneTime) {
2843                        dprint(2, "\t max %d tables monitored. next idxMon: %d\n", nEitMonitor, idxMon);
2844                        break;
2845                }
2846               
2847                if (aPID[idxMon] == 0) {  // PID¸¦ 0À¸·Î ÁöÁ¤Çϸé skip Ç϶ó´Â ÀÇ¹Ì·Î ÇØ¼®. ¿¡·¯°¡ ¾Æ´Ï´Ù.
2848                        dprint(3, "\t NULL PID in eit[%d]..\n", idxMon);
2849                        continue;
2850                }
2851               
2852                if (aPID[idxMon] <= 0 || aPID[idxMon] >= 0x1FFF) {  // cafrii 050315 add
2853                        dprint(0, "!! eit[%d] pid 0x%x invalid\n", idxMon, aPID[idxMon]);
2854                        continue;       
2855                }
2856               
2857                if (aEitPtrPtr[idxMon] == NULL) { 
2858                        dprint(0, "!! output eit ptr NULL.. skip eit[%d]\n", idxMon);
2859                        continue;
2860                }
2861               
2862                err = MonitorEit(tsd, aPID[idxMon], aSourceID[idxMon], ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, 
2863                                                _Dmc_MultiEventProc, (UINT32)&aProcData[idxMon], &aPsiCtl[idxMon]);
2864                if (err) {
2865                        dprint(0, "!! %d-th Eit monitor (pid %d, source %d) failed! err %d %s\n", 
2866                                                idxMon, aPID[idxMon], aSourceID[idxMon], err, ErrorString((DHL_RESULT)err));
2867
2868                        if (!returnStatus) returnStatus = statusOutOfResource;
2869                                // ¿¡·¯°¡ ³ª´Â ÁÖ¿ä ¿øÀÎÀº ½Ã½ºÅÛÀÇ °¡¿ë ¸®¼Ò½º°¡ ºÎÁ·ÇÑ °æ¿ìÀÌ´Ù.
2870                                // ÃÖ´ë·Î »ç¿ë °¡´ÉÇÑ monitor°¹¼ö¸¦ ÃʰúÇ߱⠶§¹®..
2871                                // ÀÌ·± °æ¿ì °è¼Ó monitor ÇØºÃÀÚ µ¿ÀÏÇÑ ¿¡·¯°¡ ¹ß»ýÇÑ´Ù.
2872                                // ÇöÀç±îÁö ¼º°øÇÑ Monitor¸¸ÀÌ¶óµµ ÁøÇàÇϱâ À§ÇØ ¿©±â¼­ ³ª°£´Ù.
2873
2874                        if (err != DHL_FAIL_BUSY)  // cafrii 041105 add condition
2875                        {
2876                                // DHL_FAIL_BUSYÀÇ ¸Þ½ÃÁö´Â ÇØ´ç PID°¡ PES ¸ðµå·Î ÀÌ¹Ì »ç¿ëÁßÀ϶§ ¹ß»ýÇÑ´Ù.
2877                                // ÀÌ´Â application¿¡¼­ ÀÌÀü ä³ÎÀÇ audio, video¸¦ Á¦´ë·Î stop ÇÏÁö ¾Ê¾Ò°Å³ª,
2878                                // PSIP generatorÀÇ ¿Àµ¿ÀÛ µîÀÌ ÀÌÀ¯ÀÌ´Ù. (av pid¿Í Eit pid¸¦ °°°Ô »ç¿ë?)
2879                                // ¹®Á¦°¡ µÇ´Â TableÀ» Á¦¿ÜÇÏ°í °è¼Ó ÁøÇàÇϵµ·Ï ÇÑ´Ù. ´Ù¸¥ tableÀº ±¦ÂúÀ» ¼ö ÀÖÀ¸¹Ç·Î..
2880                                //
2881                                // Âü°í·Î PSI monitor´Â µ¿ÀÏÇÑ ¸ð´ÏÅ͸¦ °è¼Ó °É¾îµµ Àý´ë·Î DHL_FAIL_BUSY´Â ¾È³­´Ù.
2882                                // ¸ðµÎ µ¶¸³ÀûÀÎ ¸ð´ÏÅÍ·Î °£ÁֵDZ⠶§¹®.
2883                                // °è¼Ó °É´Ù º¸¸é Prefilter ºÎÁ·, DOB ºÎÁ· µîÀÇ ¸Þ½ÃÁö°¡ ¹ß»ýÇÒ °ÍÀÓ.
2884                               
2885                                break;
2886                        }
2887                       
2888                }
2889                else {
2890                        //dprint(3, "   (%d) monitor pid %x source_id %x, psiCtl %x\n",
2891                        //                              idxMon, aPID[idxMon], aSourceID[idxMon], aPsiCtl[idxMon]);
2892                        nEitMonitor++;
2893                }
2894        }
2895
2896        if (nEitMonitor == 0) goto CancelPsiMonitor;
2897        dprint(2, "    %d monitor requested..\n", nEitMonitor);
2898       
2899        tickStart = DHL_OS_GetMsCount();
2900       
2901        while (1) {
2902                // ÃÑ nEit °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù.
2903                //
2904                err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK);
2905               
2906                if (err == DHL_OK) {
2907                        int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000;  // unit: 0.01 sec
2908                        //nReceivedEit++; // cafrii 070117 change policy!!
2909                       
2910                        // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù.
2911                       
2912                        for (i=0; i<nEit; i++) 
2913                        {
2914                                if ((aProcData[i].id & PME_MASK) != PME_SEND)
2915                                        continue; //
2916                               
2917                                // Eit-i is newly received!
2918                                nReceivedEit++; // cafrii 070117 change policy!!
2919                               
2920                                aProcData[i].id |= PME_CNFM;
2921                                if (aProcData[i].err) { // received but error occurred..
2922                                        dprint(0, "!! Eit[%d] err %d, %s\n", i, err, ErrorString((DHL_RESULT)err));
2923                                        if (!returnStatus) returnStatus = statusPSIPError;
2924                                        continue;
2925                                }
2926                                       
2927                                if (aPID[i] == 0 || aEitPtrPtr[i] == NULL) {  // this EIT is not actually requested..
2928                                        dprint(0, "!! event from non-requested Eit-%d ??\n", i);
2929                                        continue;
2930                                }
2931                                if (aProcData[i].desc == NULL) { // ÀÌ tableÀº timeout °É·Á ¼ö½ÅÇÏÁö ¸øÇÏ¿´´Ù. goto ´ÙÀ½ EIT..
2932                                        dprint(0, "!! event from non-received Eit-%d ??\n", i);
2933                                        continue;
2934                                }
2935                               
2936                                // lock eit ptr location
2937                                if (lockfn)
2938                                        lockfn(TRUE);
2939                                       
2940                                dprint(2, "*event* --> parse Eit[%d] to loc 0x%x\n", i, aEitPtrPtr[i]);
2941                               
2942                                err = ParseEit(aProcData[i].desc->sectPtr, aEitPtrPtr[i]);
2943                               
2944                                if (IsError(err)) // cafrii 050315 change
2945                                { 
2946                                        // Multiple EIT ¼ö½ÅÀÇ °æ¿ì °¢°¢ÀÇ EIT¿¡ ´ëÇØ ¿¡·¯ ¸®ÅÏÀ» ÇÒ ¼ö ¾ø´Ù.
2947                                        // ¿ÀÁ÷ EitPtr·Î¸¸ °á°ú¸¦ ¾Ë·ÁÁÙ ¼ö Àִµ¥, Parsing µµÁß¿¡ ¿¡·¯°¡ ³ªµµ EitPtrÀÌ Non-NullÀÏ ¼ö ÀÖ´Ù.
2948                                        // ÀÌ °æ¿ì ¸®ÅϵǴ EitPtrÀº FreeAtscTableµµ ÇØ¼­´Â ¾ÈµÈ´Ù. ¹Ù·Î NULL·Î ¸®¼ÂÇØ¹ö¸®ÀÚ.
2949                                        //
2950                                        dprint(0, "!! err in ParseEit of Eit-%d, err %d, %s\n", i, err, ErrorString((DHL_RESULT)err));
2951                                        *(aEitPtrPtr[i]) = NULL;
2952                                       
2953                                        if (!returnStatus) returnStatus = statusPSIPError;
2954                                }
2955                                else {
2956                                        nGoodEit++;
2957                                }
2958                                // unlock eit ptr location
2959                                if (lockfn)
2960                                        lockfn(FALSE);
2961                                       
2962                                // »ç¿ëÀÌ ³¡³­ ¸®¼Ò½º´Â ¹Ù·Î¹Ù·Î ÇØÁ¦ÇÑ´Ù.
2963                                //
2964                                DHL_PSI_FreePSIData(aProcData[i].desc); // parsingÀÌ ³¡³µ±â ¶§¹®¿¡ ÀÌ desc µ¥ÀÌÅÍ´Â ºÒÇÊ¿äÇÏ´Ù.
2965                                aProcData[i].desc = NULL;
2966                                //dprint(3, "\t\t aProcData[%d] freed\n", i);
2967
2968                                if (aPsiCtl[i]) {
2969                                        DHL_PSI_StopMonitor(aPsiCtl[i]);
2970                                        //dprint(3, "\t\t aPsiCtl[%d] freed\n", i);
2971                                }
2972                                else
2973                                        dprint(0, "!! PsiCtl[%d] NULL but event notified!\n", i);
2974                                       
2975                                aPsiCtl[i] = (tDHL_PSI_ControlHandle)0;
2976                               
2977                                // ÀÌÁ¦ »õ·Î¿î ¸ð´ÏÅ͸¦ ´Ù½Ã ½ÃÀÛÇÑ´Ù. ÇѰ³¸¸ Ãß°¡·Î ½ÃÀÛÇÏ¸é µÈ´Ù.
2978                                //
2979                                for (; idxMon<nEit; idxMon++)
2980                                {
2981                                        if (aPID[idxMon] == 0) {
2982                                                dprint(3, "\t Eit[%d] PID NULL, skip\n", idxMon);
2983                                                continue;
2984                                        }
2985                                       
2986                                        if (aPID[idxMon] <= 0 || aPID[idxMon] >= 0x1FFF) {  // cafrii 050315 add
2987                                                dprint(0, "!! Eit[%d] pid 0x%x invalid\n", idxMon, aPID[idxMon]);
2988                                                continue;
2989                                        }
2990
2991                                        if (aEitPtrPtr[idxMon] == NULL) {
2992                                                dprint(0, "!! Eit[%d] output ptr NULL\n", idxMon);
2993                                                continue;
2994                                        }
2995                                       
2996                                        err = MonitorEit(tsd, aPID[idxMon], aSourceID[idxMon], ePSIMODE_TABLE, ePSIUPDATE_ONESHOT, 
2997                                                                        _Dmc_MultiEventProc, (UINT32)&aProcData[idxMon], &aPsiCtl[idxMon]);
2998                                        if (err) {
2999                                                dprint(0, "!! %d-th Eit monitor (pid %d, source %d) failed! err %d %s\n", 
3000                                                                        idxMon, aPID[idxMon], aSourceID[idxMon], err, ErrorString((DHL_RESULT)err));
3001                                                if (!returnStatus) returnStatus = statusOutOfResource;
3002                                               
3003                                                // À̰÷Àº table ÀÌ Çϳª¾¿ ¹Þ¾ÆÁú¶§¸¶´Ù relay·Î monitor¸¦ °Å´Â °÷Àε¥,
3004                                                // monitor¿¡¼­ ¿¡·¯°¡ ¹ß»ýÇÒ °æ¿ì, À̸¦ ¹æÁöÇÏ´Â ·ÎÁ÷ÀÌ ¾ÆÁ÷ ¾ø´Ù.
3005                                                // º¸Åë Çѹø ¿¡·¯°¡ ³ª¸é °è¼Ó ¿¡·¯°¡ ³¯ °ÍÀÌ´Ù.
3006                                               
3007                                                if (err != DHL_FAIL_BUSY)   // cafrii 041105 add condition
3008                                                        break;
3009                                        }
3010                                        else {
3011                                                dprint(2, "\t relayed monitor %d-th Eit ok\n", idxMon);
3012                                                nEitMonitor++;
3013                                                idxMon++;
3014                                        }
3015                                        break; // Çϳª¸¸ ¸ð´ÏÅÍ ÇÏ°í ³ª°¡¸é µÈ´Ù.
3016                                }
3017                               
3018                               
3019                                // Eit[i]¿¡ °üÇÑ ¸ðµç ÀÛ¾÷ÀÌ ³¡³µ´Ù. cancel ¿©ºÎ¸¦ °Ë»çÇÏ°í ´ÙÀ½ Eit·Î ³Ñ¾î°¨..
3020                                //
3021                                if (chkfn && chkfn(userparam, (UINT32) aEitPtrPtr[i])) {
3022                                        // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù.
3023                                        dprint(2, "!! download cancelled\n");
3024                                        bDownloadCancelled = TRUE;
3025                                        break;
3026                                }
3027                                break; // Çѹø¿¡ Çϳª¾¿ Ç¥½Ã..
3028                               
3029                        } // for all Eits..
3030                       
3031                        if (bDownloadCancelled) break;
3032                       
3033                        if (i >= nEit)
3034                                dprint(2, " Eit event received but no related eit!!\n");
3035                        else
3036                                dprint(2, " Eit[%d] received (err %d) total %d, %d.%02d sec\n", 
3037                                        i, aProcData[i].err, nReceivedEit, elapsedTime/100, elapsedTime%100);
3038                                       
3039                } // end if semaphore taken..
3040               
3041                if (chkfn && chkfn(userparam, 0)) {
3042                        // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù.
3043                        dprint(2, "!! download cancelled\n");
3044                        bDownloadCancelled = TRUE;
3045                        break;
3046                }
3047
3048                if (nReceivedEit >= nEitMonitor) {
3049                        // ¸ðµç °ÍÀ» ´Ù ¼ö½ÅÇÏ¿´´Ù.
3050                        dprint(2, "all %d tables are received\n", nReceivedEit);
3051                        break;
3052                }
3053               
3054                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
3055                        err = DHL_FAIL_TIMEOUT;
3056                                // cafrii 060420 add
3057                                // informs that timeout is occurred.
3058                        dprint(2, "!! timeout (%ds) err, only %d/%d/%d Eits received..\n", timeOut/1000, 
3059                                                nGoodEit, nReceivedEit, nEitMonitor);
3060                        break;  // ÀϺδ ¹Þ¾ÒÀ» °ÍÀ̹ǷΠ¾Æ·¡ Parsing ÀÛ¾÷À» °ÅÃÄ¾ß ÇÑ´Ù.
3061                }
3062        }
3063
3064CancelPsiMonitor:
3065        // Á¤»óÀûÀ¸·Î Á¾·áµÇ¾ú´Ù¸é À̰÷¿¡¼­ freeµÇ´Â °ÍÀº Çϳªµµ ¾ø¾î¾ß ÇÑ´Ù.
3066        // ±×·¯³ª timeoutÀ̳ª user cancelÀÌ µÇ¾ú´Ù¸é ÇöÀç ÁøÇàÁßÀÎ °ÍµéÀÌ ÀÖÀ» °ÍÀ̹ǷΠÀ̰÷¿¡¼­ »èÁ¦ÇØ¾ß ÇÑ´Ù.
3067        //
3068        for (i=0; i<nEit; i++) {
3069                if (aPsiCtl[i]) {
3070                        if (bDownloadCancelled == FALSE && err != DHL_FAIL_TIMEOUT)
3071                                dprint(0, "!! relayeit: aPsiCtl[%d] non-Null !! err %d, check it!\n", i, err);
3072                        DHL_PSI_StopMonitor(aPsiCtl[i]); 
3073                }
3074                       
3075                if (aProcData[i].desc) {
3076                        if (bDownloadCancelled == FALSE && err != (DHL_RESULT)statusTimeout)
3077                                dprint(0, "!! aProcData[%d].desc not NULL !!\n", i);
3078                        DHL_PSI_FreePSIData(aProcData[i].desc); // parsingÀÌ ³¡³µ±â ¶§¹®¿¡ ÀÌ desc µ¥ÀÌÅÍ´Â ºÒÇÊ¿äÇÏ´Ù.
3079                }
3080        }
3081        DHL_OS_Free((void**)&aPsiCtl);
3082        DHL_OS_Free((void**)&aProcData);
3083
3084        if (sema4)
3085                DHL_OS_DeleteSemaphore(sema4);
3086       
3087        dprint(3, " Total %d good/%d recv/%d mon/%d req EITs..\n", nGoodEit, nReceivedEit, nEitMonitor, nEit);
3088#if 0
3089        for (i=0; i<nEit; i++)
3090                if (aEitPtrPtr[i]) dprint(3, "   Eit[%d]: 0x%x\n", i, *(aEitPtrPtr[i]));
3091#endif
3092               
3093        // ¿¡·¯´Â Ưº°È÷ ¸®ÅÏÇÏÁö ¾Ê¾Æµµ µÉµí.. ¾îÂ¥ÇÇ caller´Â aEitPtrÀ» °Ë»çÇØ¼­ ¿¡·¯ À¯¹«¸¦ Ã¼Å©ÇØ¾ß ÇÑ´Ù.
3094        //
3095        if (bDownloadCancelled)
3096                return statusCancelled;
3097               
3098        for (i=0; i<nEit; i++) {
3099                // aPID[i]°¡ Non-NullÀ̸é request°¡ µÈ °ÍÀε¥, aEitPtrÀÌ NULLÀÌ¸é ¹º°¡ ¿¡·¯°¡ ¹ß»ýÇÑ °ÍÀÌ´Ù.
3100                if (aPID[i] && aEitPtrPtr[i] && *(aEitPtrPtr[i]) == NULL) {
3101                        if (returnStatus)
3102                                return returnStatus;
3103                               
3104                        //return statusTimeout; 
3105                        return nEitMonitor>0 ? statusTimeout : statusError; // ¼ö½Å ¿Ï·áÇÏÁö ¸øÇß´Ù´Â ÀǹÌÀÇ ¿¡·¯°¡ ¾øÀ½..
3106                        // cafrii 070712 bugfix
3107                        //   Eit monitor¸¦ Çϳªµµ ½ÃÀÛµµ ¸øÇÏ°í ¹Ù·Î Á¾·áÇÏ´Â °æ¿ì¶ó¸é timeout °á°ú¸¦ ÁÖ¸é ¾ÈµÈ´Ù.
3108                        //   ¹Ù·Î ´Ù½Ã Àç½Ãµµ¸¦ Çϱ⠶§¹®.
3109                }
3110        }
3111        return statusOK; // requestµÈ ¸ðµç EIT°¡ ¸ðµÎ Non-NULLÀÌ¸é ¼º°øÀ¸·Î ÇÏÀÚ..
3112}
3113
3114
3115
3116STATUS Dmc_GetRelayEITs(tDHL_TSD tsd, int nEit, UINT16 *aPID, UINT16 *aSourceID, eitPtr_t *aEitPtr, 
3117                                                        int timeOut, BOOL (*chkfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL))
3118{
3119        // backward compatibile fnction..
3120        //
3121        int i;
3122        STATUS status;
3123        eitPtr_t **eitPtrPtrArry = DHL_OS_Malloc(nEit * sizeof(eitPtr_t *));
3124
3125        if (eitPtrPtrArry == NULL) return statusOutOfMemory;
3126        memset (eitPtrPtrArry, 0, nEit * sizeof(eitPtr_t *));
3127       
3128        for (i=0; i<nEit; i++)
3129                eitPtrPtrArry[i] = &aEitPtr[i];
3130       
3131        status = Dmc_GetRelayEITsEx(tsd, nEit, aPID, aSourceID, eitPtrPtrArry, timeOut, chkfn, userparam, lockfn);
3132       
3133        DHL_OS_Free((void**)&eitPtrPtrArry);
3134
3135        return status;
3136}
3137
3138
3139
3140
3141
3142STATUS Dmc_GetRelayETTsEx(tDHL_TSD tsd, int nETT, UINT16 *aEttPID, UINT32 *aETMID, ettSectionPtr_t **aEttPtrPtr,
3143                                                        int timeOut, BOOL (*ckfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL))
3144{
3145        // Dmc_GetRelayEITs¿Í µ¿ÀÏÇÑ ±¸Á¶¿¡ µ¿ÀÏÇÑ »ç¿ë¹ýÀ» °¡Áö°í ÀÖ´Ù.
3146        //
3147        // aEttPID[x] °¡ 0À̸é request¸¦ ÇÏÁö ¾Ê´Â´Ù.
3148        //
3149        // aETMID[x] °¡ 0 À̸é request¸¦ ÇÏÁö ¾Ê´Â´Ù. <-- »èÁ¦.. aETMID ´ë½Å aEttPID¸¦ »ç¿ëÇÏÀÚ..
3150        // Áï nETT °¹¼ö¸¸Å­ÀÇ request°¡ µÇÁö ¾ÊÀ» ¼öµµ ÀÖ´Ù.
3151        // ETM_id ÀÇ ±¸Á¶´Â ¾Æ·¡¿Í °°´Ù.
3152        //
3153        //    bits           31          16  15           2  1  0
3154        //  channel ETM_id      source_id     0 ...       0  0  0
3155        //  event ETM_id        source_id        event_id    1  0
3156        //
3157        // source_id°¡ 0 ÀÎ °æ¿ì ETM_id °ª 0Àº Àǹ̰¡ ÀÖ´Â °ªÀÌ µÇ¹Ç·Î requestÀÇ À¯¹« ÆÇÁ¤ ±âÁØÀ¸·Î 0À» »ç¿ëÇÒ ¼ö ¾ø´Ù.
3158        // ±×·¯³ª source_id 0´Â »ç¿ëÇÏÁö ¸øÇϵµ·Ï reserve µÇ¾î ÀÖ´Â °ªÀ̹ǷΠ¾È½ÉÇϰí requestÀÇ Àǹ̷Π»ç¿ëÇÒ ¼ö ÀÖ´Ù.
3159        //
3160        //   <-- spec »ó ±×·¯ÇÏÁö¸¸ Ȥ source_id 0 ÀÌ »ç¿ëµÉ °æ¿ì¸¦ ´ëºñÇÏ¿© ETMID 0 ÀÇ °ªÀ» Ưº°ÇÑ Àǹ̷Π»ç¿ëÇÏÁö ¾Êµµ·Ï ¼öÁ¤µÊ
3161        //
3162        // aEttPtrPtr[i]´Â i¹øÂ° Ett pointer°¡ ÀúÀåµÉ °ø°£ (ettSectionPtr_t *)ÀÇ ÁÖ¼Ò¸¦ °¡Áö°í ÀÖ´Ù.
3163        //
3164        // GetMultipleETTsEx¿Í ´Ù¸¥Á¡Àº aEttPID[x]°¡ Non-zero ÀÌ¸é ¹Ýµå½Ã aEttPtrPtr[x]µµ Non-NULL À̾î¾ß ÇÑ´Ù.
3165        // aEttPtrPtr[x]¸¦ skip ¿©ºÎ·Î »ç¿ëÇÒ ¼ö ¾ø´Ù. (skipÈÄ °è¼Ó ÁøÇàÇϱâ´Â ÇÏÁö¸¸ ¿¡·¯ ¸Þ½ÃÁö°¡ Ç¥½ÃµÊ)
3166        //
3167       
3168       
3169        PSIMultiEventProcData *aProcData;
3170        tDHL_PSI_ControlHandle *aPsiCtl;
3171        DHL_OS_SEMA_ID sema4;
3172        int i, idxMon, nReceivedEtt, nGoodEtt, nEttMonitor;
3173        UINT32 tickStart;
3174        BOOL bDownloadCancelled = FALSE;
3175        DHL_RESULT err = DHL_OK; 
3176                // cafrii 060420 add default value,
3177                // in some case, CancelPsiMonitor reached without initializing this variable.
3178        STATUS returnStatus = statusOK;
3179       
3180        nGoodEtt = nReceivedEtt = 0; // cafrii 041105 move to here
3181       
3182        dprint(1, "Dmc_GetRelayETTsEx(%d ett, timeout %d sec)\n", nETT, timeOut/1000);
3183
3184        if (nETT <= 0 || aEttPID == NULL || aETMID == NULL || aEttPtrPtr == NULL) {
3185                dprint(0, "!! Invalid Arguments, nEtt %d, aEttPid %x, aETMID %x, aEttSectPtr %x\n", nETT, aEttPID, aETMID, aEttPtrPtr);
3186                return statusInvalidArgument;
3187        }
3188        aPsiCtl = (tDHL_PSI_ControlHandle *) DHL_OS_Malloc(nETT * sizeof(tDHL_PSI_ControlHandle));
3189        if (aPsiCtl == NULL) {
3190                dprint(0, "!! out of memory for PsiCtls..\n");
3191                return statusOutOfMemory;
3192        }
3193        memset (aPsiCtl, 0, nETT * sizeof(tDHL_PSI_ControlHandle));
3194       
3195        aProcData = (PSIMultiEventProcData *) DHL_OS_Malloc(nETT * sizeof(PSIMultiEventProcData));
3196        if (aProcData == NULL) {
3197                dprint(0, "!! out of memory for ProcData..\n");
3198                DHL_OS_Free((void**)&aPsiCtl);
3199                return statusOutOfMemory;
3200        }
3201        memset (aProcData, 0, nETT * sizeof(PSIMultiEventProcData));
3202
3203        // semaphoreÀº Çϳª¸¸ ¸¸µé¾î¼­ ¸ðµç ProcData¿¡ ¶È°°ÀÌ ³Ö¾îÁÖÀÚ.
3204        sema4 = DHL_OS_CreateCountingSemaphore("GetETTs", OS_SEM_FIFO, 0);
3205        if (!sema4) {
3206                DHL_OS_Free((void**)&aProcData);
3207                DHL_OS_Free((void**)&aPsiCtl);
3208                return statusOutOfMemory;
3209        }
3210
3211        // Event report¿¡ ÇÊ¿äÇÑ µ¥ÀÌÅ͸¦ ÁغñÇÑ´Ù.
3212        for (i=0; i<nETT; i++) {
3213                // ettPtrÀÌ ÀúÀåµÉ Æ÷ÀÎÅÍ´Â caller°¡ NULL·Î ÁöÁ¤ÇßÀ» ¼öµµ ÀÖ´Ù. Ç×»ó NULL ¿©ºÎ¸¦ Ã¼Å©ÇØ¾ß ÇÑ´Ù.
3214                if (aEttPtrPtr[i])
3215                        *(aEttPtrPtr[i]) = NULL; // ½ÃÀÛÇϱâ Àü¿¡ ÃʱâÈ­¸¦ ÇÑ´Ù.
3216                aProcData[i].err = DHL_OK; // it will be initialized at EventProc..
3217                aProcData[i].sema4 = sema4; // it will be used in EventProc to notify Data arrival
3218                aProcData[i].id = i;        // id for just debugging..
3219                //dprint(3, "    aEttPtrPtr[%d] = %x, *aEttPtrPtr[%d] = %x\n",
3220                //                                      i, aEttPtrPtr[i], i, aEttPtrPtr[i] ? *(aEttPtrPtr[i]) : 0);
3221        }
3222
3223        // Psi Monitor¸¦ ½ÃÀÛÇÑ´Ù. ¼ö½ÅÇϰíÀÚ ÇÏ´Â Table °¹¼ö¸¸Å­ PsiCtlÀ» »ý¼º ÇØ¾ß ÇÑ´Ù.
3224        //
3225        for (idxMon=0, nEttMonitor=0; idxMon<nETT; idxMon++) 
3226        {
3227                if (nEttMonitor >= gMaxTableMonitorsAtOneTime) {
3228                        dprint(2, "\t maax %d tables monitored. next idxMon: %d\n", nEttMonitor, idxMon);
3229                        break;
3230                }
3231               
3232                if (aEttPID[idxMon] == 0) {
3233                        dprint(3, "\t NULL PID in ett[%d]..\n", idxMon);
3234                        continue;
3235                }
3236               
3237                if (aEttPID[idxMon] <= 0 || aEttPID[idxMon] >= 0x1FFF) {  // cafrii 050315 add
3238                        dprint(0, "!! ett[%d] pid 0x%x invalid\n", idxMon, aEttPID[idxMon]);
3239                        continue;
3240                }
3241               
3242                if (aEttPtrPtr[idxMon] == NULL) {
3243                        dprint(0, "!! output ett ptr NULL.. skip ett[%d]\n", idxMon);
3244                        continue;       
3245                }
3246               
3247                // ett´Â Ç×»ó SectionMode·Î µ¿ÀÛÇϱ⠶§¹®¿¡ (Table Àüü¸¦ ¹Þ´Â°Ô Àǹ̰¡ ¾ø´Ù) PSIMode ÀÎÀÚ°¡ ¾øÀ½.
3248                err = MonitorEtt(tsd, aEttPID[idxMon], aETMID[idxMon], ePSIUPDATE_ONESHOT, 
3249                                                _Dmc_MultiEventProc, (UINT32)&aProcData[idxMon], &aPsiCtl[idxMon]);
3250                if (err) {
3251                        dprint(0, "!! %d-th Ett monitor (pid %d, etm 0x%x) failed! err %d %s\n", 
3252                                                idxMon, aEttPID[idxMon], aETMID[idxMon], err, ErrorString((DHL_RESULT)err));
3253
3254                        if (!returnStatus) returnStatus = statusOutOfResource;
3255                       
3256                        if (err != DHL_FAIL_BUSY) // cafrii 041105 add condition
3257                                break;
3258                }
3259                else {
3260                        //dprint(3, "   (%d) monitor pid %x etm %x, psiCtl %x\n", 
3261                        //                              idxMon, aEttPID[idxMon], aETMID[idxMon], aPsiCtl[idxMon]);
3262                        nEttMonitor++;
3263                }
3264        }
3265
3266        if (nEttMonitor == 0) goto CancelPsiMonitor;
3267        dprint(2, "    %d monitor requested..\n", nEttMonitor);
3268
3269        tickStart = DHL_OS_GetMsCount();
3270
3271        while (1) {
3272                // ÃÑ nETT °¹¼ö ¸¸Å­ÀÇ Semaphore¸¦ takeÇØ¾ß ¸ðµç ÀÛ¾÷ÀÌ ¿Ï·áµÈ °ÍÀÌ´Ù.
3273                //
3274                err = (DHL_RESULT) DHL_OS_TakeSemaphore(sema4, PSIP_WAIT_IN_TICK);
3275               
3276                if (err == DHL_OK) {
3277                        int elapsedTime = (DHL_OS_GetMsCount() - tickStart)*100/1000;  // unit: 0.01 sec
3278                        //nReceivedEtt++; // cafrii 070117 change policy!!
3279
3280                        // ¸î¹ø tableÀÌ ¼ö½ÅµÇ¾ú´ÂÁö¸¦ Ç¥½ÃÇÏ°í ½ÍÀ¸¸é aProcData[i].id ÀÇ MSB Çʵ带 °üÂûÇÏ¸é µÈ´Ù.
3281                       
3282                        for (i=0; i<nETT; i++)
3283                        {
3284                                if ((aProcData[i].id & PME_MASK) != PME_SEND)
3285                                        continue;
3286
3287                                // Ett-i is newly received..   
3288                                nReceivedEtt++; // cafrii 070117 change policy!!
3289                               
3290                                aProcData[i].id |= PME_CNFM;
3291                                if (aProcData[i].err) {
3292                                        dprint(0, "!! Ett[%d] err %d, %s\n", i, err, ErrorString((DHL_RESULT)err));
3293                                        if (!returnStatus) returnStatus = statusPSIPError;
3294                                        continue; // goto ´ÙÀ½ EIT..
3295                                }
3296                               
3297                                if (aEttPID[i] == 0 || aEttPtrPtr[i] == NULL) {  // this ETT is not actually requested..
3298                                        dprint(0, "!! event from non-requested Ett-%d ??\n", i);
3299                                        continue;
3300                                }
3301                                if (aProcData[i].desc == NULL) { // ÀÌ sectionÀº timeout °É·Á ¼ö½ÅÇÏÁö ¸øÇÏ¿´´Ù. goto ´ÙÀ½ Ett..
3302                                        dprint(0, "!! event from non-received Eit-%d ??\n", i);
3303                                        continue;
3304                                }
3305                       
3306                                // lock eit ptr location
3307                                if (lockfn)
3308                                        lockfn(TRUE);
3309                                       
3310                                dprint(3, "  parse Ett[%d] to loc 0x%x (cur %x)\n", i, aEttPtrPtr[i], (*(aEttPtrPtr[i])));
3311                               
3312                                err = ParseEttSection(aProcData[i].desc->sectPtr[0], aEttPtrPtr[i]);
3313                               
3314                                if (IsError(err)) // cafrii 050315 change
3315                                { 
3316                                        // Multiple ETT ¼ö½ÅÀÇ °æ¿ì °¢°¢ÀÇ ETT¿¡ ´ëÇØ ¿¡·¯ ¸®ÅÏÀ» ÇÒ ¼ö ¾ø´Ù.
3317                                        // ¿ÀÁ÷ EttSectPtr·Î¸¸ °á°ú¸¦ ¾Ë·ÁÁÙ ¼ö Àִµ¥, Parsing µµÁß¿¡ ¿¡·¯°¡ ³ªµµ EttSectPtrÀÌ Non-NullÀÏ ¼ö ÀÖ´Ù.
3318                                        // ÀÌ °æ¿ì ¸®ÅϵǴ EttSectPtrÀº FreeAtscTableµµ ÇØ¼­´Â ¾ÈµÈ´Ù. ¹Ù·Î NULL·Î ¸®¼ÂÇØ¹ö¸®ÀÚ.
3319                                        //
3320                                        dprint(0, "!! err in ParseEttSection, err %d, %s\n", err, ErrorString((DHL_RESULT)err));
3321                                        *(aEttPtrPtr[i]) = NULL;
3322                                       
3323                                        if (!returnStatus) returnStatus = statusPSIPError;
3324                                }
3325                                else {
3326                                        nGoodEtt++;
3327                                        //dprint(3, "      --> ett[%d]: [%x]=%x\n", i, aEttPtrPtr[i], *(aEttPtrPtr[i]));
3328                                }
3329                                // unlock eit ptr location
3330                                if (lockfn)
3331                                        lockfn(FALSE);
3332                               
3333                               
3334                                // »ç¿ëÀÌ ³¡³­ ¸®¼Ò½º´Â ¹Ù·Î¹Ù·Î ÇØÁ¦ÇÑ´Ù.
3335                                //
3336                                DHL_PSI_FreePSIData(aProcData[i].desc); // parsingÀÌ ³¡³µ±â ¶§¹®¿¡ ÀÌ desc µ¥ÀÌÅÍ´Â ºÒÇÊ¿äÇÏ´Ù.
3337                                aProcData[i].desc = NULL;
3338                                //dprint(3, "\t\t aProcData[%d] freed\n", i);
3339
3340                                if (aPsiCtl[i]) {
3341                                        DHL_PSI_StopMonitor(aPsiCtl[i]);
3342                                        //dprint(3, "\t\t aPsiCtl[%d] freed\n", i);
3343                                }
3344                                else
3345                                        dprint(0, "!! PsiCtl[%d] NULL but event notified!\n", i);
3346                                       
3347                                aPsiCtl[i] = (tDHL_PSI_ControlHandle)0;
3348                               
3349                                // ÀÌÁ¦ »õ·Î¿î ¸ð´ÏÅ͸¦ ´Ù½Ã ½ÃÀÛÇÑ´Ù. ÇѰ³¸¸ Ãß°¡·Î ½ÃÀÛÇÏ¸é µÈ´Ù.
3350                                //
3351                                for (; idxMon<nETT; idxMon++)
3352                                {
3353                                        if (aEttPID[idxMon] == 0) {
3354                                                dprint(3, "\t Ett[%d] PID NULL, skip\n", idxMon);
3355                                                continue;
3356                                        }
3357                                       
3358                                        if (aEttPID[idxMon] <= 0 || aEttPID[idxMon] >= 0x1FFF) {  // cafrii 050315 add
3359                                                dprint(0, "!! Ett[%d] pid 0x%x invalid\n", idxMon, aEttPID[idxMon]);
3360                                                continue;
3361                                        }
3362                                       
3363                                        if (aEttPtrPtr[idxMon] == NULL) {
3364                                                dprint(0, "!! Ett[%d] output ptr NULL\n", idxMon);
3365                                                continue;
3366                                        }
3367
3368                                        err = MonitorEtt(tsd, aEttPID[idxMon], aETMID[idxMon], ePSIUPDATE_ONESHOT, 
3369                                                                        _Dmc_MultiEventProc, (UINT32)&aProcData[idxMon], &aPsiCtl[idxMon]);
3370                                        if (err) {
3371                                                dprint(0, "!! %d-th Ett monitor (pid %d, etm 0x%x) failed! err %d %s\n", 
3372                                                                        idxMon, aEttPID[idxMon], aETMID[idxMon], err, ErrorString((DHL_RESULT)err));
3373                                                if (!returnStatus) returnStatus = statusOutOfResource;
3374                                               
3375                                                if (err != DHL_FAIL_BUSY) // cafrii 041105 add condition
3376                                                        break;
3377                                        }
3378                                        else {
3379                                                dprint(2, "\t relayed monitor %d-th Ett ok\n", idxMon);
3380                                                nEttMonitor++;
3381                                                idxMon++;
3382                                        }
3383                                        break; // Çϳª¸¸ ¸ð´ÏÅÍ ÇÏ°í ³ª°¡¸é µÈ´Ù.
3384                                }
3385                               
3386                               
3387                                // Ett[i]¿¡ °üÇÑ ¸ðµç ÀÛ¾÷ÀÌ ³¡³µ´Ù. cancel ¿©ºÎ¸¦ °Ë»çÇÏ°í ´ÙÀ½ Eit·Î ³Ñ¾î°¨..
3388                                //
3389                                if (ckfn && ckfn(userparam, (UINT32) aEttPtrPtr[i])) {
3390                                        // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù.
3391                                        dprint(2, "!! download cancelled\n");
3392                                        bDownloadCancelled = TRUE;
3393                                        break;
3394                                }
3395                                       
3396                                break; // Çѹø¿¡ Çϳª¾¿ Ç¥½Ã..
3397                               
3398                        } // for all Etts..
3399                       
3400                        if (bDownloadCancelled) break;
3401                       
3402                        if (i >= nETT) 
3403                                dprint(2, " Ett event received but no related ett!!\n");
3404                        else
3405                                dprint(2, " Ett[%d] received (err %d) total %d, %d.%02d sec\n", i, 
3406                                        aProcData[i].err, nReceivedEtt, elapsedTime/100, elapsedTime%100);
3407                                       
3408                }// end if semaphore taken..
3409               
3410                if (ckfn && ckfn(userparam, 0)) {
3411                        // ¸ðµÎ´Ù Ãë¼ÒÇÏ¸é ¾ÈµÇ°í, ÇöÀç±îÁö ¼ö½ÅµÈ °ÍÀº 󸮸¦ ÇØ¾ß ÇÑ´Ù.
3412                        dprint(2, "!! download cancelled\n");
3413                        bDownloadCancelled = TRUE;
3414                        break;
3415                }
3416
3417                if (nReceivedEtt >= nEttMonitor) {
3418                        // ¸ðµç °ÍÀ» ´Ù ¼ö½ÅÇÏ¿´´Ù.
3419                        dprint(2, "all %d etts are received!!\n", nReceivedEtt);
3420                        break;
3421                }
3422               
3423                if ((int)(DHL_OS_GetMsCount() - tickStart) > timeOut) {
3424                        err = DHL_FAIL_TIMEOUT;
3425                                // cafrii 060420 add
3426                                // informs that timeout is occurred.
3427                        dprint(2, "!! timeout (%ds) err, only %d/%d/%d Etts received..\n", timeOut/1000,
3428                                                nGoodEtt, nReceivedEtt, nEttMonitor);
3429                        break;  // ÀϺδ ¹Þ¾ÒÀ» °ÍÀ̹ǷΠ¾Æ·¡ Parsing ÀÛ¾÷À» °ÅÃÄ¾ß ÇÑ´Ù.
3430                }
3431        }
3432       
3433       
3434CancelPsiMonitor:
3435        // Á¤»óÀûÀ¸·Î Á¾·áµÇ¾ú´Ù¸é À̰÷¿¡¼­ freeµÇ´Â °ÍÀº Çϳªµµ ¾ø¾î¾ß ÇÑ´Ù.
3436        // ±×·¯³ª timeoutÀ̳ª user cancelÀÌ µÇ¾ú´Ù¸é ÇöÀç ÁøÇàÁßÀÎ °ÍµéÀÌ ÀÖÀ» °ÍÀ̹ǷΠÀ̰÷¿¡¼­ »èÁ¦ÇØ¾ß ÇÑ´Ù.
3437        //
3438        for (i=0; i<nETT; i++) {
3439                if (aPsiCtl[i]) {
3440                        //dprint(3, "  cancel PsiCtls [%d] %x\n", i, aPsiCtl[i]);
3441                        if (bDownloadCancelled == FALSE && err != DHL_FAIL_TIMEOUT)
3442                                dprint(0, "!! relayett: aPsiCtl[%d] non-Null !! err %d, check it!\n", i, err);
3443                        DHL_PSI_StopMonitor(aPsiCtl[i]); 
3444                }
3445                if (aProcData[i].desc) {
3446                        //dprint(3, "  DHL_PSI_FreePSIData[%d] %x\n", i, aProcData[i].desc);
3447                        if (bDownloadCancelled == FALSE && err != (DHL_RESULT)statusTimeout)
3448                                dprint(0, "!! aProcData[%d].desc not NULL !!\n", i);
3449                        DHL_PSI_FreePSIData(aProcData[i].desc); // parsingÀÌ ³¡³µ±â ¶§¹®¿¡ ÀÌ desc µ¥ÀÌÅÍ´Â ºÒÇÊ¿äÇÏ´Ù.
3450                }
3451        }
3452        //dprint(3, "Free aPsiCtl %x, aProcData %x\n", aPsiCtl, aProcData);
3453        DHL_OS_Free((void**)&aPsiCtl);
3454        DHL_OS_Free((void**)&aProcData);
3455
3456        //dprint(3, "Deleting sema4 %x..\n", sema4);
3457        if (sema4)
3458                DHL_OS_DeleteSemaphore(sema4);
3459       
3460        dprint(3, " Total good %d /recv %d /mon %d /req %d ETTs..\n", nGoodEtt, nReceivedEtt, nEttMonitor, nETT);
3461#if 0
3462        for (i=0; i<nETT; i++)
3463                if (aEttPtrPtr[i]) dprint(3, "   Ett[%d]: 0x%x\n", i, *(aEttPtrPtr[i]));
3464#endif
3465               
3466        // ¿¡·¯´Â Ưº°È÷ ¸®ÅÏÇÏÁö ¾Ê¾Æµµ µÉµí.. ¾îÂ¥ÇÇ caller´Â ETT section pointer¸¦ °Ë»çÇØ¼­ ¿¡·¯ À¯¹«¸¦ Ã¼Å©ÇØ¾ß ÇÑ´Ù.
3467        //
3468        if (bDownloadCancelled)
3469                return statusCancelled;
3470
3471        for (i=0; i<nETT; i++) {
3472                // aPID[i]°¡ Non-NullÀ̸é request°¡ µÈ °ÍÀε¥, aEttSectPtrÀÌ NULLÀÌ¸é ¹º°¡ ¿¡·¯°¡ ¹ß»ýÇÑ °ÍÀÌ´Ù.
3473                if (aEttPID[i] && aEttPtrPtr[i] && *(aEttPtrPtr[i]) == NULL) {
3474                        if (returnStatus) 
3475                                return returnStatus;
3476
3477                        //return statusTimeout;
3478                        return nEttMonitor>0 ? statusTimeout : statusError; // ¼ö½Å ¿Ï·áÇÏÁö ¸øÇß´Ù´Â ÀǹÌÀÇ ¿¡·¯°¡ ¾øÀ½..
3479                        // cafrii 070712 bugfix
3480                        //   Ett monitor¸¦ Çϳªµµ ½ÃÀÛµµ ¸øÇÏ°í ¹Ù·Î Á¾·áÇÏ´Â °æ¿ì¶ó¸é timeout °á°ú¸¦ ÁÖ¸é ¾ÈµÈ´Ù.
3481                        //   ¹Ù·Î ´Ù½Ã Àç½Ãµµ¸¦ Çϱ⠶§¹®.
3482                }
3483        }
3484        return statusOK; // requestµÈ ¸ðµç EIT°¡ ¸ðµÎ Non-NULLÀÌ¸é ¼º°øÀ¸·Î ÇÏÀÚ..
3485}
3486
3487
3488STATUS Dmc_GetRelayETTs(tDHL_TSD tsd, int nETT, UINT16 *aEttPID, UINT32 *aETMID, ettSectionPtr_t *aEttSectPtr,
3489                                                        int timeOut, BOOL (*ckfn)(UINT32, UINT32), UINT32 userparam, void (*lockfn)(BOOL))
3490{
3491        // backward compatibile fnction..
3492        //
3493        int i;
3494        STATUS status;
3495        ettSectionPtr_t **ettPtrPtrArry = DHL_OS_Malloc(nETT * sizeof(ettSectionPtr_t *));
3496       
3497        if (ettPtrPtrArry == NULL) return statusOutOfMemory;
3498        memset (ettPtrPtrArry, 0, nETT * sizeof(ettSectionPtr_t *));
3499       
3500        for (i=0; i<nETT; i++)
3501                ettPtrPtrArry[i] = &aEttSectPtr[i];
3502       
3503        status = Dmc_GetRelayETTsEx(tsd, nETT, aEttPID, aETMID, ettPtrPtrArry, timeOut, ckfn, userparam, lockfn);
3504       
3505        DHL_OS_Free((void**)&ettPtrPtrArry);
3506
3507        return status;
3508}
3509
3510
3511
3512#if 0
3513_____________()
3514#endif
3515
3516#if 0
3517
3518// relay ÇÔ¼ö Å×½ºÆ®¿ë..
3519
3520#if 0 // test script
3521
3522        g_TuneNoEpgUpdate = 1
3523        g_Trace_DmcDemux = 4
3524       
3525        ch 11,1
3526       
3527        TestGetRelayEITs 1
3528
3529#endif
3530
3531int TestGetRelayEITs(int source_id)
3532{
3533        extern STATUS Dmc_EmmGetMgtSection(tDHL_TSD tsd, mgtSectionPtr_t *pMgtSectPtr, int timeOut, BOOL (*ckfn)());
3534
3535        int i, err, nEit = 0;
3536        mgtSectionPtr_t mgt;
3537       
3538        UINT16 aPID[128];
3539        UINT16 aSourceID[128];
3540       
3541        eitPtr_t aEit[128];
3542       
3543        int timeOut = 1000 * 61;
3544       
3545        tDHL_TSD tsd = Demux_getTSD(TU_TSD1);
3546       
3547        err = Dmc_EmmGetMgtSection(tsd, &mgt, 1000*3, NULL);
3548       
3549        if (err) {
3550                DHL_OS_Printf("!! No mgt!!\n");
3551                return 0;
3552        }
3553        DHL_OS_Printf("mgt section -0x%x\n", mgt);
3554       
3555        memset(aEit, 0, sizeof(aEit));
3556        memset(aPID, 0, sizeof(aPID));
3557        memset(aSourceID, 0, sizeof(aSourceID));
3558       
3559        for (i=0; i<mgt->tables_defined; i++) // search all tables..
3560        {
3561                int index;
3562               
3563                if (mgt->table[i].table_type >= tt_EIT_min &&
3564                        mgt->table[i].table_type <= tt_EIT_max)     
3565                {
3566                        index = (mgt->table[i].table_type - tt_EIT_min);
3567
3568                        aPID[index] = mgt->table[i].table_type_PID;
3569                        aSourceID[index] = source_id;
3570                       
3571                        DHL_OS_Printf("  [%d] Eit-%d : pid %d\n", nEit, index, aPID[index]);
3572
3573                        nEit++;
3574                }
3575        }
3576       
3577        DHL_OS_Printf("total %d Eits detected..\n", nEit);
3578       
3579        if (nEit > 0) {
3580                err = Dmc_GetRelayEITs(tsd, nEit, aPID, aSourceID, aEit, timeOut, NULL, 0, NULL);
3581
3582                if (err) {
3583                        DHL_OS_Printf("!! err in getting relayed eits..\n");
3584                }
3585                else {
3586                        for (i=0; i<nEit; i++) {
3587                                DHL_OS_Printf("Eit-%d   0x%x\n", i, aEit[i]);
3588                        }
3589                }
3590        }
3591       
3592}
3593
3594#endif
3595
3596
3597#if 0
3598int TestGetAllMajorTable()
3599{
3600        int err;
3601        tvctPtr_t tvct;
3602        cvctPtr_t cvct;
3603        MPEG_PAT  *pat;
3604
3605        tDHL_TSD tsd = Demux_getTSD(TU_TSD1);
3606       
3607        Dmc_PausePsiMonitor();
3608
3609        err = Dmc_GetVctAndPat(tsd, &tvct, &cvct, &pat, 1000*5, NULL);
3610
3611        dprint(2, "**** return %d, tvct %x, cvct %x, pat %x\n", err, tvct, cvct, pat);
3612       
3613        if (tvct) PrintTvct(tvct);
3614               
3615        if (cvct) PrintCvct(cvct);
3616       
3617        if (pat) PrintPAT(pat);
3618
3619        Dmc_ResumePsiMonitor();
3620       
3621        if (tvct) FreeAtscTable(tvct);
3622        if (cvct) FreeAtscTable(tvct);
3623        if (pat)  FreePAT(pat);
3624       
3625}
3626#endif
3627
3628
3629
3630
3631
3632
3633#if 0
3634_____________()
3635#endif
3636
3637
3638// cafrii 041126 add XVCT structure and Translate function
3639
3640// VCT¿¡ ä³ÎÀÌ 200ÀÌ»ó ÀÖÀ¸¸é 16K·Î ºÎÁ·ÇÑ °æ¿ì°¡ ¹ß»ý..
3641#undef MEM_LIMIT
3642#define MEM_LIMIT 0x8000 // 32k
3643
3644
3645/*==============================================================================
3646STATUS Dmc_TranslateCvct (cvctPtr_t cvctPtr, xvctPtr_t *xvctPtr)
3647
3648Translate CVCT into General XVCT structure and return its pointer
3649==============================================================================*/
3650STATUS Dmc_TranslateCvct (cvctPtr_t cvctPtr, xvctPtr_t *xvctPtr)
3651{
3652        UINT16 numChannels;
3653        UINT16 i;
3654        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
3655        memId_t memId = NULL;
3656        DHL_RESULT err;
3657        STATUS status = statusOK;
3658
3659        if (cvctPtr == NULL) return statusInvalidArgument;
3660       
3661        // create the memChain
3662        err = memChainCreate(&memId,&memSetup);
3663        if (err) {
3664                status = statusOutOfMemory;
3665                goto ParseExit;
3666        }
3667       
3668        // allocate memory for cvct
3669        *xvctPtr = (xvctPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(xvct_t)+sizeof(memId_t))) + 1);
3670        checkMemoryError(*xvctPtr);
3671
3672        // Get the total number of channels in all sections
3673        numChannels = cvctPtr->numChannels;
3674        //for (i=0; i<numSections; i++) {
3675        //      numChannels += sectionArr[i][9];
3676        //}
3677
3678        (*xvctPtr)->numChannels = numChannels;
3679
3680        // allocate space in xvct for channels
3681        (*xvctPtr)->channel = (xvctChannelPtr_t)memChainAlloc(memId,numChannels*sizeof(xvctChannel_t));
3682        checkMemoryError((*xvctPtr)->channel);
3683
3684        (*xvctPtr)->is_cvct = (vct_type_k)TRUE;  // cafrii 041130 move position
3685        (*xvctPtr)->transport_stream_id = cvctPtr->transport_stream_id;
3686        (*xvctPtr)->version_number = cvctPtr->version_number;
3687
3688        // allocate space for descriptors and copy (if any)
3689        if (cvctPtr->additional_descriptor_length > 0) {
3690                (*xvctPtr)->additional_descriptors = (UINT8 *)memChainAlloc(memId,cvctPtr->additional_descriptor_length*sizeof(UINT8));
3691                if ((*xvctPtr)->additional_descriptors == NULL) {
3692                        status = statusOutOfMemory; // cafrii 050713 add
3693                        goto ParseExit;
3694                }
3695                memcpy((*xvctPtr)->additional_descriptors,cvctPtr->additional_descriptors, (*xvctPtr)->additional_descriptor_length);
3696        }
3697
3698        for (i=0; i<numChannels; i++) {
3699               
3700                cvctChannelPtr_t cvctChannel = &cvctPtr->channel[i];
3701                xvctChannelPtr_t xvctChannel = &(*xvctPtr)->channel[i];
3702               
3703                memcpy(xvctChannel->short_name, cvctChannel->short_name, sizeof(UINT16)*7);
3704               
3705                xvctChannel->major_channel_number = cvctChannel->major_channel_number;
3706                xvctChannel->minor_channel_number = cvctChannel->minor_channel_number;
3707                xvctChannel->modulation_mode      = cvctChannel->modulation_mode;
3708                xvctChannel->carrier_frequency    = cvctChannel->carrier_frequency;
3709                xvctChannel->channel_TSID         = cvctChannel->channel_TSID;
3710                xvctChannel->program_number       = cvctChannel->program_number;
3711                xvctChannel->ETM_location         = cvctChannel->ETM_location;
3712                xvctChannel->access_controlled    = cvctChannel->access_controlled;
3713                xvctChannel->hidden               = cvctChannel->hidden;
3714       
3715                //xvctChannel->is_cvct              = TRUE;  // if cvct..
3716                xvctChannel->path_select          = cvctChannel->path_select;
3717                xvctChannel->out_of_band          = cvctChannel->out_of_band;
3718       
3719                xvctChannel->show_guide           = cvctChannel->show_guide;
3720                xvctChannel->service_type         = cvctChannel->service_type;
3721                xvctChannel->source_id            = cvctChannel->source_id;
3722       
3723                // allocate space for descriptors and copy (if any)
3724                if (cvctChannel->descriptor_length > 0) {
3725                        xvctChannel->descriptors = (UINT8 *)memChainAlloc(memId,cvctChannel->descriptor_length*sizeof(UINT8));
3726                        if (xvctChannel->descriptors == NULL) {
3727                                status = statusOutOfMemory; // cafrii 050713 add
3728                                goto ParseExit;
3729                        }
3730                        memcpy(xvctChannel->descriptors, cvctChannel->descriptors, cvctChannel->descriptor_length);
3731                        xvctChannel->descriptor_length = cvctChannel->descriptor_length;
3732                }
3733                else {
3734                        xvctChannel->descriptors = NULL;
3735                        xvctChannel->descriptor_length = 0;
3736                }
3737        }
3738
3739        // parsing complete
3740        *(((memId_t *)(*xvctPtr))-1) = memId;
3741        memId = NULL;           // so memChain not deleted
3742
3743ParseExit:
3744        if (memId) {
3745                // delete the xvct memory
3746                memChainDestroy(memId);
3747        }
3748
3749        return status;
3750}
3751
3752
3753
3754/*==============================================================================
3755STATUS Dmc_TranslateTvct (tvctPtr_t tvctPtr, xvctPtr_t *xvctPtr)
3756
3757Translate TVCT into General XVCT structure and return its pointer
3758==============================================================================*/
3759STATUS Dmc_TranslateTvct (tvctPtr_t tvctPtr, xvctPtr_t *xvctPtr)
3760{
3761        UINT16 numChannels;
3762        UINT16 i;
3763        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
3764        memId_t memId = NULL;
3765        DHL_RESULT err;
3766        STATUS status = statusOK;
3767       
3768        if (tvctPtr == NULL) return statusInvalidArgument;
3769       
3770        // create the memChain
3771        err = memChainCreate(&memId,&memSetup);
3772        if (err) {
3773                status = statusOutOfMemory;
3774                goto ParseExit;
3775        }
3776       
3777        // allocate memory for tvct
3778        *xvctPtr = (xvctPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(xvct_t)+sizeof(memId_t))) + 1);
3779        checkMemoryError(*xvctPtr);
3780
3781        // Get the total number of channels in all sections
3782        numChannels = tvctPtr->numChannels;
3783        //for (i=0; i<numSections; i++) {
3784        //      numChannels += sectionArr[i][9];
3785        //}
3786
3787        (*xvctPtr)->numChannels = numChannels;
3788
3789        // allocate space in xvct for channels
3790        (*xvctPtr)->channel = (xvctChannelPtr_t)memChainAlloc(memId,numChannels*sizeof(xvctChannel_t));
3791        checkMemoryError((*xvctPtr)->channel);
3792
3793        (*xvctPtr)->is_cvct = (vct_type_k)FALSE;  // cafrii 041130 move position
3794        (*xvctPtr)->transport_stream_id = tvctPtr->transport_stream_id;
3795        (*xvctPtr)->version_number = tvctPtr->version_number;
3796
3797        // allocate space for descriptors and copy (if any)
3798        if (tvctPtr->additional_descriptor_length > 0) {
3799                (*xvctPtr)->additional_descriptors = (UINT8 *)memChainAlloc(memId,tvctPtr->additional_descriptor_length*sizeof(UINT8));
3800                if ((*xvctPtr)->additional_descriptors == NULL) {
3801                        status = statusOutOfMemory; // cafrii 050713 add
3802                        goto ParseExit;
3803                }
3804                memcpy((*xvctPtr)->additional_descriptors,tvctPtr->additional_descriptors, (*xvctPtr)->additional_descriptor_length);
3805        }
3806
3807        for (i=0; i<numChannels; i++) {
3808               
3809                tvctChannelPtr_t tvctChannel = &tvctPtr->channel[i];
3810                xvctChannelPtr_t xvctChannel = &(*xvctPtr)->channel[i];
3811               
3812                memcpy(xvctChannel->short_name, tvctChannel->short_name, sizeof(UINT16)*7);
3813               
3814                xvctChannel->major_channel_number = tvctChannel->major_channel_number;
3815                xvctChannel->minor_channel_number = tvctChannel->minor_channel_number;
3816                xvctChannel->modulation_mode      = tvctChannel->modulation_mode;
3817                xvctChannel->carrier_frequency    = tvctChannel->carrier_frequency;
3818                xvctChannel->channel_TSID         = tvctChannel->channel_TSID;
3819                xvctChannel->program_number       = tvctChannel->program_number;
3820                xvctChannel->ETM_location         = tvctChannel->ETM_location;
3821                xvctChannel->access_controlled    = tvctChannel->access_controlled;
3822                xvctChannel->hidden               = tvctChannel->hidden;
3823       
3824                //xvctChannel->is_cvct              = FALSE;  // this is tvct..
3825                xvctChannel->path_select          = (path_select_k)0;
3826                xvctChannel->out_of_band          = 0;
3827       
3828                xvctChannel->show_guide           = tvctChannel->show_guide;
3829                xvctChannel->service_type         = tvctChannel->service_type;
3830                xvctChannel->source_id            = tvctChannel->source_id;
3831       
3832                // allocate space for descriptors and copy (if any)
3833                if (tvctChannel->descriptor_length > 0) {
3834                        xvctChannel->descriptors = (UINT8 *)memChainAlloc(memId,tvctChannel->descriptor_length*sizeof(UINT8));
3835                        if (xvctChannel->descriptors == NULL) {
3836                                status = statusOutOfMemory; // cafrii 050713 add
3837                                goto ParseExit;
3838                        }
3839                        memcpy(xvctChannel->descriptors, tvctChannel->descriptors, tvctChannel->descriptor_length);
3840                        xvctChannel->descriptor_length = tvctChannel->descriptor_length;
3841                }
3842                else {
3843                        xvctChannel->descriptors = NULL;
3844                        xvctChannel->descriptor_length = 0;
3845                }
3846        }
3847
3848        // parsing complete
3849        *(((memId_t *)(*xvctPtr))-1) = memId;
3850        memId = NULL;           // so memChain not deleted
3851
3852ParseExit:
3853        if (memId) {
3854                // delete the xvct memory
3855                memChainDestroy(memId);
3856        }
3857
3858        return status;
3859}
3860
3861
3862
3863void TestTranslateTvct(tvctPtr_t tvct, int number)
3864{
3865        int err, i;
3866        xvctPtr_t xvct;
3867       
3868        if (tvct == NULL) return;
3869       
3870        if (number == 0) number = 10;
3871       
3872        for (i=0; i<number; i++) {
3873
3874                DHL_OS_Printf("(%d) translate..\n", i);         
3875                err = Dmc_TranslateTvct(tvct, &xvct);
3876                if (err) {
3877                        DHL_OS_Printf("!! %d-th translate err\n", i);
3878                        break;
3879                }
3880               
3881                FreeAtscTable(xvct);
3882                xvct = NULL;
3883        }
3884}
3885
3886
3887
3888void PrintXvct(xvctPtr_t xvctPtr)
3889{
3890        INT32                           i,j;
3891       
3892        DHL_OS_Printf("\n------ XVCT (%s) ------\n", xvctPtr->is_cvct ? "CVCT" : "TVCT");
3893        DHL_OS_Printf("transport_stream_id:    0x%04X (%d)\n",(int)xvctPtr->transport_stream_id,(int)xvctPtr->transport_stream_id);
3894        DHL_OS_Printf("version_number:         %d\n", (int)xvctPtr->version_number);
3895        DHL_OS_Printf("numChannels:%d\n", (int)xvctPtr->numChannels);
3896        for (i=0; i<xvctPtr->numChannels; i++) {
3897                DHL_OS_Printf("channel[%d]:\n", i);
3898                DHL_OS_Printf("\tshort_name:                ");
3899                for (j=0; (j<7) && (xvctPtr->channel[i].short_name[j] != 0x0000); j++) {
3900                        if ((xvctPtr->channel[i].short_name[j] >> 8) == 0x00) {
3901                                DHL_OS_Printf("%c",(int)xvctPtr->channel[i].short_name[j]);
3902                        }
3903                        else {
3904                                DHL_OS_Printf("?");
3905                        }
3906                }
3907                DHL_OS_Printf("\n");
3908                DHL_OS_Printf("\tmajor_channel_number:      %d\n", (int)xvctPtr->channel[i].major_channel_number);
3909                DHL_OS_Printf("\tminor_channel_number:      %d\n", (int)xvctPtr->channel[i].minor_channel_number);
3910                DHL_OS_Printf("\tmodulation_mode:           0x%02X ", xvctPtr->channel[i].modulation_mode);
3911                switch (xvctPtr->channel[i].modulation_mode) {
3912                        case 0x00:
3913                                DHL_OS_Printf("(reserved)\n");
3914                                break;
3915                        case mm_analog:
3916                                DHL_OS_Printf("(analog)\n");
3917                                break;
3918                        case mm_SCTE_mode_1:
3919                                DHL_OS_Printf("(mm_SCTE_mode_1)\n");
3920                                break;
3921                        case mm_SCTE_mode_2:
3922                                DHL_OS_Printf("(mm_SCTE_mode_2)\n");
3923                                break;
3924                        case mm_ATSC_8VSB:
3925                                DHL_OS_Printf("(ATSC_8VSB)\n");
3926                                break;
3927                        case mm_ATSC_16VSB:
3928                                DHL_OS_Printf("(ATSC_16VSB)\n");
3929                                break;
3930                        case mm_private_descriptor:
3931                                DHL_OS_Printf("(Modulation defined in private descriptor)\n");
3932                                break;
3933                        default:
3934                                DHL_OS_Printf("(User Private)\n");
3935                                break;
3936                }
3937                DHL_OS_Printf("\tcarrier_frequency:         %f MHz\n", xvctPtr->channel[i].carrier_frequency/1000000.0);
3938                DHL_OS_Printf("\tchannel_TSID:              0x%04X\n", (int)xvctPtr->channel[i].channel_TSID);
3939                DHL_OS_Printf("\tprogram_number:            0x%04X\n", (int)xvctPtr->channel[i].program_number);
3940                DHL_OS_Printf("\tETM_location:              0x%02X ", xvctPtr->channel[i].ETM_location);
3941                switch (xvctPtr->channel[i].ETM_location) {
3942                        case    ETM_none:
3943                                DHL_OS_Printf("(No ETM)\n");
3944                                break;
3945                        case    ETM_in_this_PTC:
3946                                DHL_OS_Printf("(ETM in PTC carrying this PSIP)\n");
3947                                break;
3948                        case    ETM_in_channel_TSID_PTC:
3949                                DHL_OS_Printf("(ETM in PTC specified by channel_TSID)\n");
3950                                break;
3951                        default:
3952                                DHL_OS_Printf("(Reserved for future ATSC use)\n");
3953                                break;
3954                }
3955                DHL_OS_Printf("\taccess_controlled:         0x%01X (%s)\n", (int)xvctPtr->channel[i].access_controlled, xvctPtr->channel[i].access_controlled ? "Yes" : "No");
3956                DHL_OS_Printf("\thidden:                    0x%01X (%s)\n", (int)xvctPtr->channel[i].hidden,xvctPtr->channel[i].hidden ? "Yes" : "No");
3957                DHL_OS_Printf("\tpath_select:               0x%01X (path %d)\n", xvctPtr->channel[i].path_select,xvctPtr->channel[i].path_select+1);
3958                DHL_OS_Printf("\tout_of_band:               0x%01X (%s)\n", (int)xvctPtr->channel[i].out_of_band, xvctPtr->channel[i].out_of_band ? "Yes" : "No");
3959                DHL_OS_Printf("\tshow_guide:                0x%01X (%s)\n", (int)xvctPtr->channel[i].show_guide, xvctPtr->channel[i].show_guide ? "Yes" : "No");
3960                DHL_OS_Printf("\tservice_type:              0x%02X ", xvctPtr->channel[i].service_type);
3961                switch (xvctPtr->channel[i].service_type) {
3962                        case    st_analog_television:
3963                                DHL_OS_Printf("(analog_television)\n");
3964                                break;
3965                        case    st_ATSC_digital_television:
3966                                DHL_OS_Printf("(ATSC_digital_television)\n");
3967                                break;
3968                        case    st_ATSC_audio_only:
3969                                DHL_OS_Printf("(ATSC_audio_only)\n");
3970                                break;
3971                        case    st_ATSC_data_broadcast_service:
3972                                DHL_OS_Printf("(ATSC_data_broadcast_service)\n");
3973                                break;
3974                        default:
3975                                DHL_OS_Printf("(Reserved)\n");
3976                                break;
3977                }
3978                DHL_OS_Printf("\tsource_id:                 0x%04X\n", (int)xvctPtr->channel[i].source_id);
3979                DHL_OS_Printf("\tdescriptor_length:         %d\n", (int)xvctPtr->channel[i].descriptor_length);
3980               
3981                for (j=0; j<xvctPtr->channel[i].descriptor_length; j++)
3982                        DHL_OS_Printf("%02x ", (int)(xvctPtr->channel[i].descriptors[j]));
3983                if (xvctPtr->channel[i].descriptor_length)
3984                        DHL_OS_Printf("\n");
3985        }
3986        DHL_OS_Printf("additional_descriptor_length:  %d\n", (int)xvctPtr->additional_descriptor_length);
3987       
3988        for (j=0; j<xvctPtr->additional_descriptor_length; j++)
3989                DHL_OS_Printf("%02x ", (int)(xvctPtr->additional_descriptors[j]));
3990        if (xvctPtr->additional_descriptor_length)
3991                DHL_OS_Printf("\n");
3992}
3993
3994
3995
3996
3997#if 0
3998
3999
4000        Dmc_GetEttSection dmc_tsd, 0x1200, 0x3683a, &ett, 5*60*60, 0
4001        Dmc_GetEit dmc_tsd, 0x1001, 3, &eit, 10*60*60, 0
4002
4003#endif
4004
4005
4006
4007#if COMMENT
4008__________(){}
4009#endif
4010
4011
4012#if TEST_CHANNEL_DEMUX
4013
4014
4015static int gCancelRequestCount;
4016static int gTimeout = 2;
4017
4018void PsiCancel()
4019{
4020        gCancelRequestCount = 1;
4021}
4022
4023static BOOL _SimpleCheck(UINT32 param)
4024{
4025        if (gCancelRequestCount) {
4026                gCancelRequestCount = 0;
4027                printf("!!!! cancelled\n");
4028                return TRUE;
4029        }
4030        return FALSE;
4031}
4032
4033#include "DHL_FE.h"
4034void TestPsi(int id, int param1, int param2, int param3, int param4)
4035{
4036        STATUS status;
4037        tDHL_TSD tsd = DHL_DMX_GetTsd();
4038        int sec = 1000;
4039
4040        if (id == 0) { // Tuner set:   TestPsi 0, 1, 81
4041                DHL_RESULT dhlResult;
4042                printf("Tune RF, channeltype %d, RF %d\n", param1, param2);
4043
4044                // param1 (0:AIR, 1:STD)
4045                param2=DHL_FE_ChannelToFrequency(param2, (tDHL_FreqStd)param1);
4046
4047                dhlResult = DHL_FE_Start(DEFAULT_TUNER_ID, param2, eDHL_DEMOD_8VSB, NULL);
4048                printf("Ch %d start result %d\n", param2, dhlResult);
4049        }
4050        else if (id == 100) { // Timeout:   TestPsi 100 10
4051                printf("\n timeout changed to %d sec\n", param1);
4052                gTimeout = param1;
4053        }
4054        if (id == 1) {  // GetPAT:  TestPsi 1
4055                MPEG_PAT *pat;
4056                gCancelRequestCount = 0;
4057                status = Dmc_GetPAT(tsd, &pat, gTimeout*sec, _SimpleCheck);
4058                if (!status) {
4059                        PrintPAT(pat);
4060                        Dmc_FreeAtscTable(&pat);
4061                }
4062                else
4063                        printf("!! status %d %s\n", status, DMW_CDB_ErrString(status));
4064        }
4065        else if (id == 2) { // GetPMT:  TestPsi 2, 16, 1
4066                MPEG_PMT *pmt;
4067                printf("Get PMT of pid %u, #%u..\n", param1, param2);
4068                gCancelRequestCount = 0;
4069                status = Dmc_GetPMT(tsd, param1, param2, &pmt, gTimeout*sec, _SimpleCheck);
4070                if (!status) {
4071                        PrintPMT(pmt);
4072                        Dmc_FreeAtscTable(&pmt);
4073                }
4074                else
4075                        printf("!! status %d %s\n", status, DMW_CDB_ErrString(status));
4076        }
4077        else if (id == 3) { // GetTvct:  TestPsi 3
4078                tvctPtr_t tvct;
4079                gCancelRequestCount = 0;
4080                status = Dmc_GetTvct(tsd, &tvct, gTimeout*sec, _SimpleCheck);
4081                if (!status) {
4082                        PrintTvct(tvct);
4083                        Dmc_FreeAtscTable(&tvct);
4084                }
4085                else
4086                        printf("!! status %d %s\n", status, DMW_CDB_ErrString(status));
4087        }
4088        else if (id == 4) { // Xvct:   TestPsi 4
4089                xvctPtr_t xvct;
4090                gCancelRequestCount = 0;
4091                status = Dmc_GetXvct(tsd, &xvct, gTimeout*sec, _SimpleCheck);
4092                if (!status) {
4093                        PrintXvct(xvct);
4094                        Dmc_FreeAtscTable(&xvct);
4095                }
4096                else
4097                        printf("!! status %d %s\n", status, DMW_CDB_ErrString(status));
4098        }
4099        else if (id == 10) {  // TVCT, CVCT, PAT multi:  TestPsi 10
4100                tvctPtr_t tvct = NULL;
4101                cvctPtr_t cvct = NULL;
4102                MPEG_PAT *pat = NULL;
4103                gCancelRequestCount = 0;
4104                status = Dmc_GetVctAndPat(tsd, &tvct, &cvct, &pat, gTimeout*sec, _SimpleCheck);
4105                if (!status) {
4106                        if (tvct)
4107                                PrintTvct(tvct);
4108                        if (cvct)
4109                                PrintCvct(cvct);
4110                        if (pat)
4111                                PrintPAT(pat);
4112
4113                        Dmc_FreeAtscTable(&tvct);
4114                        Dmc_FreeAtscTable(&cvct);
4115                        Dmc_FreeAtscTable(&pat);
4116                }
4117                else
4118                        printf("!! status %d %s\n", status, DMW_CDB_ErrString(status));
4119        }
4120        else if (id == 20) {  // Main Channel Table multi
4121                DmcMainTables tbls;
4122                gCancelRequestCount = 0;
4123                status = Dmc_GetMainChannelTables(tsd, &tbls, gTimeout*sec, _SimpleCheck);
4124                if (!status) {
4125                        printf("  tvct 0x%x, cvct 0x%x, pat 0x%x, #pmt %d\n", 
4126                                tbls.tvct, tbls.cvct, tbls.pat, tbls.num_programs);
4127               
4128                        Dmc_FreeMainChannelTables(&tbls);
4129                }
4130                else
4131                        printf("!! status %d %s\n", status, DMW_CDB_ErrString(status));
4132        }
4133
4134}
4135
4136
4137/*
4138        cafrii 070730 add
4139        TVCT continuous reception test
4140                for prot sarnoff stream analysis
4141*/
4142void _TvctContTestEventProc(tDHL_PSI_Event event, tDHL_PSI_ControlHandle psiCtl, UINT32 userParam)
4143{
4144        //PSIMultiEventProcData *procData = (PSIMultiEventProcData *)userParam;
4145        tDHL_PSI_DataArray *desc;
4146        DHL_RESULT err;
4147        tvctPtr_t tvct;
4148
4149        switch (event) {
4150                case ePSIEVENT_DATARECEIVED:
4151                        err = DHL_PSI_ReadPSIData(psiCtl, &desc);
4152                        if (err) {
4153                                dprint(0, "@@@@ !! DHL_PSI_ReadPSIData returned %s\n",ErrorString(err));
4154                                break;
4155                        }
4156                        dprint(0, "===== TVCT =====\n");
4157                        err = ParseTvct(desc->sectPtr, &tvct);
4158                        if (err) {
4159                                dprint(0, "@@@@ !! ParseTvct err %d\n", err);
4160                                DHL_PSI_FreePSIData(desc);
4161                                break;
4162                        }
4163                        DHL_PSI_FreePSIData(desc);
4164                        PrintTvct(tvct);
4165                        Dmc_FreeAtscTable(&tvct);
4166                        break;
4167
4168                default:
4169                        dprint(0, "@@@@ %s\n", DHL_PSIEventString(event));
4170                        break;
4171        }
4172}
4173
4174/*
4175        test ½ÃÀÛÇϱâ: TvctContTest &
4176        test Á¾·á: TvctContTest 1
4177*/
4178void TvctContTest(BOOL bStop)
4179{
4180        DHL_RESULT err;
4181        tDHL_TSD tsd = DHL_DMX_GetTsd();
4182
4183        static tDHL_PSI_ControlHandle s_psiCtl;
4184
4185        if (bStop) {
4186                if (s_psiCtl) {
4187                        DHL_PSI_StopMonitor(s_psiCtl);
4188                        s_psiCtl = 0;
4189                }
4190                else
4191                        DHL_OS_Printf("!! no psictrl\n");
4192                return;
4193        }
4194       
4195        err = MonitorTvct(tsd, ePSIMODE_TABLE, ePSIUPDATE_CONTINEOUS, _TvctContTestEventProc, 
4196                                                (UINT32)0, &s_psiCtl);
4197        if (err) {
4198                DHL_OS_Printf("!! Monitor err %d\n", err);
4199        }
4200}
4201
4202
4203
4204#endif // TEST_CHANNEL_DEMUX
4205
4206
4207
4208
4209#if COMMENT
4210___________(){}
4211#endif
4212
4213
4214#if DMW_REGISTER_DEBUG_SYMBOL
4215
4216static DHL_SymbolTable ChannelDemuxSymbols[] =
4217{
4218        //---- functions
4219       
4220        //---- variables
4221        //DHL_VAR_SYM_ENTRY(g_Trace_DmcDemux),
4222        0,
4223};
4224
4225#endif // DMW_REGISTER_DEBUG_SYMBOL
4226
4227
4228void Dmc_RegisterChannelDemuxSymbols()
4229{
4230#if DMW_REGISTER_DEBUG_SYMBOL
4231        DHL_DBG_RegisterSymbols(ChannelDemuxSymbols, DHL_NUMSYMBOLS(ChannelDemuxSymbols));
4232#endif
4233}
4234
4235
4236
4237
4238
4239/********************************************************************
4240   $Log: DMW_ChannelDemux.c,v $
4241
4242        1.45 2005/3/15  ParseXXX È£Ãâ ÈÄ ¸®ÅϰªÀÌ ¿¡·¯À̸é pointer¸¦ NULL·Î ¼³Á¤
4243                        PMT, Eit, Ett ¸ð´ÏÅÍ¿¡ pid °ª validity üũ
4244       
4245        1.44 2004/11/30 is_cvct À§Ä¡ À̵¿
4246        1.43 2004/11/29 DmcMainTables ±¸Á¶ Ãß°¡ ¹× MainChannelTable ¼ö½Å ÇÔ¼ö Ãß°¡
4247       
4248        1.42 2004/11/26 Dmc_Translate*vct Ãß°¡
4249
4250        1.41 2004/11/5  ƯÁ¤ »óȲ¿¡¼­ nGoodEit µî º¯¼öµé ÃʱâÈ­ ¾ÈµÈ ¹®Á¦ ¼öÁ¤
4251                        MonitorEit/Ett µî¿¡¼­ ¿¡·¯³¯ °æ¿ì ´ëÀÀ ÄÚµå Ãß°¡
4252        1.4  2004/10/20 move DMW_DEMUX_DEBUG block to Epg-X module
4253        1.3  2004/7/12  change ckfn prototype,
4254                        parse tables while MulipleRx
4255                        add userparam, lock fn in multi-rx function
4256                        timeOut value now can be negative in all GetXX fn
4257                        wait tick is unified using PSIP_WAIT_IN_TICK
4258        1.25 2004/7/02  DMW_DEMUX_DEBUG flag added
4259        1.24 2004/6/17  Dmc_GetVctAndPat redesigned
4260        1.23 2004/06/07 SYS_TIME_MODULE_ENABLED, DMW_UNIPRINT_ENABLED add
4261        1.22 2004/04/28 bugfix, debug line update
4262        1.21 2004/04/20 GetMultipleExxEx, Dmc_GetStt/Rrt added
4263        1.2  2004/04/01 add GetMultipleETTs
4264        1.1  2004/03/31 add GetMultipleEITs
4265        1.0  2004/01/?? add Cancellable GetPsi functions
4266
4267*********************************************************************/
Note: See TracBrowser for help on using the repository browser.