source: svn/trunk/zasc/app_c/DST_ISDBT_ChannelTask.c

Last change on this file was 73, checked in by phkim, 10 years ago
  1. phkim
  2. zasc
  3. 변경 내용
    • CT_ChMapUpdatePMTAC3AudioDescriptor 메모리 leak 버그 수정
File size: 87.2 KB
Line 
1#include "DST_ISDBT_ChannelTask.h"
2#include "DST_CommonAPI.h"
3#include "DST_HostInterface.h"
4#include "DST_WinManagerTask.h"
5//#include "sqlite3.h"
6#include "dst_eroum_interface.h"
7#include "DST_DB_Engine.h"
8#include "DST_DB.h"
9#include "DST_Parser.h"
10#include "DST_MultipleStringStructure.h"
11#include "DST_MemoryDB.h"
12//#include "DST_OTC_Main.h"
13
14DS_U16 DST_GetMHzFrequencybyIndex(int index);
15int DST_GetAppShortVersionNumber();
16
17void DST_SignalInfoCallBack(int nWidth, int nHeight, int RefreshRate, bool bInterlaced, DHL_SOURCE_ASEPCT Aspect);
18void DST_VideoFreezeEndProc();
19void DST_SBTVDCC_Reset();
20DS_U8* JST_Arib2Utf8(DS_U8* strArib, int nLen);
21
22#define MAX_EIT_COUNT 4
23#define MAX_PMT_COUNT 16
24
25typedef enum 
26{
27        POS_TVCT,
28        POS_STT,
29        POS_PAT,
30        POS_RFUPDATE,
31        POS_CVT,
32        POS_OTC_DII,
33        POS_OTC_DDB,
34#if CVCT_SUPPORT
35        POS_CVCT,
36#endif
37        POS_PMT,
38#if EPG_SUPPORT
39        POS_MGT = POS_PMT + MAX_PMT_COUNT,
40        POS_EIT,
41        POS_ETT =  POS_EIT+MAX_EIT_COUNT,
42#endif
43} POS_PSIP;
44
45
46static char* GetSiName(int nPos)
47{
48        switch (nPos)
49        {
50                case POS_TVCT: return "POS_TVCT";
51#if CVCT_SUPPORT
52                case POS_CVCT: return "POS_CVCT";
53#endif
54                case POS_STT: return "POS_STT";
55#if EPG_SUPPORT
56                case POS_MGT: return "POS_MGT";
57                case POS_EIT: return "POS_EIT";
58                case POS_ETT: return "POS_ETT";
59#endif
60                case POS_PAT: return "POS_PAT";
61                case POS_PMT: return "POS_PMT";
62                case POS_RFUPDATE: return "POS_RFUPDATE";
63                case POS_CVT: return "POS_CVT";
64                case POS_OTC_DII: return "POS_OTC_DII";
65                case POS_OTC_DDB: return "POS_OTC_DDB";
66        }
67#if EPG_SUPPORT
68        if (nPos > POS_EIT && nPos < POS_EIT + MAX_EIT_COUNT)
69        {
70                return "POS_EIT";
71        }
72        if (nPos > POS_ETT && nPos < POS_ETT + MAX_EIT_COUNT)
73        {
74                return "POS_ETT";
75        }
76#endif
77        if (nPos > POS_PMT && nPos < POS_PMT + MAX_PMT_COUNT)
78        {
79                return "POS_PMT";
80        }
81        return "Unknown";
82}
83
84#if 0
85____FREQUENCY___()
86#endif
87
88DS_U8* JST_Uni2Utf8(DS_U16* strUni, int nLen)
89{
90        if (nLen == 0) return 0;
91        if (strUni == 0) return 0;
92        DS_U16 strTmp16[4097];
93        memset(strTmp16, 0,  sizeof(strTmp16));
94        if (nLen > 4096) nLen = 4096;
95        memcpy(strTmp16, strUni, nLen * sizeof(DS_U16));
96        nLen = strlen16(strTmp16);
97        if (nLen == 0) return 0;
98        DS_U8* buff = (DS_U8*)DST_OS_Calloc(nLen*4+1,1);
99        int nPos = 0;
100        int i;
101        for ( i = 0; i < nLen; i++)
102        {
103                DS_U32 uni = strUni[i];
104                if (uni <= 0x7F)
105                { // 0xxxxxxx
106                        buff[nPos] = uni;
107                        nPos++;
108                        continue;
109                }
110                if (uni <= 0x7FF)
111                { // 110xxxxx 10xxxxxx
112                        buff[nPos] = 0xC0 | (uni >> 6);
113                        nPos++;
114                        buff[nPos] = 0x80 | (uni & 0x3F);
115                        nPos++;
116                        continue;                       
117                }
118                if (uni <= 0xFFFF)
119                { // 1110xxxxx 10xxxxxx 10xxxxxx
120                        buff[nPos] = 0xE0 | (uni >> 12);
121                        nPos++;
122                        buff[nPos] = 0x80 | ((uni >> 6) & 0x3F);
123                        nPos++;
124                        buff[nPos] = 0x80 | (uni & 0x3F);
125                        nPos++;
126                        continue;                       
127                }
128                // 11110zzz 10zzxxxx 10xxxxxx 10xxxxxx
129                uni = uni & 0x1FFFFF;
130                buff[nPos] = 0xF0 | (uni >> 18);
131                nPos++;
132                buff[nPos] = 0x80 | ((uni >> 12) & 0x3F);
133                nPos++;
134                buff[nPos] = 0x80 | ((uni >> 6) & 0x3F);
135                nPos++;
136                buff[nPos] = 0x80 | (uni & 0x3F);
137                nPos++;
138        }
139        return buff;
140}
141
142static char* mss2utf8(DS_U8 nLen, DS_U8 *text)
143{
144        static char strUTF8[4096];
145        static DS_U16 strUni[4096];
146        if (nLen == 0 || text == 0) return 0;
147        memset(strUTF8, 0, 4096);
148        memset(strUni, 0,4096*2);
149        DMW_Decode_MultipleStringStructure(nLen, text, (char*)"kor",4096-1, strUni);
150        char *strTmp = (char*)JST_Uni2Utf8(strUni, 4096-1);
151        strcpy(strUTF8, strTmp);
152        DST_OS_Free(&strTmp);
153        return strUTF8;
154}
155
156#if 0
157____MUTE___()
158#endif
159
160static DS_U32 g_VideoMute = 0;
161static DS_U32 g_AudioMute = 0;
162static DS_U8  g_AudioVolume = 0;
163
164static void CT_VideoMute(DS_U8 nPos, bool bVal)
165{
166        DS_U32 nVal = bVal ? (g_VideoMute | (1 << nPos)) : (g_VideoMute & (~(1 << nPos)));
167        if (nVal == g_VideoMute) return;
168        if (g_VideoMute == 0 || nVal == 0) DHL_VID_Mute(bVal);
169        g_VideoMute = nVal;
170}
171
172static void CT_AudioMute(DS_U8 nPos, bool bVal)
173{
174        if (bVal)
175        {
176                g_AudioMute |= (1 << nPos);
177        }
178        else
179        {
180                g_AudioMute &= (~(1 << nPos));
181        }
182        DHL_AUD_Volume(g_AudioMute ? 0 : g_AudioVolume);
183}
184
185void CT_AudioVolume(DS_U8 nVal)
186{
187        g_AudioVolume = nVal;
188        DHL_AUD_Volume(g_AudioMute ? 0 : g_AudioVolume);
189}
190
191// mute ó¸®
192static void CT_ChannelChangeVideoMute(bool bMute)
193{
194        CT_VideoMute(1, bMute);
195}
196static void CT_ChannelChangeAudioMute(bool bMute)
197{
198        CT_AudioMute(1, bMute);
199}
200
201void CT_WeakSignalMute(bool bMute)
202{
203        CT_VideoMute(2, bMute);
204        CT_AudioMute(2, bMute);
205}
206
207void CT_AutoScanMute(bool bMute)
208{
209        CT_VideoMute(3, bMute);
210        CT_AudioMute(3, bMute);
211}
212
213void CT_RatingMute(bool bMute)
214{
215        CT_VideoMute(4, bMute);
216        CT_AudioMute(4, bMute);
217}
218
219
220#if 0
221____CHANNEL_MAP___()
222#endif
223// CDBSting Class
224//char* CDBStringAdd(char*strText, const char* strSQL, ...)
225//{
226//      if (strSQL == 0) return 0;
227//      va_list ap;
228//      char *z;
229//      va_start(ap, strSQL);
230//      z = sqlite3_vmprintf(strSQL, ap);
231//      va_end(ap);
232//      int nLen = strlen(z) + 1;
233//      char* strTmp = 0;
234//      if (strText)
235//      {
236//              nLen += strlen(strText);
237//              strTmp = (char*)DST_OS_Calloc(nLen,1);
238//              sprintf(strTmp, "%s%s",strText, z);
239//              DST_OS_Free(&strText);
240//      }
241//      else
242//      {
243//              strTmp = (char*)DST_OS_Calloc(nLen,1);
244//              sprintf(strTmp, "%s", z);
245//      }
246//      sqlite3_free(z);       
247//      return strTmp; 
248//}
249
250//static void CDBStringRun(char* strText)
251//{
252//      // insert ¹®À» ½±°Ô ó¸®Çϱâ À§Çؼ­ ¸¶Áö¸· ±ÛÀÚ°¡ ½°Ç¥¸é ½ºÆäÀ̽º·Î º¯È¯
253//      int nLen = strlen(strText);
254//      if (strText[nLen-1] == ',')
255//      {
256//              strText[nLen-1] = ' ';
257//              CDB db; NewCDB(&db);
258//              db.Query(&db, "%s", strText);
259//              DeleteCDB(&db);
260//      }
261////    strText[0] = 0; // clear
262////    DST_OS_Free(&strText);
263//}
264
265static DS_U8* GetMpegDescriptor (DS_U8 *descriptors, DS_U16 len, DS_U8 tag, DS_U8* tag_len)
266{
267        if (descriptors == 0 || len == 0) return 0;
268        int nPos = 0;
269        *tag_len = 0;
270        while (nPos < len)
271        {
272                DS_U8 nTag = descriptors[nPos];
273                DS_U8 nLen = descriptors[nPos+1];
274                if (nPos + nLen + 2 > len) break; // ÀԷµȵ¥ÀÌÅÍÀÇ ¹üÀ§¸¦ ¹ù¾î³ª µ¥ÀÌÅͰ¡ Àִ°æ¿ì
275                if (nTag == tag)
276                {
277                        *tag_len = nLen;
278                        return &descriptors[nPos];
279                }
280                nPos += (nLen + 2);
281        }
282        return 0;
283}
284
285static int GetMpegDescriptorCount (DS_U8 *descriptors, DS_U16 len, DS_U8 tag)
286{
287        if (descriptors == 0 || len == 0) return 0;
288
289        int nCount = 0;
290        int nPos = 0;
291        while (nPos < len)
292        {
293                DS_U8 nTag = descriptors[nPos];
294               
295                DS_U8 nLen = descriptors[nPos+1];
296                if (nPos + nLen + 2 > len) break; // ÀԷµȵ¥ÀÌÅÍÀÇ ¹üÀ§¸¦ ¹ù¾î³ª µ¥ÀÌÅͰ¡ Àִ°æ¿ì
297                if (nTag == tag) nCount++;
298                nPos += (nLen + 2);
299        }
300        return nCount;
301}
302
303// ¹®ÀÚ¿­ µÚÀÇ ' ' Á¦°Å
304static void Trim(DS_U16 *strText, int nLen)
305{
306        int i;
307        for ( i=nLen-1; i >= 0; i--)
308        {
309                if (strText[i] == ' ')
310                {
311                        strText[i] = 0;
312                        continue;
313                }
314                break;
315        }
316}
317
318static bool CT_ChMapUpdateTVCT(DS_U8 RF, TVCT *tvct, DS_U32 CRC32)
319{
320        if (tvct == 0) return false;
321        if (tvct->numChannels == 0) return false;
322        if (tvct->channel == 0) return false;
323               
324        int i =0;
325        DBLock(true);
326        for (i = 0; i < DB_TVCT_MAX; i++)
327        {
328                if (db_tvct[i].crc == 0) continue;
329                if (db_tvct[i].rf != RF) continue;     
330                if (db_tvct[i].crc == CRC32)
331                {
332                        DBLock(false);
333                        return false; // ÀÌ¹Ì µ¿ÀÏÇÑ TVCT°¡ ä³Î¸Ê¿¡ Àִ°æ¿ìÀÓ
334                }
335        }
336        for (i = 0; i < DB_TVCT_MAX; i++)
337        {
338                if (db_tvct[i].crc == 0) continue;
339                if (db_tvct[i].rf == RF) memset(&db_tvct[i], 0, sizeof(_DB_TVCT_));
340        }
341        for (i = 0; i < DB_TVCT_MAX; i++)
342        {
343                if (db_tvct[i].crc != 0) continue;
344                db_tvct[i].rf = RF;
345                db_tvct[i].transport_stream_id = tvct->transport_stream_id;
346                db_tvct[i].version_number = tvct->version_number;
347                db_tvct[i].crc = CRC32;
348                break;
349        }
350        for (i = 0; i < DB_TVCT_SUB_MAX; i++)
351        {
352                if (db_tvct_sub[i].program_number == 0) continue;
353                if (db_tvct_sub[i].rf == RF) db_tvct_sub[i].program_number = 0;
354        }
355       
356        tvctChannelPtr_t channel = tvct->channel;
357        for ( i = 0; i < tvct->numChannels; i++, channel++)
358        {
359                Trim(channel->short_name, 7);
360                DS_U8* strName = JST_Uni2Utf8(channel->short_name, 7);
361                char* strExtName = 0;
362                if (GetMpegDescriptorCount(channel->descriptors, channel->descriptor_length, extended_channel_name_tag))
363                {
364                        DS_U8 tag_len = 0;
365                        DS_U8 *p = GetMpegDescriptor(channel->descriptors, channel->descriptor_length, extended_channel_name_tag, &tag_len);
366                        strExtName = mss2utf8(tag_len, p+2);
367                }
368                int j;
369                for (j = 0; j < DB_TVCT_SUB_MAX; j++)
370                {
371                        if (db_tvct_sub[j].program_number != 0) continue;
372                        db_tvct_sub[j].rf = RF;
373                        if (strName) strcpy(db_tvct_sub[j].short_name, (char*)strName); 
374                        if (strExtName) strcpy(db_tvct_sub[j].long_name, strExtName);
375                        db_tvct_sub[j].major_channel_number = channel->major_channel_number;
376                        db_tvct_sub[j].minor_channel_number = channel->minor_channel_number;
377                        db_tvct_sub[j].modulation_mode = channel->modulation_mode;
378                        db_tvct_sub[j].carrier_frequency = channel->carrier_frequency;
379                        db_tvct_sub[j].channel_TSID = channel->channel_TSID;
380                        db_tvct_sub[j].program_number = channel->program_number;
381                        db_tvct_sub[j].ETM_location = channel->ETM_location;
382                        db_tvct_sub[j].access_controlled = channel->access_controlled;
383                        db_tvct_sub[j].hidden = channel->hidden;
384                        db_tvct_sub[j].show_guide = channel->show_guide;
385                        db_tvct_sub[j].service_type = channel->service_type;
386                        db_tvct_sub[j].source_id =channel->source_id;
387                        break;
388                }
389                DST_OS_Free(&strName);
390#if 1
391                if (0) DST_Printf("tvct descriptor = %x\n",  (int)channel->descriptors);
392                if (0) DST_Printf("descriptor_length = %d\n", (int)channel->descriptor_length);
393                int i;
394                for ( i = 0; i < channel->descriptor_length; i++) if (0) DST_Printf("%02X ", channel->descriptors[i]);
395                if (0) DST_Printf("\n");
396#endif
397        }
398        for (i = 0; i < DB_TVCT_SUB_MAX; i++)
399        {
400                if (db_tvct_sub[i].program_number == 0) continue;
401                if (0) DST_Printf("db_tvct_sub[%d].rf = %d\n", i, db_tvct_sub[i].rf);
402                if (0) DST_Printf("db_tvct_sub[%d].short_name = %s\n", i, db_tvct_sub[i].short_name);
403                if (0) DST_Printf("db_tvct_sub[%d].long_name = %s\n", i, db_tvct_sub[i].long_name);
404                if (0) DST_Printf("db_tvct_sub[%d].major_channel_number = %d\n", i, db_tvct_sub[i].major_channel_number);
405                if (0) DST_Printf("db_tvct_sub[%d].minor_channel_number = %d\n", i, db_tvct_sub[i].minor_channel_number);
406                if (0) DST_Printf("db_tvct_sub[%d].program_number = 0x%X\n", i, db_tvct_sub[i].program_number);
407                if (0) DST_Printf("db_tvct_sub[%d].source_id = %d\n", i, db_tvct_sub[i].source_id);
408        }
409        DBLock(false);
410        return true;
411}
412
413#if CVCT_SUPPORT
414static bool CT_ChMapUpdateCVCT(DS_U32 RF, CVCT *cvct, DS_U32 CRC32)
415{
416        if (cvct == 0) return false;
417        if (cvct->numChannels == 0) return false;
418        if (cvct->channel == 0) return false;
419
420//      CDB db; NewCDB(&db);
421//      db.Query("create table if not exists cvct(rf int unique, transport_stream_id int, version_number int, crc32)");
422//      db.Query("create table if not exists cvct_sub("
423//              "rf int, short_name text, long_name text, major_channel_number int, minor_channel_number int, "
424//              "modulation_mode int, carrier_frequency int, channel_TSID int, program_number int, ETM_location int, "
425//              "access_controlled int, hidden int, show_guide int, service_type int, source_id int)");
426
427//      db.GetTable(&db, "select crc32 from cvct where rf = %d and crc32 = %d", RF, CRC32);
428//      if(db.GetRow(&db) > 0)
429//      {
430//              DeleteCDB(&db);
431//              return false; // ÀÌ¹Ì µ¿ÀÏÇÑ CVCT°¡ ä³Î¸Ê¿¡ Àִ°æ¿ìÀÓ
432//      }
433        int i =0;
434        for (i = 0; i < DB_CVCT_MAX; i++)
435        {
436                if (db_cvct[i].crc == CRC32) return false; // ÀÌ¹Ì µ¿ÀÏÇÑ CVCT°¡ ä³Î¸Ê¿¡ Àִ°æ¿ìÀÓ
437        }
438//      db.Query(&db, "delete from cvct where rf = %d", RF);
439        for (i = 0; i < DB_CVCT_MAX; i++)
440        {
441                if (db_cvct[i].crc == 0) continue;
442                if (db_cvct[i].rf == RF) memset(&db_cvct[i], 0, sizeof(_DB_CVCT_));
443        }
444//      db.Query(&db, "insert into cvct values(%d, %d, %d, %d)",
445//              RF, cvct->transport_stream_id, cvct->version_number, (int)CRC32);
446        for (i = 0; i < DB_CVCT_MAX; i++)
447        {
448                if (db_cvct[i].crc != 0) continue;
449                db_cvct[i].rf = RF;
450                db_cvct[i].transport_stream_id = cvct->transport_stream_id;
451                db_cvct[i].version_number = cvct->version_number;
452                db_cvct[i].crc = CRC32;
453                break;
454        }
455        for (i = 0; i < DB_CVCT_SUB_MAX; i++)
456        {
457                if (db_cvct_sub[i].program_number != 0  && db_cvct_sub[i].rf == RF) memset(&db_cvct_sub[i], 0, sizeof(_DB_CVCT_SUB_));
458        }
459//      char* cvct_sub = CDBStringAdd(0, "insert into cvct_sub values");
460        cvctChannelPtr_t channel = cvct->channel;
461        int nValidCount = 0;
462//      int i;
463        for ( i = 0; i < cvct->numChannels; i++, channel++)
464        {
465                Trim(channel->short_name, 7);
466                DS_U8* strName = JST_Uni2Utf8(channel->short_name, 7);
467                char *strExtName = 0;
468                if (GetMpegDescriptorCount(channel->descriptors, channel->descriptor_length, extended_channel_name_tag))
469                {
470                        DS_U8 tag_len = 0;
471                        DS_U8 *p = GetMpegDescriptor(channel->descriptors, channel->descriptor_length, extended_channel_name_tag, &tag_len);
472                        strExtName = mss2utf8(tag_len, p+2);
473                }
474                // ATSC_private_information_descriptor
475                // KLabsŬ¸®¾îÄæDTV_¼Û¼ö½ÅÁ¤ÇÕÇ¥ÁØ_°³Á¤º»-1
476                bool bCrear = true;
477                if (GetMpegDescriptorCount(channel->descriptors, channel->descriptor_length, 0xAD))
478                {
479                        DS_U8 tag_len = 0;
480                        DS_U8 *p = GetMpegDescriptor(channel->descriptors, channel->descriptor_length, 0xAD, &tag_len);
481                        if (p[0] == 0xAD) // descriptor_tag
482                        {
483                                if (p[1] >= 9) // descriptor_length
484                                {
485                                        if (p[2] == 0x54 && p[3] == 0x54 && p[4] == 0x41 && p[5] == 0x30) // format_identifier
486                                        {
487                                                if (p[6] >= 1) // private_info_count
488                                                {
489                                                        if (p[7] == 0x02) // private_info_type Ŭ¸®¾îÄæ DTV¿ë ¼­¼úÀÚ
490                                                        {
491                                                                if (p[8] == 0x02) // private_info_length
492                                                                {
493                                                                        DS_U8 ch_frequency_version_number = p[9];
494                                                                        DS_U8 channel_mode = (p[10] >> 4) & 0x0F;
495                                                                        DS_U8 resolution = p[10] & 0x0F;
496                                                                        if (0) DST_Printf("ch_frequency_version_number = %d channel_mode =%d resolution =%d\n", ch_frequency_version_number, channel_mode, resolution);
497                                                                        bCrear = (channel_mode == 0) ? true : false;
498                                                                }
499                                                        }
500                                                }
501                                        }
502                                }
503                        }
504                }
505               
506                bool bValidMajorMinor = true;
507                int major = channel->major_channel_number;
508                int minor = channel->minor_channel_number;
509                if (major < 1000)
510                {
511                        bValidMajorMinor = (minor > 0 && minor < 1000);
512                }       
513                else if (major >= 0x3F0)
514                {
515                        major = (major & 0x0F) * 1024 + minor;
516                        minor = 0;
517                }
518                else
519                {
520                        bValidMajorMinor = false;
521                }
522                bool bIsCurrentRF = true;
523                {
524                        if (channel->carrier_frequency)
525                        {
526                                DS_U32 freq = 1000000 * DST_GetMHzFrequencybyIndex(RF);
527                                //freq = 645000000; // TEST ÄÚµå
528                                bIsCurrentRF = (freq == channel->carrier_frequency);
529                        }
530                }
531                if (bCrear && bValidMajorMinor && channel->hidden==0 && bIsCurrentRF)
532                {
533                        nValidCount++;
534                        int j;
535                        for (j = 0; j < DB_CVCT_SUB_MAX; j++)
536                        {
537                                if (db_cvct_sub[j].program_number == 0)
538                                {
539                                        db_cvct_sub[j].rf = RF;
540                                        if (strName) strcpy(db_cvct_sub[j].short_name, (char*)strName); 
541                                        if (strExtName) strcpy(db_cvct_sub[j].long_name, strExtName);
542                                        db_cvct_sub[j].major_channel_number = major;
543                                        db_cvct_sub[j].minor_channel_number = minor;
544                                        db_cvct_sub[j].modulation_mode = channel->modulation_mode;
545                                        db_cvct_sub[j].carrier_frequency = channel->carrier_frequency;
546                                        db_cvct_sub[j].channel_TSID = channel->channel_TSID;
547                                        db_cvct_sub[j].program_number = channel->program_number;
548                                        db_cvct_sub[j].ETM_location = channel->ETM_location;
549                                        db_cvct_sub[j].access_controlled = channel->access_controlled;
550                                        db_cvct_sub[j].hidden = channel->hidden;
551                                        db_cvct_sub[j].show_guide = channel->show_guide;
552                                        db_cvct_sub[j].service_type = channel->service_type;
553                                        db_cvct_sub[j].source_id =channel->source_id;
554                                        break;
555                                }
556                        }
557//                      cvct_sub = CDBStringAdd(cvct_sub, "(%d, %Q, %Q, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d),",
558//                              RF, strName, strExtName ? strExtName : "",
559//                              major, minor,
560//                              channel->modulation_mode, channel->carrier_frequency,
561//                              channel->channel_TSID, channel->program_number,
562//                              channel->ETM_location, channel->access_controlled,
563//                              channel->hidden, channel->show_guide,
564//                              channel->service_type, channel->source_id
565//                              );
566                }
567                DST_OS_Free(&strName);
568#if 1
569                if (0) DST_Printf("cvct descriptor = %x\n",  (int)channel->descriptors);
570                if (0) DST_Printf("descriptor_length = %d\n", (int)channel->descriptor_length);
571                int i;
572                for ( i = 0; i < channel->descriptor_length; i++) if (0) DST_Printf("%02X ", channel->descriptors[i]);
573                if (0) DST_Printf("\n");
574#endif
575        }
576//      db.Query(&db, "delete from cvct_sub where rf = %d", RF);
577//      if (nValidCount > 0) CDBStringRun(cvct_sub);
578//      DST_OS_Free(&cvct_sub);
579       
580#if 1
581                if (0) DST_Printf("cvct additional_descriptors = %x\n",  (int)cvct->additional_descriptors);
582                if (0) DST_Printf("cvct additional_descriptor_length = %d\n", (int)cvct->additional_descriptor_length);
583//              int i;
584                for ( i = 0; i < cvct->additional_descriptor_length; i++) if (0) DST_Printf("%02X ", cvct->additional_descriptors[i]);
585                if (0) DST_Printf("\n");
586#endif
587//      DeleteCDB(&db);
588        return true;
589}
590#endif
591
592// ±âÁ¸ÀÇ PAT°¡ ¾÷µ¥ÀÌÆ® µÇ¸é VCT¸¦ Áö¿ì°í »õ·Î ¹Þ´Â´Ù
593// ¹Ýȯ°ªÀº °»½Å¿©ºÎÀÌ´Ù.
594static bool CT_ChMapUpdatePAT(DS_U8 RF, MPEG_PAT *pat, DS_U32 CRC32)
595{
596        if (pat == 0) return false;
597        int i =0, j = 0;
598        // µ¿ÀÏ RF CRC °Ë»çÇÏ¿© ¾÷µ¥ÀÌÆ® µÈ »óȲÀÎÁö ±¸ºÐÇÔ
599        bool bUpdate = false;
600        DBLock(true);
601        for (i = 0; i < DB_PAT_MAX; i++)
602        {
603                if (db_pat[i].program_number == 0) continue;
604                if (db_pat[i].rf != RF) continue;
605                if (db_pat[i].crc != CRC32) bUpdate = true;
606                break;
607        }
608        // ÇöÀç RF Á¦°Å
609        for (i = 0; i < DB_PAT_MAX; i++)
610        {
611                if (db_pat[i].program_number == 0) continue;
612                if (db_pat[i].rf != RF) continue;
613                db_pat[i].program_number = 0;
614        }
615        for ( i = 0; i < pat->numPrograms; i++)
616        {
617                DS_U16 program_number = pat->programs[i].program_number;
618                DS_U16 pid = pat->programs[i].program_map_PID;
619                for ( j= 0; j < DB_PAT_MAX; j++)
620                {
621                        if (db_pat[j].program_number != 0) continue;
622                        db_pat[j].rf = RF;
623                        db_pat[j].program_number =program_number;
624                        db_pat[j].pid = pid;
625                        db_pat[j].crc = CRC32;
626                        break;
627                }
628        }
629        // PAT¿¡ ¾ø´Â ÇÁ·Î±×·¥³Ñ¹ö´Â Á¦°Å
630        for (i = 0; i < DB_PMT_MAX; i++)
631        {
632                if (db_pmt[i].program_number == 0) continue;
633                bool bFind = false;
634                for ( j= 0; j < DB_PAT_MAX; j++)
635                {
636                        if (db_pat[j].program_number == 0) continue;
637                        if (db_pmt[i].rf == db_pat[j].rf && db_pmt[i].program_number == db_pat[j].program_number)
638                        {
639                                bFind = true;
640                                break;
641                        }
642                }
643                if (bFind == false) db_pmt[i].program_number = 0; // ¾ø´Ù¸é PMT Áö¿ò
644        }
645        DBLock(false);
646        return bUpdate; // ¾÷µ¥ÀÌÆ®ÀÎÁö ¾Æ´ÑÁö ¹Ýȯ
647}
648
649
650static int g_ChCount = 0;
651int CT_ChMapCount()
652{
653        return g_ChCount;
654}
655
656void CT_ChMapUpdate()
657{
658        DBLock(true);
659        memset(db_channel_db, 0, sizeof(_DB_CHANNEL_DB_) * DB_CHANNEL_DB_MAX);
660        int i,j;
661        // TVCTÀÇ Ã¤³ÎÀ» Ãß°¡ÇÑ´Ù.
662        for (i=0; i < DB_TVCT_SUB_MAX; i++)
663        {
664                if (db_tvct_sub[i].program_number == 0) continue;
665                if (db_tvct_sub[i].hidden != 0) continue;
666                int pcr_pid = 0;
667                int video_pid = 0;
668                int video_type = 0;
669                for (j = 0;  j < DB_PMT_MAX; j++)
670                {
671                        if (db_pmt[j].program_number == 0) continue;
672                        if (db_tvct_sub[i].rf != db_pmt[j].rf) continue;
673                        if (db_tvct_sub[i].program_number != db_pmt[j].program_number) continue;
674                        pcr_pid = db_pmt[j].pcr_pid;
675                        video_pid = db_pmt[j].video_pid;
676                        video_type = db_pmt[j].video_type;
677                        break;
678                }
679                for (j = 0;  j < DB_CHANNEL_DB_MAX; j++)
680                {
681                        if (db_channel_db[j].program_number != 0) continue;
682                        db_channel_db[j].rf = db_tvct_sub[i].rf;
683                        if (strlen(db_tvct_sub[i].short_name)) strcpy(db_channel_db[j].name, db_tvct_sub[i].short_name);
684//                      if (strlen(db_tvct_sub[i].long_name)) strcpy(db_channel_db[j].name, db_tvct_sub[i].long_name);
685                        db_channel_db[j].major = db_tvct_sub[i].major_channel_number;
686                        db_channel_db[j].minor = db_tvct_sub[i].minor_channel_number;
687                        db_channel_db[j].program_number = db_tvct_sub[i].program_number;
688                        db_channel_db[j].source_id = db_tvct_sub[i].source_id;
689                        db_channel_db[j].pcr_pid = pcr_pid;
690                        db_channel_db[j].video_pid = video_pid;
691                        db_channel_db[j].video_type = video_type;
692                        break;
693                }
694        }
695        // TVCT¿¡ ¾ø´Â PMT ä³ÎÀ» Ãß°¡ÇÑ´Ù.
696        for (i = 0;  i < DB_PMT_MAX; i++)
697        {
698                if (db_pmt[i].program_number == 0) continue;
699                bool bFind = false;
700                for (j=0; j < DB_TVCT_MAX;j++)
701                {
702                        if (db_tvct[j].crc == 0) continue;
703                        if (db_tvct[j].rf !=db_pmt[i].rf) continue;
704                        bFind = true;
705                        break;
706                }
707                if (bFind == true) continue; // TVCT¿¡ ÀÖÀ¸¹Ç·Î ¹«½Ã
708                for (j = 0;  j < DB_CHANNEL_DB_MAX; j++)
709                {
710                        if (db_channel_db[j].program_number != 0) continue;
711                        db_channel_db[j].rf = db_pmt[i].rf;
712                        db_channel_db[j].major = (db_pmt[i].rf < 96) ? db_pmt[i].rf +2 : db_pmt[i].rf +4;
713                        db_channel_db[j].minor = db_pmt[i].minor;
714                        db_channel_db[j].program_number = db_pmt[i].program_number;
715                        db_channel_db[j].source_id = 0;
716                        db_channel_db[j].pcr_pid = db_pmt[i].pcr_pid;
717                        db_channel_db[j].video_pid = db_pmt[i].video_pid;
718                        db_channel_db[j].video_type = db_pmt[i].video_type;
719                        break;
720                }       
721        }
722        // db_channel_db Á¤·ÄÇÑ´Ù.
723        for (i=0; i < DB_CHANNEL_DB_MAX-1; i++)
724        {
725                if (db_channel_db[i].program_number == 0) continue;
726                for (j = i+1; j < DB_CHANNEL_DB_MAX; j++)
727                {
728                        if (db_channel_db[j].program_number == 0) continue;
729                                                if ((db_channel_db[i].major > db_channel_db[j].major) ||
730                                 (db_channel_db[i].major == db_channel_db[j].major && db_channel_db[i].minor > db_channel_db[j].minor) ||
731                                  (db_channel_db[i].major == db_channel_db[j].major && db_channel_db[i].minor == db_channel_db[j].minor &&  db_channel_db[i].rf > db_channel_db[j].rf))
732                        {
733                                struct DB_CHANNEL_DB tmp = db_channel_db[i];
734                                db_channel_db[i] = db_channel_db[j];
735                                db_channel_db[j] = tmp;
736                        }
737                }
738        }
739        // ä³Î ¾÷´Ù¿î µðºñ ÃʱâÈ­
740        memset(db_channel_updn, 0, sizeof(_DB_CHANNEL_UPDN_) * DB_CHANNEL_UPDN_MAX);
741        for (i =0; i <DB_CHANNEL_DB_MAX; i++)
742        {
743                if (db_channel_db[i].program_number == 0) continue;
744#if CHANNEL_EDIT_SUPPORT
745                bool bSkip = false;
746                for (j=0; j < DB_SKIP_LIST_MAX; j++)
747                {
748                        if (db_skip_list[j].program_number == 0) continue;
749                        if (db_skip_list[j].rf != db_channel_db[i].rf) continue;
750                        if (db_skip_list[j].program_number != db_channel_db[i].program_number) continue;
751                        bSkip = true;
752                        break;
753                }
754                if (bSkip) continue;
755#endif
756                for (j=0; j < DB_CHANNEL_UPDN_MAX; j++)
757                {
758                        if (db_channel_updn[j].program_number) continue; 
759                        db_channel_updn[j].major = db_channel_db[i].major;
760                        db_channel_updn[j].rf = db_channel_db[i].rf;
761                        db_channel_updn[j].minor = db_channel_db[i].minor;
762                        db_channel_updn[j].program_number = db_channel_db[i].program_number;
763                        break;
764                }
765        }
766        // db_channel_updn Á¤·ÄÇÑ´Ù.
767        for (i=0; i < DB_CHANNEL_UPDN_MAX-1; i++)
768        {
769                if (db_channel_updn[i].program_number==0) continue;
770                for (j = i+1; j < DB_CHANNEL_UPDN_MAX; j++)
771                {
772                        if (db_channel_updn[j].program_number==0) continue;
773                        if ((db_channel_updn[i].major > db_channel_updn[j].major) ||
774                                 (db_channel_updn[i].major == db_channel_updn[j].major && db_channel_updn[i].minor > db_channel_updn[j].minor) ||
775                                  (db_channel_updn[i].major == db_channel_updn[j].major && db_channel_updn[i].minor == db_channel_updn[j].minor &&  db_channel_updn[i].rf > db_channel_updn[j].rf))
776                        {
777                                struct DB_CHANNEL_UPDN tmp = db_channel_updn[i];
778                                db_channel_updn[i] = db_channel_updn[j];
779                                db_channel_updn[j] = tmp;
780                        }
781                }
782        }
783        int nCount = 0;
784        for (i = 0; i < DB_CHANNEL_DB_MAX; i++)
785        {
786                if (db_channel_db[i].program_number) nCount++;
787        }
788        g_ChCount = nCount;
789        DBLock(false);
790        DST_DB_Sync();
791}
792
793static bool g_bReceiveCCDescriptor = false;
794
795
796static void CT_ChMapUpdatePMTCCDescriptor(DS_U32 RF, DS_U16 prog_num, DS_U8 *descriptors, DS_U16 descriptor_length)
797{
798//      T();
799        if(descriptors == 0 || descriptor_length == 0) return;
800        DS_U8 tag_len = 0;
801        DS_U8 *p = GetMpegDescriptor(descriptors, descriptor_length, caption_service_tag, &tag_len );
802        if (tag_len == 0)       return;
803        if (0) DST_Printf("tag_len = %d\n", tag_len); 
804        int i;
805        for ( i=0; i < tag_len+2; i++) if (0) DST_Printf("0x%02X ", p[i]); 
806        if (0) DST_Printf("\n");
807       
808        captionServiceDescriptorPtr_t descripPtr = 0;
809//      T();
810        if (DHL_PSI_ParseCaptionServiceDescriptor(p, &descripPtr))      return;
811//      T();
812        if (descripPtr == 0)    return;
813//      CDB db; NewCDB(&db);
814        if (0) DST_Printf("descripPtr->number_of_services = %d\n", descripPtr->number_of_services);
815        captionServicePtr_t captionService = descripPtr->service;
816        int idx;
817        for( idx = 0 ; idx < descripPtr->number_of_services ; idx++, captionService++)
818        {
819                if(captionService == 0) break;
820                DS_U8 ccId = (captionService->cc_type == cct_line21) ? captionService->cc_id.line21_field : captionService->cc_id.caption_service_number;
821                char strLanguage[4] = "kor";
822                strcpy(strLanguage, captionService->language);
823                if (0) DST_Printf("strLanguage = %s\n", strLanguage);
824                int i;
825                for ( i = 0; i < MAX_PMT_CC_TABLE_COUNT; i++)
826                {
827                        if (pmt_cc_table[i].program_number != 0) continue;
828                        pmt_cc_table[i].rf = RF;
829                        pmt_cc_table[i].program_number = prog_num;
830                        strcpy(pmt_cc_table[i].language,strLanguage);
831                        pmt_cc_table[i].cc_type = captionService->cc_type;
832                        pmt_cc_table[i].cc_id = ccId;
833                        pmt_cc_table[i].easy_reader = captionService->easy_reader;
834                        pmt_cc_table[i].wide_aspect_ratio = captionService->wide_aspect_ratio;
835                        pmt_cc_table[i].korean_code = captionService->korean_code;
836                        if (0) DST_Printf("%s|pmt_cc_table|captionService->cc_type = %d\n", __func__, captionService->cc_type);
837                        if (0) DST_Printf("%s|pmt_cc_table|ccId = %d\n", __func__, ccId);
838                        if (0) DST_Printf("%s|pmt_cc_table|captionService->easy_reader = %d\n", __func__, captionService->easy_reader);
839                        if (0) DST_Printf("%s|pmt_cc_table|captionService->wide_aspect_ratio = %d\n", __func__, captionService->wide_aspect_ratio);
840                        if (0) DST_Printf("%s|pmt_cc_table|captionService->korean_code = %d\n", __func__, captionService->korean_code);
841                        break;
842                }
843                g_bReceiveCCDescriptor = true;
844        }
845        DHL_PSI_FreeMpegDescriptor(descripPtr);
846//      DeleteCDB(&db);
847}
848
849
850static void CT_ChMapUpdatePMTAC3AudioDescriptor(DS_U32 RF, DS_U16 prog_num, DS_U16 pid, DS_U8 *descriptors, DS_U16 descriptor_length)
851{
852//      T();
853        if (descriptors == 0 || descriptor_length == 0) return;
854//      T();
855        DS_U8 tag_len = 0;
856        DS_U8 *p = GetMpegDescriptor(descriptors, descriptor_length, AC3_audio_stream_tag, &tag_len );
857        if (tag_len == 0)       return;
858        if (0) DST_Printf("tag_len = %d\n", tag_len); 
859        int i;
860        for ( i=0; i < tag_len+2; i++) if (0) DST_Printf("0x%02X ", p[i]);
861        if (0) DST_Printf("\n");
862        ac3AudioStreamDescriptorPtr_t descripPtr = 0;
863        if (DHL_PSI_ParseAc3AudioStreamDescriptor(p, &descripPtr))      return;
864        if (descripPtr == 0)    return;
865//      CDB db; NewCDB(&db);
866        char strLanguage[4] = {0,0,0,0};
867        strcpy(strLanguage, descripPtr->language);
868        if (0) DST_Printf("strLanguage = %s\n", strLanguage);
869       
870        // ±âÁ¸¿¡ ÀÖµ· µ¿ÀÏÇÑ ÇÁ·Î±×·¥ ³Ñ¹ö pidÀÇ Á¤º¸ ÃʱâÈ­
871        for ( i = 0; i < MAX_PMT_AC3_TABLE_COUNT; i++)
872        {
873                if (pmt_ac3_table[i].program_number == 0) continue;
874                if (pmt_ac3_table[i].rf == (int)RF && pmt_ac3_table[i].program_number == prog_num
875                                && pmt_ac3_table[i].pid == pid) pmt_ac3_table[i].program_number = 0;
876        }
877        for ( i = 0; i < MAX_PMT_AC3_TABLE_COUNT; i++)
878        {
879                if (pmt_ac3_table[i].program_number != 0) continue;
880                pmt_ac3_table[i].rf = RF;
881                pmt_ac3_table[i].program_number = prog_num;
882                pmt_ac3_table[i].pid = pid;
883                pmt_ac3_table[i].bsmod = descripPtr->bsmod;
884                pmt_ac3_table[i].full_svc = descripPtr->full_svc;
885                pmt_ac3_table[i].langcod = descripPtr->langcod;
886                strcpy(pmt_ac3_table[i].language, strLanguage);
887                if (0) DST_Printf("%s|pmt_ac3_table|%d\n", __func__, i);
888                if (0) DST_Printf("%s|pmt_ac3_table|pid = %d\n", __func__, pid);
889                if (0) DST_Printf("%s|pmt_ac3_table|descripPtr->bsmod = %d\n", __func__, descripPtr->bsmod);
890                if (0) DST_Printf("%s|pmt_ac3_table|descripPtr->full_svc = %d\n", __func__, descripPtr->full_svc);
891                if (0) DST_Printf("%s|pmt_ac3_table|descripPtr->langcod = %d\n", __func__, descripPtr->langcod);
892                break;
893        }
894        DHL_PSI_FreeMpegDescriptor(descripPtr);
895}
896
897
898static void CT_ChMapUpdatePMTISO639LanguageDescriptor(DS_U32 RF, DS_U16 prog_num, DS_U16 pid, DS_U8 *descriptors, DS_U16 descriptor_length)
899{
900        // T();
901        if (descriptors == 0 || descriptor_length == 0) return;
902        // T();
903        DS_U8 tag_len = 0;
904        DS_U8 *p =  GetMpegDescriptor(descriptors, descriptor_length, ISO_639_language_tag, &tag_len);
905        if (tag_len == 0)       return;
906        if (0) DST_Printf("tag_len = %d\n", tag_len); 
907        int i;
908        for ( i=0; i < tag_len+2; i++) if (0) DST_Printf("0x%02X ", p[i]); 
909        if (0) DST_Printf("\n");
910        if (p[1] < 4) return;
911        char ISO_639_Language_code[4];
912        ISO_639_Language_code[0] = (char)p[2];
913        ISO_639_Language_code[1] = (char)p[3];
914        ISO_639_Language_code[2] = (char)p[4];
915        ISO_639_Language_code[3] = 0;
916        DS_U8 audio_type = p[5];
917        // ±âÁ¸¿¡ ÀÖµ· µ¿ÀÏÇÑ ÇÁ·Î±×·¥ ³Ñ¹ö pidÀÇ Á¤º¸ ÃʱâÈ­
918        for ( i = 0; i < MAX_PMT_AC3_TABLE_COUNT; i++)
919        {
920                if (pmt_iso_table[i].program_number == 0) continue;
921                if (pmt_iso_table[i].rf == (int)RF && pmt_iso_table[i].program_number == prog_num
922                        && pmt_iso_table[i].pid == pid) pmt_iso_table[i].program_number = 0;
923        }
924        for ( i = 0; i < MAX_PMT_AC3_TABLE_COUNT; i++)
925        {
926                if (pmt_iso_table[i].program_number != 0) continue;
927                pmt_iso_table[i].rf = RF;
928                pmt_iso_table[i].program_number = prog_num;
929                pmt_iso_table[i].pid = pid;
930                strcpy(pmt_iso_table[i].lang, ISO_639_Language_code);
931                pmt_iso_table[i].type = audio_type;
932                if (0) DST_Printf("%s|pmt_iso_table|%d\n", __func__, i);
933                if (0) DST_Printf("%s|pmt_iso_table|pid = %d\n", __func__, pid);
934                if (0) DST_Printf("%s|pmt_iso_table|ISO_639_Language_code = %s\n", __func__, ISO_639_Language_code);
935                if (0) DST_Printf("%s|pmt_iso_table|audio_type = %d\n", __func__, audio_type);
936                break;
937        }
938}
939
940
941static void CT_PMT_AudioTableUpdate(int rf, int program_number, int pid, int type, int component_tag)
942{
943        int j;
944        // µ¿ÀÏÇÑ program_number & µ¿ÀÏÇÑ PID
945        for ( j = 0; j < MAX_PMT_AUDIO_TABLE_COUNT; j++)
946        {
947                if (pmt_audio_table[j].program_number == 0) continue;
948                if (pmt_audio_table[j].rf == rf && pmt_audio_table[j].program_number == program_number && 
949                                pmt_audio_table[j].pid == pid) pmt_audio_table[j].program_number = 0;
950        }
951        // ºó°÷¿¡ ã¾Æ ³Ö´Â´Ù.
952        for ( j = 0; j < MAX_PMT_AUDIO_TABLE_COUNT; j++)
953        {
954                if (pmt_audio_table[j].program_number != 0) continue;
955                pmt_audio_table[j].rf = rf;
956                pmt_audio_table[j].program_number = program_number;
957                pmt_audio_table[j].pid = pid;
958                pmt_audio_table[j].type = type;
959                pmt_audio_table[j].component_tag = component_tag;
960                break;
961        }
962}
963
964static bool CT_ChMapUpdatePMT(DS_U8 RF, MPEG_PMT *pmt, int minor, DS_U32 CRC32)
965{
966        if (pmt == 0 || pmt->program_number == 0) return false;
967        int i;
968        DBLock(true);
969        for ( i = 0 ; i < MAX_PMT_AUDIO_TABLE_COUNT; i++) 
970        {
971                if (pmt_audio_table[i].rf != (int)RF) pmt_audio_table[i].program_number = 0;
972                if (pmt_audio_table[i].rf == (int)RF && pmt_audio_table[i].program_number == pmt->program_number) pmt_audio_table[i].program_number = 0;
973        }
974        for ( i = 0 ; i < MAX_PMT_CC_TABLE_COUNT; i++) 
975        {
976                if (pmt_cc_table[i].rf != (int)RF) pmt_cc_table[i].program_number = 0;
977                if (pmt_cc_table[i].rf == (int)RF && pmt_cc_table[i].program_number == pmt->program_number) pmt_cc_table[i].program_number = 0;
978        }
979        for ( i = 0 ; i < MAX_PMT_AC3_TABLE_COUNT; i++)
980        { 
981                if (pmt_ac3_table[i].rf != (int)RF) pmt_ac3_table[i].program_number = 0;       
982                if (pmt_ac3_table[i].rf == (int)RF && pmt_ac3_table[i].program_number == pmt->program_number) pmt_ac3_table[i].program_number = 0;     
983        }
984        for ( i = 0 ; i < MAX_PMT_ISO_TABLE_COUNT; i++) 
985        {
986                if (pmt_iso_table[i].rf != (int)RF) pmt_iso_table[i].program_number = 0;
987                if (pmt_iso_table[i].rf == (int)RF && pmt_iso_table[i].program_number == pmt->program_number) pmt_iso_table[i].program_number = 0;
988        }
989        for ( i = 0 ; i < DB_PMT_MAX; i++) 
990        {
991//              if (db_pmt[i].rf != (int)RF) db_pmt[i].program_number = 0;
992                if (db_pmt[i].rf == (int)RF && db_pmt[i].program_number == pmt->program_number) db_pmt[i].program_number = 0;
993        }
994       
995        DS_U16 video_pid = 0;
996        DS_U8  video_stream_type = 0;
997        for ( i = 0; i < pmt->numStreams; i++)
998        {
999                DS_U16 pid = pmt->streams[i].elementary_PID;
1000                if (pid == 0 || pid >= 0x1FFF) continue;
1001                DS_U8 stream_type = pmt->streams[i].stream_type;
1002                DS_U8 component_tag = pmt->streams[i].component_tag;
1003                switch (stream_type)
1004                {
1005                        case StreamType_MPEG1Video:
1006                        case StreamType_MPEG2Video:
1007                        case StreamType_MPEG4Video:
1008                        case StreamType_DC2Video:
1009                                video_pid = pid;
1010                                video_stream_type = stream_type;
1011                                CT_ChMapUpdatePMTCCDescriptor(RF, pmt->program_number, pmt->streams[i].descriptors, pmt->streams[i].descriptor_length);
1012                                break;
1013                        case StreamType_MPEG1Audio:
1014                        case StreamType_MPEG2Audio:
1015                        case StreamType_MPEG4Audio:
1016                        case StreamType_AACAudio:
1017                        case StreamType_AC3Audio:
1018                                CT_PMT_AudioTableUpdate(RF, pmt->program_number, pid, stream_type, component_tag);
1019                                CT_ChMapUpdatePMTAC3AudioDescriptor(RF, pmt->program_number, pid, pmt->streams[i].descriptors, pmt->streams[i].descriptor_length);
1020                                CT_ChMapUpdatePMTISO639LanguageDescriptor(RF, pmt->program_number, pid, pmt->streams[i].descriptors, pmt->streams[i].descriptor_length);
1021                                break;
1022                }
1023        }
1024        for (i = 0; i < DB_PMT_MAX; i++) // µ¿ÀÏÇÑ Á¤º¸´Â Áö¿î´Ù.
1025        {
1026                if (db_pmt[i].program_number != 0) continue;
1027                db_pmt[i].rf = RF;
1028                db_pmt[i].program_number = pmt->program_number;
1029                db_pmt[i].pcr_pid = pmt->PCR_PID;
1030                db_pmt[i].video_pid =  video_pid;
1031                db_pmt[i].video_type = video_stream_type;
1032                db_pmt[i].minor = minor;
1033                db_pmt[i].crc = CRC32;
1034                break;
1035        }
1036        DBLock(false);
1037        return true;
1038}
1039
1040#if EPG_SUPPORT
1041static bool CT_ChMapUpdateEIT(DS_U8 rf, EIT *eit, DS_U8 id, DS_U32 CRC32)
1042{
1043        if (eit == 0) return false;
1044        //CDB db; NewCDB(&db);
1045        //db.GetTable(&db, "select crc from eit where rf =%d and id=%d and source_id=%d", rf, id, eit->source_id);
1046        int i;
1047        bool bFind = false;
1048        for (i = 0; i < DB_EIT_MAX; i++)
1049        {
1050                if (db_eit[i].crc == 0) continue;
1051                if (db_eit[i].rf != rf) continue; 
1052                if (db_eit[i].id != id) continue; 
1053                if (db_eit[i].source_id != eit->source_id) continue; 
1054                if (db_eit[i].crc == CRC32) return false;
1055                bFind = true;
1056                break;
1057        }
1058        if(bFind)
1059        {
1060                // db.Query(&db, "delete from eit where rf = %d and id=%d and source_id=%d", rf, id, eit->source_id);
1061                for (i = 0; i < DB_EIT_MAX; i++)
1062                {
1063                        if (db_eit[i].crc == 0) continue;
1064                        if (db_eit[i].rf != rf) continue; 
1065                        if (db_eit[i].id != id) continue; 
1066                        if (db_eit[i].source_id != eit->source_id) continue;
1067                        memset(&db_eit[i], 0, sizeof(_DB_EIT_)); 
1068                }
1069                // db.Query(&db, "delete from eit_sub where rf = %d and id=%d and source_id=%d", rf, id, eit->source_id);
1070                for (i = 0; i < DB_EIT_SUB_MAX; i++)
1071                {
1072                        if (db_eit_sub[i].rf != rf) continue; 
1073                        if (db_eit_sub[i].id != id) continue; 
1074                        if (db_eit_sub[i].source_id != eit->source_id) continue;
1075                        if (db_eit_sub[i].title) DST_OS_Free(&db_eit_sub[i].title);
1076                        memset(&db_eit_sub[i], 0, sizeof(_DB_EIT_SUB_)); 
1077                }
1078        }
1079        //db.Query(&db, "insert into eit values(%d, %d, %d, %d, %d)", rf, id, eit->source_id, eit->version_number, CRC32);
1080        for (i = 0; i < DB_EIT_MAX; i++)
1081        {
1082                if (db_eit[i].crc != 0) continue;
1083                db_eit[i].rf = rf;
1084                db_eit[i].id = id;
1085                db_eit[i].source_id = eit->source_id;
1086                db_eit[i].version_number = eit->version_number;
1087                db_eit[i].crc = CRC32;
1088                break;
1089        }
1090        //char* eit_sub = CDBStringAdd(0, "%s", "insert into eit_sub values");
1091        eitEventPtr_t event = eit->event;
1092        for ( i = 0; i < eit->numEvents; i++, event++)
1093        {
1094//              eit_sub  = CDBStringAdd(eit_sub, "(%d, %d, %d, %d, %d, %d, %Q),",
1095//                              rf, id, eit->source_id,  event->event_id, event->start_time, event->length_in_seconds,
1096//                              mss2utf8(event->title_length,event->title));
1097                int j;
1098                bool bVacancy = false; // ºóÀÚ¸®°¡ ¾ø´Ù¸é ´Ù¸¥ RFÁ¤º¸¸¦ Áö¿î´Ù
1099                for (j =0; j < DB_EIT_SUB_MAX; j++)
1100                {
1101                        if (db_eit_sub[j].source_id) continue;
1102                        bVacancy = true;
1103                        break;
1104                }
1105                if (bVacancy == false)
1106                {
1107                        for (j =0; j < DB_EIT_SUB_MAX; j++)
1108                        {
1109                                if (db_eit_sub[j].rf == rf) continue;
1110                                if (db_eit_sub[i].title) DST_OS_Free(&db_eit_sub[i].title);
1111                                memset(&db_eit_sub[i], 0, sizeof(_DB_EIT_SUB_)); 
1112                        }
1113                }
1114                for (j =0; j < DB_EIT_SUB_MAX; j++)
1115                {
1116                        if (db_eit_sub[j].source_id) continue;
1117                        db_eit_sub[j].rf = rf;
1118                        db_eit_sub[j].id =id;
1119                        db_eit_sub[j].source_id = eit->source_id; // not zero
1120                        db_eit_sub[j].event_id = event->event_id;
1121                        db_eit_sub[j].start_time = event->start_time;
1122                        db_eit_sub[j].length_in_seconds = event->length_in_seconds;
1123                        char* title = mss2utf8(event->title_length,event->title);
1124                        if (title && strlen(title))
1125                        {
1126                                db_eit_sub[j].title = (char*)DST_OS_Malloc(strlen(title)+1);
1127                                strcpy(db_eit_sub[j].title, title);
1128                        }
1129                        break;
1130                }
1131        }
1132        //if (eit->numEvents > 0) CDBStringRun(eit_sub);
1133        //DST_OS_Free(&eit_sub);
1134        //DeleteCDB(&db);
1135        return true;
1136}
1137
1138static bool CT_ChMapUpdateETT(DS_U8 rf, ETT *ett, DS_U32 crc)
1139{
1140        if (ett == 0) return false;
1141        int i;
1142        for (i=0; i < DB_ETT_MAX; i++) // ÀÌ¹Ì ÀÖ´Â Á¤º¸ÀÎÁö È®ÀÎÇÑ´Ù.
1143        {
1144                if (db_ett[i].crc == crc) return false;
1145        }
1146       
1147        bool bVacancy = false; // ºóÀÚ¸®°¡ ÀÖ´ÂÁö È®ÀÎÇÑ´Ù.
1148        for (i =0; i < DB_ETT_MAX; i++)
1149        {
1150                if (db_ett[i].crc) continue;
1151                bVacancy = true;
1152                break;
1153        }
1154       
1155        if (bVacancy == false) // ºóÀÚ¸®°¡ ¾ø´Ù¸é ´Ù¸¥ RF Á¤º¸´Â Áö¿î´Ù.
1156        {
1157                for (i =0; i < DB_ETT_MAX; i++)
1158                {
1159                        if (db_ett[i].rf == rf) continue;
1160                        if (db_ett[i].title) DST_OS_Free(&db_ett[i].title);
1161                        memset(&db_ett[i], 0, sizeof(_DB_ETT_)); 
1162                }
1163        }
1164       
1165        for (i =0; i < DB_ETT_MAX; i++) // ºóÀÚ¸®°¡ ÀÖ´ÂÁö ´Ù½Ã È®ÀÎÇÑ´Ù.
1166        {
1167                if (db_ett[i].crc) continue;
1168                bVacancy = true;
1169                break;
1170        }
1171       
1172        if (bVacancy == false) // EIT¿Í ¿¬°á¾ÈµÈ Á¤º¸´Â Áö¿î´Ù.
1173        {
1174                for (i=0; i < DB_ETT_MAX; i++)
1175                {
1176                        if (db_ett[i].crc == 0) continue;
1177                        int j;
1178                        bool bFind = false;
1179                        for (j=0; j < DB_EIT_SUB_MAX; j++)
1180                        {
1181                                if (db_eit_sub[j].source_id == 0) continue;
1182                                if (db_ett[i].rf != db_eit_sub[j].rf) continue;
1183                                if (db_ett[i].source_id != db_eit_sub[j].source_id) continue;
1184                                if (db_ett[i].event_id != db_eit_sub[j].event_id) continue;
1185                                bFind = true;
1186                                break;
1187                        }
1188                        if (bFind == false)
1189                        {
1190                                if (db_ett[i].title) DST_OS_Free(&db_ett[i].title);
1191                                memset(&db_ett[i], 0, sizeof(_DB_ETT_));
1192                        }
1193                }
1194        }
1195       
1196        for (i=0; i < DB_ETT_MAX; i++) // Á¤º¸ Ãß°¡
1197        {
1198                if (db_ett[i].crc) continue;
1199                db_ett[i].rf = rf;
1200                db_ett[i].source_id = (ett->ETM_id>>16) & 0xFFFF;
1201                db_ett[i].event_id = (ett->ETM_id>>2) & 0x3FFF ;
1202                char* title = mss2utf8(ett->extended_text_message_length,ett->extended_text_message);
1203                if (title && strlen(title))
1204                {
1205                        db_ett[i].title = (char*)DST_OS_Malloc(strlen(title)+1);
1206                        strcpy(db_ett[i].title, title);
1207                }
1208                db_ett[i].crc = crc;   
1209                break;
1210        }
1211        return true;
1212}
1213#endif
1214
1215// ä³Î½ºÄµ¿¡ ½ÇÆÐÇÑ °æ¿ì ÇØ´ç RF Á¦°Å
1216void JST_DB_Del(DS_U8 nRF)
1217{
1218        int i;
1219        DBLock(true);
1220#if EPG_SUPPORT
1221        for (i =0 ; i < DB_EIT_MAX; i++)
1222        {
1223                if (db_eit[i].rf != nRF) continue;
1224                memset(&db_eit[i], 0, sizeof(_DB_EIT_));
1225        }
1226        for (i =0 ; i < DB_EIT_SUB_MAX; i++)
1227        {
1228                if (db_eit_sub[i].rf != nRF) continue;
1229                if (db_eit_sub[i].title) DST_OS_Free(&db_eit_sub[i].title);
1230                memset(&db_eit_sub[i], 0, sizeof(_DB_EIT_SUB_));
1231        }
1232        for (i =0 ; i < DB_ETT_MAX; i++)
1233        {
1234                if (db_ett[i].rf != nRF) continue;
1235                if (db_ett[i].title) DST_OS_Free(&db_ett[i].title);
1236                memset(&db_ett[i], 0, sizeof(_DB_ETT_));
1237        }
1238#endif
1239        for (i =0 ; i < DB_PAT_MAX; i++)
1240        {
1241                if (db_pat[i].rf != nRF) continue;
1242                memset(&db_pat[i], 0, sizeof(_DB_PAT_));
1243        }
1244        for (i =0 ; i < DB_PMT_MAX; i++)
1245        {
1246                if (db_pmt[i].rf != nRF) continue;
1247                memset(&db_pmt[i], 0, sizeof(_DB_PMT_));
1248        }
1249        for (i =0 ; i < DB_TVCT_MAX; i++)
1250        {
1251                if (db_tvct[i].rf != nRF) continue;
1252                memset(&db_tvct[i], 0, sizeof(_DB_TVCT_));
1253        }
1254        for (i =0 ; i < DB_TVCT_SUB_MAX; i++)
1255        {
1256                if (db_tvct_sub[i].rf != nRF) continue;
1257                memset(&db_tvct_sub[i], 0, sizeof(_DB_TVCT_SUB_));
1258        }
1259#if CVCT_SUPPORT
1260        for (i =0 ; i < DB_CVCT_MAX; i++)
1261        {
1262                if (db_cvct[i].rf != nRF) continue;
1263                memset(&db_cvct[i], 0, sizeof(_DB_CVCT_));
1264        }
1265        for (i =0 ; i < DB_CVCT_SUB_MAX; i++)
1266        {
1267                if (db_cvct_sub[i].rf != nRF) continue;
1268                memset(&db_cvct_sub[i], 0, sizeof(_DB_CVCT_SUB_));
1269        }
1270#endif
1271        CT_ChMapUpdate();
1272        DBLock(false);
1273//      CDB db; NewCDB(&db);
1274//      db.Query(&db, "delete from eit where rf=%d", nRF);
1275//      db.Query(&db, "delete from eit_sub where rf=%d", nRF);
1276//      db.Query(&db, "delete from ett where rf=%d", nRF);
1277//      db.Query(&db, "delete from pat where rf=%d", nRF);
1278//      db.Query(&db, "delete from pmt where rf=%d", nRF);
1279////    db.Query("delete from signal where rf=%d", nRF);
1280//      db.Query(&db, "delete from tvct where rf=%d", nRF);
1281//      db.Query(&db, "delete from tvct_sub where rf=%d", nRF);
1282//      db.Query(&db, "delete from cvct where rf=%d", nRF);
1283//      db.Query(&db, "delete from cvct_sub where rf=%d", nRF);
1284//      db.Query(&db, "delete from channel_db where rf=%d", nRF);
1285//      db.Query(&db, "delete from channel_updn where rf=%d", nRF);
1286//      DeleteCDB(&db);
1287}
1288
1289#if 0
1290____CHANNEL_TASK___()
1291#endif
1292
1293static int gMsgQ = 0;
1294static int gSIMsgQ = 0;
1295
1296typedef struct  {
1297        DS_U8   Cmd;
1298        DHL_MODULATION_MODE demod;
1299        DS_U8 RF;
1300        DS_U16 program_number;
1301} CT_Msg;
1302
1303#define CMD_NULL               0
1304#define CMD_TUNE               1
1305#define CMD_SCAN                2
1306#define CMD_RF_UPDATE 3
1307#define CMD_CVT              4
1308#define CMD_OTC             5
1309#define CMD_OTC_STOP   6
1310#define CMD_STOP               7
1311#define CMD_CLOSE              8
1312
1313char* CT_GetMsgName(DS_U8 Cmd)
1314{
1315        static char strText[32];
1316        sprintf(strText, "Unknown");
1317        switch (Cmd)
1318        {
1319                case CT_RECEIVE_PAT:sprintf(strText, "CT_RECEIVE_PAT"); break;
1320                case CT_RECEIVE_PMT:sprintf(strText, "CT_RECEIVE_PMT"); break;
1321#if EPG_SUPPORT
1322                case CT_RECEIVE_MGT:sprintf(strText, "CT_RECEIVE_MGT"); break;
1323#endif
1324                case CT_CHMAP_UPDATE:sprintf(strText, "CT_CHMAP_UPDATE"); break;
1325                case CT_SIGNAL_INFO:sprintf(strText, "CT_SIGNAL_INFO"); break;
1326                case CT_AV_START:sprintf(strText, "CT_AV_START"); break;
1327                case CT_SCAN_PSIP_WAIT:sprintf(strText, "CT_SCAN_PSIP_WAIT"); break;
1328                case CT_SCAN_LOCK_WAIT:sprintf(strText, "CT_SCAN_LOCK_WAIT"); break;
1329                case CT_TUNE_START:sprintf(strText, "CT_TUNE_START"); break;
1330                case CT_SCAN_START:sprintf(strText, "CT_SCAN_START"); break;
1331                case CT_STOPPED:sprintf(strText, "CT_STOPPED"); break;
1332                case CT_RECEIVE_PMT_CC:sprintf(strText, "CT_RECEIVE_PMT_CC"); break;
1333                case CT_RECEIVE_PMT_AUDIO:sprintf(strText, "CT_RECEIVE_PMT_AUDIO"); break;
1334        }
1335        return strText;
1336}
1337
1338static jst_callback g_callback = 0;
1339
1340static void CT_CallBack(DS_U8 Cmd /*= 0*/, DS_U32 p1 /*= 0*/, DS_U32 p2 /*= 0*/, DS_U32 p3 /*= 0*/, DS_U32 p4 /*= 0*/, DS_U32 p5 /*= 0*/, DS_U32 p6 /*= 0*/)
1341{
1342        ////if (0) DST_Printf("Cmd = %s(%d) %d %d %d\n", CT_GetMsgName(Cmd), Cmd, p1, p2, p3);
1343        if (g_callback) g_callback(Cmd, p1, p2, p3, p4, p5, p6);
1344}
1345
1346static void DST_FreeAtscTable(void *tablePtrPtr)
1347{
1348        if (tablePtrPtr == NULL || *(void **) tablePtrPtr == NULL) return;
1349        DHL_PSI_FreeMpegSection(*(void **) tablePtrPtr);
1350        *(void **) tablePtrPtr = NULL;
1351}
1352
1353typedef struct  {
1354        DS_U32 RF;
1355        DHL_MODULATION_MODE demod;
1356        DS_U32 nRequestID;
1357        DS_U32 *SI;
1358        DS_U32 CRC32;
1359} CT_SI_Msg;
1360
1361typedef struct 
1362{
1363        DS_U16 pid;
1364        DS_U8  type;
1365        bool bKorean;
1366        bool bVI;
1367} MTS;
1368
1369static int CT_DB_GetAudioPidSub(MTS *mts, int mts_count)
1370{
1371//      for (int i = 0; i < mts_count; i++)
1372//      {
1373//              if (0) DST_Printf("mts[%d].bVI = %d mts[%d].bKorean = %d\n", i, mts[i].bVI, i, mts[i].bKorean);
1374//      }
1375        int i;
1376        // È­¸éÇØ¼³¹æ¼Û + Çѱ¹¾î
1377        if (DST_EEPROM_GetVI() == 1 && DST_EEPROM_GetAudioPref() == 0) // È­¸éÇØ¼³¹æ¼Û
1378        {
1379                // È­¸éÇØ¼³¹æ¼ÛÀ̸鼭 Çѱ¹¾î
1380                for ( i = 0; i < mts_count; i++) if (mts[i].bVI == true && mts[i].bKorean == true) return i;
1381                // ù¹øÂ° Çѱ¹¾î
1382                for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == true) return i;
1383                // ù¹øÀç Æ®·¢
1384                return 0;
1385        }
1386        // È­¸éÇØ¼³¹æ¼Û + ¿Ü±¹¾î
1387        if (DST_EEPROM_GetVI() == 1 && DST_EEPROM_GetAudioPref() == 1) // È­¸éÇØ¼³¹æ¼Û
1388        {
1389                // È­¸éÇØ¼³¹æ¼ÛÀ̸鼭 ¿Ü±¹¾î
1390                for ( i = 0; i < mts_count; i++) if (mts[i].bVI == true && mts[i].bKorean == false) return i;
1391                // ù¹øÂ° ¿Ü±¹¾î
1392                for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == false) return i;
1393                // µÎ¹øÀç Æ®·¢
1394                return 1;
1395        }
1396        // È­¸éÇØ¼³ ¹æ¼Û(x) + Çѱ¹¾î
1397        if (DST_EEPROM_GetAudioPref() == 0) // È­¸éÇØ¼³¹æ¼Û
1398        {
1399                // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ Çѱ¹¾î
1400                for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == true) return i;
1401                // ù¹øÂ° Çѱ¹¾î
1402                for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == true) return i;
1403                // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ ¿Ü±¹¾î
1404                for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == false) return i;
1405                // ù¹øÀç Æ®·¢
1406                return 0;
1407        }
1408        // È­¸éÇØ¼³ ¹æ¼Û(x) + ¿Ü±¹¾î
1409        // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ ¿Ü±¹¾î
1410        for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == false) return i;
1411        // ù¹øÂ° ¿Ü±¹¾î
1412        for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == false) return i;
1413        // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ Çѱ¹¾î
1414        for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == true) return i;
1415        // µÎ¹øÀç Æ®·¢
1416        return 1;
1417}
1418
1419// ÀÔ·ÂµÈ ¹®ÀÚ¿­ÀÌ "kor"ÀÎÁö °Ë»çÇÑ´Ù.
1420// -1 unknown 0: ¿Ü±¹¾î 1: Çѱ¹¾î
1421static int isKOR(char* strText)
1422{
1423        if (strText == 0) return -1;
1424        int nLen = strlen(strText);
1425        if (nLen != 3) return -1;
1426        int i;
1427        for ( i= 0; i < nLen; i++) if (strText[i] >='A' && strText[i] <= 'Z') strText[i] -= ('A'-'a'); // tolower
1428        return (strcmp(strText, "kor") == 0) ? 1 : 0;
1429}
1430
1431
1432int CT_GetAudioCount(DS_U8 RF, DS_U16 program_number)
1433{
1434        int pmt_audio_count = 0;
1435        int i;
1436        DBLock(true);
1437        for ( i = 0; i < MAX_PMT_AUDIO_TABLE_COUNT; i++)
1438        {
1439                if (pmt_audio_table[i].program_number == 0) continue;
1440                if (pmt_audio_table[i].rf == (int)RF && pmt_audio_table[i].program_number == program_number)
1441                        pmt_audio_count++;
1442        }
1443        DBLock(false);
1444        return pmt_audio_count;
1445}
1446
1447static bool g_ReceivePMTAudio = false;
1448void CT_DB_GetAudioPid(DS_U8 RF, DS_U16 program_number, DS_U16* pid, DS_U8* type)
1449{
1450        static DS_U32 old_RF = 0;
1451        static DS_U16 old_program_number = 0;
1452        static DS_U16 old_pid = 0;
1453        static DS_U8 old_type = 0;
1454        if (program_number == 0) return;
1455        DBLock(true);
1456        if (g_ReceivePMTAudio == true || DST_g_AudioSettingChanged == true || old_RF != RF || old_program_number != program_number)
1457        {
1458                DST_g_AudioSettingChanged = false;
1459               
1460                int pmt_audio_count = 0;
1461                typedef struct 
1462                {
1463                        int pid;
1464                        int type;
1465                } PMT_AUDIO;
1466                PMT_AUDIO pmt_audio[32];
1467                memset(pmt_audio, 0, sizeof(pmt_audio));
1468                int i;
1469                for ( i = 0; i < MAX_PMT_AUDIO_TABLE_COUNT; i++)
1470                {
1471                        if (pmt_audio_table[i].program_number == 0) continue;
1472                        if (pmt_audio_table[i].rf == (int)RF && pmt_audio_table[i].program_number == program_number)
1473                        {
1474                                pmt_audio[pmt_audio_count].pid = pmt_audio_table[i].pid;
1475                                pmt_audio[pmt_audio_count].type = pmt_audio_table[i].type;
1476                                pmt_audio_count++;
1477                        }
1478                        if (pmt_audio_count == 32) break;
1479                }
1480                if (pmt_audio_count < 1)
1481                {
1482                        *pid = 0; *type = 0;
1483                }
1484                else
1485                {
1486                        if (pmt_audio_count == 1)
1487                        {
1488                                *pid = pmt_audio[0].pid;
1489                                *type = pmt_audio[0].type;
1490                        }
1491                        else
1492                        {
1493                                int mts_count = pmt_audio_count;
1494                                MTS *mts = (MTS*)DST_OS_Malloc(sizeof(MTS)*mts_count);
1495                                int i;
1496                                for ( i = 0; i < mts_count; i++)
1497                                {
1498                                        mts[i].pid = pmt_audio[i].pid;
1499                                        mts[i].type = pmt_audio[i].type;
1500                                        mts[i].bKorean = true;
1501                                        mts[i].bVI = false;
1502                                        int nKorean[3] = {-1, -1, -1}; // unknown
1503                                        // AC-3 Audio Descriptor °¡ ¿ì¼± ¼øÀ§°¡ ³ô´Ù
1504                                        int j;
1505                                        for ( j = 0; j < MAX_PMT_ISO_TABLE_COUNT; j++)
1506                                        {
1507                                                if (pmt_iso_table[j].rf == (int)RF && pmt_iso_table[j].program_number == program_number && pmt_iso_table[j].pid == mts[i].pid)
1508                                                {
1509                                                DS_U8 audio_type = pmt_iso_table[j].type;
1510                                                mts[i].bVI = (audio_type == 0x03);
1511                                                nKorean[0] = isKOR(pmt_iso_table[j].lang);
1512                                                break;
1513                                        }
1514                                        }
1515                                        for ( j = 0; j < MAX_PMT_AC3_TABLE_COUNT; j++)
1516                                        {
1517                                                if (pmt_ac3_table[j].rf == (int)RF && pmt_ac3_table[j].program_number == program_number && pmt_ac3_table[j].pid == mts[i].pid)
1518                                                {
1519                                                        DS_U8 bsmod = pmt_ac3_table[j].bsmod;
1520                                                        DS_U8 full_svc = pmt_ac3_table[j].full_svc;
1521                                                        DS_U8 langcod = pmt_ac3_table[j].langcod;
1522                                                        mts[i].bVI = (bsmod == 0x02 && full_svc == 0x01);
1523                                                        nKorean[1] = (langcod == 0xFF) ? -1 : (langcod == 0x65) ? 1 : 0;
1524                                                        nKorean[2] = isKOR(pmt_ac3_table[j].language);
1525                                                        break;
1526                                                }
1527                                        }
1528//                                      if (0) DST_Printf("nKorean[0] = %d nKorean[1] = %d nKorean[2] = %d\n", nKorean[0], nKorean[1], nKorean[2]);
1529                                        if (nKorean[0] == 0 || nKorean[1] == 0 || nKorean[2] == 0) mts[i].bKorean = false; // µÑ ÁßÇϳª ¿Ü±¹¾îÀÎ °æ¿ì ¿Ü±¹¾î
1530                                        if (nKorean[0] == 1 || nKorean[1] == 1 || nKorean[2] == 1) mts[i].bKorean = true; // µÑ Áß Çϳª Çѱ¹¾îÀÎ °æ¿ì Çѱ¹¾î
1531                                        //isoÁ¤º¸  ac3Á¤º¸  °áÁ¤µÈ¾ð¾î
1532                                        //¾Ë¼ö¾øÀ½ ¾Ë¼ö¾øÀ½ Çѱ¹¾î
1533                                        //¾Ë¼ö¾øÀ½ ¿Ü±¹¾î   ¿Ü±¹¾î
1534                                        //¾Ë¼ö¾øÀ½ Çѱ¹¾î   Çѱ¹¾î
1535                                        //¿Ü±¹¾î   ¾Ë¼ö¾øÀ½ ¿Ü±¹¾î
1536                                        //¿Ü±¹¾î   ¿Ü±¹¾î   ¿Ü±¹¾î
1537                                        //¿Ü±¹¾î   Çѱ¹¾î   Çѱ¹¾î
1538                                        //Çѱ¹¾î   ¾Ë¼ö¾øÀ½ Çѱ¹¾î
1539                                        //Çѱ¹¾î   ¿Ü±¹¾î   Çѱ¹¾î
1540                                        //Çѱ¹¾î         Çѱ¹¾î   Çѱ¹¾î
1541                                }
1542                                int nPos = CT_DB_GetAudioPidSub(mts, mts_count);
1543                                *pid =  mts[nPos].pid;
1544                                *type = mts[nPos].type;
1545                                DST_OS_Free(&mts);                             
1546                        }
1547                }
1548                g_ReceivePMTAudio = false;
1549                old_RF = RF;
1550                old_program_number = program_number;
1551                old_pid = *pid;
1552                old_type = *type;
1553        }
1554        else
1555        {
1556                *pid = old_pid; *type = old_type;
1557        }
1558        DBLock(false);
1559}
1560
1561//static void CT_DB_GetCCPid(DS_U8 RF, DS_U16 sID,DS_U16 pid[8])
1562//{
1563//      CDB db;
1564//      db.GetTable("select pid from pmt_cc where rf=%d and program_number=%d", RF, sID);
1565//      memset(pid, 0, sizeof(DS_U16)*8);
1566//      for (int i = 0; i < db.GetRow(); i++) pid[i] = dst_atoi(db.GetResult(i+1));
1567//}
1568
1569void CT_DB_GetVideoPid(DS_U8 RF, DS_U16 sID,DS_U16* pcr, DS_U16* pid, DS_U8* type)
1570{
1571        //CDB db; NewCDB(&db);
1572        //db.GetTable(&db, "select pcr_pid, video_pid, video_type from pmt where rf=%d and program_number=%d", RF, sID);
1573        int i;
1574        DBLock(true);
1575        for (i=0; i < DB_PMT_MAX; i++)
1576        {
1577                if (db_pmt[i].program_number == 0) continue;
1578                if (db_pmt[i].rf != RF) continue;
1579                if (db_pmt[i].program_number != sID) continue; 
1580                if (pcr) *pcr = db_pmt[i].pcr_pid;
1581                if (pid) *pid = db_pmt[i].video_pid;
1582                if (type) *type = db_pmt[i].video_type;
1583                DBLock(false);
1584                return;
1585        }
1586        DBLock(false);
1587}
1588
1589#if 0 // Newcon3Kr¿¡¼­ »ç¿ë ¾ÈÇÔ
1590#define MAX_CRC_COUNT 400
1591class CheckCRC32
1592{
1593private:
1594        int nPos;
1595        DS_U32 CRC32[MAX_CRC_COUNT];
1596public:
1597        CheckCRC32()
1598        {
1599                memset(CRC32, 0, sizeof(CRC32));
1600                nPos = 0;
1601        }
1602        void Add(DS_U32 crc32)
1603        {
1604                for (int i = 0; i < MAX_CRC_COUNT; i++) if (CRC32[i] == crc32) return;
1605                CRC32[nPos] =  crc32;
1606                nPos++;
1607                if (nPos >= MAX_CRC_COUNT) nPos = 0;
1608        }
1609        bool IsDuplicate(DS_U32 crc32)
1610        {
1611                for (int i = 0; i < MAX_CRC_COUNT; i++) if (CRC32[i] == crc32) return true;
1612                return false;
1613        }
1614        // CRC LIST¿¡ ¾ø´Â CRC´Â Áö¿î´Ù.
1615        void Clear(DS_U32 *crclist, int nCount)
1616        {
1617                for (int i = 0; i < MAX_CRC_COUNT; i++)
1618                {
1619                        if (CRC32[i] == 0) continue;
1620                        bool bFind = false;
1621                        for (int j=0; j <nCount;j++)
1622                        {
1623                                if (CRC32[i] != crclist[j]) continue;
1624                                bFind = true;
1625                                break;
1626                        }
1627                        if (bFind == false) CRC32[i] = 0;
1628                }
1629        }
1630};
1631
1632static CheckCRC32 check_crc;
1633#endif
1634
1635static DS_U32 CalcCRC(DS_U8* buff)
1636{
1637        DS_U32 len = (((DS_U32)buff[1]&0x0F) << 8) + (DS_U32)buff[2]-1;
1638        return ((DS_U32)buff[len] << 24) + ((DS_U32)buff[len+1] << 16) + ((DS_U32)buff[len+2] << 8) + (DS_U32)buff[len+3];
1639}
1640
1641static void CT_TunePSIP(DS_U8 RF /*= 0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_8VSB*/, 
1642                        DS_U16 program_number /*= 0*/, DS_U16 source_id /*= 0*/, bool bOn /*= false*/)
1643{
1644        static bool bStart = false;
1645
1646        static DHL_HANDLE hTVCT = 0;
1647#if CVCT_SUPPORT
1648        static DHL_HANDLE hCVCT = 0;
1649#endif
1650        static DHL_HANDLE hSTT = 0;
1651#if EPG_SUPPORT
1652        static DHL_HANDLE hMGT = 0;
1653        static DHL_HANDLE hEIT[MAX_EIT_COUNT];
1654        static DHL_HANDLE hETT[MAX_EIT_COUNT];
1655#endif
1656        static DHL_HANDLE hPAT = 0;
1657        static DHL_HANDLE hPMT[MAX_PMT_COUNT];
1658#if EPG_SUPPORT
1659        static DS_U16 eit_pid[MAX_EIT_COUNT];
1660        static DS_U16 ett_pid[MAX_EIT_COUNT];
1661#endif
1662#if EPG_SUPPORT
1663        bool g_bReceiveMGT = false;
1664#endif
1665        static bool bReceivePMT =  false; // PMT¸¦ »¡¸® ¹Þ±â À§ÇØ PMT ¹Þ±â Àü¿¡ ´Ù¸¥ ¸ð´ÏÅ͸µÀº ¸ØÃá´Ù.
1666        if (bOn)
1667        {
1668                if (bStart)
1669                {
1670                        CT_SI_Msg msg;
1671                        DS_U32 retLen = 0;
1672                        while (DST_OS_ReceiveMessage_NoWait(gSIMsgQ, (DS_U32*)&msg, sizeof(CT_SI_Msg), &retLen) == noError)
1673                        {
1674                                if (RF == msg.RF) 
1675                                {
1676                                        if (msg.nRequestID == POS_TVCT)
1677                                        {
1678                                                bool bFind = true;
1679                                                if (CT_ChMapUpdateTVCT(RF, (TVCT*)msg.SI, msg.CRC32)) 
1680                                                {
1681                                                        bFind = false;
1682                                                        CT_ChMapUpdate();
1683                                                        // program_number°¡ ä³Î¸Ê¿¡ ÀÖ´ÂÁö È®ÀÎ
1684                                                        DBLock(true);
1685                                                        int i;
1686                                                        for (i = 0; i < DB_CHANNEL_DB_MAX; i++)
1687                                                        {
1688                                                                if (db_channel_db[i].rf != RF) continue;
1689                                                                if (db_channel_db[i].program_number !=  program_number) continue;
1690                                                                bFind = true;
1691                                                                break;
1692                                                        }
1693                                                        DBLock(false);
1694                                                }
1695                                                CT_CallBack(CT_RECEIVE_TVCT, RF, bFind ? 0 : 1, 0, 0, 0, 0);
1696                                        }
1697#if CVCT_SUPPORT
1698                                        if (msg.nRequestID == POS_CVCT)
1699                                        {
1700                                                if (CT_ChMapUpdateCVCT(RF, (CVCT*)msg.SI, msg.CRC32)) CT_ChMapUpdate();
1701                                                CT_CallBack(CT_RECEIVE_CVCT, RF, 0,0,0,0,0);
1702                                        }
1703#endif
1704#if EPG_SUPPORT
1705                                        if (msg.nRequestID == POS_MGT)
1706                                        {
1707                                                g_bReceiveMGT = true;
1708                                                MGT *mgt = (MGT*)msg.SI;
1709                                                if (0) DST_Printf("mgt->tables_defined = %d\n", mgt->tables_defined);
1710                                                int i;
1711                                                for( i = 0 ; i< mgt->tables_defined ; i++)
1712                                                {
1713                                                        if (0) DST_Printf("mgt->table[%d].table_type = 0x%X table_type_PID = 0x%X\n", i, mgt->table[i].table_type, mgt->table[i].table_type_PID);
1714                                                        if (mgt->table[i].table_type >= 0x100 && mgt->table[i].table_type <0x100 + MAX_EIT_COUNT)
1715                                                        {
1716                                                                T();
1717                                                                int pos = mgt->table[i].table_type - 0x100;
1718                                                                if (eit_pid[pos] == mgt->table[i].table_type_PID) continue;
1719                                                                eit_pid[pos] = mgt->table[i].table_type_PID;
1720                                                                //DHL_SI_MonitorStop(&hEIT[pos]);
1721                                                                //hEIT[pos] = DHL_SI_MonitorEIT(RF, POS_EIT+pos, eit_pid[pos]);
1722                                                        }
1723                                                        if (mgt->table[i].table_type >= 0x200 && mgt->table[i].table_type <0x200 + MAX_EIT_COUNT)
1724                                                        {
1725                                                                T();
1726                                                                int pos = mgt->table[i].table_type - 0x200;
1727                                                                if (ett_pid[pos] == mgt->table[i].table_type_PID) continue;
1728                                                                ett_pid[pos] = mgt->table[i].table_type_PID;
1729                                                                //DHL_SI_MonitorStop(&hETT[pos]);
1730                                                                //hETT[pos] = DHL_SI_MonitorETT(RF, POS_ETT+pos, ett_pid[pos]);
1731                                                        }
1732                                                }
1733                                                CT_CallBack(CT_RECEIVE_MGT, RF, 0,0,0,0,0);
1734                                        }
1735                                        if (msg.nRequestID >= POS_EIT && msg.nRequestID < POS_EIT+MAX_EIT_COUNT)
1736                                        {
1737                                                EIT *eit = (EIT*)msg.SI;
1738                                                if (eit->source_id == source_id)
1739                                                {
1740                                                        CT_ChMapUpdateEIT(RF, eit, msg.nRequestID - POS_EIT, msg.CRC32);
1741                                                        CT_CallBack(CT_RECEIVE_EIT, RF, 0,0,0,0,0);
1742                                                }
1743                                        }
1744                                        if (msg.nRequestID >= POS_ETT && msg.nRequestID < POS_ETT+MAX_EIT_COUNT)
1745                                        {
1746                                                ETT *ett = (ETT*)msg.SI;
1747                                                if ((ett->ETM_id >> 16) == source_id)
1748                                                {
1749                                                        CT_ChMapUpdateETT(RF, ett, msg.CRC32);
1750                                                        CT_CallBack(CT_RECEIVE_ETT, RF, 0,0,0,0,0);
1751                                                }
1752                                        }
1753#endif
1754                                        if (msg.nRequestID == POS_PAT)
1755                                        {
1756                                                MPEG_PAT *pat = (MPEG_PAT*)msg.SI;
1757                                                CT_ChMapUpdatePAT(RF, pat, msg.CRC32);
1758                                                int nPos = 0;
1759                                                int i;
1760                                                for ( i = 0; i < MAX_PMT_COUNT; i++)
1761                                                {
1762                                                        if (hPMT[i]) DHL_SI_MonitorStop(&hPMT[i]);
1763                                                }
1764                                                for ( i = 0; i < pat->numPrograms; i++)
1765                                                {
1766                                                        if (pat->programs[i].program_map_PID == 0) continue;
1767                                                        if (pat->programs[i].program_map_PID == 0x1FFF) continue;
1768                                                        hPMT[nPos] = DHL_SI_MonitorPMT(RF, POS_PMT+nPos, pat->programs[i].program_map_PID, pat->programs[i].program_number);
1769                                                        nPos++;
1770                                                        if (nPos >= MAX_PMT_COUNT) break;
1771                                                }
1772                                                CT_CallBack(CT_RECEIVE_PAT, RF, 0,0,0,0,0);
1773                                        }
1774                                        if (msg.nRequestID >= POS_PMT && msg.nRequestID < POS_PMT+MAX_PMT_COUNT)
1775                                        {
1776                                                bReceivePMT = true;
1777                                                MPEG_PMT *pmt = (MPEG_PMT*)msg.SI;
1778                                                if (CT_ChMapUpdatePMT(RF, pmt, msg.nRequestID - POS_PMT+1, msg.CRC32))
1779                                                {
1780                                                        CT_ChMapUpdate();
1781                                                }
1782                                                CT_CallBack(CT_RECEIVE_PMT, RF, pmt->program_number, 0,0,0,0);
1783                                                g_ReceivePMTAudio = true;
1784                                                CT_CallBack(CT_RECEIVE_PMT, RF, 0,0,0,0,0);
1785                                        }
1786                                }
1787                                DST_FreeAtscTable(&msg.SI); // ¸Þ¸ð¸® ÇØÁ¦´Â ¿©±â¿¡¼­
1788                        } // while
1789                        { // CC µð½ºÅ©¸³ÅÍ ¸ð´ÏÅ͸µ
1790                                static DS_U32 old_RF = 0;
1791                                static DS_U16 old_program_number = 0;
1792                                if (old_RF != RF || old_program_number != program_number || g_bReceiveCCDescriptor == true)
1793                                {
1794                                        old_RF = RF;
1795                                        old_program_number = program_number;
1796                                        g_bReceiveCCDescriptor = false;
1797                                        bool bFind = false;
1798                                        int i;
1799                                        for ( i=0; i < MAX_PMT_CC_TABLE_COUNT; i++)
1800                                        {
1801                                                if (pmt_cc_table[i].rf == (int)RF && pmt_cc_table[i].program_number == program_number && pmt_cc_table[i].cc_type > 0 && pmt_cc_table[i].cc_id == 1) 
1802                                                {
1803                                                        DST_g_CC_bCCKorean = (strcmp(pmt_cc_table[i].language, "kor") != 0 && strcmp(pmt_cc_table[i].language, "KOR") != 0) ? false : true;
1804                                                        DST_g_CC_bWideScreen = pmt_cc_table[i].wide_aspect_ratio ? true : false;
1805                                                        DST_g_CC_bUnicode = pmt_cc_table[i].korean_code ? true : false;
1806                                                        bFind = true;
1807                                                        break;
1808                                                }
1809                                        }
1810                                        if (bFind == false)
1811                                        {
1812                                                DST_g_CC_bCCKorean = true;
1813                                                DST_g_CC_bWideScreen = true;
1814                                                DST_g_CC_bUnicode = false;
1815                                        }
1816                                }
1817                        }
1818#if EPG_SUPPORT
1819                        { // EIT ETT ¸ð´ÏÅ͸µ
1820                                static DS_U8 old_RF = 0;
1821                                static DS_U16 old_source_id = 0;
1822                                if (old_RF != RF || old_source_id != source_id || g_bReceiveMGT == true)
1823                                {
1824                                        old_RF = RF;
1825                                        old_source_id = source_id;
1826                                        int i;
1827                                        for ( i = 0; i < MAX_EIT_COUNT; i++)
1828                                        {
1829                                                if (hEIT[i]) DHL_SI_MonitorStop(&hEIT[i]);
1830                                                if (hETT[i]) DHL_SI_MonitorStop(&hETT[i]);
1831                                        }
1832                                        for ( i = 0; i < MAX_EIT_COUNT; i++)
1833                                        {
1834                                                if (eit_pid[i]) hEIT[i] = DHL_SI_MonitorEIT(RF, POS_EIT+i, eit_pid[i], source_id);
1835                                                if (ett_pid[i]) hETT[i] = DHL_SI_MonitorETT(RF, POS_ETT+i, ett_pid[i], source_id);
1836                                        }
1837                                }
1838                        }
1839#endif
1840                        if (bReceivePMT) // PMT  ¹ÞÀº ÈÄ ´Ù¸¥ ¸ð´ÏÅ͸µ ½ÃÀÛÇÏÀÚ
1841                        {
1842#if EPG_SUPPORT
1843                                if (hMGT== 0) hMGT = DHL_SI_MonitorMGT(RF, POS_MGT);
1844#endif
1845#if CVCT_SUPPORT
1846                                if (hCVCT== 0) hCVCT = DHL_SI_MonitorCVCT(RF, POS_CVCT);
1847#endif
1848                                if (hSTT == 0) hSTT = DHL_SI_MonitorSTT(RF, POS_STT);
1849                                if (hTVCT == 0) hTVCT = DHL_SI_MonitorTVCT(RF, POS_TVCT);
1850                        }
1851                }
1852                else // bStart == false
1853                {
1854                        CT_TunePSIP(0, DHL_MODULATION_8VSB, 0, 0, false);
1855                        bStart = true;
1856                        hPAT = DHL_SI_MonitorPAT(RF, POS_PAT); // PMT¸¦ »¡¸® ¹Þ±â À§ÇØ ´Ù¸¥ SI´Â ´Ê°Ô ¹Þ´Â´Ù.
1857                }
1858        }
1859        else
1860        {
1861                if (bStart)
1862                {
1863                        DHL_SI_MonitorStop(&hTVCT);
1864//                      DHL_SI_MonitorStop(&hCVCT);
1865                        DHL_SI_MonitorStop(&hSTT);
1866#if EPG_SUPPORT
1867                        DHL_SI_MonitorStop(&hMGT);
1868#endif
1869                        int i;
1870#if EPG_SUPPORT
1871                        for ( i = 0; i < MAX_EIT_COUNT; i++) 
1872                        {
1873                                DHL_SI_MonitorStop(&hEIT[i]);
1874                                eit_pid[i] = 0;
1875                                DHL_SI_MonitorStop(&hETT[i]);
1876                                ett_pid[i] = 0;
1877                        }
1878#endif
1879                        DHL_SI_MonitorStop(&hPAT);
1880                        for ( i = 0; i < MAX_PMT_COUNT; i++) 
1881                        {
1882                                DHL_SI_MonitorStop(&hPMT[i]);
1883                        }
1884                        CT_SI_Msg msg;
1885                        DS_U32 retLen = 0;
1886                        while (DST_OS_ReceiveMessage_NoWait(gSIMsgQ, (DS_U32*)&msg, sizeof(CT_SI_Msg), &retLen) == noError)
1887                        {
1888                                if (0) DST_Printf("Remove msg.nRequestID == %d\n", (int)msg.nRequestID);
1889                                DST_FreeAtscTable(&msg.SI);
1890                        }
1891                        bStart = false;
1892                        bReceivePMT = false;
1893                }
1894        }
1895}
1896
1897static void CT_VideoAudio(DS_U16 pcr /*= 0*/, DS_U16 vpid /*= 0*/, DS_U8 vtype /*= 0*/, DS_U16 apid /*= 0*/, DS_U8 atype /*= 0*/)
1898{
1899        static DS_U16 _pcr  = 0;
1900        static DS_U16 _vpid  = 0;
1901        static DS_U8  _vtype = 0;
1902        static DS_U16 _apid = 0;
1903        static DS_U8  _atype = 0;
1904        if (pcr == _pcr && vpid == _vpid && vtype == _vtype && apid == _apid && atype == _atype) return;
1905        if (vpid != _vpid)
1906        {
1907                if (vpid)
1908                {
1909                        DHL_VIDEO_TYPE VidStreamType = DHL_VIDEO_NONE;
1910                        switch (vtype) // ABNT NBR 15602-3:2007 Table 5 ? Strem_type
1911                        {
1912                                case 0x01: VidStreamType = DHL_VIDEO_MPEG1; break;
1913                                case 0x02: VidStreamType = DHL_VIDEO_MPEG2; break;
1914                                case 0x1B: VidStreamType = DHL_VIDEO_MPEG4; break;
1915                        };
1916                        if (DHL_VID_Start(vpid, pcr, VidStreamType) != 0) return;
1917                        DST_g_LastVideoStartTime = DST_OS_GetTickCount();
1918                        _apid = 0; // ºñµð¿À º¯°æ ½Ã ¿Àµð¿Àµµ ´Ù½Ã ½ÃÀÛÇϱâ À§Çؼ­ ÀÌÀü ¿Àµð¿À »óŸ¦ Áö¿î´Ù.
1919                }
1920                else
1921                {
1922//                      CT_ChannelChangeVideoMute(true);
1923                        DHL_VID_Stop();
1924                        DST_g_LastVideoStartTime = 0;
1925                }
1926        }
1927        if (apid != _apid)
1928        {
1929                if (apid)
1930                {
1931                        DHL_AUDIO_TYPE AudStreamType = DHL_AUDIO_NONE;
1932                       
1933                        switch (atype) // ABNT NBR 15602-3:2007 Table 5 ? Strem_type
1934                        {
1935                                case 0x03: AudStreamType = DHL_AUDIO_MPEG1; break;
1936                                case 0x04: AudStreamType = DHL_AUDIO_MPEG2; break;
1937                                case 0x0F: AudStreamType = DHL_AUDIO_AAC_ADTS; break;
1938                                case 0x11: AudStreamType = DHL_AUDIO_AAC_LATM; break;
1939                                case 0x81: AudStreamType = DHL_AUDIO_AC3; break;
1940                        };
1941                        DHL_AUD_Start(apid, pcr == 0 ? 0x1FFF : pcr, AudStreamType);
1942                        CT_ChannelChangeAudioMute(false);
1943                        DST_g_LastAudioStartTime = DST_OS_GetTickCount();
1944                }
1945                else
1946                {
1947                        CT_ChannelChangeAudioMute(true);
1948                        DHL_AUD_Stop();
1949                        DST_g_LastAudioStartTime = 0;
1950                }       
1951        }
1952        _pcr  = pcr;
1953        _vpid  = vpid;
1954        _vtype = vtype;
1955        _apid = apid;
1956        _atype = atype;
1957}
1958
1959static void CT_AV(DS_U8 RF /*= 0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_8VSB*/, 
1960                        DS_U16 program_number /*= 0*/, DS_U16 source_id /*= 0*/, bool bOn /*= false*/)
1961{
1962        if (bOn)
1963        {
1964                // ½ÅÈ£ Á¤º¸
1965                bool bLock = false;
1966                int ss = 0, power = 0, snr = 0;
1967                DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr);
1968                CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0);
1969       
1970                // ¼Ò½º¾ÆÀ̵𿡠µû¶ó AV¸¦ ½ÃÀÛÇÑ´Ù.
1971                DS_U16 PcrPid = 0;
1972                DS_U16 VideoPid = 0;
1973                DS_U8  VideoType = 0;
1974                DS_U16 AudioPid = 0;
1975                DS_U8  AudioType = 0;
1976                CT_DB_GetVideoPid(RF, program_number, &PcrPid, &VideoPid, &VideoType);
1977               
1978                // if (0) DST_Printf("VideoPid = %d\n", VideoPid);
1979               
1980                CT_DB_GetAudioPid(RF, program_number, &AudioPid, &AudioType);
1981               
1982                 //if (0) DST_Printf("AudioPid = %d\n", AudioPid);
1983               
1984                CT_VideoAudio(PcrPid, VideoPid, VideoType, AudioPid, AudioType);
1985                CT_CallBack(CT_AV_START, RF, program_number,  source_id, 0,0,0);
1986                CT_CallBack(CT_AV_INFO, RF, PcrPid, VideoPid, AudioPid, VideoType, AudioType);         
1987                // CC ¸ð´ÏÅ͸µÀ» ½ÃÀÛÇÑ´Ù.
1988               
1989                // AV »óÅ Á¤º¸ Äݹé
1990                CT_CallBack(CT_SIGNAL, RF, program_number, VideoPid ? DHL_VID_Alive() : 0, AudioPid ? DHL_AUD_Alive() : 0, 0,0);
1991                CT_CallBack(CT_AUDIO_MODE, DHL_AUD_GetMode(),0,0,0,0, 0);
1992                CT_TunePSIP(RF, demod, program_number, source_id, bOn);
1993        }
1994        else
1995        {
1996                CT_TunePSIP(0, DHL_MODULATION_8VSB, 0, 0, false); // PSIP ¸ð´ÏÅ͸µ ÁßÁö
1997                CT_VideoAudio(0,0,0,0,0);
1998        }
1999}
2000
2001static void CT_Tune(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_8VSB*/, 
2002                        DS_U16 program_number/*=0*/, DS_U16 source_id /*= 0*/, bool bOn/*= false*/)
2003{
2004        static bool bStart = false;
2005        static DS_U8 CurrentRF = 0;
2006        static DHL_MODULATION_MODE CurrentDemod = DHL_MODULATION_NULL;
2007        if (bOn)
2008        {
2009                if (bStart == false || CurrentRF != RF || CurrentDemod != demod)
2010                {
2011                        CT_AV(0, DHL_MODULATION_8VSB, 0, 0, false);
2012                        DHL_TUN_Start(RF, demod);
2013                        DST_g_LastTuneTime = DST_OS_GetTickCount();
2014                        CurrentRF = RF;
2015                        CurrentDemod = demod;
2016                        bStart = true;
2017                }
2018                CT_AV(RF, demod, program_number, source_id, bOn);
2019        }
2020        else
2021        {
2022                CT_AV(0, DHL_MODULATION_8VSB, 0,0,false);
2023                if (bStart)
2024                {
2025                        DST_g_LastTuneTime = 0;
2026                        DHL_TUN_Stop();
2027                        bStart = false;
2028                }
2029        }
2030}
2031
2032typedef struct 
2033{
2034        DS_U8  vendor_id[3];
2035        DS_U8  hardware_version_id[4];
2036        DS_U8  software_version_id[4];
2037        DS_U8  so_id[2];
2038        DS_U8  download_type; /* 4bits */
2039        DS_U8  download_command; /* 4bits */
2040        DS_U16 frequency_vector; /* 16bits */
2041        DS_U8  modulation_type;
2042        DS_U16 PID;
2043} AirCodeCVT;
2044
2045static bool DST_SCTESI_ParseAirCodeCVT(DS_U8 *p, AirCodeCVT *cvt)
2046{
2047        if (p == 0 || cvt == 0) return false;
2048        if (p[0] != 0x90) return false; // invalid table
2049        memset(cvt, 0, sizeof(AirCodeCVT));
2050        DS_U8 number_of_descriptor = p[8];
2051        int nPos = 9;
2052        if (0) DST_Printf("number_of_descriptor = %d", number_of_descriptor);
2053        int i;
2054        for ( i = 0; i < number_of_descriptor; i++)
2055        {
2056                DS_U8 tag = p[nPos];
2057                DS_U8 length = p[nPos+1];
2058                if (0) DST_Printf("tag = %d\n", tag);
2059                if (0) DST_Printf("length = %d\n", length);
2060                switch (tag)
2061                {
2062                        case 0: // vendor_id
2063//                              T();
2064                                if (length == 3) memcpy(cvt->vendor_id, &p[nPos+2], length);
2065                                break;
2066                        case 1: // hardware_version_id
2067//                              T();
2068                                if (length == 4) memcpy(cvt->hardware_version_id, &p[nPos+2], length);
2069                                break;
2070                        case 2: // softeware_version_id
2071//                              T();
2072                                if (length == 4) memcpy(cvt->software_version_id, &p[nPos+2], length);
2073                                break;
2074                        case 0x80:
2075//                              T();
2076                                if (length == 2) memcpy(cvt->so_id, &p[nPos+2], length);
2077                                break;
2078                }
2079                nPos = nPos + length + 2;               
2080        }
2081        cvt->download_type = (p[nPos]&0xF0) >> 4;
2082        cvt->download_command = (p[nPos]&0x0F);
2083        cvt->frequency_vector = p[nPos+1]*256 + p[nPos+2];
2084        cvt->modulation_type = p[nPos+3];
2085        cvt->PID = (p[nPos+4]&0x1F)*256 + p[nPos+5];
2086        return true;
2087}
2088
2089static void CT_SI_Proc(DS_U32 RF, DS_U32 nRequestID, DS_U8** buff, DS_U32 nBuffLength)
2090{
2091        if (0) DST_Printf("%s | RF = %d | nRequestID = %d %s\n", __func__, (int)RF, (int)nRequestID, GetSiName(nRequestID));
2092        CT_SI_Msg msg;
2093        msg.RF = RF;
2094        msg.nRequestID = nRequestID;
2095        msg.SI = 0;
2096        msg.CRC32 =  CalcCRC(buff[0]);
2097
2098#if 1
2099        if (msg.CRC32 != DST_CRC32(buff[0], (*(buff[0]+1)&0x0F) * 256 + *(buff[0]+2) - 1)) 
2100        {
2101                DST_Printf("%s|Invalid CRC nRequestID =%d %s\n", __func__, nRequestID, GetSiName(nRequestID));
2102                return;
2103        }
2104#endif
2105
2106        if (nRequestID == POS_TVCT)
2107        {
2108                if (DHL_PSI_ParseTVCT(buff, (TVCT **)&msg.SI)) if (0) DST_Printf("%s|%d|TVCT Parse Error\n", __func__, __LINE__);
2109        }
2110#if CVCT_SUPPORT
2111        if (nRequestID == POS_CVCT)
2112        {
2113                if (DHL_PSI_ParseCVCT(buff, (CVCT **)&msg.SI)) if (0) DST_Printf("%s|%d|CVCT Parse Error\n", __func__, __LINE__);
2114        }
2115#endif
2116        if (nRequestID == POS_STT)
2117        {
2118                DS_U8* p = buff[0];
2119                CT_CallBack(CT_RECEIVE_STT,  RF, p[9] * 0x1000000 + p[10] * 0x10000 + p[11] * 0x100 + p[12] ,  p[13], DST_OS_GetTickCount(), 0,0);
2120        }
2121#if EPG_SUPPORT
2122        if (nRequestID == POS_MGT)
2123        {
2124                if (DHL_PSI_ParseMGTSection(buff[0], (MGT **)&msg.SI)) if (0) DST_Printf("%s|%d|MGT Parse Error\n", __func__, __LINE__);
2125        }
2126        if (nRequestID >= POS_EIT && nRequestID < POS_EIT+MAX_EIT_COUNT)
2127        {
2128                if (DHL_PSI_ParseEIT(buff, (EIT **)&msg.SI)) if (0) DST_Printf("%s|%d|EIT Parse Error\n", __func__, __LINE__);
2129        }
2130        if (nRequestID >= POS_ETT && nRequestID < POS_ETT+MAX_EIT_COUNT)
2131        {
2132                if (DHL_PSI_ParseETTSection(buff[0], (ETT **)&msg.SI)) if (0) DST_Printf("%s|%d|ETT Parse Error\n", __func__, __LINE__);
2133        }
2134#endif
2135        if (nRequestID == POS_PAT)
2136        {
2137                if (DHL_PSI_ParsePAT(buff, (MPEG_PAT **)&msg.SI)) if (0) DST_Printf("%s|%d|PAT Parse Error\n", __func__, __LINE__);
2138        }
2139        if (nRequestID >= POS_PMT && msg.nRequestID < POS_PMT+MAX_PMT_COUNT)
2140        {
2141                if (DHL_PSI_ParsePMT(buff[0], (MPEG_PMT **)&msg.SI)) if (0) DST_Printf("%s|%d|PMT Parse Error\n", __func__, __LINE__); 
2142        }
2143        if (nRequestID == POS_RFUPDATE)
2144        {
2145                CT_CallBack(CT_RECEIVE_RF_UPDATE, RF, (DS_U32)buff[0],0,0,0,0);
2146        }
2147        if (nRequestID == POS_CVT) // CVT
2148        {
2149//              DST_g_ReceiveCVT++;
2150               
2151                // CMB´Â DDBµ¥ÀÌÅÍ¿¡ ¹Ýº¹µÇ´Â CVT ½Ç·Á¿Â´Ù.
2152                // CVT ÆÄÀÏÀ» °ËÃâÇÏ¿© 0x90À¸·Î ½ÃÀÛÇÏ´Â Å×À̺í·Î º¯È¯ÇÑ´Ù.
2153                // CVT°¡ ¿¬¼ÓÇØ¼­ ¿À±â ¶§¹®¿¡ ¼ö½ÅÇÑ CVT´Â ÀúÀåÇÏ¿© µÎ¾î Áߺ¹ 󸮸¦ ¹æÁöÇÑ´Ù.
2154                static DS_U8 received_cvt[300]; 
2155                DS_U8 cvt_new[300];
2156                DS_U8* p = buff[0];
2157                DS_U16 section_length = (p[1] & 0x0F) * 256 + p[2];
2158                bool bFind = false;
2159                int i;
2160                for ( i = 26; i < section_length - 32; i++)  // CVT Å×ÀÌºí ¾ÕÀÇ 26¹ÙÀÌÆ®´Â ´õ¹Ì CVT Å×À̺íÀÇ ÃÖ¼Ò Å©±â´Â 32¹ÙÀÌÆ®
2161                {
2162                        if (p[i] == 0xD9 && p[i+1] == 0x30 && p[i+3] == 0x9F && p[i+4] == 0x9C && p[i+5] == 0x02)
2163                        {
2164                                if (i+p[i+6] > section_length) return; // ÀÔ·ÂµÈ µ¥ÀÌÅͱæÀ̺¸´Ù Å« °æ¿ì ¿¡·¯Ã³¸®
2165                                memset(cvt_new, 0, 300);
2166                                cvt_new[0] = 0x90;
2167                                memcpy(&cvt_new[1], &p[i], p[i+6] + 3);
2168                                if (!memcmp(cvt_new, received_cvt, 300)) return; // ÀÌ¹Ì ¹ÞÀ½
2169                                bFind = true;
2170                                break;
2171                        }
2172                }
2173
2174                if (bFind == false) 
2175                {
2176                        return;
2177                }
2178                static bool bReceiveValidCVT = false;
2179                if (bReceiveValidCVT == true) return;
2180                AirCodeCVT cvt;
2181                memset(&cvt, 0, sizeof(AirCodeCVT));
2182                if (DST_SCTESI_ParseAirCodeCVT(cvt_new, &cvt) == false) return;
2183#if 1
2184                if (1) DST_Printf("============================================\n");
2185                if (1) DST_Printf("Request ID = POS_CVT\n");
2186                if (1) DST_Printf("vendor_id %02X %02X %02X\n", cvt.vendor_id[0], cvt.vendor_id[1], cvt.vendor_id[2]);
2187                if (1) DST_Printf("hardware_version_id %02X %02X %02X %02X\n", cvt.hardware_version_id[0], cvt.hardware_version_id[1], cvt.hardware_version_id[2], cvt.hardware_version_id[3]);
2188                if (1) DST_Printf("software_version_id %02X %02X %02X %02X\n", cvt.software_version_id[0], cvt.software_version_id[1], cvt.software_version_id[2], cvt.software_version_id[3]);
2189                if (1) DST_Printf("so_id %02X %02X\n", cvt.so_id[0], cvt.so_id[1]);
2190                if (1) DST_Printf("download_type %d\n", cvt.download_type);
2191                if (1) DST_Printf("download_command %d\n", cvt.download_command);
2192                if (1) DST_Printf("frequency_vector %d\n", cvt.frequency_vector);
2193                if (1) DST_Printf("modulation_type %d\n", cvt.modulation_type);
2194                if (1) DST_Printf("PID 0x%X\n", cvt.PID);
2195                if (1) DST_Printf("============================================\n");
2196#endif
2197               
2198                // °¢ ÇÊµå °ªÀÇ À¯È¿¼º °Ë»ç             
2199                if (cvt.vendor_id[0] != 'D') return;
2200                if (cvt.vendor_id[1] != 'S') return;
2201                if (cvt.vendor_id[2] != 'T') return;
2202                if (cvt.hardware_version_id[0] != 'N') return;
2203                if (cvt.hardware_version_id[1] != '3') return;
2204                if (cvt.hardware_version_id[2] != 'K') return;
2205                if (cvt.hardware_version_id[3] != 'R') return;
2206//              if (cvt.so_id[0] != DST_g_SO_ID/256) return;
2207//              if (cvt.so_id[1] != DST_g_SO_ID%256) return;
2208               
2209                // º¥´õ¾ÆÀ̵ð¿Í H/W ¹öÀüÀÌ ÀÏÄ¡ÇÏÁö ¾Ê´Â Á¤º¸°¡ °°Àº PID·Î ¿Ã °¡´É¼º ´ëºñÇÏ¿© ¹é¾÷ À§Ä¡´Â H/W ¹öÀü üũ ÀÌÈÄ·Î
2210                memcpy(received_cvt, cvt_new, 300); // »õ·Î ¹ÞÀº µ¥ÀÌÅ͸¦ ¹é¾÷
2211               
2212                int major = 0, minor = DST_GetAppShortVersionNumber(); 
2213                if (1) DST_Printf("major = %d minor = %d\n", major, minor);
2214                int new_major = cvt.software_version_id[0]*256+cvt.software_version_id[1];
2215                int new_minor = cvt.software_version_id[2]*256+cvt.software_version_id[3];
2216                if (1) DST_Printf("new_major = %d new_minor = %d\n", new_major, new_minor);
2217                if ((major * 0x10000 + minor) >= (new_major * 0x10000 + new_minor))
2218                {
2219                        if (1) DST_Printf("Old or Same version. ignore it.\n");
2220                        return;
2221                }
2222                if (cvt.download_command > 2) 
2223                {
2224                        if (1) DST_Printf("download_command invalid(%d)\n", cvt.download_command);
2225                        return;
2226                }
2227                if (cvt.frequency_vector == 0)
2228                {
2229                        if (1) DST_Printf("frequency_vector invalid(%d)\n", cvt.frequency_vector);
2230                        return;
2231                }
2232                if (cvt.modulation_type < 1 || cvt.modulation_type > 2)
2233                {
2234                        if (1) DST_Printf("modulation_type invalid(%d)\n", cvt.modulation_type);
2235                         return;
2236                }
2237                if (cvt.PID == 0) 
2238                {
2239                        if (1) DST_Printf("PID invalid(%d)\n", cvt.PID);
2240                        return;
2241                }
2242                bReceiveValidCVT = true;
2243#if 1
2244                switch (cvt.download_command)
2245                {
2246                        case 0: if (1) DST_Printf("Download Now\n"); break;
2247                        case 1: if (1) DST_Printf("Deferred Download\n"); break;
2248                        case 2: if (1) DST_Printf("No Exception\n"); break;
2249                }
2250                if (1) DST_Printf("OTC RF = %dHz\n", cvt.frequency_vector * 250000);
2251                switch (cvt.modulation_type)
2252                {
2253                        case 1: if (1) DST_Printf("64QAM\n"); break;
2254                        case 2: if (1) DST_Printf("256QAM\n"); break;
2255                }
2256#endif
2257                SWinEventMsg event;
2258                memset(&event, 0, sizeof(SWinEventMsg));
2259                event.cmd = WM_CVT;
2260                memcpy(&event.data[0], &cvt.software_version_id[0], 16);
2261                event.data32[4] = cvt.download_command;
2262                event.data32[5] = cvt.modulation_type;
2263                event.data32[6] = cvt.frequency_vector * 250000;
2264                event.data32[7] = cvt.PID;
2265                DST_SendWindowEvent(event);
2266#ifdef DSTAR
2267                DST_g_OTC_Modulation_type = (event.data32[5]==1)?(DHL_MODULATION_64QAM):(DHL_MODULATION_256QAM);
2268                DST_g_OTC_RF = event.data32[6];
2269                DST_g_OTC_PID = event.data32[7];
2270//              DST_OTC_Start();
2271#endif
2272        }
2273        if (nRequestID == POS_OTC_DII) // OTC_DII
2274        {
2275                if (1) DST_Printf("################## Request ID = POS_OTC_DII\n");
2276                 // DST_OTC_ParseDsmcc(buff[0]);
2277                DS_U8 *p = buff[0];
2278                if (p[0] != 0x3B) return; // TABLE ID
2279                DS_U16 section_length = ((p[1]&0x0F) * 0x100) + p[2];
2280                if (section_length < 48) return; // SECTION TOO SHORT
2281                if (p[10] != 0x10 || p[11] != 0x02) return; // DSMCC_DM_MSG_DII 0x1002
2282                DS_U8 adaptationLength = p[17];
2283                if (section_length < 48 + adaptationLength) return; // SECTION TOO SHORT
2284                p += adaptationLength; // adaptationLength ±æÀ̸¸Å­ Æ÷ÀÎÅÍ À̵¿
2285                DS_U16 blockSize = p[24] * 0x100 + p[25];
2286                DS_U32 moduleSz = p[42]* 0x1000000 +    p[43]* 0x10000 + p[44]* 0x100 + p[45];
2287                if (1) DST_Printf("blockSize = %d moduleSz = %d\n", blockSize, (int)moduleSz);
2288                CT_CallBack(CT_OTC_RECEIVE_DII, moduleSz, blockSize,0,0,0,0);
2289        }
2290        if (nRequestID == POS_OTC_DDB) // OTC_DDB
2291        {
2292                //if (0) DST_Printf("############## Request ID = POS_OTC_DDB\n");
2293                //DST_OTC_ParseDsmcc(buff[0]);
2294                DS_U8 *p = buff[0];
2295                if (p[0] != 0x3C) return; // TABLE ID
2296                //DS_U16 section_length = ((p[1]&0x0F) * 0x100) + p[2];
2297                //if (section_length < 48) return; // SECTION TOO SHORT
2298                if (p[10] != 0x10 || p[11] != 0x03) return; // DSMCC_DM_MSG_DDB 0x1003
2299                DS_U8 adaptationLength = p[17];
2300                //if (section_length < 48 + adaptationLength) return; // SECTION TOO SHORT
2301                p += adaptationLength; // adaptationLength ±æÀ̸¸Å­ Æ÷ÀÎÅÍ À̵¿
2302                DS_U16 blockSize = p[18] * 0x100 + p[19];
2303                DS_U16 blockNumber = p[24]* 0x100 + p[25];
2304                //if (0) DST_Printf("blockSize = %d blockNumber = %d\n", blockSize-6, blockNumber);
2305                CT_CallBack(CT_OTC_RECEIVE_DDB, blockNumber, (DS_U32)&p[26], blockSize-6,0,0,0);
2306        }
2307        if (msg.SI) DST_OS_SendMessage(gSIMsgQ, (DS_U32 *)&msg, sizeof(CT_SI_Msg));
2308}
2309
2310
2311// ÇÑ RF¿¡ ´ëÇÑ ¿ÀÅ佺ĵÀÌ ³¡³ª°í ³ª¼­ ´ÙÀ½ ä³Î·Î °¥¶§ ÇöÀç RF¿¡¼­ SI¸¦ ¹Þ¾Ò´ÂÁö ¿©ºÎ¸¦ ÆÇ´ÜÇØ¼­
2312// ä³Î¸ÊÀ» Áö¿ö¾ß ÇÑ´Ù.
2313static bool g_bRemovedOldChannel = false; // PAT/CVCT/TVCT Áß Çϳª¸¦ ¹ÞÀ¸¸é ÀÌÀü ä³ÎÀ» Áö¿î´Ù.
2314bool CT_ScanFindChannel()
2315{
2316        return g_bRemovedOldChannel;
2317}
2318
2319static void CT_ScanPSIP(DS_U8 RF/*=0*/, bool bOn/*=false*/)
2320{
2321        static bool bStart = false;
2322        static DS_U32 startTick = 0;
2323        static DHL_HANDLE hTVCT = 0;
2324#if CVCT_SUPPORT
2325        static DHL_HANDLE hCVCT = 0;
2326#endif
2327        static DHL_HANDLE hPAT = 0;
2328        static DHL_HANDLE hPMT[MAX_PMT_COUNT];
2329        static int remain_pmt_count = 0;
2330       
2331       
2332        if (bOn)
2333        {
2334                if (bStart)
2335                {
2336                        CT_SI_Msg msg;
2337                        DS_U32 retLen = 0;
2338                        while (DST_OS_ReceiveMessage_NoWait(gSIMsgQ, (DS_U32*)&msg, sizeof(CT_SI_Msg), &retLen) == noError)
2339                        {
2340                                if (RF == msg.RF) 
2341                                {
2342                                         // PAT/CVCT/TVCT Áß Çϳª¸¦ ¹ÞÀ¸¸é ÀÌÀü ä³ÎÀ» Áö¿î´Ù.
2343                                        if (msg.nRequestID == POS_TVCT ||
2344#if CVCT_SUPPORT
2345                                                msg.nRequestID == POS_CVCT || 
2346#endif
2347                                                msg.nRequestID == POS_PAT)
2348                                        {
2349                                                if (g_bRemovedOldChannel == false)
2350                                                {
2351                                                        // JST_DB_Del(RF);
2352                                                        g_bRemovedOldChannel = true;
2353                                                }
2354                                        }
2355                                        if (msg.nRequestID == POS_TVCT)
2356                                        {
2357                                                TVCT *tvct = (TVCT*)msg.SI;
2358                                                if (CT_ChMapUpdateTVCT(RF, tvct, msg.CRC32))
2359                                                {
2360                                                        CT_ChMapUpdate();
2361                                                }
2362                                                CT_CallBack(CT_SCAN_RECEIVE_TVCT, msg.RF, (DS_U32)tvct,0,0,0,0);
2363                                        }
2364#if CVCT_SUPPORT
2365                                        if (msg.nRequestID == POS_CVCT)
2366                                        {
2367                                                CVCT *cvct = (CVCT*)msg.SI;
2368                                                if (CT_ChMapUpdateCVCT(RF, cvct, msg.CRC32))
2369                                                {
2370                                                        CT_ChMapUpdate();
2371                                                }
2372                                                CT_CallBack(CT_SCAN_RECEIVE_CVCT, msg.RF, (DS_U32)cvct,0,0,0,0);
2373                                        }
2374#endif
2375                                        if (msg.nRequestID == POS_PAT)
2376                                        {
2377                                                MPEG_PAT *pat = (MPEG_PAT*)msg.SI;
2378                                                if (CT_ChMapUpdatePAT(RF, pat, msg.CRC32)) // PAT°¡ °»½ÅµÇ¾ú´Ù
2379                                                {
2380                                                        // VCT°¡ ÀÖ´ø ä³Î¿¡¼­ VCT°¡ ¾ø´Â ä³Î·Î ½ºÆ®¸²ÀÌ º¯°æµÈ °æ¿ì ¹Ý¿µÇϱâ À§ÇÑ ÄÚµå
2381                                                        // VCT°¡ ¾ø´Â ä³ÎÀϼö ÀÖÀ¸´Ï VCT Á¤º¸¸¦ Áö¿ì°í »õ·Î ¹Þ¾Æº»´Ù.
2382                                                        DHL_SI_MonitorStop(&hTVCT);
2383//                                                      DHL_SI_MonitorStop(&hCVCT);
2384                                                        // VCT Á¤º¸¸¦ Á¦°ÅÇÑ´Ù
2385                                                        {
2386        //                                                      CDB db; NewCDB(&db);
2387        //                                                      db.Query(&db, "delete from tvct where rf = %d", RF);
2388        //                                                      db.Query(&db, "delete from tvct_sub where rf = %d", RF);
2389        //                                                      db.Query(&db, "delete from cvct where rf = %d", RF);
2390        //                                                      db.Query(&db, "delete from cvct_sub where rf = %d", RF);
2391        //                                                      DeleteCDB(&db);
2392                                                                int i;
2393                                                                DBLock(true);
2394                                                                for (i =0 ; i < DB_TVCT_MAX; i++)
2395                                                                {
2396                                                                        if (db_tvct[i].rf != RF) continue;
2397                                                                        memset(&db_tvct[i], 0, sizeof(_DB_TVCT_));
2398                                                                }
2399                                                                for (i =0 ; i < DB_TVCT_SUB_MAX; i++)
2400                                                                {
2401                                                                        if (db_tvct_sub[i].rf != RF) continue;
2402                                                                        memset(&db_tvct_sub[i], 0, sizeof(_DB_TVCT_SUB_));
2403                                                                }
2404#if CVCT_SUPPORT
2405                                                                for (i =0 ; i < DB_CVCT_MAX; i++)
2406                                                                {
2407                                                                        if (db_cvct[i].rf != RF) continue;
2408                                                                        memset(&db_cvct[i], 0, sizeof(_DB_CVCT_));
2409                                                                }
2410                                                                for (i =0 ; i < DB_CVCT_SUB_MAX; i++)
2411                                                                {
2412                                                                        if (db_cvct_sub[i].rf != RF) continue;
2413                                                                        memset(&db_cvct_sub[i], 0, sizeof(_DB_CVCT_SUB_));
2414                                                                }
2415#endif
2416                                                                DBLock(false);
2417                                                                CT_ChMapUpdate();
2418                                                        }
2419                                                        // VCT ¸ð´ÏÅ͸µ Àç½ÃÀÛ
2420                                                        hTVCT = DHL_SI_MonitorTVCT(RF, POS_TVCT);
2421#if CVCT_SUPPORT
2422                                                        hCVCT = DHL_SI_MonitorCVCT(RF, POS_CVCT);
2423#endif
2424                                                }
2425                                                int nPos = 0;
2426                                                int i;
2427                                                for ( i = 0; i < MAX_PMT_COUNT; i++)
2428                                                {
2429                                                        if (hPMT[i]) DHL_SI_MonitorStop(&hPMT[i]);
2430                                                }
2431                                                for ( i = 0; i < pat->numPrograms; i++)
2432                                                {
2433                                                        if (pat->programs[i].program_map_PID == 0) continue;
2434                                                        if (pat->programs[i].program_map_PID == 0x1FFF) continue;
2435                                                        hPMT[nPos] = DHL_SI_MonitorPMT(RF, POS_PMT+nPos, pat->programs[i].program_map_PID, pat->programs[i].program_number);
2436                                                        nPos++;
2437                                                        if (nPos >= MAX_PMT_COUNT) break;
2438                                                }
2439                                                remain_pmt_count = nPos;
2440                                        }
2441                                        if (msg.nRequestID >= POS_PMT && msg.nRequestID < POS_PMT+MAX_PMT_COUNT)
2442                                        {
2443                                                MPEG_PMT *pmt = (MPEG_PMT*)msg.SI;
2444                                                if (CT_ChMapUpdatePMT(RF, pmt, msg.nRequestID-POS_PMT+1, msg.CRC32))
2445                                                {
2446                                                        CT_ChMapUpdate();
2447                                                }
2448                                                remain_pmt_count--;
2449                                                CT_CallBack(CT_SCAN_RECEIVE_PMT, RF, pmt->program_number, remain_pmt_count,0,0,0);
2450                                                if (0) DST_Printf("remain_pmt_count = %d\n", remain_pmt_count);
2451                                        }
2452                                }
2453                                DST_FreeAtscTable(&msg.SI); // ¸Þ¸ð¸® ÇØÁ¦´Â ¿©±â¿¡¼­
2454                        } // while
2455                        if (startTick > DST_OS_GetTickCount()) startTick =  DST_OS_GetTickCount();
2456                        CT_CallBack(CT_SCAN_PSIP_WAIT, RF, (DST_OS_GetTickCount() - startTick) * 1000/DST_OS_GetTicksPerSecond(),0,0,0,0); // PSIP ¸ðµðÅ͸µ ½ÃÀÛ ÈÄ ¸î msÀÌ Áö³µ´ÂÁö
2457                }
2458                else // bStart == false
2459                {
2460                        T();
2461                        CT_ScanPSIP(0, false);
2462                        bStart = true;
2463                        g_bRemovedOldChannel = false; 
2464                        startTick = DST_OS_GetTickCount();
2465                        hTVCT = DHL_SI_MonitorTVCT(RF, POS_TVCT);
2466#if CVCT_SUPPORT
2467                        hCVCT = DHL_SI_MonitorCVCT(RF, POS_CVCT);
2468#endif
2469                        // hPAT = DHL_SI_MonitorPAT(RF, POS_PAT);
2470                }
2471        }
2472        else
2473        {
2474                if (bStart)
2475                {
2476                        T();
2477                        DHL_SI_MonitorStop(&hTVCT);
2478//                      DHL_SI_MonitorStop(&hCVCT);
2479                        DHL_SI_MonitorStop(&hPAT);
2480                        int i;
2481                        for ( i = 0; i < MAX_PMT_COUNT; i++) 
2482                        {
2483                                DHL_SI_MonitorStop(&hPMT[i]);
2484                        }
2485                        bStart = false;
2486                        g_bRemovedOldChannel = false; 
2487                        startTick = 0;
2488                        CT_SI_Msg msg;
2489                        DS_U32 retLen = 0;
2490                        while (DST_OS_ReceiveMessage_NoWait(gSIMsgQ, (DS_U32*)&msg, sizeof(CT_SI_Msg), &retLen) == noError)
2491                        {
2492                                if (0) DST_Printf("Remove msg.nRequestID == %d\n", (int)msg.nRequestID);
2493                                DST_FreeAtscTable(&msg.SI);
2494                        }
2495                }
2496        }
2497}
2498
2499static void CT_Scan(DS_U8 RF/*=0*/, bool bOn/*=false*/)
2500{
2501        static bool bStart = false;
2502        static DS_U8 CurrentRF = 0;
2503        static DS_U32 startTick = 0;
2504        if (bOn)
2505        {
2506                if (bStart == false || CurrentRF != RF)
2507                {
2508                        CT_ScanPSIP(0, false);
2509                        DHL_TUN_Start(RF, DHL_MODULATION_8VSB);
2510                        DST_g_LastTuneTime = DST_OS_GetTickCount();
2511                        CurrentRF = RF;
2512                        //bLock = false;
2513                        bStart = true;
2514                        startTick = DST_OS_GetTickCount();
2515                }
2516                CT_ScanPSIP(RF, bOn);
2517                bool bLock = false;
2518                int ss = 0, power = 0, snr = 0;
2519                DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr);
2520                if (startTick > DST_OS_GetTickCount()) startTick = DST_OS_GetTickCount();
2521                CT_CallBack(CT_SCAN_LOCK_WAIT, RF, (DST_OS_GetTickCount() - startTick) * 1000/DST_OS_GetTicksPerSecond() , ss, power,0,0);
2522        }
2523        else
2524        {
2525                CT_ScanPSIP(0, false); // SCAN PSIP ¸ð´ÏÅ͸µ Ãë¼Ò
2526                if (bStart)
2527                {
2528                        DST_g_LastTuneTime = 0;
2529                        DHL_TUN_Stop();
2530                        bStart = false;
2531                        CurrentRF = 0;
2532                        startTick = 0;
2533                        //bLock = false;
2534                }
2535        }
2536}
2537
2538static void CT_RF_Update(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_256QAM*/,  bool bOn /*=false*/)
2539{
2540        static bool bStart = false;
2541        static DHL_HANDLE hRfUpdate = 0;
2542        if (bOn)
2543        {
2544                if (bStart == false)
2545                {
2546                        DHL_TUN_Start(RF, demod);
2547                        hRfUpdate = DHL_SI_MonitorRFUpdate(RF,  POS_RFUPDATE);
2548                        bStart = true;
2549                }
2550                else
2551                {
2552                        // ½ÅÈ£ Á¤º¸
2553                        bool bLock = false;
2554                        int ss = 0, power = 0, snr = 0;
2555                        DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr);
2556                        CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0);
2557                }
2558        }
2559        else
2560        {
2561                if (bStart == true)
2562                {
2563                        DHL_SI_MonitorStop(&hRfUpdate);
2564                        DHL_TUN_Stop();
2565                        bStart = false;
2566                }
2567        }
2568}
2569
2570// CMB OTC ¸¦ À§ÇØ ¸ÕÀú CVT¸¸ È®ÀÎÇÑ´Ù.
2571static void CT_CVT(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_256QAM*/,  bool bOn/*=false*/)
2572{
2573        static bool bStart = false;
2574        static DHL_HANDLE hCVT = 0;
2575        if (bOn)
2576        {
2577                if (bStart == false)
2578                {
2579                        DHL_TUN_Start(RF, demod);
2580                        hCVT = DHL_SI_MonitorSCTE_CVT(RF,  POS_CVT);
2581                        bStart = true;
2582                }
2583                else
2584                {
2585                        // ½ÅÈ£ Á¤º¸
2586                        bool bLock = false;
2587                        int ss = 0, power = 0, snr = 0;
2588                        DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr);
2589                        CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0);
2590                }
2591        }
2592        else
2593        {
2594                if (bStart == true)
2595                {
2596                        DHL_SI_MonitorStop(&hCVT);
2597                        DHL_TUN_Stop();
2598                        bStart = false;
2599                }
2600        }
2601}
2602
2603static void CT_OTC(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_256QAM*/,  DS_U16 otc_pid /*= 0*/, bool bOn/*=false*/)
2604{
2605        static bool bStart = false;
2606        static DHL_HANDLE hDII = 0;
2607        static DHL_HANDLE hDDB = 0;
2608        if (bOn)
2609        {
2610                if (bStart == false)
2611                {
2612                        DHL_TUN_Start(RF, demod);
2613                        DST_g_LastTuneTime = DST_OS_GetTickCount();
2614                        //CT_CallBack(CT_OTC_START);
2615                        hDII = DHL_SI_MonitorSCTE_DII(RF,  POS_OTC_DII, otc_pid);
2616                        hDDB = DHL_SI_MonitorSCTE_DDB(RF, POS_OTC_DDB, otc_pid);
2617                        bStart = true;
2618                }
2619                else
2620                {
2621                        // ½ÅÈ£ Á¤º¸
2622                        bool bLock = false;
2623                        int ss = 0, power = 0, snr = 0;
2624                        DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr);
2625                        CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0);
2626                }
2627        }
2628        else
2629        {
2630                if (bStart == true)
2631                {
2632                        DST_g_LastTuneTime = 0;
2633                        DHL_SI_MonitorStop(&hDII);
2634                        DHL_SI_MonitorStop(&hDDB);
2635                        DHL_TUN_Stop();
2636                        bStart = false;
2637                }
2638        }
2639//      if(DST_OTC_GetStatus() == CD_INBAND_DOWNLOAD)
2640//      {
2641//              if(hDII)
2642//              {
2643//                      DHL_SI_MonitorStop(&hDII);
2644//                      hDII = 0;
2645//              }
2646//              if(hDDB == 0)
2647//              {
2648//                      hDDB = DHL_SI_MonitorSCTE_DDB(RF, POS_OTC_DDB, otc_pid);
2649//              }
2650//      }
2651//      if(DST_OTC_GetStatus() == CD_INBAND_DOWNLOAD_UPDATE)
2652//      {
2653//              if(hDDB)
2654//              {
2655//                      DHL_SI_MonitorStop(&hDDB);
2656//                      hDDB = 0;
2657//              }
2658//      }       
2659}
2660
2661
2662static void CT_VideoFreezeEndProc()
2663{
2664        if (0) DST_Printf("DST_VideoFreezeEndProc\n");
2665        CT_ChannelChangeVideoMute(false);
2666}
2667
2668static void CT_SignalInfoCallBack(int nWidth, int nHeight, int RefreshRate, bool bInterlaced,   DHL_SOURCE_ASEPCT Aspect)
2669{
2670        CT_CallBack(CT_VIDEO_RESOLUTION, nWidth, nHeight, RefreshRate, bInterlaced, Aspect,0);
2671}
2672
2673void DST_708_Callback(DS_U8 *bytearray,int size);
2674void DST_IrCallBack(DS_U32 key, DS_U32 repeat, DS_U32 tick);
2675
2676static bool g_VideoDisplay = true;
2677void JST_POWER_Display(bool bOn)
2678{
2679        g_VideoDisplay = bOn;
2680}
2681
2682static void tChannel(void)
2683{
2684        DHL_SYS_TV_Open(CT_SignalInfoCallBack, CT_VideoFreezeEndProc, 0, 
2685                CT_SI_Proc, DST_708_Callback, DST_IrCallBack);
2686        CT_Msg msg = {CMD_NULL, DHL_MODULATION_8VSB, 0,0};
2687        while (1)
2688        {
2689                DS_U32 retLen;
2690                CT_Msg tmp;
2691                bool bChanged = false;
2692                // ½×¿©ÀÖ´Â ¸ðµç ¸Þ½ÃÁö¸¦ °¡Á®¿Â´Ù.
2693#ifdef DSTAR
2694                DST_OS_Delay(50);
2695#else
2696                DST_OS_Delay(10);
2697#endif
2698                while (DST_OS_ReceiveMessage_NoWait(gMsgQ, (DS_U32*)&tmp, sizeof(CT_Msg), &retLen) == noError)
2699                {
2700                        if (0) DST_Printf("\n\n\n\n\nReceive Cmd = %d RF = %d demod = %d program_number = %d\n\n\n\n\n\n", 
2701                                        tmp.Cmd, tmp.RF, tmp.demod, tmp.program_number);
2702                        if (msg.Cmd != tmp.Cmd || msg.RF != tmp.RF || msg.demod != tmp.demod || msg.program_number != tmp.program_number)
2703                        { 
2704                                msg = tmp;
2705                                bChanged = true;
2706                        }
2707                }
2708                ////if (0) DST_Printf("Current Cmd = %d RF = %d Minor = %d Mode = %d\n", msg.Cmd, msg.RF, msg.Minor, msg.Mode);
2709
2710                static DS_U16 program_number = 0;
2711                static DS_U16 source_id = 0;
2712                if (msg.Cmd == CMD_TUNE)
2713                {
2714                        DBLock(true);
2715                        DS_U16 new_program_number = 0;
2716                        DS_U16 new_source_id = 0;
2717                        if (msg.program_number == 0) // RF Æ©´×ÀÎ °æ¿ì
2718                        {
2719                                int i;
2720                                int min_minor = 10000;
2721                                int min_minor_pos = -1;
2722                                for (i = 0; i < DB_CHANNEL_DB_MAX; i++)
2723                                {
2724                                        if (db_channel_db[i].program_number == 0) continue;
2725                                        if (db_channel_db[i].rf !=      msg.RF) continue;
2726                                        if (min_minor > db_channel_db[i].minor)
2727                                        {
2728                                                        min_minor = db_channel_db[i].minor;
2729                                                        min_minor_pos = i;
2730                                        } 
2731                                }
2732                                if (min_minor_pos >= 0)
2733                                {
2734                                        new_program_number = db_channel_db[min_minor_pos].program_number;
2735                                        new_source_id = db_channel_db[min_minor_pos].source_id;
2736                                }
2737                        }
2738                        else
2739                        {
2740                                int i;
2741                                for (i = 0; i < DB_CHANNEL_DB_MAX; i++)
2742                                {
2743                                        if (db_channel_db[i].program_number == 0) continue;
2744                                        if (db_channel_db[i].program_number != msg.program_number) continue;
2745                                        if (db_channel_db[i].rf !=      msg.RF) continue;
2746                                        new_program_number = db_channel_db[i].program_number;
2747                                        new_source_id = db_channel_db[i].source_id;
2748                                        break;
2749                                }
2750                        }
2751                        if (program_number != new_program_number || source_id != new_source_id)
2752                        {
2753                                program_number = new_program_number;
2754                                source_id = new_source_id;
2755                                bChanged = true;
2756                        }
2757                        DBLock(false);
2758                }
2759                else
2760                {
2761                        program_number = 0;
2762                        source_id = 0;
2763                }
2764
2765                switch (msg.Cmd)
2766                {
2767                        case CMD_NULL:
2768                                break;
2769                        case CMD_TUNE:
2770                                CT_Scan(0, false);
2771                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2772                                CT_RF_Update(0, DHL_MODULATION_256QAM, false);
2773                                CT_CVT(0, DHL_MODULATION_256QAM, false);
2774                                CT_Tune(msg.RF, msg.demod, program_number, source_id, true);
2775                                if (bChanged) CT_CallBack(CT_TUNE_START, msg.RF, program_number, source_id,0,0,0);
2776                                CT_AutoScanMute(false);
2777                                break;
2778                        case CMD_SCAN:
2779                                CT_AutoScanMute(true);
2780                                CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2781                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2782                                CT_RF_Update(0, DHL_MODULATION_256QAM, false);
2783                                CT_CVT(0, DHL_MODULATION_256QAM, false);
2784                                CT_Scan(msg.RF, true);
2785                                if (bChanged) CT_CallBack(CT_SCAN_START, msg.RF,0,0,0,0,0);
2786                                break;
2787                        case CMD_RF_UPDATE:
2788                                CT_AutoScanMute(true);
2789                                CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2790                                CT_Scan(0, false);
2791                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2792                                CT_CVT(0, DHL_MODULATION_256QAM, false);
2793                                CT_RF_Update(msg.RF, msg.demod, true);
2794                                if (bChanged) CT_CallBack(CT_RF_UPDATE_START, msg.RF,0,0,0,0,0);
2795                                break;
2796                       
2797                        case CMD_CVT:
2798                                CT_AutoScanMute(true);
2799                                CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2800                                CT_Scan(0, false);
2801                                CT_RF_Update(0, DHL_MODULATION_256QAM, false);
2802                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2803                                CT_CVT(msg.RF, msg.demod, true);
2804                                if (bChanged) CT_CallBack(CT_CVT_START, msg.RF, msg.program_number,0,0,0,0);
2805                                break;
2806                               
2807                        case CMD_OTC:
2808                                CT_AutoScanMute(true);
2809                                CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2810                                CT_Scan(0, false);
2811                                CT_RF_Update(0, DHL_MODULATION_256QAM, false);
2812                                CT_CVT(0, DHL_MODULATION_256QAM, false);
2813                                CT_OTC(msg.RF, msg.demod, msg.program_number, true);
2814                                if (bChanged) CT_CallBack(CT_OTC_START, msg.RF, msg.program_number,0,0,0,0);
2815                                break;
2816                               
2817                        case CMD_OTC_STOP:
2818                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2819                                break;
2820                               
2821                        case CMD_STOP:
2822                                CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2823                                CT_Scan(0, false);
2824                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2825                                CT_RF_Update(0, DHL_MODULATION_256QAM, false);
2826                                if (bChanged) CT_CallBack(CT_STOPPED,0,0,0,0,0,0);
2827                                break;
2828                }
2829               
2830                DHL_POWER_Display(g_VideoDisplay);
2831                if (msg.Cmd == CMD_CLOSE) break;
2832        }
2833        CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2834        CT_Scan(0, false);
2835        DHL_SYS_TV_Close();
2836        CT_CallBack(CT_CLOSE, 0, 0, 0, 0,0,0);
2837        DST_OS_DeleteMessageQueue(gMsgQ);
2838        DST_OS_DeleteMessageQueue(gSIMsgQ);
2839        gMsgQ = 0;
2840        gSIMsgQ = 0;
2841//      DST_DB_Close();
2842        g_callback = 0;
2843        DST_OS_SelfDeleteTask();
2844}
2845
2846static void CT_Init()
2847{
2848        static int taskID = 0;
2849        // ŽºÅ©¿Í ¸Þ½ÃÁöÅ¥ »ý¼º
2850        if (taskID == 0)
2851        {
2852                gMsgQ = DST_OS_CreateMessageQueue("qChannelTask", 0, 100, sizeof(CT_Msg));
2853                gSIMsgQ = DST_OS_CreateMessageQueue("qChannelTask", 0, 100, sizeof(CT_SI_Msg));
2854                taskID = DST_OS_SpawnTask((void (*)(void *)) tChannel, (char*)"tChannel", APP_TASK_PRIO_CHANNEL, WIN_MGR_TASK_STACKSIZE, 0);
2855        }
2856}
2857
2858// jstack open
2859void JST_Open(jst_callback callcack)
2860{
2861        g_callback = callcack;
2862        CT_Init();
2863}
2864
2865static void JST_SendMsg(int Cmd /*= CMD_NULL*/, DS_U32 RF /*= 0*/, 
2866                DHL_MODULATION_MODE demod /*= DHL_MODULATION_8VSB*/, DS_U16 program_number /*= 0*/)
2867{
2868        switch (demod)
2869        {
2870                case    DHL_MODULATION_64QAM:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|64QAM|%d\n", __func__, Cmd, RF, program_number);break;
2871                case    DHL_MODULATION_256QAM:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|256QAM|%d\n", __func__, Cmd, RF, program_number);break;
2872                case    DHL_MODULATION_8VSB:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|8VSB|%d\n", __func__, Cmd, RF, program_number);break;
2873                case    DHL_MODULATION_16VSB:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|16VSB|%d\n", __func__, Cmd, RF, program_number);break;
2874                default:
2875                        break;
2876        }
2877        CT_Init();
2878        CT_Msg msg;
2879        msg.Cmd = Cmd;
2880        msg.RF = RF;
2881        msg.demod =  demod;
2882        msg.program_number = program_number;
2883        if (gMsgQ) DST_OS_SendMessage(gMsgQ, (DS_U32 *)&msg, sizeof(CT_Msg));
2884} 
2885
2886// jstack close
2887void JST_Close()
2888{
2889        JST_SendMsg(CMD_CLOSE, 0, DHL_MODULATION_8VSB, 0);
2890}
2891
2892// Channel Task Start
2893void JST_Tune(DS_U8 RF, DHL_MODULATION_MODE demod, DS_U16 program_number)
2894{
2895        JST_SendMsg(CMD_TUNE, RF, demod, program_number);
2896}
2897
2898// Channel Task Start
2899void JST_Scan(DS_U8 RF)
2900{
2901        DST_Printf("JST_Scan %d\n", RF);
2902        JST_SendMsg(CMD_SCAN, RF, DHL_MODULATION_8VSB, 0);
2903}
2904
2905void JST_RFUpdate(DS_U8 RF)
2906{
2907        T();
2908        JST_SendMsg(CMD_RF_UPDATE, RF, DHL_MODULATION_8VSB, 0);
2909}
2910
2911void JST_CVT(DS_U8 RF, DHL_MODULATION_MODE demod)
2912{
2913        JST_SendMsg(CMD_CVT, RF, demod, 0);
2914}
2915
2916void JST_OTC(DS_U8 RF, DHL_MODULATION_MODE demod, DS_U16 otc_pid)
2917{
2918        JST_SendMsg(CMD_OTC, RF, DHL_MODULATION_256QAM, otc_pid);
2919}
2920
2921void JST_OTC_STOP()
2922{
2923        JST_SendMsg(CMD_OTC_STOP, 0, DHL_MODULATION_8VSB, 0);
2924}
2925
2926// Channel Task Stop
2927void JST_Stop(void)
2928{
2929        JST_SendMsg(CMD_STOP, 0, DHL_MODULATION_8VSB, 0);
2930}
Note: See TracBrowser for help on using the repository browser.