source: svn/newcon3bcm2_21bu/dst/dmw/src/psi/DMW_PsiDatabase.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: 77.2 KB
Line 
1/*
2        DMW_PsiDatabase.c
3
4        DST TV MW PSI Scan Module
5
6        PSI Database management implementation
7
8        Copyright 2006~2009 Digital STREAM Technology, Inc.
9        All Rights Reserved
10
11*/
12
13
14#include "DMW_Platform.h"
15
16#include "DMW_PsiUtil.h"
17#include "DMW_PsiDatabase.h"
18#include "DMW_PsiEngine.h"
19#include "DMW_PsiLinkedList.h"
20
21#include "DMW_PsiAPI.h"
22
23
24// additional headers
25#include "DMW_Mutex.h"
26#include "DMW_CodeConv.h"
27
28
29
30
31
32#if COMMENT
33____DbgPrint____(){}
34#endif
35
36
37DHL_MODULE("psidb", 1);
38
39
40
41#if COMMENT
42____Config____(){}
43#endif
44
45
46int gPsiDontDownloadChannelEtt = 0;
47        // ½ÇÁ¦ Çʵ忡¼­ Channel ETT°°Àº °æ¿ì´Â Mgt¿¡ µî·ÏÀº µÇ¾î ÀÖÀ¸¸é¼­ ½ÇÁ¦·Î´Â ¾ø´Â °æ¿ì°¡ ÀÖ´Ù.
48        // ±×·¡¼­ Å×/½º/Æ®/·Î À̸¦ ¸·¾Æ¹ö¸®´Â ¿É¼ÇÀ» µÎ¾úÀ½.
49        // ±×·¯³ª ÀÌ ¿É¼ÇÀ» ½ÇÁ¦ ¾ç»ê ÇÁ·Î±×·¥¿¡ Àû¿ëÇϱâ´Â ¾î·Æ´Ù..
50
51
52
53int gPsiReloadAllTableAtMgtChange = 0;
54        // Mgt check·çƾÀÌ ¹®Á¦°¡ ÀÖÀ» °æ¿ì À̰ÍÀ» 1·Î ÇØ¼­ ¹«Á¶°Ç ´Ù½Ã ¹Þµµ·Ï ÇÏ´Â ¿É¼Ç..
55        // ÀÌ ¿É¼ÇÀ» ¾²¸é À߸øµÈ PSIP¿¡ ´ëÇØ Á» ´õ ¾ÈÀüÇÏ°Ô ´ëÀÀÀÌ °¡´ÉÇϱâ´Â ÇÏ´Ù..
56        // ´ë½Å ´Ù½Ã ¸ðµç tableÀ» ¹Þ¾Æ¾ß ÇϹǷΠ½Ã°£Àº ´õ °É¸±°ÍÀÓ..
57        // Á¦´ë·Î ÇÏ·Á¸é FALSE À̾î¾ß ÇÔ.
58        // Å×½ºÆ® °á°ú ÀÌ ¿É¼ÇÀÌ ¾øÀ̵µ ´ëü·Î Àß µ¿ÀÛÇÏ´Â °Í °°¾Æ¼­ ¸·¾ÆµÒ..
59
60
61int gPsiFakeMgtVersionChange = 0;
62        // mgt°¡ ¹öÀüÀÌ ¹Ù²ï°Íó·³ Èä³»³»´Â Å×½ºÆ® Ç÷¡±×..
63        // TRUEÀÌ¸é ¸Å¹ø mgt ÀÌÇÏ ¸ðµç Å×À̺íÀ» ´Ù½Ã ¹ÞÀ¸¹Ç·Î »ç¿ë ÁÖÀÇ!!!
64
65int gPsiInterTableCompareInMgtChange = 1;
66        // ÀÌ °ªÀÌ TRUE À̸é Mgt version change ½Ã¿¡ ¼­·Î ´Ù¸¥ index °£ÀÇ Eit/Ett tableµéÀ»
67        // ºñ±³Çغ¸¾Æ¼­ ÃÖ´ëÇÑ Àç»ç¿ëÀ» ÇÑ´Ù.
68        // ¿¹¸¦ µé¾î ÀÌÀü mgtÀÇ Eit-3 °ú »õ mgtÀÇ Eit-2 °¡ ¹öÀü°ú table Å©±â°¡ °°À¸¸é À̸¦
69        // Àç»ç¿ëÀ» ÇÑ´Ù.
70        // ±×·±µ¥ Spec¿¡ ÀÇÇϸé ÀÌ °ªÀº 0ÀÌ µÇ¾î¾ß ÇÑ´Ù. (A/65)
71        // ¾îµð±îÁö³ª À̰ÍÀº ¹æ¼Û»ç PSIP generation programÀÇ µ¿ÀÛ¿¡ µû¶ó À¯¿ëÇÒ¼öµµ, ¾øÀ» ¼öµµ ÀÖ´Ù.
72        // ±×·¯³ª 1À̶ó¸é Sarnoff ¿¹Á¦¿Í °°ÀÌ Eit shiftÇÏ´Â °æ¿ì ÁÁÀº ¼º´ÉÀ» º¸ÀÏ ¼ö ÀÖ´Ù.
73        // ´ëü·Î ¿ÏÀüÈ÷ ¼­·Î ´Ù¸¥ Å×À̺íÀÌ ¹öÀüµµ °°°í, table sizeµµ °°À» °æ¿ì°¡ ÈçÇÏÁö ¾ÊÀ¸¹Ç·Î
74        // ÀÏ´Ü TRUE·Î ÇØ¼­ Å×½ºÆ®¸¦ Çϰí ÀÖÀ½..
75        // ¹®Á¦°¡ µÇ¸é 0À¸·Î ¼³Á¤Çϱ⠹ٶ÷.
76
77int gPsiDeleteEttsWhenEitChange = 1;
78        // Eit°¡ ¹Ù²ð°æ¿ì ±×¿¡ ÇØ´çÇÏ´Â Ett¸¦ ¹«Á¶°Ç Áö¿ì´Â Ç÷¡±×
79        // º¸ÅëÀº Ettµµ ¹öÀü üũ¸¦ ÇØ¼­ º¯°æµÇ¾ú´Ù°í ÆÇ´ÜµÇ´Â °æ¿ì¿¡¸¸ Áö¿ì´Â°Ô ÁÁ°Ú´Ù.
80        // PSIP Ç¥ÁØ¿¡ ÀÇÇÏ¸é ³»¿ëÀÌ ¹Ù²î¸é ¹Ýµå½Ã ¹öÀüµµ ¹Ù²ð °ÍÀ̹ǷÎ
81        // ¹«Á¶°Ç Áö¿ìÁö ¾Ê¾Æµµ ¹öÀü üũ ·çƾ¿¡¼­ ÆÇ´ÜÇÏ¿© ÇÊ¿äÇÏ¸é ´Ù½Ã ¹ÞÀ» °ÍÀÌ´Ù.
82
83int gPsiMaxEitEttIndexToReceive = 127;
84        //
85        // Eit/Ett¸¦ ¸ðµÎ ´Ù ¹ÞÀ» Çʿ䰡 ¾ø´Â ½Ã½ºÅÛÀÌ Àִµ¥,
86        // ±×·± °æ¿ì ÃÖ´ë Index¸¦ ÁöÁ¤ÇØ ³õÀ¸¸é ÇÊ¿äÇÑ ¸¸Å­¸¸ ¹Þ°Ô µÈ´Ù.
87        // 127 ÀÌ¸é ¸ðµÎ ´Ù ¹Þ´Â °ÍÀ̰í,
88        // -1·Î ÁöÁ¤Çϸé Eit/Ett´Â Çϳªµµ ¹ÞÁö ¾Ê´Â´Ù..
89        //
90        // 0 ºÎÅÍ 127 ±îÁö ÀÓÀÇÀÇ ¼ö¸¦ ÁöÁ¤ ÇÒ ¼ö ÀÖ´Ù. ´Ü Runtime Áß¿¡´Â º¯°æµÇÁö ¾Êµµ·Ï ÇÏÀÚ.
91
92
93int gPsiSkipCheckVersionMatchMgtAndEit = 0;
94int gPsiSkipCheckVersionMatchMgtAndEtt = 0;
95        //
96        // mgt¿¡¼­ ±â¼úÇϰí ÀÖ´Â EitÀÇ version ¹øÈ£¿Í ½ÇÁ¦ EitÀÇ version ¹øÈ£°¡
97        // ÀÏÄ¡ÇÏ´ÂÁö üũÇÏ´Â Äڵ带 skip.
98        // ºÎÀÛ¿ëÀÌ ÀÖÀ» ¼ö ÀÖÀ½.
99        // mgt versionÀÌ º¯°æµÇ¸é¼­ ½ÇÁ¦·Î eit versionÀº º¯°æµÇÁö ¾Ê¾Ò´õ¶óµµ
100        // eit¸¦ ´Ù½Ã ´Ù¿î·Îµå ¹Þ°Ô µÊ.
101        // ORIONÀÇ ¿©·¯ ½ºÆ®¸²µéÀ» Å×½ºÆ® ÇÏ·Á¸é ÀÌ flag ÇÊ¿ä.
102
103
104
105#if COMMENT
106____DB____(){}
107#endif
108
109
110#if DMW_EPG_SUPPORT_RRT
111
112        extern rrtSectionPtr_t g_EpgRrt;
113                // ¼ö½ÅÇÑ rrt
114
115        extern UINT32 g_EpgRrtUpdateCount;
116                // rrt°¡ update µÉ ¶§ ¸¶´Ù Áõ°¡ÇÏ´Â counter
117       
118        extern int g_EpgRrtForceUpdateMode;
119                // force update mode:
120                // ÀÌ¹Ì ¼ö½ÅµÇ¾î ÀÖ´Â rrt version¿¡ °ü°è¾øÀÌ ¹«Á¶°Ç rrt¸¦ ´Ù½Ã ¹Þ´Â ¸ðµå.
121                // ³»ºÎ state variable À̸ç,
122                // menu¿¡¼­ »ç¿ëÀÚ°¡ "rrt update" ±â´ÉÀ» ¼±ÅÃÇϸé ÀÌ flag°¡ setµÇ°í
123                // rrt¸¦ 1ȸ updateÇϸé ÀÚµ¿À¸·Î reset µÈ´Ù.
124       
125#endif
126
127
128
129#if COMMENT
130____Mutex____(){}
131#endif
132
133
134//===========================================================================
135//
136//   Mutex Service
137//
138
139//   Mutex = { SemID, Owner, lockCnt, FailCnt, UseOsMutex, Name, flag,        traceLvl }
140//
141DMW_MUTEX
142   g_MutexPsiDB = { 0,     0,     0,       0,       TRUE,  "PSI", OS_SEM_PRIO, FALSE, };
143                        // cafrii 050701 change UseOsMutex param to TRUE
144                        // ThreadX¿¡¼­´Â OS mutex°¡ ¾ÈÀüÇϱ⠶§¹®¿¡ µð¹ö±ë ÆíÀÇ»ó OS Mutex¸¦ »ç¿ëÇÑ´Ù.
145
146   // g_EpgDB --> ChannelInfo, SubChannelInfo µ¥ÀÌÅ͸¦ º¸È£Çϴµ¥ »ç¿ëµÇ´Â mutex semaphore
147   //
148   // Rule 1:
149   //     EPG Scan Task ¿¡¼­´Â EpgDB´Â ¾Æ¹«¶§³ª ¸¶À½µ¥·Î ÀÐÀ» ¼ö ÀÖ´Ù.
150   //     EPG Scan Task ¿¡¼­ EpgDB¸¦ ¼öÁ¤ (write) ÇÒ °æ¿ì¿¡´Â Mutex LockÀ» ÇØ¾ß ÇÑ´Ù.
151   //
152   // Rule 2:
153   //     ÀÓÀÇÀÇ Task ¿¡¼­´Â EpgDB¸¦ Àý´ë ¼öÁ¤ ÇÒ ¼ö ¾ø´Ù.
154   //     ÀÓÀÇÀÇ Task ¿¡¼­ EpgDB¸¦ ÀÐÀ¸·Á¸é Mutex Lock »óÅ¿¡¼­ Àоî¾ß ÇÑ´Ù.
155   //
156
157
158PSI_STATIC void LockPsiDB(BOOL bLock)
159{
160        if (bLock)
161                DMW_LockMutex(&g_MutexPsiDB);
162        else
163                DMW_UnlockMutex(&g_MutexPsiDB);
164}
165
166#if 0
167void DeletePsiDBMutex(void)
168{
169        DMW_DeleteMutex(&g_MutexPsiDB);
170}
171#endif
172
173
174
175
176
177
178
179
180#if COMMENT
181____Get_API____(){}
182#endif
183
184
185PSI_STATIC S_PSIM_SUBCHINFO *GetSubChInfo(int id, int source_id)
186{
187        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
188        int i;
189
190        if (!chInfo) return NULL;
191
192        if (chInfo->n_subchannel == 0 || chInfo->subchannel == NULL) return NULL;
193
194        for (i=0; i<chInfo->n_subchannel; i++) {
195                if (chInfo->subchannel[i].source_id == source_id)
196                        return &chInfo->subchannel[i];
197        }
198        return NULL;
199}
200
201/*
202        database lockÀº ÇÏÁö ¾ÊÀ¸¹Ç·Î, caller°¡ ÁÖÀÇÇØ¼­ »ç¿ëÇÒ °Í.
203*/
204MPEG_PAT *PSIDB_GetPAT(int id)
205{
206        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
207        return chInfo ? chInfo->pat : NULL;
208}
209
210MPEG_PMT **PSIDB_GetPMTs(int id)
211{
212        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
213        return chInfo ? chInfo->pmts : NULL;
214}
215
216mgtSectionPtr_t PSIDB_GetMgt(int id)
217{
218        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
219        return chInfo ? chInfo->mgt : NULL;
220}
221
222xvctPtr_t PSIDB_GetVct(int id)
223{
224        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
225        return chInfo ? chInfo->vct : NULL;
226}
227
228sttSectionPtr_t PSIDB_GetStt(int id)
229{
230        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
231        return (chInfo && chInfo->stt_valid) ? &chInfo->flat_stt : NULL;
232}
233
234eitPtr_t *PSIDB_GetEits(int id, int source_id)
235{
236        S_PSIM_SUBCHINFO *subchInfo = GetSubChInfo(id, source_id);
237
238        return subchInfo ? subchInfo->eits : NULL;
239}
240
241eitPtr_t PSIDB_GetEit(int id, int source_id, int iEit)
242{
243        eitPtr_t *eits;
244        if (iEit<0 || iEit>=128) return NULL;
245
246        eits = PSIDB_GetEits(id, source_id);
247        return eits ? eits[iEit] : NULL;
248}
249
250S_PSIM_MGT_DIGEST *PSIDB_GetMgtDigest(int id)
251{
252        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
253        return chInfo ? &chInfo->smgt : NULL;
254}
255
256
257#if COMMENT
258____Check____(){}
259#endif
260
261
262/*
263        check that all pmts (and pat) are received.
264
265*/
266BOOL PSIDB_IsPmtsCompleted(int id)
267{
268        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
269        int i;
270        BOOL bPmtComplete = TRUE;
271
272        if (!chInfo) return FALSE;
273        if (!chInfo->pat || !chInfo->pmts) return FALSE;
274       
275        for (i=0; i<chInfo->pat->numPrograms; i++) {
276                if (chInfo->pmts[i] == NULL) {
277                        bPmtComplete = FALSE;
278                        break;
279                }
280        }
281        return bPmtComplete;
282}
283
284/*
285        check that subchannel scan is ready to start.
286
287        both mgt and vct is required.
288*/
289BOOL PSIDB_IsSubChScanReadyToStart(int id)
290{
291        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
292
293        if (!chInfo) return FALSE;
294        return (chInfo->mgt && chInfo->vct) ? TRUE : FALSE;
295}
296
297
298/*
299        ÇØ´ç subchannel (@id, @source_id)ÀÇ ¸ðµç EIT°¡ ¼ö½ÅµÇ¾ú´ÂÁö °Ë»ç.
300        complete µÇ¾ú´Ù¸é TRUE ¸®ÅÏ.
301       
302        return true if all eits in the specified subchannel (with @source_id)
303        are received.
304*/
305BOOL PSIDB_IsSubChEitsCompleted(int id, int source_id)
306{
307        int i, maxEitIndex;
308        BOOL bEitsCompleted = FALSE;
309
310        S_PSIM_SUBCHINFO *subchInfo;
311        S_PSIM_CHINFO *chInfo;
312
313        S_PSIM_MGT_DIGEST *smgt;
314       
315        subchInfo = PSIDB_GetPsiSubChInfo(id, source_id);
316        if (!subchInfo) goto label_end;
317       
318        chInfo = subchInfo->parent;
319        if (!chInfo) goto label_end;
320
321        smgt = &chInfo->smgt;
322
323        maxEitIndex = min(127, gPsiMaxEitEttIndexToReceive);
324
325        for (i=0; i<=maxEitIndex; i++)
326        {
327                if (smgt->eit_pids[i] == 0) continue; // no such eit[i].
328
329                if (subchInfo->eits[i] == NULL) {
330                        dprint(2, " eit-%d not received..\n", i);
331                        goto label_end;
332                }
333                if (smgt->eit_ver[i] != subchInfo->eits[i]->version_number) {
334                        if (gPsiSkipCheckVersionMatchMgtAndEit)
335                                dprint(1, "!! eit-%d (ver %d) version mismatch (mgt's %d), but continue\n", i, 
336                                                subchInfo->eits[i]->version_number, smgt->eit_ver[i]);
337                        else {
338                                dprint(0, "!! eit-%d (ver %d) version mismatch (mgt's %d)\n", i, 
339                                                subchInfo->eits[i]->version_number, smgt->eit_ver[i]);
340                                goto label_end; // need to receive again..
341                        }
342                }
343        }
344        bEitsCompleted = TRUE;
345
346label_end:
347        return bEitsCompleted;
348
349}
350
351
352/*
353        check eit[@iEit] of all subch received or not.
354        if all received, return true.
355        if it returns true, caller will close eit psi filter.
356        it is used for autoscan mode.
357
358        if status is not correct, return false.
359*/
360BOOL PSIDB_IsAllSubChEitsCompleted(int id, int iEit)
361{
362        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
363        int i;
364
365        if (iEit < 0 || iEit >= 128) return FALSE;
366       
367        if (!chInfo) return FALSE;
368
369        if (chInfo->n_subchannel == 0 || chInfo->subchannel == NULL) return FALSE;
370
371        for (i=0; i<chInfo->n_subchannel; i++) {
372                if (chInfo->subchannel[i].eits[iEit] == NULL) return FALSE;
373        }
374        return TRUE;
375}
376
377/*
378        PSIDB_IsSubChEttVRequired
379       
380        ƯÁ¤ subchannel (@id, @source_id)ÀÇ channel_ett°¡ ¼ö½ÅµÇ¾î¾ß ÇÏ´ÂÁö¸¦ °Ë»ç.
381        ¼ö½ÅµÇ¾î¾ß ÇÑ´Ù¸é true ¸®ÅÏ.
382
383        ÁÖÀÇ! channel_ett°¡ ¹Þ¾ÆÁ³´ÂÁö¸¦ üũÇÏ´Â °ÍÀÌ ¾Æ´Ï¶ó ¹Þ¾Æ¾ß ÇÏ´ÂÁö¸¦ üũ.
384*/
385BOOL PSIDB_IsSubChEttVRequired(int id, int source_id)
386{
387        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
388
389        BOOL bEttvRequired = FALSE;
390        int i;
391        int ettv_etm_loc = -1;
392       
393        if (chInfo->vct && chInfo->vct->channel) {
394                for (i=0; i<chInfo->vct->numChannels; i++) {
395                        if (chInfo->vct->channel[i].source_id == source_id) {
396                                ettv_etm_loc = chInfo->vct->channel[i].ETM_location;
397                                break;
398                        }
399                }
400        }
401
402        if (ettv_etm_loc == -1) { 
403                dprint(0, "!! vct invalid! cannot find source_id %d\n", source_id);
404        }
405        else if (chInfo->smgt.channel_ett_pid &&          // MGT¿¡ channel ETT°¡ µî·ÏÀÌ µÇ¾î ÀÖ°í,
406                        gPsiDontDownloadChannelEtt == FALSE &&  // Å×½ºÆ® Á¶°ÇÀÌ ¾Æ´Ï¸é¼­,
407                        (ettv_etm_loc == ETM_in_this_PTC || ettv_etm_loc == ETM_in_channel_TSID_PTC))  // ETT°¡ ÀÖ´Ù°í µî·ÏµÇ¾î ÀÖÀ¸¸é,
408        {
409                bEttvRequired = TRUE;
410        }
411#if 0 // IgnoreEtmLocationInfo optionÀº psi engine module ¿¡¼­¸¸ »ç¿ëÇϵµ·Ï ÇÏÀÚ.
412        else if (chInfo->smgt.channel_ett_pid &&
413                        gPsiDontDownloadChannelEtt == FALSE &&
414                        gPsiIgnoreEtmLocationInfo)  // ettv_etm_locÀÇ °ª¿¡ °ü°è¾øÀÌ (ETM_none Æ÷ÇÔ) ¹«Á¶°Ç ¹Þ´Â ¿É¼Ç
415        {
416                bEttvRequired = TRUE;
417        }
418#endif
419
420        return bEttvRequired;
421}
422
423
424/*
425        PSIDB_IsSubChEttSlotCompleted
426
427        ÁöÁ¤ÇÑ subchannelÀÇ Æ¯Á¤ time slot (iEit)ÀÇ ¸ðµç Eit/Ett °¡ ¼ö½Å ¿Ï·á µÇ¾ú´ÂÁö¸¦ üũÇÑ´Ù.
428
429        return true if all etts in the specified subchannel (with @source_id)
430        are received.
431*/
432BOOL PSIDB_IsSubChEttSlotCompleted(int id, int source_id, int iEit)
433{
434        // ÀÌ ÇÔ¼ö´Â Eit °¡ ¸ðµÎ ¿Ï·áµÈ »óÅ¿¡¼­¸¸ ±× Àǹ̰¡ ÀÖ´Ù.
435        // Eit°¡ ¾øÀÌ Ett¸¦ ¼ö½ÅÇÒ ¼ö´Â ¾ø±â ¶§¹®...
436        // Eit°¡ ¾øÀ¸¸é FALSE ¸®ÅÏ..  Ett°¡ ¾ø¾îµµ FALSE ¸®ÅÏ..  Eit/Ett ¸ðµÎ ÀÖÀ¸¸é TRUE ¸®ÅÏ..
437        //
438        int k; //, maxEttIndex;
439        int n_etm;  // number of etm in one eit instance.
440        BOOL bEttsCompleted = FALSE;
441       
442        S_PSIM_SUBCHINFO *subchInfo;
443        S_PSIM_CHINFO *chInfo;
444
445        S_PSIM_MGT_DIGEST *smgt;
446
447        subchInfo = PSIDB_GetPsiSubChInfo(id, source_id);
448        if (!subchInfo) goto label_end;
449       
450        chInfo = subchInfo->parent;
451        if (!chInfo) goto label_end;
452
453        // get mgt digest info
454        smgt = &chInfo->smgt;
455
456        if (iEit == 128) {
457                if (!PSIDB_IsSubChEttVRequired(id, source_id) || subchInfo->channel_ett)
458                        bEttsCompleted = TRUE;
459                goto label_end;
460        }
461        if (iEit < 0 || iEit >= 128) { // invalid index..
462                goto label_end;
463        }
464       
465        do
466        {
467                //---------- ¸ÕÀú eit À¯È¿¼º ºÎÅÍ Ã¼Å© -----------
468               
469                if (smgt->eit_pids[iEit] == 0) continue; // Á¸ÀçÇÏÁö ¾Ê´Â EIT
470
471                if (subchInfo->eits[iEit] == NULL) {
472                        dprint(2, " Eit-%d not received..\n", iEit);
473                        goto label_end;
474                }
475                if (smgt->eit_ver[iEit] != subchInfo->eits[iEit]->version_number) {
476                        if (gPsiSkipCheckVersionMatchMgtAndEit)
477                                dprint(1, "!! eit-%d (ver %d) version mismatch (mgt's %d) but continue\n", iEit, 
478                                                subchInfo->eits[iEit]->version_number, smgt->eit_ver[iEit]);
479                        else {
480                                dprint(0, "!! eit-%d (ver %d) version mismatch (mgt's %d)\n", iEit, 
481                                                subchInfo->eits[iEit]->version_number, smgt->eit_ver[iEit]);
482                                goto label_end; // need to receive again..
483                        }
484                }
485                if (subchInfo->eits[iEit]->event == NULL) 
486                        continue; // ºñ¾ú´Â eitÀ̸é?  ETT°¡ ÀÖÀ» ¼ö°¡ ¾øÀ» °ÍÀÌ´Ù.. ´ÙÀ½ eit üũ..
487
488                //---------- ett À¯È¿¼º üũ -----------
489
490                if (smgt->ett_pids[iEit] == 0) continue;  // ETT°¡ ¾ø´Ù¸é ´ÙÀ½..
491
492                for (k=0, n_etm=0; k<subchInfo->eits[iEit]->numEvents; k++) {
493                        if (subchInfo->eits[iEit]->event[k].ETM_location != ETM_none)
494                                n_etm++;  // ÀÌ EIT¿¡ °ü·ÃµÈ ETT °¹¼ö..
495                }
496                if (n_etm <= 0) continue;  // ¿ø·¡ ETT ¾øÀ½..
497               
498                if (subchInfo->etts[iEit] == NULL || subchInfo->n_ett[iEit] == 0) {
499                        dprint(2, " eit[%d] exist, but etts array NULL or n_ett 0 %d\n", iEit, subchInfo->n_ett[iEit]);
500                        goto label_end;
501                }
502                if (subchInfo->eits[iEit]->numEvents != subchInfo->n_ett[iEit]) {
503                        dprint(2, " num event %d != n_ett %d\n", subchInfo->eits[iEit]->numEvents, subchInfo->n_ett[iEit]);
504                        goto label_end;
505                }
506               
507                //---------- ett °¢ event º° üũ -----------
508
509                for (k=0; k<subchInfo->n_ett[iEit]; k++) 
510                {
511                        BOOL bSkipThisEtt = FALSE; 
512                        UINT32 etmid = PSIUTIL_MakeEventETMID(subchInfo->source_id, subchInfo->eits[iEit]->event[k].event_id);
513
514                        int ii, kk;
515                       
516                        if (subchInfo->etts[iEit][k] && subchInfo->etts[iEit][k]->ETM_id == etmid)
517                                continue;  // ¼ö½ÅµÇ¾úÀ½.. ´ÙÀ½..
518
519                        // ²À ÀÌ Eit PID¿¡¸¸ ¾Æ´Ï¶ó ±× ÀÌÀü EitµéÀÇ PID¿¡µµ Á¸ÀçÇÒ °æ¿ì°¡ ÀÖ´Ù..
520                        // 3-hour °æ°è¿¡ °ÉÃÄ ÀÖ´Â eventÀÇ °æ¿ì ¾ÕÂÊ eventÀÇ PID¿¡ ett°¡ ÀÖÀ» ¼ö ÀÖ´Ù.
521                        // ±×·¯¹Ç·Î ÇöÀç Ett table pointer°¡ NULL À̶ó°í ÇØ¼­ ¹Ù·Î FALSE ó¸®ÇÏ¸é ¾ÈµÈ´Ù.
522                        // ¾ÕÀÇ ¸ðµç tableµéÀ» ã¾ÆºÁ¾ß ÇÑ´Ù.
523                        //
524                        for (ii=iEit; ii>=0; ii--) {  // ÇöÀç Etts[iEit]ºÎÅÍ  Etts[0] ±îÁö ¾ÕÀ¸·Î µÇµ¹¾Æ°¡¸é¼­,
525                                if (subchInfo->etts[ii] == NULL) continue;
526                                // °¢ Ett sectionÀ» °Ë»çÇØ¼­ ÇöÀç ¹ÞÀ¸·Á°í ÇÏ´Â etm_idÀÇ ett°¡ ¹Þ¾ÆÁ® ÀÖ´ÂÁö °Ë»çÇÑ´Ù.
527                                for (kk=0; kk<subchInfo->n_ett[ii]; kk++) {
528                                        if (subchInfo->etts[ii][kk] && subchInfo->etts[ii][kk]->ETM_id == etmid) {
529                                                // °°Àº etm_id¸¦ °¡Áø Ett°¡ ÀÌ¹Ì ¼ö½ÅµÇ¾î ÀÖ´Ù¸é, ¹ÞÀ» ÇÊ¿ä ¾ø´Ù.
530                                                dprint(3, "  Ett-%d[ev %d]: same etmid 0x%x (ett-%d ev%d pid %d) exist. \n", 
531                                                        iEit, k, etmid, ii, kk, smgt->ett_pids[ii]);
532                                                bSkipThisEtt = TRUE;
533                                                break;
534                                        }
535                                }
536                                if (bSkipThisEtt) break;
537                        }
538                        if (bSkipThisEtt)
539                                continue;
540                       
541                        if (subchInfo->eits[iEit]->event[k].ETM_location != ETM_none && 
542                                subchInfo->etts[iEit][k] == NULL) {
543                                dprint(2, "  ett-%d[ev %d] etm_loc %d, but ett NULL\n", 
544                                                iEit, k, subchInfo->eits[iEit]->event[k].ETM_location);
545                                goto label_end;         
546                        }
547                }
548
549        } while (0);
550       
551        bEttsCompleted = TRUE;  // OK.. All eits are completed.
552
553label_end:
554
555        return bEttsCompleted;
556       
557}
558
559
560/*
561        PSIDB_IsSubChAllEttsCompleted
562
563        ÁöÁ¤ÇÑ subchannelÀÇ ¸ðµç Eit/Ett °¡ ¼ö½Å ¿Ï·á µÇ¾ú´ÂÁö¸¦ üũÇÑ´Ù.
564
565        ÀÌ ÇÔ¼ö´Â channel ett ÀÇ ¼ö½Å ¿©ºÎ¸¦ üũÇÒ ¶§ ¹Ì¸® °è»êµÈ boolean flag¸¦ »ç¿ëÇϱ⠶§¹®¿¡
566        ÇØ´ç subchannel¿¡ ´ëÇØ¼­ update etts ÇÔ¼ö°¡ ¸ÕÀú ºÒ¸° ´ÙÀ½¿¡¸¸ »ç¿ëµÇ¾î¾ß ÇÑ´Ù.
567        Áï »ç¿ë ½ÃÁ¡¿¡ ÁÖÀǸ¦ ¿äÇÑ´Ù.
568
569        return true if all etts in the specified subchannel (with @source_id)
570        are received.
571*/
572BOOL PSIDB_IsSubChAllEttsCompleted(int id, int source_id)
573{
574        // ÀÌ ÇÔ¼ö´Â Eit °¡ ¸ðµÎ ¿Ï·áµÈ »óÅ¿¡¼­¸¸ ±× Àǹ̰¡ ÀÖ´Ù.
575        // Eit°¡ ¾øÀÌ Ett¸¦ ¼ö½ÅÇÒ ¼ö´Â ¾ø±â ¶§¹®...
576        // Eit°¡ ¾øÀ¸¸é FALSE ¸®ÅÏ..  Ett°¡ ¾ø¾îµµ FALSE ¸®ÅÏ..  Eit/Ett ¸ðµÎ ÀÖÀ¸¸é TRUE ¸®ÅÏ..
577        //
578        int i, k, maxEttIndex;
579        int n_etm;  // number of etm in one eit instance.
580        BOOL bEttsCompleted = FALSE;
581       
582        S_PSIM_SUBCHINFO *subchInfo;
583        S_PSIM_CHINFO *chInfo;
584
585        S_PSIM_MGT_DIGEST *smgt;
586
587        // ÀÓÀÇ task¿¡¼­µµ »ç¿ëÇÒ ¼ö ÀÖ´Â ¿ëµµ¸¦ °í·ÁÇÒ ÇÊ¿ä´Â ¾øÀ» µí ÇÔ.
588        //if (PSITASK_IsPsiTask())
589        //      PSIDB_LockDB(TRUE);  //-------------------------
590
591        subchInfo = PSIDB_GetPsiSubChInfo(id, source_id);
592        if (!subchInfo) goto label_end;
593       
594        chInfo = subchInfo->parent;
595        if (!chInfo) goto label_end;
596
597        // get mgt digest info
598        smgt = &chInfo->smgt;
599
600        if (PSIDB_IsSubChEttVRequired(id, source_id) && subchInfo->channel_ett == NULL)
601                goto label_end;  // ett-v °¡ ¼ö½ÅµÇ¾î¾ß Çϴµ¥ ¾ÆÁ÷ ¼ö½ÅÀÌ ¾ÈµÇ¾úÀ¸¹Ç·Î FALSE..
602
603        maxEttIndex = min(127, gPsiMaxEitEttIndexToReceive);   // cafrii 041202 add
604
605        for (i=0; i<=maxEttIndex; i++) 
606        {
607                if (smgt->eit_pids[i] == 0) continue; // Á¸ÀçÇÏÁö ¾Ê´Â EIT
608
609                if (subchInfo->eits[i] == NULL) {
610                        dprint(2, " Eit-%d not received..\n", i);
611                        goto label_end;
612                }
613                if (smgt->eit_ver[i] != subchInfo->eits[i]->version_number) {
614                        if (gPsiSkipCheckVersionMatchMgtAndEit)
615                                dprint(1, "!! eit-%d (ver %d) version mismatch (mgt's %d) but continue\n", i, 
616                                                subchInfo->eits[i]->version_number, smgt->eit_ver[i]);
617                        else {
618                                dprint(0, "!! eit-%d (ver %d) version mismatch (mgt's %d)\n", i, 
619                                                subchInfo->eits[i]->version_number, smgt->eit_ver[i]);
620                                goto label_end; // need to receive again..
621                        }
622                }
623                if (subchInfo->eits[i]->event == NULL) 
624                        continue; // ºñ¾ú´Â eitÀ̸é?  ETT°¡ ÀÖÀ» ¼ö°¡ ¾øÀ» °ÍÀÌ´Ù.. ´ÙÀ½ eit üũ..
625
626                if (smgt->ett_pids[i] == 0) continue;  // ETT°¡ ¾ø´Ù¸é ´ÙÀ½..
627
628                for (k=0, n_etm=0; k<subchInfo->eits[i]->numEvents; k++) {
629                        if (subchInfo->eits[i]->event[k].ETM_location != ETM_none)
630                                n_etm++;  // ÀÌ EIT¿¡ °ü·ÃµÈ ETT °¹¼ö..
631                }
632                if (n_etm <= 0) continue;  // ¿ø·¡ ETT ¾øÀ½..
633               
634                if (subchInfo->etts[i] == NULL || subchInfo->n_ett[i] == 0) {
635                        dprint(2, " eit[%d] exist, but etts array NULL or n_ett 0 %d\n", i, subchInfo->n_ett[i]);
636                        goto label_end;
637                }
638                if (subchInfo->eits[i]->numEvents != subchInfo->n_ett[i]) {
639                        dprint(2, " num event %d != n_ett %d\n", subchInfo->eits[i]->numEvents, subchInfo->n_ett[i]);
640                        goto label_end;
641                }
642               
643                for (k=0; k<subchInfo->n_ett[i]; k++) 
644                {
645                        BOOL bSkipThisEtt = FALSE; 
646                        UINT32 etmid = PSIUTIL_MakeEventETMID(subchInfo->source_id, subchInfo->eits[i]->event[k].event_id);
647
648                        int ii, kk;
649                       
650                        if (subchInfo->etts[i][k] && subchInfo->etts[i][k]->ETM_id == etmid)
651                                continue;  // ¼ö½ÅµÇ¾úÀ½.. ´ÙÀ½..
652
653                        // ²À ÀÌ Eit PID¿¡¸¸ ¾Æ´Ï¶ó ±× ÀÌÀü EitµéÀÇ PID¿¡µµ Á¸ÀçÇÒ °æ¿ì°¡ ÀÖ´Ù..
654                        // 3-hour °æ°è¿¡ °ÉÃÄ ÀÖ´Â eventÀÇ °æ¿ì ¾ÕÂÊ eventÀÇ PID¿¡ ett°¡ ÀÖÀ» ¼ö ÀÖ´Ù.
655                        // ±×·¯¹Ç·Î ÇöÀç Ett table pointer°¡ NULL À̶ó°í ÇØ¼­ ¹Ù·Î FALSE ó¸®ÇÏ¸é ¾ÈµÈ´Ù.
656                        // ¾ÕÀÇ ¸ðµç tableµéÀ» ã¾ÆºÁ¾ß ÇÑ´Ù.
657                        //
658                        for (ii=i; ii>=0; ii--) {  // ÇöÀç Etts[i]ºÎÅÍ  Etts[0] ±îÁö ¾ÕÀ¸·Î µÇµ¹¾Æ°¡¸é¼­,
659                                if (subchInfo->etts[ii] == NULL) continue;
660                                // °¢ Ett sectionÀ» °Ë»çÇØ¼­ ÇöÀç ¹ÞÀ¸·Á°í ÇÏ´Â etm_idÀÇ ett°¡ ¹Þ¾ÆÁ® ÀÖ´ÂÁö °Ë»çÇÑ´Ù.
661                                for (kk=0; kk<subchInfo->n_ett[ii]; kk++) {
662                                        if (subchInfo->etts[ii][kk] && subchInfo->etts[ii][kk]->ETM_id == etmid) {
663                                                // °°Àº etm_id¸¦ °¡Áø Ett°¡ ÀÌ¹Ì ¼ö½ÅµÇ¾î ÀÖ´Ù¸é, ¹ÞÀ» ÇÊ¿ä ¾ø´Ù.
664                                                dprint(3, " Ett-%d[ev %d]: same etmid 0x%x (ett-%d ev%d pid %d) exist. \n", 
665                                                        i, k, etmid, ii, kk, smgt->ett_pids[ii]);
666                                                bSkipThisEtt = TRUE;
667                                                break;
668                                        }
669                                }
670                                if (bSkipThisEtt) break;
671                        }
672                        if (bSkipThisEtt)
673                                continue;
674                       
675                        if (subchInfo->eits[i]->event[k].ETM_location != ETM_none && 
676                                subchInfo->etts[i][k] == NULL) {
677                                dprint(2, " ett-%d[ev %d] etm_loc %d, but ett NULL\n", 
678                                                i, k, subchInfo->eits[i]->event[k].ETM_location);
679                                goto label_end;         
680                        }
681                }
682               
683        }
684       
685        bEttsCompleted = TRUE;  // OK.. All eits are completed.
686
687label_end:
688        //if (PSITASK_IsPsiTask())
689        //      PSIDB_LockDB(FALSE);  //-------------------------
690
691        return bEttsCompleted;
692       
693}
694
695
696
697#if COMMENT
698____Free____(){}
699#endif
700
701//
702// note!! below PSIDB_FreeXXX don't care mutex lock. caller should lock.
703//
704
705
706/*
707        eit[iEit]¿Í ¿¬°üµÈ ¸ðµç ettµé, ±×¸®°í ±×°Íµé°ú °ü·Ã data structure¸¦ Á¦°ÅÇÑ´Ù.
708
709        ÃÖ´ë eit[iEit]->numEvents ¸¸Å­ÀÇ ettµé, ±×¸®°í ÀÌ ettµéÀ» ´ã°í ÀÖ´Â ett array¸¦ freeÇÔ.
710
711        channel ett´Â ÇØ´ç »çÇ× ¾øÀ½. ÀÏ¹Ý event ett¸¸ »èÁ¦ÇÑ´Ù.
712*/
713void PSIDB_FreeEtts(S_PSIM_SUBCHINFO *subchInfo, int iEit)
714{
715        // subchInfo´Â Non-NULL, i´Â 0 ~ 128-1 »çÀÌÀÇ °ªÀ̾î¾ß ÇÑ´Ù.
716        int k;
717
718        if (subchInfo == 0 || iEit < 0 || iEit >= 128)
719                return;
720       
721        if (subchInfo->etts[iEit] == NULL) { // it is already freed.
722                subchInfo->n_ett[iEit] = 0;
723                return;
724        }
725       
726        // ett ¸ðµÎ »èÁ¦
727        for (k=0; k<subchInfo->n_ett[iEit]; k++)
728                PSIUTIL_FreeTable(&subchInfo->etts[iEit][k]);
729               
730        // ett container »èÁ¦
731        DHL_OS_Free((void **)&subchInfo->etts[iEit]);
732        subchInfo->n_ett[iEit] = 0;
733}
734
735/*
736        eit[iEit]¸¦ Æ÷ÇÔÇÏ¿© °ü·ÃµÈ ¸ðµç ettµé°ú data structure¸¦ Á¦°ÅÇÑ´Ù.
737
738*/
739void PSIDB_FreeEitAndRelatedEtts(S_PSIM_SUBCHINFO *subchInfo, int iEit)
740{
741        // subchInfo´Â Non-NULL, i´Â 0 ~ 128-1 »çÀÌÀÇ °ªÀ̾î¾ß ÇÑ´Ù.
742        int k;
743
744        if (subchInfo == NULL || iEit < 0 || iEit >= 128)
745                return;       // invalid argument error
746       
747        if (subchInfo->etts[iEit] == NULL) {
748                subchInfo->n_ett[iEit] = 0;
749        }
750        else {
751                // ett ¸ðµÎ »èÁ¦
752                for (k=0; k<subchInfo->n_ett[iEit]; k++)
753                        PSIUTIL_FreeTable(&subchInfo->etts[iEit][k]);
754       
755                // ett container »èÁ¦
756                DHL_OS_Free((void **)&subchInfo->etts[iEit]);
757                subchInfo->n_ett[iEit] = 0;
758        }
759
760        // eit »èÁ¦
761        PSIUTIL_FreeTable(&subchInfo->eits[iEit]);
762
763}
764
765/*
766        subchannel³»ÀÇ ¸ðµç Á¤º¸¸¦ freeÇÑ´Ù.
767        subchInfo ±¸Á¶Ã¼ ÀÚü´Â free ÇÏÁö ¾ÊÀ½.
768*/
769void PSIDB_FreeSubChInfo(S_PSIM_SUBCHINFO *subchInfo)
770{
771        // subchannel info ¸ðµç Á¤º¸¸¦ »èÁ¦ÇÑ´Ù.
772        int j, k;
773       
774        if (subchInfo == NULL) return;
775
776        // todo.. inactive subchÀÇ °æ¿ì ÀÌ ÇÔ¼ö°¡ ºÒ¸®´Â°¡?
777        if (subchInfo->active == 0) return;
778
779        if (subchInfo->channel_ett) {
780                dprint(2, "  delete ett-v.. \n");
781                PSIUTIL_FreeTable(&subchInfo->channel_ett);
782        }
783
784#if 0
785        for (k=0; k<128; k++)
786                PSIDB_FreeEitAndRelatedEtts(subchInfo, k);
787#else
788        // ¾î¶² tableµéÀÌ Áö¿öÁö´ÂÁö debug print¸¦ À§ÇØ Àç ÀÛ¼º..
789        // free etts
790        for (k=0; k<128; k++) {
791                if (subchInfo->etts[k] == NULL) continue; // No ETTs here..
792                for (j=0; j<subchInfo->n_ett[k]; j++) {
793                        if (subchInfo->etts[k][j]) {
794                                dprint(3, "   ett[%d][%d]: %x\n", k, j, subchInfo->etts[k][j]);
795                                PSIUTIL_FreeTable(&subchInfo->etts[k][j]);
796                        }
797                }
798                DHL_OS_Free((void **)&subchInfo->etts[k]); // ett container »èÁ¦
799                subchInfo->n_ett[k] = 0;
800        }
801       
802        // free eits
803        for (k=0; k<128; k++) {
804                if (subchInfo->eits[k] == NULL) continue;
805                dprint(3, "    eit[%d]: %x\n", k, subchInfo->eits[k]);
806                PSIUTIL_FreeTable(&subchInfo->eits[k]);
807        }
808#endif
809       
810        //DHL_OS_Free((void **)&(subchInfo->eits)); // À̰ÍÀº µ¿ÀûÇÒ´çµÈ °ÍÀÌ ¾Æ´Ô!!
811       
812        subchInfo->active = FALSE;
813}
814
815void PSIDB_FreeChInfo(S_PSIM_CHINFO *chInfo)
816{
817        int i;
818       
819        if (chInfo == NULL) return;
820
821        if (chInfo->subchannel) 
822        {
823                //dprint(2, "  total %d subchannels..\n", chInfo->n_subchannel);
824                for (i=0; i<chInfo->n_subchannel; i++)  {
825                        //dprint(2, "  delete subchannel[%d] data..\n", i);
826                        PSIDB_FreeSubChInfo(&chInfo->subchannel[i]);
827                }
828        }
829        //dprint(2, "  delete subchannel info itself..\n");
830        DHL_OS_Free((void **)&(chInfo->subchannel));
831
832        //dprint(2, "  delete tables in channel..\n");
833        //PSIUTIL_FreeTable(&chInfo->tvct);
834        //PSIUTIL_FreeTable(&chInfo->cvct);
835        PSIUTIL_FreeTable(&chInfo->vct);
836       
837#if 0
838        PSIUTIL_FreeTable(&chInfo->stt); // cafrii 050330, stt changed to flat_stt
839#endif
840        PSIUTIL_FreeTable(&chInfo->mgt);
841        PSIUTIL_FreeTable(&chInfo->mgt_old);
842
843        for (i=0; chInfo->pat && chInfo->pmts && i<chInfo->pat->numPrograms; i++) {
844                //dprint(2, "  delete pmt[%d]..\n", i);
845                PSIUTIL_FreeTable(&chInfo->pmts[i]);
846        }
847        //dprint(2, "  delete pat..\n");
848        PSIUTIL_FreeTable(&chInfo->pat);
849
850        // do not reset contents!!
851        //  we need prev/next link to remove from linked list.
852        //---memset(chInfo, 0, sizeof(S_PSIM_CHINFO));
853}
854
855
856
857#if COMMENT
858____Alloc_Remove____(){}
859#endif
860
861
862STATUS PSIDB_AllocateChInfoNode(int id)
863{
864        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
865        if (chInfo)
866                return statusOK;
867
868        chInfo = PSI_NewChInfo(id);
869        if (chInfo == NULL)
870                return statusOutOfMemory;
871
872        LockPsiDB(TRUE);
873        PSI_InsertChInfo(chInfo);
874        LockPsiDB(FALSE);
875
876        return statusOK;
877}
878
879STATUS PSIDB_RemoveChInfoNode(int id)
880{
881        S_PSIM_CHINFO *chInfo = PSI_GetChInfo(id);
882        if (!chInfo)
883                return statusOK; // not exist.
884
885        LockPsiDB(TRUE);
886        PSI_RemoveChInfo(chInfo);
887        LockPsiDB(FALSE);
888
889        return statusOK;
890}
891
892
893
894#if COMMENT
895____Private____(){}
896#endif
897
898
899/*
900        »õ·Î ¼ö½ÅµÈ MGT¸¦ º¸°í, ±âÁ¸ EpgDBÀÇ TableµéÀ» Á¤¸®ÇÑ´Ù.
901        »õ·Î ¹Þ¾Æ¾ß ÇÏ´Â tableµéÀ̶ó¸é »èÁ¦, Àç»ç¿ëÀÌ °¡´ÉÇÏ¸é ±×´ë·Î µÐ´Ù.
902
903        ÇöÀç @chInfo ³»¿¡ ÀúÀåµÇ¾î ÀÖ´Â mgt´Â old_mgt À̰í, ÀÎÀÚ·Î Àü´ÞµÈ @mgt´Â »õ mgtÀÌ´Ù.
904*/
905PSI_STATIC STATUS CheckAndProcessMgtVersionChange(S_PSIM_CHINFO *chInfo, mgtSectionPtr_t mgt)
906{
907        // mgt version change ºÐ¼®..
908        // ÁÖÀÇ:
909        // ÀÌ ÇÔ¼ö°¡ ºÒ¸®´Â ½ÃÁ¡Àº update ¶Ç´Â ÃÖÃÊ downloadÀÎ °æ¿ìÀε¥,
910        // ÃÖÃÊ·Î ºÒ¸®´Â °æ¿ì¶ó¸é subchannel Á¤º¸°¡ ¾øÀ» ¼öµµ ÀÖÀ¸¹Ç·Î À¯ÀÇÇÑ´Ù.
911        //
912        int i, j, k;
913        int offset;   // EIT, ETTµéÀÇ shiftµÈ Â÷ÀÌ..
914        UINT8 candidate[128];
915                // Eit/EttÀÇ time-shift¿¡ ÀÇÇÑ mgt version changeÀÇ °æ¿ì ÇöÀç tableÀÇ Èĺ¸ °ªÀÌ´Ù.
916                // ¿¹¸¦ µé¾î EitÀÇ °æ¿ì candidate[3] == 4 ÀÎ °æ¿ì,
917                // ÇöÀç Eit-3 ÀÇ È帴 ¿¹Àü Eit-4 ÀÌ´Ù.
918                // Áï, ÇöÀç mgtÀÇ Eit-3°ú ¿¹Àü mgtÀÇ Eit-4ÀÇ version°ú byte size°¡ µ¿ÀÏÇÏ´Ù´Â ÀǹÌÀÌ´Ù.
919                // candidateÀÇ µðÆúÆ® °ªÀº 0xff ·Î¼­ ÀÌ´Â È帰¡ ¾øÀ½À» ÀǹÌÇÑ´Ù.
920
921        S_PSIM_SUBCHINFO *subchInfo;
922
923        mgtTablePtr_t tbl1, tbl2;
924
925        dprint(1, "%s:\n", __FUNCTION__);
926
927        if (chInfo == NULL) return statusInvalidArgument;
928
929        if (chInfo->mgt == NULL) {
930                dprint(2, "No Previous mgt..\n");
931                return statusOK;
932        }
933       
934        if (chInfo->mgt->version_number == mgt->version_number && !gPsiFakeMgtVersionChange) 
935        {
936                dprint(2, "MGT version (%d) same.. \n", mgt->version_number);
937
938                // cafrii 050331
939                // ¹öÀü ºñ±³ ¸¸À¸·Î´Â ¾ÈÀüÇÏÁö ¸øÇÒ ¼ö ÀÖ´Ù.
940                // version bit°¡ Àû±â ¶§¹®¿¡ ¼­·Î ´Ù¸¥ MgtÀÓ¿¡µµ ºÒ±¸ÇÏ°í ¹öÀüÀº °°À» ¼ö Àֱ⠶§¹®.
941                //
942                if (PSIUTIL_IsEquivalentMgt(chInfo->mgt, mgt)) 
943                {
944                        // equivalent¶õ Àǹ̴ mgtÀÇ versionÀº ½Å°æ¾²Áö ¾Ê°í
945                        // mgt ¾ÈÀÇ tableµéÀ» Çϳª¾¿ ºñ±³ÇØ ºÁ¼­ ³»¿ëÀÌ °°Àº ³»¿ëÀ̶ó´Â ¶æ.
946                        //dprint(2, "MGTs are equivalent..\n");
947                        return statusOK;
948                }
949                else
950                        dprint(2, "!! MGTs are different while versions are same\n");
951        }
952
953       
954        // Basic Rule:
955        // 1. ±âÁ¸ Å×À̺í Á¤º¸°¡ ¾ø¾úÀ¸¸é ´ç¿¬È÷ ¹«Á¶°Ç ¹Þ¾Æ¾ß ÇÑ´Ù.
956        //    (Ȥ½Ã Á¤º¸µµ ¾øÀÌ tableÀº ÀÖÀ» ¼öµµ ÀÖÀ¸¹Ç·Î ÀÌ °æ¿ì ±âÁ¸ Å×À̺íÀº »èÁ¦Çعö¸®ÀÚ)
957        //
958        // 2. ±âÁ¸ Å×ÀÌºí ¹öÀü°ú »õ Å×ÀÌºí ¹öÀüÀÌ ´Ù¸£¸é, ±âÁ¸ Å×À̺íÀÌ ÀÌ¹Ì ¼ö½ÅµÇ¾î ÀÖ´Â »óȲÀ̶óµµ
959        //    ±âÁ¸ Å×À̺íÀ» »èÁ¦ÇÏ°í ´Ù½Ã ¹Þ´Â´Ù. (¹°·Ð ±âÁ¸ Å×À̺íÀº ½Ã°£Á¦ÇÑÀ¸·Î ¸ø ¹Þ¾Æ¼­ ¾øÀ» ¼öµµ ÀÖ´Ù)
960        //
961        // 3. ±âÁ¸ Å×ÀÌºí ¹öÀü°ú »õ Å×ÀÌºí ¹öÀüÀÌ °°À¸¸é ±âÁ¸ Å×À̺íÀÌ ¾ø´Â °æ¿ì¿¡¸¸ Ãß°¡ÇÏ¿© ¹Þ´Â´Ù.
962        //
963       
964        dprint(2, "MGT version changed  %d -> %d.. analyzing..\n", chInfo->mgt->version_number, mgt->version_number);
965        dprint(2, "  old mgt : 0x%x,  new mgt : 0x%x\n", chInfo->mgt, mgt);
966
967        PSIUTIL_ComparePrintTwoMgts(chInfo->mgt, mgt, 3);
968
969        // ÀÌ ½ÃÁ¡ºÎÅÍ ÀÌ ÇÔ¼ö ³¡³¯¶§±îÁö ¸ðµÎ DB LockÀ» ÇÑ´Ù. 
970        LockPsiDB(TRUE);
971       
972        // ¸ðµç subchannel¿¡ ÀÖ´Â eit/ett complete flag¸¦ reset ÇÑ´Ù..
973       
974        for (i=0; i<chInfo->n_subchannel; i++) {
975                chInfo->subchannel[i].eit_complete = FALSE;
976                chInfo->subchannel[i].ett_complete = FALSE;
977        }
978       
979        if (gPsiReloadAllTableAtMgtChange) // mgt ¹öÀüÀÌ ¹Ù²î¸é Ç×»ó ¸ðµç Å×À̺íÀ» ´Ù½Ã ¹Þ´Â ¾ÈÀüÇÑ ¸ðµå..
980        {
981                dprint(2, "## Policy1: Reload all tables at mgt version change\n");
982
983                if (chInfo->subchannel) // subchannel Á¤º¸°¡ ¾øÀ» ¼öµµ ÀÖÀ¸¹Ç·Î Ç×»ó üũÇÑ´Ù.
984                {
985                        dprint(2, "  total %d subchannels..\n", chInfo->n_subchannel);
986                        for (i=0; i<chInfo->n_subchannel; i++)  {
987                                PSIDB_FreeSubChInfo(&chInfo->subchannel[i]);
988                        }
989                        dprint(2, "  delete subchannel info..\n"); // subchannel info ±× ÀÚü±îÁö ´Ù Áö¿ï Çʿ䰡 ÀÖ³ª?
990                        DHL_OS_Free((void **)&(chInfo->subchannel));
991                }
992                dprint(2, "  delete vct tables in channel..\n");
993                PSIUTIL_FreeTable(&chInfo->vct);
994        }
995
996        if (chInfo->vct && !chInfo->vct->is_cvct) {
997                // ---------- TVCT check
998                tbl1 = PSIUTIL_FindTableInMgt(chInfo->mgt, tt_terrestrial_VCT_cni_1);  // ±âÁ¸ MGT¿¡¼­ ã°í,
999                tbl2 = PSIUTIL_FindTableInMgt(mgt, tt_terrestrial_VCT_cni_1);          // »õ MGT¿¡¼­ ã´Â´Ù.
1000               
1001                if (tbl2 == NULL || tbl1 == NULL)
1002                        //PSIUTIL_FreeTable(&chInfo->tvct);
1003                        PSIUTIL_FreeTable(&chInfo->vct);
1004                else {
1005                        if (tbl1->table_type_version_number != tbl2->table_type_version_number) {
1006                                dprint(2, "TVCT version changed %d->%d\n", tbl1->table_type_version_number, tbl2->table_type_version_number);
1007                                //PSIUTIL_FreeTable(&chInfo->tvct);
1008                                PSIUTIL_FreeTable(&chInfo->vct);
1009                                // todo..
1010                                // À̶§ subchannel infoÀÇ ³»¿ëÀ» ´Ù Áö¿ö¾ß Çϴ°¡? source_idÀÇ ³»¿ëÀÌ º¯°æµÇ¾ú´ÂÁö üũ´Â?
1011                                // n_subchannelÀÇ °¹¼ö°¡ º¯°æµÇ¾ú´ÂÁöÀÇ ¿©ºÎ??
1012                        }
1013                }
1014        }
1015        else if (chInfo->vct && chInfo->vct->is_cvct) {
1016                // ----------- CVCT check
1017                tbl1 = PSIUTIL_FindTableInMgt(chInfo->mgt, tt_cable_VCT_cni_1);
1018                tbl2 = PSIUTIL_FindTableInMgt(mgt, tt_cable_VCT_cni_1);
1019               
1020                if (tbl2 == NULL || tbl1 == NULL)
1021                        //PSIUTIL_FreeTable(&chInfo->cvct);
1022                        PSIUTIL_FreeTable(&chInfo->vct);
1023                else {
1024                        if (tbl1->table_type_version_number != tbl2->table_type_version_number) {
1025                                dprint(2, "CVCT version changed %d->%d\n", tbl1->table_type_version_number, tbl2->table_type_version_number);
1026                                //PSIUTIL_FreeTable(&chInfo->cvct);
1027                                PSIUTIL_FreeTable(&chInfo->vct);
1028                                // todo..
1029                                // À̶§ subchannel infoÀÇ ³»¿ëÀ» ´Ù Áö¿ö¾ß Çϴ°¡? source_idÀÇ ³»¿ëÀÌ º¯°æµÇ¾ú´ÂÁö üũ´Â?
1030                                // n_subchannelÀÇ °¹¼ö°¡ º¯°æµÇ¾ú´ÂÁöÀÇ ¿©ºÎ??
1031                        }
1032                }
1033        }
1034       
1035        if (gPsiFakeMgtVersionChange) {
1036                dprint(2, "******** simulation of mgt version change\n");
1037                // ¸¶Ä¡ mgt version change°¡ ÀϾ°Í°ú °°Àº Èä³»¸¦ ³½´Ù. candidate´Â Çϳªµµ ¾ø´Â »óÅ·Π°¡Á¤..
1038                //
1039                for (i=0; i<128; i++)
1040                        candidate[i] = 0xff; // ¸ðµÎ ÀûÀýÇÑ candidate°¡ ¾ø´Â »óÅÂ..
1041                offset = 0;
1042                goto label_move_new_eits;
1043        }
1044       
1045        // ----------- All EIT check
1046        dprint(2, " check eit version..\n");
1047        for (i=0; i<128; i++) 
1048        {
1049                // EITÀÇ °æ¿ì´Â 3-hour time shiftÀÇ °æ¿ì¸¦ °í·ÁÇÏ¿©, PID, version, byte size°¡ °°À¸¸é ´Ù¸¥ EIT¶ó ÇÏ¿©µµ
1050                // °°Àº ³»¿ëÀÏ ¼ö°¡ ÀÖ´Ù.
1051                //
1052                int search_end;
1053                candidate[i] = 0xff; // no candidate yet..
1054               
1055                tbl2 = PSIUTIL_FindTableInMgt(mgt, tt_EIT_min+i); // »õ MGT¿¡¼­ EIT-i Á¤º¸¸¦ ã´Â´Ù.
1056                if (tbl2 == NULL) {
1057                        //dprint(3, "  new EIT-%d not exist..\n", i);
1058                        continue;
1059                }
1060               
1061                if (gPsiInterTableCompareInMgtChange) 
1062                        search_end = min(i+3, 127);  // Eit-i ºÎÅÍ Eit-(i+3)±îÁö ºñ±³..
1063                else
1064                        search_end = i;              // µ¿ÀÏÇÑ Eit-i¸¸ ºñ±³..
1065                       
1066                // ±âÁ¸ MGT¿¡¼­ »õ EIT-iÀÇ Á¤º¸ (PID, version, bytesize)¿Í °°Àº EIT¸¦ ã´Â´Ù..
1067                //
1068                for (k=i; k<=search_end; k++) 
1069                {
1070                        tbl1 = PSIUTIL_FindTableInMgt(chInfo->mgt, tt_EIT_min+k); // ¿¾³¯ MGT¿¡¼­ EIT-k Á¤º¸¸¦ ã´Â´Ù.
1071                        if (tbl1 == NULL) continue;
1072                       
1073                        if (tbl1->table_type_PID == tbl2->table_type_PID && 
1074                            tbl1->table_type_version_number == tbl2->table_type_version_number &&
1075                            tbl1->number_bytes == tbl2->number_bytes) 
1076                        {
1077                                // ÀÏ´Ü ¸ðµç Á¤º¸°¡ °°À¸¹Ç·Î ÀÌ tblÀ» »ç¿ëÇÒ ¼ö ÀÖÀ»°Í °°´Ù..
1078                                candidate[i] = k;
1079                                dprint(3, "   new Eit-%d same as Eit-%d (PID %x, v%d, %d)\n", 
1080                                                i, k, tbl1->table_type_PID, tbl1->table_type_version_number, tbl1->number_bytes);
1081                                break;
1082                        }
1083                }
1084                if (candidate[i] == 0xff)
1085                        dprint(3, "   new Eit-%d should be downloaded..\n", i);
1086        }
1087       
1088        // ÀÌÁ¦ candidate[i]´Â
1089        //   »õ EIT-i°¡ ¾ø´Ù¸é 0xff
1090        //   »õ EIT-i°¡ Á¸ÀçÇϴµ¥ µ¿ÀÏÇÑ ¿¹Àü EIT°¡ ¾ø´Ù¸é 0xff
1091        //   »õ EIT-i°¡ Á¸ÀçÇÏ°í µ¿ÀÏÇÑ ¿¹Àü EIT-k°¡ Á¸ÀçÇÑ´Ù¸é k¸¦ °¡Áø´Ù.
1092        //   (±×·¯³ª EIT-k°¡ Áö±Ý ÇöÀç ¼ö½ÅµÇ¾î ÀÖ´Â »óŶó´Â°ÍÀ» ÀǹÌÇÏÁö´Â ¾Ê´Â´Ù. ´Ü¼øÈ÷ MGT Á¤º¸¿¡ ÀÇÇÑ °ªÀÌ´Ù.)
1093
1094        // case 1: 3-hour boundary shiftÀÎ °æ¿ì
1095        // case 2: ÀϺΠEITÀÇ ³»¿ë¸¸ º¯°æµÈ °æ¿ì
1096        //  µÎ °æ¿ì ¸ðµÎ µ¿ÀÏÇÑ ·ÎÁ÷À¸·Î ó¸® °¡´ÉÇÏ´Ù..
1097        //
1098        // ¸ðµç offsetµéÀÌ µ¿ÀÏÇÑÁö üũÇÑ´Ù. Çϳª¶óµµ Ʋ¸®¸é ¸ðµÎ ¹«È¿È­ ½ÃŰÀÚ!!
1099        offset = -1;  // offset default value..
1100        for (i=0; i<128; i++) 
1101        {
1102                if (candidate[i] == 0xff) continue;
1103                if (offset < 0)
1104                        offset = candidate[i] - i;         // candidate[i]´Â ¹Ýµå½Ã iº¸´Ù Å©°Å³ª °°Àº °ªÀÌ´Ù.
1105                else if (offset != (candidate[i] - i))
1106                {
1107                        dprint(2, "  !! candidate[%d]=%d mismatch with offset %d\n", i, candidate[i], offset);
1108                        dprint(2, "     ignore all candidate offset value..\n");
1109                        for (k=0; k<128; k++) candidate[k] = 0xff; // ¸ðµÎ ¹«È¿È­...
1110                        break;
1111                }
1112        }
1113        if (offset >= 0)
1114                dprint(2, " Eit match offset value is %d\n", offset);
1115        else {
1116                dprint(2, " No available old tables. offset is set to default 0\n");
1117                offset = 0; // ÀÏÄ¡ÇÏ´Â °ÍÀÌ Çϳªµµ ¾ø´Ù¸é..
1118        }
1119
1120label_move_new_eits:
1121
1122        // ÀÌÁ¦ candidate°¡ ¾Æ´Ñ EIT´Â »èÁ¦Çϰí À̵¿ÇÑ´Ù..
1123        for (k=0; chInfo->subchannel && k<chInfo->n_subchannel; k++)
1124        {
1125                if (chInfo->subchannel[k].active == 0) continue;
1126                subchInfo = &chInfo->subchannel[k];
1127               
1128                dprint(2, " move eits for subchannel[%d]..\n", k);
1129               
1130                for (i=0; i<128; i++) {
1131                        if (candidate[i] == i) {          // same
1132                                dprint(3, "    reuse old Eit-%d\n", i);
1133                        }
1134                        else if (candidate[i] == 0xff) {  // no match
1135                                if (subchInfo->eits[i])
1136                                        dprint(3, "    delete old Eit-%d\n", i);
1137                                // Ett±îÁö ´Ù °°ÀÌ Áö¿ï±î??
1138                                if (gPsiDeleteEttsWhenEitChange)
1139                                        PSIDB_FreeEitAndRelatedEtts(subchInfo, i);
1140                                else
1141                                        PSIUTIL_FreeTable(&subchInfo->eits[i]);
1142                        }
1143                        else {                            // match with other eit
1144                                if (subchInfo->eits[i]) {
1145                                        dprint(3, "    overwrite old EIT-%d --> EIT-%d\n", candidate[i], i);
1146
1147                                        if (gPsiDeleteEttsWhenEitChange) 
1148                                                //dprint(3, "      delete old Eit-%d and Ett-%d\n", i, i);
1149                                                PSIDB_FreeEitAndRelatedEtts(subchInfo, i);
1150                                        else {
1151                                                //dprint(3, "      delete old Eit-%d\n", i);
1152                                                PSIUTIL_FreeTable(&subchInfo->eits[i]);
1153                                        }
1154                                       
1155                                        subchInfo->eits[i] = subchInfo->eits[candidate[i]];
1156                                        subchInfo->eits[candidate[i]] = NULL;  // cafrii add 040713
1157                                }
1158                                else {
1159                                        dprint(3, "    move old Eit-%d --> Eit-%d\n", candidate[i], i);
1160                                        subchInfo->eits[i] = subchInfo->eits[candidate[i]];
1161                                        subchInfo->eits[candidate[i]] = NULL;  // cafrii add 040713
1162                                }
1163                        }
1164                }
1165        }
1166        // ----------- ETT check
1167        // ETTÀÇ °æ¿ì´Â EIT¿¡¼­ Á¤ÇØÁø offset value¸¦ ±×´ë·Î »ç¿ëÇϵµ·Ï ÇÑ´Ù. ¸ÂÁö ¾Ê´Â °æ¿ì ¸ðµÎ reloadÇÏÀÚ.
1168
1169        if (gPsiInterTableCompareInMgtChange == 0)
1170                offset = 0;   // inter table compare ¸ðµå°¡ ¾Æ´Ñ °æ¿ì¿¡´Â Ç×»ó °°Àº ¹øÈ£ÀÇ Ett-j : Ett-k¸¸À» ºñ±³ÇØ¾ß ÇÑ´Ù.
1171       
1172        dprint(2, " check ett version..\n");
1173        for (i=0; i<128; i++) 
1174        {
1175                candidate[i] = 0xff; // no candidate yet..
1176               
1177                tbl2 = PSIUTIL_FindTableInMgt(mgt, tt_event_ETT_min+i); // »õ MGT¿¡¼­ EIT-i Á¤º¸¸¦ ã´Â´Ù.
1178                if (tbl2 == NULL) {
1179                        //dprint(3, "  new ETT-%d not exist..\n", i);
1180                        continue;
1181                }
1182               
1183                tbl1 = PSIUTIL_FindTableInMgt(chInfo->mgt, tt_event_ETT_min+i+offset); // ¿¾³¯ MGT¿¡¼­ ETT-(i+offset) Á¤º¸¸¦ ã´Â´Ù.
1184                if (tbl1 == NULL) continue;
1185                       
1186                if (tbl1->table_type_PID == tbl2->table_type_PID && 
1187                    tbl1->table_type_version_number == tbl2->table_type_version_number &&
1188                    tbl1->number_bytes == tbl2->number_bytes) 
1189                {
1190                        // ÀÏ´Ü ¸ðµç Á¤º¸°¡ °°À¸¹Ç·Î ÀÌ tblÀ» »ç¿ëÇÒ ¼ö ÀÖÀ»°Í °°´Ù..
1191                        candidate[i] = i + offset;
1192                        dprint(3, "   new Ett-%d same as Ett-%d (PID %x, v%d, %d)\n", 
1193                                        i, i+offset, tbl1->table_type_PID, tbl1->table_type_version_number, tbl1->number_bytes);
1194                }
1195                else {
1196                        dprint(3, "   new Ett-%d should be downloaded..\n", i);
1197                }
1198        }
1199
1200        // ÀÌÁ¦ candidate°¡ ¾Æ´Ñ ETT´Â »èÁ¦Çϰí À̵¿ÇÑ´Ù..
1201        for (k=0; chInfo->subchannel && k<chInfo->n_subchannel; k++)
1202        {
1203                if (chInfo->subchannel[k].active == 0) continue;
1204                subchInfo = &chInfo->subchannel[k];
1205               
1206                dprint(2, " move Etts for subchannel[%d]..\n", k);
1207               
1208                for (i=0; i<128; i++) {
1209                        if (candidate[i] == i) {          // same
1210                                dprint(3, "    reuse old Ett-%d (%d events)\n", i, subchInfo->n_ett[i]);
1211                        }
1212                        else if (candidate[i] == 0xff) {  // no match
1213                                if (subchInfo->etts[i])
1214                                        dprint(3, "    delete old Ett-%d (%d events)\n", i, subchInfo->n_ett[i]);
1215                                PSIDB_FreeEtts(subchInfo, i);
1216                        }
1217                        else {                            // match with other ett
1218                                if (subchInfo->eits[i]) {
1219                                        dprint(3, "    overwrite old %d Ett-%d --> Ett-%d\n", subchInfo->n_ett[candidate[i]], candidate[i], i);
1220                                        PSIDB_FreeEtts(subchInfo, i);
1221                                        subchInfo->etts[i] = subchInfo->etts[candidate[i]];
1222                                        subchInfo->n_ett[i] = subchInfo->n_ett[candidate[i]];
1223                                       
1224                                        subchInfo->etts[candidate[i]] = NULL;  // cafrii 040713 add
1225                                        subchInfo->n_ett[candidate[i]] = 0;
1226                                }
1227                                else {
1228                                        dprint(3, "    move old %d Ett-%d --> Ett-%d\n", subchInfo->n_ett[candidate[i]], candidate[i], i);
1229                                        subchInfo->etts[i] = subchInfo->etts[candidate[i]];
1230                                        subchInfo->n_ett[i] = subchInfo->n_ett[candidate[i]];
1231                                       
1232                                        subchInfo->etts[candidate[i]] = NULL;  // cafrii 040713 add
1233                                        subchInfo->n_ett[candidate[i]] = 0;
1234                                }
1235                        }
1236                }
1237        }
1238       
1239        // ----------- channel ETT check
1240        tbl1 = PSIUTIL_FindTableInMgt(chInfo->mgt, tt_channel_ETT);
1241        tbl2 = PSIUTIL_FindTableInMgt(mgt, tt_channel_ETT);
1242        if (tbl2 == NULL || tbl1 == NULL) {
1243                dprint(2, " Delete all channel ETT\n");
1244                for (k=0; chInfo->subchannel && k<chInfo->n_subchannel; k++) {
1245                        if (chInfo->subchannel[k].active == 0) continue;
1246                        PSIUTIL_FreeTable(&chInfo->subchannel[k].channel_ett);
1247                }
1248        }
1249        else {
1250                if (tbl1->table_type_version_number != tbl2->table_type_version_number) {
1251                        dprint(2, " ETT-v version changed %d->%d\n", tbl1->table_type_version_number, tbl2->table_type_version_number);
1252                        for (k=0; chInfo->subchannel && k<chInfo->n_subchannel; k++) {
1253                                if (chInfo->subchannel[k].active == 0) continue;
1254                                PSIUTIL_FreeTable(&chInfo->subchannel[k].channel_ett);
1255                        }
1256                }
1257        }
1258
1259        // ¸ðµç tableµéÀ» Ãâ·ÂÇØº¸ÀÚ..
1260        dprint(2, "------- Eit/Ett tables after version check ---------\n");
1261        for (k=0; chInfo->subchannel && k<chInfo->n_subchannel; k++) {
1262                subchInfo = &chInfo->subchannel[k];
1263                if (subchInfo->active == 0) continue;
1264                for (i=0; i<128; i++) {
1265                        if (subchInfo->eits[i])
1266                                dprint(2, "  Eit-%d: 0x%x ver %d\n", i, subchInfo->eits[i], subchInfo->eits[i] ? subchInfo->eits[i]->version_number : 0);
1267                        for (j=0; j<subchInfo->n_ett[i]; j++)
1268                                dprint(2, "     Ett-%d [%d]: 0x%x ver %d\n", i, j, subchInfo->etts[i][j], subchInfo->etts[i][j] ? subchInfo->etts[i][j]->version_number : 0);
1269                }
1270        }
1271        dprint(2, "\n");
1272       
1273        LockPsiDB(FALSE);
1274        return statusOK;       
1275}
1276
1277
1278//-----------------------------------
1279//  PSIDB_MakeMgtSummary
1280//
1281//  mgt¿¡¼­ ¾î¶² VCT°¡ »ç¿ë °¡´ÉÇÑÁö ¾Ë¾Æ³½´Ù.
1282//  ¶Ç, ´Ù¿î·Îµå ¹ÞÀ» ¼ö ÀÖ´Â ¸ðµç EIT°¡ ¸î°³³ª µÇ´ÂÁö, PID°¡ ¾î¶²Áö ã´Â´Ù.
1283//
1284PSI_STATIC void MakeMgtDigest(S_PSIM_MGT_DIGEST *smgt, mgtSectionPtr_t mgt)
1285{
1286        int i;
1287
1288        dprint(1, "%s:\n", __FUNCTION__);
1289       
1290        if (!smgt || !mgt) return;
1291       
1292        // ÀÌ ½ÃÁ¡ºÎÅÍ ÀÌ ÇÔ¼ö ³¡±îÁö ¸ðµÎ LockÀ» ÇÑ´Ù.
1293        LockPsiDB(TRUE);
1294       
1295        smgt->tvct_exist_in_mgt = smgt->cvct_exist_in_mgt = FALSE;
1296        smgt->tvct_ver = smgt->cvct_ver = 0xFF;
1297
1298        smgt->channel_ett_pid = 0;
1299        smgt->channel_ett_ver = 0xff;
1300       
1301        for (i=0; i<128; i++) {
1302                smgt->eit_pids[i] = 0;
1303                smgt->eit_ver[i] = 0xff;
1304                smgt->ett_pids[i] = 0;
1305                smgt->ett_ver[i] = 0xff;
1306        }
1307               
1308        for (i=0; i<mgt->tables_defined; i++) // search all tables..
1309        {
1310                int index;
1311               
1312                if (mgt->table[i].table_type == tt_terrestrial_VCT_cni_1) {           // TVCT
1313                        smgt->tvct_exist_in_mgt = TRUE;
1314                        smgt->tvct_ver = mgt->table[i].table_type_version_number;
1315                }
1316                else if (mgt->table[i].table_type == tt_cable_VCT_cni_1) {            // CVCT
1317                        smgt->cvct_exist_in_mgt = TRUE;
1318                        smgt->cvct_ver = mgt->table[i].table_type_version_number;
1319                }
1320                else if (mgt->table[i].table_type >= tt_EIT_min &&                    // EIT
1321                                mgt->table[i].table_type <= tt_EIT_max)     
1322                {
1323                        index = (mgt->table[i].table_type - tt_EIT_min);
1324
1325                        if (smgt->eit_pids[index] == 0) {
1326                                // cafrii 070712 add check for bugfix
1327                                if (mgt->table[i].table_type_PID == 0 || 
1328                                        mgt->table[i].table_type_PID >= 0x1FFF) {
1329                                        dprint(0, "!! MGT table[%d] EIT-%d pid 0x%x invalid. ignored!\n", 
1330                                                        i, index, mgt->table[i].table_type_PID);
1331                                }
1332                                else {
1333                                        smgt->eit_pids[index] = mgt->table[i].table_type_PID;
1334                                        smgt->eit_ver[index] = mgt->table[i].table_type_version_number;
1335                                }
1336                        }
1337                        else {
1338                                if (mgt->table[i].table_type_PID != smgt->eit_pids[index])
1339                                        dprint(0, "!! MGT table[%d] pid 0x%x != prev EIT-%d pid 0x%x! ignored!\n", 
1340                                                        i, mgt->table[i].table_type_PID, index, smgt->eit_pids[index]);
1341                                else
1342                                        dprint(0, "!! MGT table[%d] is EIT-%d but redundant! ignored!\n", i, index);
1343                        }
1344                }
1345                else if (mgt->table[i].table_type == tt_channel_ETT) {                // channel ETT
1346
1347                        if (smgt->channel_ett_pid == 0) {
1348                                // cafrii 070712 add check for bugfix
1349                                if (mgt->table[i].table_type_PID == 0 || 
1350                                        mgt->table[i].table_type_PID >= 0x1FFF) {
1351                                        dprint(0, "!! MGT table[%d] ETT-v pid 0x%x invalid. ignored!\n", 
1352                                                        i, smgt->channel_ett_pid);
1353                                }
1354                                else {
1355                                        smgt->channel_ett_pid = mgt->table[i].table_type_PID;
1356                                        smgt->channel_ett_ver = mgt->table[i].table_type_version_number;
1357                                }
1358                        }
1359                        else {
1360                                if (mgt->table[i].table_type_PID != smgt->channel_ett_pid)
1361                                        dprint(0, "!! MGT table[%d] pid 0x%x != prev ETT-v pid 0x%x! ignored!\n", 
1362                                                        i, mgt->table[i].table_type_PID, smgt->channel_ett_pid);
1363                                else
1364                                        dprint(0, "!! MGT table[%d] is ETT-v but redundant! ignored!\n", i);
1365                        }
1366                }
1367                else if (mgt->table[i].table_type >= tt_event_ETT_min &&              // ETT
1368                                mgt->table[i].table_type <= tt_event_ETT_max)
1369                { 
1370                        index = (mgt->table[i].table_type - tt_event_ETT_min);
1371
1372                        if (smgt->ett_pids[index] == 0) {
1373                                // cafrii 070712 add check for bugfix
1374                                if (mgt->table[i].table_type_PID == 0 || 
1375                                        mgt->table[i].table_type_PID >= 0x1FFF) {
1376                                        dprint(0, "!! MGT table[%d] ETT-%d pid 0x%x invalid. ignored!\n", 
1377                                                        i, index, mgt->table[i].table_type_PID);
1378                                }
1379                                else {
1380                                        smgt->ett_pids[index] = mgt->table[i].table_type_PID;
1381                                        smgt->ett_ver[index] = mgt->table[i].table_type_version_number;
1382                                }
1383                        }
1384                        else {
1385                                if (mgt->table[i].table_type_PID != smgt->ett_pids[index])
1386                                        dprint(0, "!! MGT table[%d] pid 0x%x != prev ETT-%d pid 0x%x! ignored!\n", 
1387                                                        i, mgt->table[i].table_type_PID, index, smgt->ett_pids[index]);
1388                                else
1389                                        dprint(0, "!! MGT table[%d] is ETT-%d but redundant! ignored!\n", i, index);
1390                        }
1391                }
1392                else if (mgt->table[i].table_type >= tt_RRT_region_1 &&               // RRT
1393                                mgt->table[i].table_type <= tt_RRT_region_255) 
1394                {
1395                        //dprint(2, "RRT not supported yet..\n");
1396                }
1397                else {
1398                        dprint(0, "!! unknown table type %d\n", mgt->table[i].table_type);
1399                }
1400        }
1401       
1402        LockPsiDB(FALSE);
1403
1404        if (smgt->tvct_exist_in_mgt == FALSE && smgt->cvct_exist_in_mgt == FALSE) {
1405        #if 0
1406                sprintf(context->event_string_buf, "Neither of VCT exist in mgt");
1407                Dmc_EpgSendUserEvent(context, epgEventError, (UINT32)statusPSIPError, (UINT32) context->event_string_buf);
1408
1409                dprint(0, "!! %s\n", context->event_string_buf);
1410                return statusPSIPError;
1411                        // ÀÌ·± ¿¡·¯ÀÇ °æ¿ì¿¡´Â ´Ù½Ã retry¸¦ ÇÒ Çʿ䵵 ¾ø´Ù. ¾ÆÁÖ À߸øµÈ °ÍÀ̱⠶§¹®..
1412        #else
1413                // mgt¿¡´Â ¾øÁö¸¸ ½ÇÁ¦·Î Á¸ÀçÇÒ ¼öµµ ÀÖÀ¸¹Ç·Î °è¼Ó ÁøÇà.
1414                dprint(0, "!! neither of vct exist in mgt\n");
1415        #endif
1416        }
1417       
1418}
1419
1420
1421
1422/*
1423        vctÀÇ subch °¹¼ö¸¦ ¾Ë¾Æ³»°í, ÇÊ¿äÇÑ °æ¿ì ±âÁ¸ subch Á¤º¸¸¦ ÃʱâÈ­ ÇÑ´Ù.
1424        subch Á¤º¸ ¾ÈÀÇ vct backup ºÎºÐµµ ÃʱâÈ­ ÇÑ´Ù.
1425
1426        ó¸®ÇÒ vct´Â ÀÌ¹Ì @chInfo ¾È¿¡ ÀúÀåµÇ¾î ÀÖ¾î¾ß ÇÑ´Ù.
1427*/
1428PSI_STATIC STATUS PrepareSubchStructUsingVct(S_PSIM_CHINFO *chInfo)
1429{
1430        STATUS status = statusOK;
1431        int i;
1432        int n_subchannel;
1433        BOOL bSubchResetRequired;
1434
1435        if (!chInfo->vct)
1436                return statusInvalidArgument;
1437       
1438        // ÀÌÁ¦ ¿©±â¼­ºÎÅÍ´Â tvct³ª cvct µÑ Áß Çϳª´Â ¹Ýµå½Ã Á¸ÀçÇÑ´Ù°í °¡Á¤Çϰí ÁøÇàÇÑ´Ù.
1439        // »ç½Ç ÅëÇÕ xvct Çϳª¸¸ Á¸ÀçÇÔ.
1440
1441        dprint(2, "prepare_subch:\n");
1442
1443#if 0
1444        //------------------------------------------------------
1445        // VCT integrity check..
1446        // MGT¿¡¼­ ÁöÁ¤Çϰí ÀÖ´Â ¹öÀü°ú µ¿ÀÏÇÑ °ÍÀÎÁö üũÇÑ´Ù. ¹Ýµå½Ã ±×·² ÇÊ¿ä´Â ¾øÁö¸¸ ÇÏ´Â°Ô ÁÁ°Ú´Ù..
1447        //
1448        if (chInfo->tvct_ver != chInfo->tvct->version_number) {
1449                dprint(0, "!! Warning! TVCT version in MGT %d mismatch with real TVCT version %d\n",
1450                                chInfo->tvct_ver, chInfo->tvct->version_number);
1451                // todo..
1452                // ¹öÀüÀÌ ´Þ¶óÁø ÀÌ·± °æ¿ì ¾î¶»°Ô ÇÒ °ÍÀΰ¡?  ÀÏ´Ü ±×´ë·Î ÁøÇàÇÏÀÚ.
1453        }
1454#endif
1455
1456        //------------------------------------------------------
1457        // »õ vct Á¤º¸·ÎºÎÅÍ ¸¸µé¾î¾ß ÇÒ subch °¹¼ö ¾Ë¾Æ³¿.
1458        //
1459        if (chInfo->vct->channel == NULL) 
1460        { 
1461                // ParseTvct ¿¡¼­ numChannels °¡ 0À̸é ÀÌ·² ¼öµµ ÀÖÁö ¾Ê´Â°¡? --> No..
1462                // NULL channel ÀÎ °æ¿ì numChannels 0 À¸·Î °£ÁÖÇØ¼­ µ¿ÀÛ½ÃŰ¸é ¾ÈµÇ³ª? --> OK..
1463                //
1464                dprint(0, "!! vct channel info NULL\n");
1465                n_subchannel = 0;
1466        }
1467        else
1468                n_subchannel = chInfo->vct->numChannels;
1469                // ÁÖÀÇ! vct syntax »ó n_subchannel ÀÌ 0ÀÏ ¼öµµ ÀÖÀ½.
1470
1471        //------------------------------------------------------
1472        // subchannel Á¤º¸ ÃʱâÈ­ ÇÊ¿äÇÑ °æ¿ì..
1473        //   case 1. óÀ½ vct¸¦ ¹Þ´Â °æ¿ì (±âÁ¸ subchannel Á¤º¸°¡ ¾ø´Â °æ¿ì) -> »õ·Ó°Ô malloc
1474        //   case 2. subchannel °¹¼ö°¡ ´Þ¶óÁø °æ¿ì..   -> buffer re-alloc
1475        //   case 3. source_id Á¤º¸°¡ Çϳª¶óµµ ¹Ù²î¾î ¹ö¸° °æ¿ì -> ³»¿ë reset
1476        //
1477        bSubchResetRequired = FALSE;
1478
1479        // case 1, 2.
1480        if (chInfo->subchannel == NULL || chInfo->n_subchannel != n_subchannel) {
1481                if (chInfo->subchannel)
1482                        dprint(1, "!! subchannel number different!! old %d, new %d\n", chInfo->n_subchannel, n_subchannel);
1483                bSubchResetRequired = TRUE;
1484        }
1485        else { // case 3.
1486                for (i=0; i<n_subchannel; i++) {
1487                        if (chInfo->subchannel[i].source_id != chInfo->vct->channel[i].source_id) {
1488                                dprint(1, "!! subchannel[%d] sid changed!! %d->%d\n", i, 
1489                                                chInfo->subchannel[i].source_id, chInfo->vct->channel[i].source_id);
1490                                bSubchResetRequired = TRUE;
1491                                break;
1492                        }
1493                }
1494        }
1495       
1496        if (bSubchResetRequired)
1497        {
1498                dprint(2, "  subch reset required.. prev n_subch = %d\n", chInfo->n_subchannel);
1499                LockPsiDB(TRUE); //-------------
1500               
1501                // num channelÀÌ ´Þ¶ó¼­ reallocationÇÏ´Â °æ¿ì, ³»ºÎ ³»¿ëÀ» ´Ù free½ÃÄÑ¾ß ÇÑ´Ù..
1502                for (i=0; chInfo->subchannel && i<chInfo->n_subchannel; i++) {
1503                        //dprint(2, "  deleting subchannel info [%d] \n", i);
1504                        PSIDB_FreeSubChInfo(&chInfo->subchannel[i]);
1505                }
1506                DHL_OS_Free((void **)&chInfo->subchannel);
1507                chInfo->n_subchannel = 0;
1508
1509                // ÀÌ¹Ì ¾ð±ÞÇßµíÀÌ n_subchannelÀº 0ÀÏ °¡´É¼ºÀÌ ÀÖ´Ù.
1510                if (n_subchannel > 0) 
1511                {       
1512                        dprint(2, "  make new subchannel info.. n_subch %d\n", n_subchannel);
1513                        // subchannel Á¤º¸ ±¸Á¶Ã¼ ÃʱâÈ­..
1514                        //
1515                        chInfo->subchannel = DHL_OS_Malloc(n_subchannel * sizeof(S_PSIM_SUBCHINFO));
1516                        if (!chInfo->subchannel) {
1517                                dprint(0, "!! out of memory for %d subch..\n", n_subchannel);
1518                                chInfo->n_subchannel = 0;
1519                                status = statusOutOfMemory;
1520                        }
1521                        else {
1522                                chInfo->n_subchannel = n_subchannel;
1523                        }
1524                       
1525                        for (i=0; i<chInfo->n_subchannel; i++) {
1526                                chInfo->subchannel[i].parent = chInfo;  // make back pointer
1527                                chInfo->subchannel[i].index = i;
1528                                chInfo->subchannel[i].source_id = chInfo->vct->channel[i].source_id;
1529                                chInfo->subchannel[i].active = TRUE;
1530
1531#if DMW_PSI_SUPPORT_ELAPSED_TIMER
1532                                DMW_ResetCounter(&chInfo->subchannel[i].counter);
1533                                DMW_HoldCounter(&chInfo->subchannel[i].counter);
1534#endif
1535                        }
1536                }
1537                LockPsiDB(FALSE); //-------------
1538        }
1539        else {
1540                dprint(2, "  prev n_subch %d not changed\n", chInfo->n_subchannel);
1541        }
1542       
1543        //------------------------------------------------------
1544        // vctÀÇ ÀϺΠÁ¤º¸¸¦ °¢ subchannel ·Î ¹é¾÷ÇØµÐ´Ù.
1545        //
1546        for (i=0; i<chInfo->n_subchannel; i++) 
1547        {
1548                memcpy(chInfo->subchannel[i].vct_info.short_name, chInfo->vct->channel[i].short_name, sizeof(UINT16)*7);
1549
1550                if (chInfo->vct->is_cvct) {
1551                        chInfo->subchannel[i].vct_info.major_channel_number = EpgMajorNumberInCVCT(&chInfo->vct->channel[i]);
1552                        chInfo->subchannel[i].vct_info.minor_channel_number = EpgMinorNumberInCVCT(&chInfo->vct->channel[i]);
1553                }
1554                else {
1555                        chInfo->subchannel[i].vct_info.major_channel_number = chInfo->vct->channel[i].major_channel_number;
1556                        chInfo->subchannel[i].vct_info.minor_channel_number = chInfo->vct->channel[i].minor_channel_number;
1557                }
1558                chInfo->subchannel[i].vct_info.program_number = chInfo->vct->channel[i].program_number;
1559
1560                chInfo->subchannel[i].vct_info.analog = 
1561                        (chInfo->vct->channel[i].modulation_mode == mm_analog ||
1562                        chInfo->vct->channel[i].service_type == st_analog_television) ? 1 : 0;
1563
1564                chInfo->subchannel[i].vct_info.etm_location = chInfo->vct->channel[i].ETM_location;
1565        }
1566       
1567        return status;
1568}
1569
1570
1571#if COMMENT
1572____Update____(){}
1573#endif
1574
1575/*
1576        °¢Á¾ TableÀ» PSI DB¿¡ update ÇÔ.
1577
1578        °øÅë Rule:
1579
1580                statusOK¸¦ ¸®ÅÏÇϸé, Á¦´ë·Î DB¿¡ ¹Ý¿µµÇ¾ú´Ù´Â ÀǹÌÀÓ.
1581                µû¶ó¼­ caller´Â ÀÎÀÚ·Î ÁöÁ¤ÇÑ table pointer¸¦ Àбâ Àü¿ëÀ¸·Î »ç¿ë °¡´É.
1582
1583                statusOK°¡ ¾Æ´Ñ ¿¡·¯¸¦ ¸®ÅÏÇÑ´Ù¸é DB¿¡ ¹Ý¿µµÇÁö ¾Ê¾Ò´Ù´Â ÀǹÌÀ̹ǷÎ
1584                caller´Â »ç¿ëµÇÁö ¾ÊÀº table pointer¸¦ free ½ÃŰ´Â µîÀÇ Á¶Ä¡¸¦ ÇØ¾ß ÇÑ´Ù.
1585
1586        ±âÁ¸ table °úÀÇ Àϰü¼º ¹®Á¦:
1587
1588                »õ table ó¸® µµÁß¿¡ ¿¡·¯°¡ ¹ß»ýÇÒ °æ¿ì
1589                Àϰü¼º Â÷¿ø¿¡¼­ ÇÊ¿äÇÏ´Ù¸é ±âÁ¸ Å×À̺í (µ¥ÀÌÅ͵é) µµ »èÁ¦ÇØ¾ß ÇÑ´Ù.
1590               
1591*/
1592
1593
1594/*
1595        PAT¸¦ update ÇÑ´Ù.
1596        ÇÊ¿äÇϸé pmts array¸¦ resizeµµ ÇÑ´Ù.
1597        ÀÌ¹Ì pmt°¡ Á¸ÀçÇÏ´Â °æ¿ì »õ·Î¿î pat¿Í ºñ±³Çؼ­ ¹®Á¦°¡ ÀÖ´Ù¸é pmtµéÀ» freeÇÑ´Ù.
1598
1599        ¾î´À ¼ø°£¿¡µç Ç×»ó pat->numPrograms ¿Í pmts array Å©±â´Â ÀÏÄ¡½Ã۵µ·Ï ÇÑ´Ù.
1600        ÀÌ Á¶°ÇÀÌ À¯ÁöµÇÁö ¾ÊÀ¸¸é update ºÒ°¡!!
1601*/
1602
1603STATUS PSIDB_UpdatePAT(int id, MPEG_PAT *pat)
1604{
1605        S_PSIM_CHINFO *chInfo;
1606        int i;
1607        STATUS status = statusOK;
1608       
1609        LockPsiDB(TRUE); // >>>>>>>>>>>>
1610       
1611        chInfo = PSI_GetChInfo(id);
1612        if (!chInfo || !pat) {
1613                status = statusInvalidArgument;
1614                goto label_end;
1615        }
1616       
1617        if (chInfo->pat) // ±âÁ¸ pat °¡ Á¸ÀçÇÏ´Â °æ¿ì..
1618        {
1619                dprint(2, "pat update, ver %d -> %d, #pgm %d -> %d\n", 
1620                        chInfo->pat->version_number, pat->version_number, chInfo->pat->numPrograms, pat->numPrograms);
1621
1622                // resize pmts array
1623                if (chInfo->pat->numPrograms != pat->numPrograms) 
1624                {
1625                        // ASSERT (chInfo->pmts != NULL) <- true because chInfo->pat exists.
1626                       
1627                        // delete all pmts
1628                        for (i=0; i<chInfo->pat->numPrograms; i++) {
1629                                PSIUTIL_FreeTable(&chInfo->pmts[i]);
1630                        }
1631                        DHL_OS_Free((void **)&chInfo->pmts);
1632
1633                        // »õ·Î¿î pat¿¡ ¸ÂÃç¼­ pmt list ¹öÆÛ ´Ù½Ã ÇÒ´ç..
1634                        chInfo->pmts = DHL_OS_Malloc(pat->numPrograms * sizeof(MPEG_PMT *));
1635                        if (!chInfo->pmts) {
1636                                // critical!!
1637                                // our assumption is that (pat->numPrograms == size of pmts array).
1638                                // so, easy way to keep this assumption is delete whole pat!
1639                                dprint(0, "!! re-alloc pmts err. free pat!\n");
1640                                PSIUTIL_FreeTable(&chInfo->pat); // free previous pat also!!
1641                                status = statusOutOfMemory;
1642                                goto label_end;
1643                        }
1644                }
1645                else {
1646                        // free only inconsistent pmts..
1647                        for (i=0; i<chInfo->pat->numPrograms; i++) {
1648                                if (chInfo->pat->programs[i].program_map_PID != chInfo->pmts[i]->PID ||
1649                                        chInfo->pat->programs[i].program_number != chInfo->pmts[i]->program_number)
1650                                {
1651                                        dprint(2, "  pmt[%d] (pid %x, #%d) unmatched to pat info (pid %x, #%d). free it..\n",
1652                                                        i, chInfo->pmts[i]->PID, chInfo->pmts[i]->program_number,
1653                                                        chInfo->pat->programs[i].program_map_PID, chInfo->pat->programs[i].program_number);
1654                                        PSIUTIL_FreeTable(&chInfo->pmts[i]);
1655                                        // keep pmt whose pid & program number is unchanged.
1656                                }
1657                        }
1658                }
1659
1660                // now, replace old pat..
1661                PSIUTIL_FreeTable(&chInfo->pat);
1662                chInfo->pat = pat;
1663        }
1664        else // ±âÁ¸ pat°¡ ¾ø´Â °æ¿ì. óÀ½ ¹Þ´Â pat..
1665        {
1666                dprint(2, "new pat, ver %d, %d programs\n", pat->version_number, pat->numPrograms);
1667
1668                chInfo->pmts = DHL_OS_Malloc(pat->numPrograms * sizeof(MPEG_PMT *));
1669                if (!chInfo->pmts) {
1670                        // critical!!
1671                        dprint(0, "!! alloc pmts err. free pat!\n");
1672                        PSIUTIL_FreeTable(&chInfo->pat);
1673                        status = statusOutOfMemory;
1674                        goto label_end;
1675                }
1676                chInfo->pat = pat;
1677                pat = NULL;
1678        }
1679
1680label_end:
1681        LockPsiDB(FALSE); // <<<<<<<<<<<<
1682
1683        // caller¿¡¼­ °ü¸®ÇÔ.. »èÁ¦..
1684        // now, un-registered table pointer should be freed.
1685        //if (pat)
1686        //      PSIUTIL_FreeTable(&pat);
1687
1688        return status;
1689}
1690
1691/*
1692
1693*/
1694STATUS PSIDB_UpdatePMT(int id, MPEG_PMT *pmt)
1695{
1696        S_PSIM_CHINFO *chInfo;
1697        int i, index;
1698        STATUS status = statusOK;
1699       
1700        LockPsiDB(TRUE); // >>>>>>>>>>>>
1701       
1702        chInfo = PSI_GetChInfo(id);
1703        if (!chInfo || !pmt) {
1704                status = statusInvalidArgument;
1705                goto label_end;
1706        }
1707       
1708        // pmts list ¾È¿¡¼­ÀÇ ¼ø¼­´Â pat ³»ÀÇ ¼ø¼­´ë·Î ÇÑ´Ù.
1709        index = -1;
1710        for (i=0; i<chInfo->pat->numPrograms; i++) {
1711                if (chInfo->pat->programs[i].program_number == pmt->program_number) {
1712                        index = i;
1713                        break;
1714                }
1715        }
1716
1717        if (index < 0) {
1718                // warning! this pmt is not related to pat!!
1719                dprint(0, "!! cannot find pmt (#%d) info in pat\n", pmt->program_number);
1720                status = statusInvalidPSI;
1721                goto label_end;
1722        }
1723
1724        if (chInfo->pmts[index]) { // previous pmt already exist.
1725                dprint(2, "pmt[%d] update, #%d, ver %d -> %d\n", index, pmt->program_number, 
1726                                        chInfo->pmts[index]->version_number, pmt->version_number);
1727                PSIUTIL_FreeTable(&chInfo->pmts[index]);
1728        }
1729        else {
1730                dprint(2, "new pmt[%d], #%d, ver %d\n", index, pmt->program_number, pmt->version_number);
1731        }
1732        chInfo->pmts[index] = pmt;
1733        //pmt = NULL;
1734
1735label_end:
1736        LockPsiDB(FALSE); // <<<<<<<<<<<<
1737
1738        // caller¿¡¼­ °ü¸®ÇÔ.. »èÁ¦..
1739        // now, un-registered table pointer should be freed.
1740        //if (pmt)
1741        //      PSIUTIL_FreeTable(&pmt);
1742
1743        return status;
1744}
1745
1746
1747
1748/*
1749        »õ @mgt¸¦ DB¿¡ update ÇÑ´Ù.
1750
1751        ¹Ù·Î update Çϱâ Àü¿¡ º¯°æ µÇ´Â »çÇ׵鿡 ´ëÇÑ impact¿¡ ´ëÇÑ Ã³¸®¸¦ ¼öÇàÇÑ´Ù.
1752        ±×¸®°í mgt summary Á¤º¸ µîµµ »ý¼ºÇÑ´Ù.
1753*/
1754STATUS PSIDB_UpdateMgt(int id, mgtSectionPtr_t mgt)
1755{
1756        S_PSIM_CHINFO *chInfo;
1757        STATUS status = statusOK;
1758
1759        dprint(3, "update_mgt: id %d, %x\n", id, mgt);
1760       
1761        LockPsiDB(TRUE); // >>>>>>>>>>>>
1762       
1763        chInfo = PSI_GetChInfo(id);
1764        if (!chInfo || !mgt) {
1765                status = statusInvalidArgument;
1766                goto label_end;
1767        }
1768       
1769        //------------------------------------------------------------------------
1770        // MGT ¹öÀü º¯°æ ó¸®..
1771        //
1772        // ÀÌ ÇÔ¼ö´Â chInfo ¿¡ ÀÖ´Â mgt¿Í, mgt¸¦ ºñ±³Çϱ⠶§¹®¿¡ ÀÌ ½ÃÁ¡±îÁö´Â chInfo¿¡
1773        // mgt¸¦ ÀúÀåÇÏ¸é ¾ÈµÈ´Ù.
1774        //
1775        CheckAndProcessMgtVersionChange(chInfo, mgt);
1776
1777
1778        //------------------------------------------------------------------------
1779        // MGT ºÐ¼®
1780        // chInfo ¿¡ ÀúÀåµÈ mgt°¡ ¾Æ´Ï¶ó ÁöÁ¤ÇÑ mgt·Î üũ¸¦ ÇÑ´Ù..
1781        //
1782        MakeMgtDigest(&chInfo->smgt, mgt);
1783
1784
1785        PSIUTIL_FreeTable(&chInfo->mgt_old);
1786        chInfo->mgt_old = chInfo->mgt;          // ÀÌÀü MGT´Â º¸°üÇØµÐ´Ù.       
1787        chInfo->mgt = mgt;
1788        //mgt = NULL;
1789
1790label_end:
1791        LockPsiDB(FALSE); // <<<<<<<<<<<<
1792
1793        // caller¿¡¼­ °ü¸®ÇÔ.. »èÁ¦..
1794        // now, un-registered table pointer should be freed.
1795        //if (mgt)
1796        //      PSIUTIL_FreeTable(&mgt);
1797
1798        return status;
1799
1800}
1801
1802
1803/*
1804        DB¿¡ »õ @vct¸¦ update ÇÑ´Ù.
1805       
1806       
1807*/
1808STATUS PSIDB_UpdateVct(int id, xvctPtr_t vct)
1809{
1810        S_PSIM_CHINFO *chInfo;
1811        STATUS status = statusOK;
1812
1813        dprint(2, "update_vct: id %d, vct 0x%x\n", id, vct);
1814
1815        DHL_ASSERT(vct!=0, "null vct");
1816       
1817        LockPsiDB(TRUE); // >>>>>>>>>>>>
1818       
1819        chInfo = PSI_GetChInfo(id);
1820        if (!chInfo || !vct) {
1821                dprint(0, "!! chInfo of id %d is %x, vct %x\n", id, chInfo, vct);
1822                status = statusInvalidArgument;
1823                goto label_end;
1824        }
1825
1826        PSIUTIL_FreeTable(&chInfo->vct); // ±âÁ¸ vct¸¦ Á¦°Å..
1827        chInfo->vct = vct;
1828
1829        //---------------------------
1830        // »õ vct Á¤º¸¿¡ µû¶ó subch struct ³»¿ëÀ» ÀÏÄ¡½ÃŲ´Ù.
1831        //
1832        status = PrepareSubchStructUsingVct(chInfo);
1833        if (status) {
1834                // ¹«½¼ ÀÌÀ¯¿¡¼­ÀÎÁö subch ±¸¼ºÀÌ ½ÇÆÐÇÏ¿´À½.
1835                // vct¸¦ ±×´ë·Î µÑ °ÍÀΰ¡? ¾Æ´Ï¸é Àϰü¼ºÀ» À§ÇØ »èÁ¦ÇÒ °ÍÀΰ¡?
1836                // --> ¾ÈÁ¤¼º À§ÁÖ·Î µ¿ÀÛ.
1837                //  status ¸¦ ¿¡·¯·Î ¸®ÅÏÇϸé caller¿¡¼­ table °ü¸®¸¦ ´ã´çÇϹǷÎ
1838                // ±×³É NULL setting ¸¸ ÇÏ¸é µÈ´Ù.
1839                chInfo->vct = NULL;
1840        }
1841       
1842label_end:
1843        LockPsiDB(FALSE); // <<<<<<<<<<<<
1844
1845        // caller¿¡¼­ °ü¸®ÇÔ.. »èÁ¦..
1846        //if (vct)
1847        //      PSIUTIL_FreeTable(&vct);
1848
1849        return status;
1850}
1851
1852
1853STATUS PSIDB_UpdateStt(int id, sttSectionPtr_t stt, UINT32 tick_stt_get)
1854{
1855        S_PSIM_CHINFO *chInfo;
1856        STATUS status = statusOK;
1857
1858        LockPsiDB(TRUE); // >>>>>>>>>>>>
1859
1860        chInfo = PSI_GetChInfo(id);
1861        if (!chInfo || !stt) {
1862                status = statusInvalidArgument;
1863                goto label_end;
1864        }
1865
1866        dprint(2, "stt updated, gps %x\n", stt->system_time);
1867       
1868        // copy whole stt contents.
1869        chInfo->flat_stt = *stt;
1870       
1871        // reset descriptor info..
1872        chInfo->flat_stt.descriptors = NULL;
1873        chInfo->flat_stt.descriptor_length = 0;
1874
1875        chInfo->tick_stt_get = tick_stt_get; // stt Ãëµæ ½ÃÁ¡ÀÇ tick
1876        chInfo->stt_valid = TRUE;
1877       
1878label_end:
1879        LockPsiDB(FALSE); // <<<<<<<<<<<<
1880
1881        // caller¿¡¼­ °ü¸®ÇÔ.. »èÁ¦..
1882        // now, un-registered table pointer should be freed.
1883        //if (stt)
1884        //      PSIUTIL_FreeTable(&stt);
1885
1886        return status;
1887}
1888
1889STATUS PSIDB_InvalidateStt(int id)
1890{
1891        S_PSIM_CHINFO *chInfo;
1892        STATUS status = statusOK;
1893
1894        LockPsiDB(TRUE); // >>>>>>>>>>>>
1895
1896        chInfo = PSI_GetChInfo(id);
1897        if (!chInfo) {
1898                status = statusInvalidArgument;
1899                goto label_end;
1900        }
1901
1902        chInfo->stt_valid = FALSE;
1903
1904label_end:
1905        LockPsiDB(FALSE); // <<<<<<<<<<<<
1906
1907        return status;
1908}
1909
1910STATUS PSIDB_UpdateRrt(int id, rrtSectionPtr_t rrt)
1911{
1912        STATUS status = statusOK;
1913
1914        return status;
1915}
1916
1917
1918/*
1919        eit¸¦ DB¿¡ update ÇÑ´Ù.
1920
1921        °ü·Ã ett Á¤º¸ data structureµµ ÃʱâÈ­ÇÑ´Ù.
1922*/
1923STATUS PSIDB_UpdateEit(int id, eitPtr_t eit, int iEit)
1924{
1925        S_PSIM_CHINFO *chInfo;
1926        S_PSIM_SUBCHINFO *subchInfo;
1927        int source_id;
1928        int i;
1929        STATUS status = statusOK;
1930
1931        dprint(2, "update_eit: (rf %d, idx %d)\n", id, iEit);
1932       
1933        // 1. sanity check
1934        //    valid iEit range is 0 ~ 127.
1935        if (!eit || iEit < 0 || iEit >= 128)
1936                return statusInvalidArgument;
1937
1938        if (eit->numEvents && !eit->event) // invalid table!
1939                return statusInvalidArgument;
1940       
1941        source_id = eit->source_id;
1942
1943        LockPsiDB(TRUE); // >>>>>>>>>>>>
1944       
1945        chInfo = PSI_GetChInfo(id);
1946        if (!chInfo) {
1947                status = statusInvalidArgument;
1948                goto label_end;
1949        }
1950       
1951        // find subchannel index and get 'subchInfo' pointer.
1952        subchInfo = NULL;
1953        for (i=0; i<chInfo->n_subchannel; i++) {
1954                if (chInfo->subchannel[i].source_id == source_id) {
1955                        subchInfo = &chInfo->subchannel[i];
1956                        break;
1957                }
1958        }
1959        if (!subchInfo) { 
1960                // ¼ö½ÅÇÑ eit¿¡ ÇØ´çµÇ´Â subch°¡ ¾ø´Ù?
1961                // burst eit °¡ queue¿¡ ½×¿©¼­ ´Ê°Ô ó¸®µÉ ¶§ ÀÌ·² ¼ö ÀÖÀ½.
1962                dprint(0, "!! no subchannel of source_id %d\n", source_id);
1963                status = statusInvalidState;
1964                goto label_end;
1965        }
1966
1967        // ok.. eit index found. check if any changes of events and ett arrays.
1968
1969        if (subchInfo->eits[iEit]) 
1970        {
1971                if (subchInfo->eits[iEit]->version_number != eit->version_number)
1972                        dprint(2, "  eit[%d] update, ver %d -> %d\n", 
1973                                iEit, subchInfo->eits[iEit]->version_number, eit->version_number);
1974                else
1975                        dprint(2, "  same eit[%d] ver %d exist\n", eit->version_number);
1976
1977                // check ett arrays are consistent.
1978        #if 0
1979                // 1. n_ett vs. etts
1980                if (subchInfo->etts[iEit] == NULL && subchInfo->n_ett[iEit]) {
1981                        dprint(0, "!!!! etts[%d] null but n_ett[%d]=%d\n", iEit, iEit, subchInfo->n_ett[iEit]);
1982                        subchInfo->n_ett[iEit] = 0;
1983                }
1984                else if (subchInfo->etts[iEit] && subchInfo->n_ett[iEit] == 0) {
1985                        dprint(0, "!!!! n_ett[%d]=0, but etts[%d]=%x\n", iEit, iEit, subchInfo->etts[iEit]);
1986                        DHL_OS_Free((void **)&subchInfo->etts[iEit]);      // ÀÌ °æ¿ì´Â ºñÁ¤»óÀû »óȲÀÓ..
1987                }
1988        #endif
1989                // 2. number of events and n_ett
1990                if (subchInfo->n_ett[iEit] > 0 && eit->numEvents != subchInfo->n_ett[iEit]) {
1991                        dprint(2, "!! n_event changed, %d -> %d. clear etts[%d] array\n", 
1992                                        subchInfo->n_ett, eit->numEvents, iEit);
1993                        PSIDB_FreeEtts(subchInfo, iEit);
1994                }
1995               
1996                // 3. event_id match
1997                if (subchInfo->n_ett[iEit] && subchInfo->etts[iEit])
1998                {
1999                        // ¸¸¾à ±âÁ¸ Ett°¡ ÀÏºÎ¶óµµ Á¸ÀçÇÑ´Ù¸é, À̰͵éÀÌ ¸ðµÎ EitÀÇ event ³»¿ë°ú ÀÏÄ¡ÇØ¾ß¸¸ Àç»ç¿ëÀÌ °¡´ÉÇÏ´Ù.
2000                        // Çϳª¶óµµ ¹º°¡ ¾È¸Â´Â°Ô ÀÖÀ¸¸é À̰ÍÀº Àç»ç¿ëÇÒ ¼ö ¾ø´Ù.
2001                        //
2002                        // --> ¸Â´Â°ÍÀº Àç »ç¿ëÇϴ°ÍÀº ¾î¶³±î??
2003                        //
2004                        BOOL bReuseEtt = TRUE;
2005                        UINT16 eit_event_id;
2006                        UINT32 etm_id;
2007                       
2008                        // n_ett[k] == eits[k]->numEvents ÀÌ´Ù.
2009                        for (i=0; i<subchInfo->n_ett[iEit]; i++) {
2010                                if (subchInfo->etts[iEit][i] == NULL) continue; // ¾ø´Â ETT´Â ±»ÀÌ Ã¼Å©ÇÒ ÇÊ¿ä ¾ø´Ù.
2011                               
2012                                eit_event_id = eit->event[i].event_id;
2013                                etm_id = subchInfo->etts[iEit][i]->ETM_id;
2014                                if (eit_event_id != PSIUTIL_GetEventIDFromETMID(etm_id)) {
2015                                        dprint(0, "     !! Ett[%d][%d] event id mismatch! eit(%x) != etm(%x)\n", 
2016                                                        iEit, i, eit_event_id, PSIUTIL_GetEventIDFromETMID(etm_id));
2017                                        bReuseEtt = FALSE;
2018                                        break;
2019                                }
2020                        }
2021                        if (bReuseEtt == FALSE) {
2022                                // Àç»ç¿ë ºÒ°¡Çϸé, ¸ðµÎ Áö¿î´Ù.
2023                                dprint(1, "     !! cannot reuse old Etts[%d].. delete!\n", iEit);
2024                                PSIDB_FreeEtts(subchInfo, iEit);
2025                        }
2026                }
2027
2028                PSIUTIL_FreeTable(&subchInfo->eits[iEit]);
2029                subchInfo->eits[iEit] = eit;
2030                //eit = NULL;
2031        }
2032        else 
2033        {
2034                dprint(2, "  new eit[%d], ver %d\n", iEit, eit->version_number);
2035                subchInfo->eits[iEit] = eit;
2036                //eit = NULL;
2037                // clear any related etts. actually they should not exist at all!
2038                if (subchInfo->n_ett[iEit] || subchInfo->etts[iEit]) {
2039                        dprint(0, "!! etts should not exist! clear etts[%d]..\n", iEit);
2040                        PSIDB_FreeEtts(subchInfo, iEit);
2041                }
2042        }
2043
2044label_end:
2045        LockPsiDB(FALSE); // <<<<<<<<<<<<
2046
2047        // caller¿¡¼­ °ü¸®ÇÔ.. »èÁ¦..
2048        // now, un-registered table pointer should be freed.
2049        //if (eit)
2050        //      PSIUTIL_FreeTable(&eit);
2051       
2052        return status;
2053}
2054
2055
2056#if 0
2057void PSIDB_PrepareEttDownload(int id, int iEit)
2058{
2059        // eitÀÇ event °¹¼ö¿Í etts array °¹¼ö ÀÏÄ¡ üũ.
2060        int n_etm;
2061
2062        // ÀÌ EITÀÇ eventµé Áß¿¡¼­ ¸î°³°¡ ETMÀ» °¡Áö°í ÀÖ´ÂÁö ¼ÀÇÑ´Ù.
2063        //
2064        for (i=0, n_etm=0; i<subchInfo->eits[iEit]->numEvents; i++) {
2065                if (gPsiIgnoreEtmLocationInfo ||                          // ignore ¿É¼ÇÀÌ¸é ¹«Á¶°Ç ¹Þ´Â´Ù.
2066                        subchInfo->eits[iEit]->event[i].ETM_location != ETM_none)
2067                        n_etm++;  // ÀÌ EIT¿¡ °ü·ÃµÈ ETT °¹¼ö..
2068        }
2069        if (n_etm == 0) {  // ÀÌ EITÀÇ À̺¥Æ®µé¿¡´Â ETT°¡ Çϳªµµ ¾ø´Ù°í ÇÑ´Ù. ´Ù¿î·Îµå ¹ÞÀ» Çʿ䰡 ¾ø´Ù.
2070                dprint(3, "        no ETTs of this eit[%d]..\n", iEit);
2071                // ´ÙÀ½ ´Ü°è·Î °¡±â Àü¿¡ ÇöÀç ettµéÀÇ ÀÚ°Ý °Ë»çµµ ÇØ¾ß ÇÏÁö ¾Ê³ª????
2072        }
2073        else {
2074                dprint(3, "   %d ETM's are expected in this EIT..\n", n_etm);
2075        }
2076
2077        // ------ Ett¿ë ¸Þ¸ð¸® ÇÒ´ç..
2078        // ett¿ë ¸Þ¸ð¸®°¡ ¾øÀ¸¸é »õ·Î ÇÒ´çÇÑ´Ù..  ¸¸¾à etts°¡ ÀÖ´Ù¸é n_ett´Â numEvents¿Í °°À» °ÍÀÌ´Ù. (ÀÌ¹Ì Ã¼Å©¿Ï·á)
2079        if (subchInfo->etts[iEit] == NULL)
2080        {
2081                int n_event = subchInfo->eits[iEit]->numEvents;
2082               
2083                subchInfo->etts[iEit] = DHL_OS_Malloc(n_event * sizeof(ettSectionPtr_t));
2084                if (subchInfo->etts[iEit] == NULL) {
2085                        dprint(0, "!! out of memory for %d ETT ptr\n", n_event);
2086                        subchInfo->n_ett[iEit] = 0;
2087                        break;          // ¸Þ¸ð¸® ºÎÁ·? ´õ ÀÌ»ó ÁøÇàÇÒ Çʿ䰡 ¾ø´Ù.
2088                       
2089                        // ·çÇÁ ¹Ù±ùÀ¸·Î ³ª°¡¸é Áö±Ý±îÁö requestµÈ °Í¸¸ÀÌ¶óµµ download¸¦ ½Ãµµ ÇÒ ¼ö´Â ÀÖ´Ù...
2090                }
2091                dprint(3, "        ++ alloc etts memory %x (max %d)\n", subchInfo->etts[iEit], subchInfo->eits[iEit]->numEvents);
2092                subchInfo->n_ett[iEit] = subchInfo->eits[iEit]->numEvents; // ÀÌ Eit¿¡ ¿¬°áµÈ ETT-i ÀÇ °¹¼ö..
2093        }
2094        else
2095                dprint(3, "        ** reuse etts memory %x (max %d:%d)\n", subchInfo->etts[iEit],
2096                                        subchInfo->eits[iEit]->numEvents, subchInfo->n_ett[iEit]);
2097
2098}
2099#endif
2100
2101
2102/*
2103        channel-ett index is passed as 128.
2104
2105*/
2106STATUS PSIDB_UpdateEtt(int id, ettSectionPtr_t ett, int iEit)
2107{
2108        S_PSIM_CHINFO *chInfo;
2109        S_PSIM_SUBCHINFO *subchInfo;
2110        int source_id, event_id;
2111        UINT32 etm_id;
2112        int i, iEvent;
2113        STATUS status = statusOK;
2114       
2115        eitPtr_t eit;
2116        ettSectionPtr_t *p_ett = NULL; // pointer of ett to be updated
2117
2118        dprint(2, "update_ett: (rf %d, idx %d)\n", id, iEit);
2119       
2120        // sanity check
2121        // note that iEit 128 is considered as channel-ett.
2122        //
2123        if (!ett || iEit < 0 || iEit > 128)
2124                return statusInvalidArgument;
2125
2126        etm_id = ett->ETM_id;
2127        source_id = PSIUTIL_GetSourceIDFromETMID(etm_id);
2128        event_id = PSIUTIL_GetEventIDFromETMID(etm_id);
2129
2130        LockPsiDB(TRUE); // >>>>>>>>>>>>
2131       
2132        chInfo = PSI_GetChInfo(id);
2133        if (!chInfo) {
2134                status = statusInvalidArgument;
2135                goto label_end;
2136        }
2137       
2138        // find subchannel index and 'subchInfo' ptr
2139        subchInfo = NULL;
2140        for (i=0; i<chInfo->n_subchannel; i++) {
2141                if (chInfo->subchannel[i].source_id == source_id) {
2142                        subchInfo = &chInfo->subchannel[i];
2143                        break;
2144                }
2145        }
2146        if (!subchInfo) {
2147                dprint(0, "!! no subchannel of source_id %d\n", source_id);
2148                status = statusInvalidState;
2149                goto label_end;
2150        }
2151
2152        // first, consider channel-ett..
2153        if (iEit == 128) {
2154                iEvent = 0; // meaningless for channel-ett..
2155                p_ett = &subchInfo->channel_ett;
2156                goto label_update;
2157        }
2158
2159        // now, consider normal event ett..
2160        // check consistency..
2161       
2162        eit = subchInfo->eits[iEit];
2163        if (!eit) {
2164                dprint(0, "!! ett[%d] received without eit[%d]?\n", iEit);
2165                status = statusInvalidState;
2166                goto label_end;
2167        }
2168        if (eit->numEvents != subchInfo->n_ett[iEit]) {
2169                dprint(0, "!! eit[%d] num event %d != n_ett %d\n", eit->numEvents, subchInfo->n_ett[iEit]);
2170                status = statusInvalidState;
2171                goto label_end;
2172        }
2173       
2174        //  find related eit using event_id
2175       
2176        iEvent = -1;
2177        for (i=0; i<eit->numEvents; i++) {
2178                if (eit->event[i].event_id == event_id) {
2179                        iEvent = i;
2180                        break;
2181                }
2182        }
2183        if (iEvent < 0) {
2184                dprint(0, "ett[%d] event_id 0x%x not matched to eit\n", iEit, event_id);
2185                status = statusInvalidState;
2186                goto label_end;
2187        }
2188
2189        // check etts array exist and its length is consistent to eit events..
2190        if (eit->numEvents != subchInfo->n_ett[iEit]) {
2191                dprint(0, "!! eit events %d != n_ett[%d] %d !!\n", eit->numEvents, iEit, subchInfo->n_ett[iEit]);
2192                PSIUTIL_FreeTable(&ett);
2193                status = statusInvalidState;
2194                goto label_end;
2195        }
2196       
2197        p_ett = &subchInfo->etts[iEit][iEvent];
2198
2199label_update:
2200        if (*p_ett == NULL) {
2201                dprint(2, "  new ett[%d][%d], ver %d, etm %x\n", iEit, iEvent, ett->version_number, ett->ETM_id);
2202                (*p_ett) = ett;
2203        }
2204        else if ((*p_ett)->version_number != ett->version_number) {
2205                dprint(2, "  ett[%d][%d] update, ver %d->%d, etm %x\n", 
2206                        iEit, iEvent, (*p_ett)->version_number, ett->version_number, ett->ETM_id);
2207                PSIUTIL_FreeTable(p_ett);
2208                (*p_ett) = ett;
2209        }
2210        else { // same version number
2211                dprint(2, "  same ett[%d][%d] ver %d exist, etm %x\n", iEit, iEvent, ett->version_number, ett->ETM_id);
2212                PSIUTIL_FreeTable(&ett); // »õ·Î ¹ÞÀº ett¸¦ »èÁ¦ÇÑ´Ù.
2213        }
2214        //ett = NULL; // not to be freed later..
2215
2216label_end:
2217        LockPsiDB(FALSE); // <<<<<<<<<<<<
2218
2219        // caller¿¡¼­ °ü¸®ÇÔ.. »èÁ¦..
2220        // now, un-registered table pointer should be freed.
2221        //if (ett)
2222        //      PSIUTIL_FreeTable(&ett);
2223       
2224        return status;
2225}
2226
2227
2228
2229#if COMMENT
2230____Modify____(){}
2231#endif
2232
2233
2234void PSIDB_DeleteTables(int id)
2235{
2236        S_PSIM_CHINFO *chInfo;
2237
2238        if (!PSITASK_IsPsiTask()) {
2239                dprint(0, "!! changing psi db in other task is illegal!\n");
2240                return;
2241        }
2242
2243        LockPsiDB(TRUE);
2244        chInfo = PSI_GetChInfo(id);
2245
2246        if (chInfo){
2247                dprint(2, "delete chinfo rf %d\n", id);
2248                PSIDB_FreeChInfo(chInfo);
2249                PSIDB_RemoveChInfoNode(id);
2250        }
2251        LockPsiDB(FALSE);
2252}
2253
2254void PSIDB_DeleteAllTables(void)
2255{
2256        S_PSIM_CHINFO *chInfo;
2257        int id;
2258       
2259        if (!PSITASK_IsPsiTask()) {
2260                dprint(0, "!! changing psi db in other task is illegal!\n");
2261                return;
2262        }
2263        dprint(2, "delete all chinfo..\n");
2264       
2265        LockPsiDB(TRUE);
2266        while (1)
2267        {
2268                chInfo = PSI_FirstChInfo();
2269                if (!chInfo) break;
2270
2271                id = chInfo->id;
2272                dprint(2, "  delete chinfo rf %d\n", chInfo->id);
2273                PSIDB_FreeChInfo(chInfo);
2274                PSIDB_RemoveChInfoNode(id);
2275        }
2276        LockPsiDB(FALSE);
2277}
2278
2279#if COMMENT
2280____Public_API____(){}
2281#endif
2282
2283/*
2284        ´Ù¸¥ task¿¡¼­ DB¿¡ Á¢±ÙÇϱâ À§Çؼ­´Â ¹Ýµå½Ã lock ÇÊ¿ä.
2285        ´Ù¸¥ task¿¡¼­´Â Àб⸸ °¡´ÉÇϸç, ¾²±â´Â ±ÝÁö.
2286*/
2287void PSIDB_LockDB(BOOL bLock)
2288{
2289        LockPsiDB(bLock);
2290}
2291
2292
2293// below two function should be called with lock in arbitrary task.
2294// if not found, returns NULL.
2295//
2296S_PSIM_CHINFO *PSIDB_GetPsiChInfo(int id)
2297{
2298        return PSI_GetChInfo(id);
2299}
2300
2301S_PSIM_SUBCHINFO *PSIDB_GetPsiSubChInfo(int id, int source_id)
2302{
2303        return GetSubChInfo(id, source_id);
2304}
2305
2306
2307
2308
2309#if COMMENT
2310____Test____(){}
2311#endif
2312
2313
2314void PSIDB_PrintAllTables(int id, int source_id, BOOL bDetail)
2315{
2316        // id : channelInfo id
2317        // index : subchannel index  0 ~ n_subchannel-1
2318       
2319        int i, k;
2320        int index=0;
2321        BOOL bSimple = bDetail ? 0 : 1; // cafrii 061106, 'simple' is default now.
2322        int program_number = -1;
2323       
2324        S_PSIM_CHINFO *chInfo;
2325        S_PSIM_SUBCHINFO *subchInfo;
2326       
2327        //int org_flag;
2328        //org_flag = OS_UsePrintfSemaphore(0); // do not use printf task..
2329       
2330#undef OS_DbgPrintf
2331#define OS_DbgPrintf DMW_DBG_SimplePrint
2332
2333        OS_DbgPrintf("%s: (id %d, source_id %d)\n", __FUNCTION__, id, source_id);
2334       
2335        LockPsiDB(TRUE); //------------------
2336       
2337        chInfo = PSI_GetChInfo(id);
2338        if (chInfo == NULL) 
2339        {
2340                int cnt=0;
2341                OS_DbgPrintf(" !! EpgDB of id %d not found!!\n", id);
2342                //
2343                // ÇöÀç ¸ðµç channel Á¤º¸¸¦ Ç¥½ÃÇØÁÖÀÚ..
2344                OS_DbgPrintf("==== Summary List of all EPG ====\n");
2345               
2346                chInfo = PSI_FirstChInfo();
2347                while (chInfo) 
2348                {
2349                        OS_DbgPrintf(" (%d) id %d, num subch %d, %d sec%s\n", 
2350                                                cnt++, chInfo->id, chInfo->n_subchannel,
2351#if DMW_PSI_SUPPORT_ELAPSED_TIMER
2352                                                DMW_GetTickCount(&chInfo->counter)/OS_GetTicksPerSecond(),
2353                                                DMW_GetCounterHoldState(&chInfo->counter) ? "" : ".."
2354#else
2355                                                0, ""
2356#endif
2357                                                );
2358                        for (i=0; i<chInfo->n_subchannel; i++)
2359                                OS_DbgPrintf("     [%d] source id %d, %s [%s], #%d, %s %sactive, %d sec%s, %s\n", 
2360                                                i, chInfo->subchannel[i].source_id, 
2361
2362                                                PSIUTIL_ChannelNumberString(chInfo->subchannel[i].vct_info.major_channel_number, 
2363                                                                                chInfo->subchannel[i].vct_info.minor_channel_number, 0),
2364                                                DMW_Unicode2Ks(chInfo->subchannel[i].vct_info.short_name, 7, 0),
2365                                                chInfo->subchannel[i].vct_info.program_number,
2366                                                // cafrii 060320 add
2367                                                chInfo->subchannel[i].vct_info.analog ? "analog," : "",
2368
2369                                                chInfo->subchannel[i].active ? "" : "NOT ",
2370
2371#if DMW_PSI_SUPPORT_ELAPSED_TIMER
2372                                                DMW_GetTickCount(&chInfo->subchannel[i].counter)/OS_GetTicksPerSecond(),
2373                                                DMW_GetCounterHoldState(&chInfo->subchannel[i].counter) ? "" : "..",
2374#else
2375                                                0, "",
2376#endif
2377                                                chInfo->subchannel[i].eit_complete == 0 ? "Incomplete!!" :
2378                                                chInfo->subchannel[i].ett_complete == 0 ? "Eit Completed" : "Completed");
2379                                               
2380                        chInfo = PSI_NextChInfo(chInfo);
2381
2382                }
2383                OS_DbgPrintf("\n");
2384                goto label_exit;
2385        }
2386
2387        #if DMW_EPG_TABLE_DUMP_DEBUG
2388                //DMW_InitCodeConvLib();
2389                // cafrii 041102 delete. ÀÌ°Ô ¾øÀ̵µ Á¦´ë·Î Ãâ·Â µÇ´Â °Í °°´Ù.
2390                        // Unicode --> Ks º¯È¯ table ¹× °ü·Ã ÇÔ¼ö¸¦ ÃʱâÈ­ ÇÑ´Ù.
2391        #endif
2392
2393        OS_DbgPrintf("\nPrint EPG Tables of Ch %d, Subch %d..\n\n", id, index);
2394       
2395        // ÇöÀç´Â subchannel Çϳª¸¸ Å×½ºÆ® Çϰí ÀÖÀ¸´Ï±î, 1°³¸¸ Ãâ·ÂÇÑ´Ù.
2396        //
2397        index = -1;
2398
2399#if 0 // ÀϺη¯ Ʋ¸° sid¸¦ ÁöÁ¤ÇÏ¿© Àüü °³¿äº¸±â¸¦ ÇÒ ¼öµµ ÀÖÀ½.
2400        // cafrii 041030 add, subchannel ÀÌ ÇѰ³ÀÌ¸é ±×³É ±×°Í Ãâ·ÂÇϵµ·Ï ÇÔ..
2401        if (chInfo->n_subchannel == 1) 
2402                source_id = chInfo->subchannel[0].source_id;
2403#endif
2404
2405        // ÁöÁ¤ÇÑ source_id °¡ ÀÖ´ÂÁö È®ÀÎ..   
2406        for (i=0; i<chInfo->n_subchannel; i++) {
2407                if (chInfo->subchannel[i].source_id == source_id) {
2408                        index = i;
2409                        break;
2410                }
2411        }
2412        //--------------------------------------------------------------------
2413        // ÁöÁ¤ÇÑ source_id ¼­ºê ä³ÎÀÌ ¾ø´Â °æ¿ì..
2414       
2415        if (index < 0) {
2416                OS_DbgPrintf(" !! source id %d not found\n", source_id);
2417                //
2418                // subchannel Á¤º¸¸¸ °£´ÜÇÏ°Ô º¸¿©ÁØ´Ù..
2419                OS_DbgPrintf("**** ChannelInfo of id %d: total %d subchannel\n", chInfo->id, chInfo->n_subchannel);
2420
2421                //---- PSI info
2422                if (chInfo->pat) {
2423                        OS_DbgPrintf("   PAT : 0x%x, ver %d, %d programs\n", 
2424                                                chInfo->pat, chInfo->pat->version_number, chInfo->pat->numPrograms);
2425                        for (i=0; chInfo->pmts && i<chInfo->pat->numPrograms; i++) {
2426                                OS_DbgPrintf("     (%d) PMT: 0x%x, pid %04x, #%d, %d streams\n", 
2427                                        i, chInfo->pmts[i], chInfo->pmts[i]->PID, 
2428                                        chInfo->pmts[i]->program_number, chInfo->pmts[i]->numStreams);
2429                        }
2430                }
2431                //---- PSIP info summary
2432                OS_DbgPrintf("   MGT: 0x%x, VCT: 0x%x\n", chInfo->mgt, chInfo->vct);
2433                for (i=0; i<chInfo->n_subchannel; i++) {
2434                        OS_DbgPrintf("     [%d] source id %d, %s [%s], #%d, %sactive, %d sec%s, %s\n", 
2435                                        i, chInfo->subchannel[i].source_id, 
2436
2437                                        PSIUTIL_ChannelNumberString(chInfo->subchannel[i].vct_info.major_channel_number, 
2438                                                                        chInfo->subchannel[i].vct_info.minor_channel_number, 0),
2439                                        DMW_Unicode2Ks(chInfo->subchannel[i].vct_info.short_name, 7, 0),
2440                                        chInfo->subchannel[i].vct_info.program_number,
2441
2442                                        chInfo->subchannel[i].active ? "" : "NOT ",
2443
2444#if DMW_PSI_SUPPORT_ELAPSED_TIMER
2445                                        DMW_GetTickCount(&chInfo->subchannel[i].counter)/OS_GetTicksPerSecond(), 
2446                                        DMW_GetCounterHoldState(&chInfo->subchannel[i].counter) ? "" : "..",
2447#else
2448                                        0, "",
2449#endif
2450                                        chInfo->subchannel[i].eit_complete == 0 ? "Incomplete!!" :
2451                                        chInfo->subchannel[i].ett_complete == 0 ? "Eit Completed" : "Completed");
2452                }
2453                OS_DbgPrintf("\n");
2454                goto label_exit;       
2455        }
2456       
2457        if (chInfo->subchannel[index].active == 0) {
2458                OS_DbgPrintf("!! subchannel %d is inactive now..\n", index);
2459                goto label_exit;
2460        }
2461
2462        //--------------------------------------------------------------------
2463        // ÁöÁ¤ÇÑ source_id ¼­ºê ä³ÎÀÌ ÀÖ´Â °æ¿ì..
2464
2465        subchInfo = &chInfo->subchannel[index];
2466
2467        OS_DbgPrintf(" [%d] source id %d, %s [%s], #%d, %sactive, %d sec%s, %s\n", 
2468                        index, subchInfo->source_id, 
2469
2470                        PSIUTIL_ChannelNumberString(subchInfo->vct_info.major_channel_number, 
2471                                                        subchInfo->vct_info.minor_channel_number, 0),
2472                        DMW_Unicode2Ks(subchInfo->vct_info.short_name, 7, 0),
2473                        subchInfo->vct_info.program_number,
2474
2475                        subchInfo->active ? "" : "NOT ",
2476
2477#if DMW_PSI_SUPPORT_ELAPSED_TIMER
2478                        DMW_GetTickCount(&subchInfo->counter)/OS_GetTicksPerSecond(), 
2479                        DMW_GetCounterHoldState(&subchInfo->counter) ? "" : "..",
2480#else
2481                        0, "",
2482#endif
2483                        subchInfo->eit_complete == 0 ? "Incomplete!!" :
2484                        subchInfo->ett_complete == 0 ? "Eit Completed" : "Completed");
2485
2486        program_number = subchInfo->vct_info.program_number;
2487       
2488        if (chInfo->pat) 
2489                OS_DbgPrintf("   PAT     : 0x%x, ver %d, %d programs\n", 
2490                                        chInfo->pat, chInfo->pat->version_number, chInfo->pat->numPrograms);
2491        if (chInfo->pat && chInfo->pmts) {
2492                for (i=0; i<chInfo->pat->numPrograms; i++) {
2493                        if (chInfo->pmts[i]->program_number == program_number)
2494                                OS_DbgPrintf("   PMT[%d]  : 0x%x, ver %d, %d streams\n", 
2495                                        i, chInfo->pmts[i], chInfo->pmts[i]->version_number, chInfo->pmts[i]->numStreams);
2496                }
2497        }
2498        if (chInfo->mgt)      OS_DbgPrintf("   MGT     : 0x%x, ver %d\n", chInfo->mgt, chInfo->mgt->version_number);
2499        if (chInfo->mgt_old)  OS_DbgPrintf("   preMGT  : 0x%x, ver %d\n", chInfo->mgt_old, chInfo->mgt_old->version_number);
2500
2501        //if (chInfo->tvct) OS_DbgPrintf("   TVCT    : 0x%x, ver %d\n", chInfo->tvct, chInfo->tvct->version_number);
2502        //if (chInfo->cvct) OS_DbgPrintf("   CVCT    : 0x%x, ver %d\n", chInfo->cvct, chInfo->cvct->version_number);
2503        if (chInfo->vct) 
2504                OS_DbgPrintf("   VCT     : 0x%x, ver %d %s, %d subchannels\n", 
2505                                chInfo->vct, chInfo->vct->version_number, chInfo->vct->is_cvct ? "(cvct)" : "(tvct)",
2506                                chInfo->vct->numChannels);
2507
2508#if 0 // cafrii 050330 stt »èÁ¦
2509        if (chInfo->stt)  OS_DbgPrintf("   STT  : 0x%x\n", chInfo->stt);
2510#else
2511        // cafrii 060724, show stt time
2512        // cafrii 061106, show local time and timezone also
2513        OS_DbgPrintf("   STT time: 0x%x, (%s)\n", chInfo->flat_stt.system_time,
2514                                PSIUTIL_GpsTimeString2(chInfo->flat_stt.system_time, NULL, 4)); 
2515#endif
2516
2517#if DMW_EPG_SUPPORT_RRT
2518        if (g_EpgRrt) {
2519                OS_DbgPrintf("   RRT : 0x%x (region %d)\n", 
2520                        g_EpgRrt, (int)g_EpgRrt->rating_region);
2521                PSIUTIL_PrintRrt(g_EpgRrt, 4, 0);
2522        }
2523#endif
2524
2525        OS_DbgPrintf("   EIT-array : 0x%x\n", subchInfo->eits);
2526        OS_DbgPrintf("\n");
2527
2528        //if (subchInfo->channel_ett_exist)
2529        if (PSIDB_IsSubChEttVRequired(id, source_id))
2530        {
2531                if (subchInfo->channel_ett) {
2532                        OS_DbgPrintf("...ETT-v : 0x%x\n", subchInfo->channel_ett);
2533                        #if DMW_EPG_TABLE_DUMP_DEBUG           
2534                                Dmc_PrintEtt(subchInfo->channel_ett, 6);
2535                                OS_DbgPrintf("\n");
2536                        #endif
2537                }
2538                else 
2539                        OS_DbgPrintf("...ETT-v : **** Not loaded yet ****\n");  // cafrii 041123 add
2540        }
2541
2542       
2543        for (k=0; k<128; k++)
2544        {
2545                if (k == gPsiMaxEitEttIndexToReceive+1) { // cafrii 050412 change to variables
2546                        OS_DbgPrintf("-------- MAX EIT/ETT index %d --------\n", 
2547                                gPsiMaxEitEttIndexToReceive);
2548                        if (bSimple)
2549                                break; // simple mode¿¡¼­´Â ´õ ÀÌ»ó Ãâ·ÂÇÏÁö ¸»ÀÚ.
2550                }
2551
2552                if (chInfo->smgt.eit_pids[k] == 0) continue;
2553                        // mgt¿¡ ¾Æ¿¹ µî·ÏÀÌ ¾ÈµÈ eit´Â Ç¥½Ãµµ ÇÏÁö ¾Ê´Â´Ù.
2554                       
2555                if (subchInfo->eits[k] == NULL) {
2556                        OS_DbgPrintf("...EIT-%d : **** Not loaded yet ****\n", k); 
2557                        continue;
2558                }
2559               
2560                //OS_DbgPrintf("...EIT-%d : 0x%x,   ETT-array: 0x%x\n", k, subchInfo->eits[k], subchInfo->etts[k]);
2561                OS_DbgPrintf("...EIT-%d : 0x%x (pid 0x%x)  ETT-array: 0x%x\n", 
2562                                                        k, subchInfo->eits[k], chInfo->smgt.eit_pids[k], subchInfo->etts[k]);
2563                        // cafrii 050413, Eit PID Ç¥½Ã Ãß°¡
2564               
2565                PSIUTIL_PrintEit(subchInfo->eits[k], 6, bSimple ? subchInfo->etts[k] : 0);
2566                OS_DbgPrintf("\n");
2567               
2568                if (bSimple) // °£´ÜÇÏ°Ô Ç¥½ÃÇÏ´Â ¸ðµå¶ó¸é PrintEit ¿¡¼­ Ettµµ °°ÀÌ Ãâ·ÂµÇ¾úÀ» °ÍÀÌ´Ù. ¿©±â¼­ Á¾·á..
2569                        continue;
2570                       
2571                //if (chInfo->ett_pids[k] == 0) continue;  // pid Á¤º¸ °°Àº °ÍµéÀº ÃÖÁ¾ °á°ú¹°Àº ¾Æ´Ï´Ù. ÂüÁ¶ÇÏÁö ¸»ÀÚ.
2572                if (subchInfo->etts[k] == NULL) continue;
2573               
2574                for (i=0; i<subchInfo->n_ett[k]; i++) {
2575                        //if (subchInfo->eits[k]->event[i].ETM_location == ETM_none)  continue;
2576                       
2577                        if (subchInfo->etts[k][i] == NULL) {
2578                                if (subchInfo->eits[k]->event[i].ETM_location == ETM_none)
2579                                        OS_DbgPrintf("........ETT-%d [%d] : None\n", k, i);
2580                                else {
2581                                        UINT32 etmid = PSIUTIL_MakeEventETMID(subchInfo->source_id, subchInfo->eits[k]->event[i].event_id);
2582                                                // cafrii 041028, MakeETMID -> MakeEventETMID
2583                                               
2584                                        // ¾ÆÁ÷ ¼ö½ÅÀÌ ¾ÈµÈ °ÍÀÎÁö, ¾Æ´Ï¸é °ãÄ¡´Â°Ô ÀÖ´Â °ÍÀÎÁö Á¶»ç..
2585                                        BOOL bMatchExist = FALSE;
2586                                        int t1, t2;
2587                                       
2588                                        for (t1=k; t1>=0; t1--) {  // Çϳª¾¿ °Å²Ù·Î µÇµ¹¾Æ°¡¸é¼­..
2589                                                if (subchInfo->etts[t1] == NULL) continue;
2590                                                for (t2=0; t2<subchInfo->n_ett[t1]; t2++) {
2591                                                        if (subchInfo->etts[t1][t2] && subchInfo->etts[t1][t2]->ETM_id == etmid) {
2592                                                                bMatchExist = TRUE;
2593                                                                break;
2594                                                        }
2595                                                }
2596                                                if (bMatchExist) break;
2597                                        }
2598                                       
2599                                        if (bMatchExist)
2600                                                OS_DbgPrintf("........ETT-%d [%d] : same etm (0x%x) exist\n", k, i, etmid);
2601                                        else
2602                                                OS_DbgPrintf("........ETT-%d [%d] : **** Not loaded yet, etmid 0x%x, pid 0x%x ****\n", 
2603                                                                                k, i, etmid, chInfo->smgt.ett_pids[k]);
2604                                }
2605                                continue;
2606                        }
2607                       
2608                        OS_DbgPrintf("........ETT-%d [%d] : 0x%x (pid 0x%x)\n", 
2609                                        k, i, subchInfo->etts[k][i], chInfo->smgt.ett_pids[k]);  // ¿¡·¯°¡ ¹ß»ýÇß´Ù¸é 0x0 À¸·Î Ç¥½ÃµÈ´Ù.
2610                                        // cafrii 050413 ett pid Ç¥½Ã Ãß°¡.
2611                       
2612                        PSIUTIL_PrintEtt(subchInfo->etts[k][i], 8);
2613                        OS_DbgPrintf("\n");
2614               
2615                }
2616        }
2617       
2618       
2619label_exit:
2620
2621        LockPsiDB(FALSE); //------------------
2622        //OS_UsePrintfSemaphore(org_flag);
2623
2624#undef OS_DbgPrintf
2625       
2626}
2627
2628
2629
Note: See TracBrowser for help on using the repository browser.