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

Last change on this file since 13 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
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}
895
896
897static void CT_ChMapUpdatePMTISO639LanguageDescriptor(DS_U32 RF, DS_U16 prog_num, DS_U16 pid, DS_U8 *descriptors, DS_U16 descriptor_length)
898{
899        // T();
900        if (descriptors == 0 || descriptor_length == 0) return;
901        // T();
902        DS_U8 tag_len = 0;
903        DS_U8 *p =  GetMpegDescriptor(descriptors, descriptor_length, ISO_639_language_tag, &tag_len);
904        if (tag_len == 0)       return;
905        if (0) DST_Printf("tag_len = %d\n", tag_len); 
906        int i;
907        for ( i=0; i < tag_len+2; i++) if (0) DST_Printf("0x%02X ", p[i]); 
908        if (0) DST_Printf("\n");
909        if (p[1] < 4) return;
910        char ISO_639_Language_code[4];
911        ISO_639_Language_code[0] = (char)p[2];
912        ISO_639_Language_code[1] = (char)p[3];
913        ISO_639_Language_code[2] = (char)p[4];
914        ISO_639_Language_code[3] = 0;
915        DS_U8 audio_type = p[5];
916        // ±âÁ¸¿¡ ÀÖµ· µ¿ÀÏÇÑ ÇÁ·Î±×·¥ ³Ñ¹ö pidÀÇ Á¤º¸ ÃʱâÈ­
917        for ( i = 0; i < MAX_PMT_AC3_TABLE_COUNT; i++)
918        {
919                if (pmt_iso_table[i].program_number == 0) continue;
920                if (pmt_iso_table[i].rf == (int)RF && pmt_iso_table[i].program_number == prog_num
921                        && pmt_iso_table[i].pid == pid) pmt_iso_table[i].program_number = 0;
922        }
923        for ( i = 0; i < MAX_PMT_AC3_TABLE_COUNT; i++)
924        {
925                if (pmt_iso_table[i].program_number != 0) continue;
926                pmt_iso_table[i].rf = RF;
927                pmt_iso_table[i].program_number = prog_num;
928                pmt_iso_table[i].pid = pid;
929                strcpy(pmt_iso_table[i].lang, ISO_639_Language_code);
930                pmt_iso_table[i].type = audio_type;
931                if (0) DST_Printf("%s|pmt_iso_table|%d\n", __func__, i);
932                if (0) DST_Printf("%s|pmt_iso_table|pid = %d\n", __func__, pid);
933                if (0) DST_Printf("%s|pmt_iso_table|ISO_639_Language_code = %s\n", __func__, ISO_639_Language_code);
934                if (0) DST_Printf("%s|pmt_iso_table|audio_type = %d\n", __func__, audio_type);
935                break;
936        }
937}
938
939
940static void CT_PMT_AudioTableUpdate(int rf, int program_number, int pid, int type, int component_tag)
941{
942        int j;
943        // µ¿ÀÏÇÑ program_number & µ¿ÀÏÇÑ PID
944        for ( j = 0; j < MAX_PMT_AUDIO_TABLE_COUNT; j++)
945        {
946                if (pmt_audio_table[j].program_number == 0) continue;
947                if (pmt_audio_table[j].rf == rf && pmt_audio_table[j].program_number == program_number && 
948                                pmt_audio_table[j].pid == pid) pmt_audio_table[j].program_number = 0;
949        }
950        // ºó°÷¿¡ ã¾Æ ³Ö´Â´Ù.
951        for ( j = 0; j < MAX_PMT_AUDIO_TABLE_COUNT; j++)
952        {
953                if (pmt_audio_table[j].program_number != 0) continue;
954                pmt_audio_table[j].rf = rf;
955                pmt_audio_table[j].program_number = program_number;
956                pmt_audio_table[j].pid = pid;
957                pmt_audio_table[j].type = type;
958                pmt_audio_table[j].component_tag = component_tag;
959                break;
960        }
961}
962
963static bool CT_ChMapUpdatePMT(DS_U8 RF, MPEG_PMT *pmt, int minor, DS_U32 CRC32)
964{
965        if (pmt == 0 || pmt->program_number == 0) return false;
966        int i;
967        DBLock(true);
968        for ( i = 0 ; i < MAX_PMT_AUDIO_TABLE_COUNT; i++) 
969        {
970                if (pmt_audio_table[i].rf != (int)RF) pmt_audio_table[i].program_number = 0;
971                if (pmt_audio_table[i].rf == (int)RF && pmt_audio_table[i].program_number == pmt->program_number) pmt_audio_table[i].program_number = 0;
972        }
973        for ( i = 0 ; i < MAX_PMT_CC_TABLE_COUNT; i++) 
974        {
975                if (pmt_cc_table[i].rf != (int)RF) pmt_cc_table[i].program_number = 0;
976                if (pmt_cc_table[i].rf == (int)RF && pmt_cc_table[i].program_number == pmt->program_number) pmt_cc_table[i].program_number = 0;
977        }
978        for ( i = 0 ; i < MAX_PMT_AC3_TABLE_COUNT; i++)
979        { 
980                if (pmt_ac3_table[i].rf != (int)RF) pmt_ac3_table[i].program_number = 0;       
981                if (pmt_ac3_table[i].rf == (int)RF && pmt_ac3_table[i].program_number == pmt->program_number) pmt_ac3_table[i].program_number = 0;     
982        }
983        for ( i = 0 ; i < MAX_PMT_ISO_TABLE_COUNT; i++) 
984        {
985                if (pmt_iso_table[i].rf != (int)RF) pmt_iso_table[i].program_number = 0;
986                if (pmt_iso_table[i].rf == (int)RF && pmt_iso_table[i].program_number == pmt->program_number) pmt_iso_table[i].program_number = 0;
987        }
988        for ( i = 0 ; i < DB_PMT_MAX; i++) 
989        {
990//              if (db_pmt[i].rf != (int)RF) db_pmt[i].program_number = 0;
991                if (db_pmt[i].rf == (int)RF && db_pmt[i].program_number == pmt->program_number) db_pmt[i].program_number = 0;
992        }
993       
994        DS_U16 video_pid = 0;
995        DS_U8  video_stream_type = 0;
996        for ( i = 0; i < pmt->numStreams; i++)
997        {
998                DS_U16 pid = pmt->streams[i].elementary_PID;
999                if (pid == 0 || pid >= 0x1FFF) continue;
1000                DS_U8 stream_type = pmt->streams[i].stream_type;
1001                DS_U8 component_tag = pmt->streams[i].component_tag;
1002                switch (stream_type)
1003                {
1004                        case StreamType_MPEG1Video:
1005                        case StreamType_MPEG2Video:
1006                        case StreamType_MPEG4Video:
1007                        case StreamType_DC2Video:
1008                                video_pid = pid;
1009                                video_stream_type = stream_type;
1010                                CT_ChMapUpdatePMTCCDescriptor(RF, pmt->program_number, pmt->streams[i].descriptors, pmt->streams[i].descriptor_length);
1011                                break;
1012                        case StreamType_MPEG1Audio:
1013                        case StreamType_MPEG2Audio:
1014                        case StreamType_MPEG4Audio:
1015                        case StreamType_AACAudio:
1016                        case StreamType_AC3Audio:
1017                                CT_PMT_AudioTableUpdate(RF, pmt->program_number, pid, stream_type, component_tag);
1018                                CT_ChMapUpdatePMTAC3AudioDescriptor(RF, pmt->program_number, pid, pmt->streams[i].descriptors, pmt->streams[i].descriptor_length);
1019                                CT_ChMapUpdatePMTISO639LanguageDescriptor(RF, pmt->program_number, pid, pmt->streams[i].descriptors, pmt->streams[i].descriptor_length);
1020                                break;
1021                }
1022        }
1023        for (i = 0; i < DB_PMT_MAX; i++) // µ¿ÀÏÇÑ Á¤º¸´Â Áö¿î´Ù.
1024        {
1025                if (db_pmt[i].program_number != 0) continue;
1026                db_pmt[i].rf = RF;
1027                db_pmt[i].program_number = pmt->program_number;
1028                db_pmt[i].pcr_pid = pmt->PCR_PID;
1029                db_pmt[i].video_pid =  video_pid;
1030                db_pmt[i].video_type = video_stream_type;
1031                db_pmt[i].minor = minor;
1032                db_pmt[i].crc = CRC32;
1033                break;
1034        }
1035        DBLock(false);
1036        return true;
1037}
1038
1039#if EPG_SUPPORT
1040static bool CT_ChMapUpdateEIT(DS_U8 rf, EIT *eit, DS_U8 id, DS_U32 CRC32)
1041{
1042        if (eit == 0) return false;
1043        //CDB db; NewCDB(&db);
1044        //db.GetTable(&db, "select crc from eit where rf =%d and id=%d and source_id=%d", rf, id, eit->source_id);
1045        int i;
1046        bool bFind = false;
1047        for (i = 0; i < DB_EIT_MAX; i++)
1048        {
1049                if (db_eit[i].crc == 0) continue;
1050                if (db_eit[i].rf != rf) continue; 
1051                if (db_eit[i].id != id) continue; 
1052                if (db_eit[i].source_id != eit->source_id) continue; 
1053                if (db_eit[i].crc == CRC32) return false;
1054                bFind = true;
1055                break;
1056        }
1057        if(bFind)
1058        {
1059                // db.Query(&db, "delete from eit where rf = %d and id=%d and source_id=%d", rf, id, eit->source_id);
1060                for (i = 0; i < DB_EIT_MAX; i++)
1061                {
1062                        if (db_eit[i].crc == 0) continue;
1063                        if (db_eit[i].rf != rf) continue; 
1064                        if (db_eit[i].id != id) continue; 
1065                        if (db_eit[i].source_id != eit->source_id) continue;
1066                        memset(&db_eit[i], 0, sizeof(_DB_EIT_)); 
1067                }
1068                // db.Query(&db, "delete from eit_sub where rf = %d and id=%d and source_id=%d", rf, id, eit->source_id);
1069                for (i = 0; i < DB_EIT_SUB_MAX; i++)
1070                {
1071                        if (db_eit_sub[i].rf != rf) continue; 
1072                        if (db_eit_sub[i].id != id) continue; 
1073                        if (db_eit_sub[i].source_id != eit->source_id) continue;
1074                        if (db_eit_sub[i].title) DST_OS_Free(&db_eit_sub[i].title);
1075                        memset(&db_eit_sub[i], 0, sizeof(_DB_EIT_SUB_)); 
1076                }
1077        }
1078        //db.Query(&db, "insert into eit values(%d, %d, %d, %d, %d)", rf, id, eit->source_id, eit->version_number, CRC32);
1079        for (i = 0; i < DB_EIT_MAX; i++)
1080        {
1081                if (db_eit[i].crc != 0) continue;
1082                db_eit[i].rf = rf;
1083                db_eit[i].id = id;
1084                db_eit[i].source_id = eit->source_id;
1085                db_eit[i].version_number = eit->version_number;
1086                db_eit[i].crc = CRC32;
1087                break;
1088        }
1089        //char* eit_sub = CDBStringAdd(0, "%s", "insert into eit_sub values");
1090        eitEventPtr_t event = eit->event;
1091        for ( i = 0; i < eit->numEvents; i++, event++)
1092        {
1093//              eit_sub  = CDBStringAdd(eit_sub, "(%d, %d, %d, %d, %d, %d, %Q),",
1094//                              rf, id, eit->source_id,  event->event_id, event->start_time, event->length_in_seconds,
1095//                              mss2utf8(event->title_length,event->title));
1096                int j;
1097                bool bVacancy = false; // ºóÀÚ¸®°¡ ¾ø´Ù¸é ´Ù¸¥ RFÁ¤º¸¸¦ Áö¿î´Ù
1098                for (j =0; j < DB_EIT_SUB_MAX; j++)
1099                {
1100                        if (db_eit_sub[j].source_id) continue;
1101                        bVacancy = true;
1102                        break;
1103                }
1104                if (bVacancy == false)
1105                {
1106                        for (j =0; j < DB_EIT_SUB_MAX; j++)
1107                        {
1108                                if (db_eit_sub[j].rf == rf) continue;
1109                                if (db_eit_sub[i].title) DST_OS_Free(&db_eit_sub[i].title);
1110                                memset(&db_eit_sub[i], 0, sizeof(_DB_EIT_SUB_)); 
1111                        }
1112                }
1113                for (j =0; j < DB_EIT_SUB_MAX; j++)
1114                {
1115                        if (db_eit_sub[j].source_id) continue;
1116                        db_eit_sub[j].rf = rf;
1117                        db_eit_sub[j].id =id;
1118                        db_eit_sub[j].source_id = eit->source_id; // not zero
1119                        db_eit_sub[j].event_id = event->event_id;
1120                        db_eit_sub[j].start_time = event->start_time;
1121                        db_eit_sub[j].length_in_seconds = event->length_in_seconds;
1122                        char* title = mss2utf8(event->title_length,event->title);
1123                        if (title && strlen(title))
1124                        {
1125                                db_eit_sub[j].title = (char*)DST_OS_Malloc(strlen(title)+1);
1126                                strcpy(db_eit_sub[j].title, title);
1127                        }
1128                        break;
1129                }
1130        }
1131        //if (eit->numEvents > 0) CDBStringRun(eit_sub);
1132        //DST_OS_Free(&eit_sub);
1133        //DeleteCDB(&db);
1134        return true;
1135}
1136
1137static bool CT_ChMapUpdateETT(DS_U8 rf, ETT *ett, DS_U32 crc)
1138{
1139        if (ett == 0) return false;
1140        int i;
1141        for (i=0; i < DB_ETT_MAX; i++) // ÀÌ¹Ì ÀÖ´Â Á¤º¸ÀÎÁö È®ÀÎÇÑ´Ù.
1142        {
1143                if (db_ett[i].crc == crc) return false;
1144        }
1145       
1146        bool bVacancy = false; // ºóÀÚ¸®°¡ ÀÖ´ÂÁö È®ÀÎÇÑ´Ù.
1147        for (i =0; i < DB_ETT_MAX; i++)
1148        {
1149                if (db_ett[i].crc) continue;
1150                bVacancy = true;
1151                break;
1152        }
1153       
1154        if (bVacancy == false) // ºóÀÚ¸®°¡ ¾ø´Ù¸é ´Ù¸¥ RF Á¤º¸´Â Áö¿î´Ù.
1155        {
1156                for (i =0; i < DB_ETT_MAX; i++)
1157                {
1158                        if (db_ett[i].rf == rf) continue;
1159                        if (db_ett[i].title) DST_OS_Free(&db_ett[i].title);
1160                        memset(&db_ett[i], 0, sizeof(_DB_ETT_)); 
1161                }
1162        }
1163       
1164        for (i =0; i < DB_ETT_MAX; i++) // ºóÀÚ¸®°¡ ÀÖ´ÂÁö ´Ù½Ã È®ÀÎÇÑ´Ù.
1165        {
1166                if (db_ett[i].crc) continue;
1167                bVacancy = true;
1168                break;
1169        }
1170       
1171        if (bVacancy == false) // EIT¿Í ¿¬°á¾ÈµÈ Á¤º¸´Â Áö¿î´Ù.
1172        {
1173                for (i=0; i < DB_ETT_MAX; i++)
1174                {
1175                        if (db_ett[i].crc == 0) continue;
1176                        int j;
1177                        bool bFind = false;
1178                        for (j=0; j < DB_EIT_SUB_MAX; j++)
1179                        {
1180                                if (db_eit_sub[j].source_id == 0) continue;
1181                                if (db_ett[i].rf != db_eit_sub[j].rf) continue;
1182                                if (db_ett[i].source_id != db_eit_sub[j].source_id) continue;
1183                                if (db_ett[i].event_id != db_eit_sub[j].event_id) continue;
1184                                bFind = true;
1185                                break;
1186                        }
1187                        if (bFind == false)
1188                        {
1189                                if (db_ett[i].title) DST_OS_Free(&db_ett[i].title);
1190                                memset(&db_ett[i], 0, sizeof(_DB_ETT_));
1191                        }
1192                }
1193        }
1194       
1195        for (i=0; i < DB_ETT_MAX; i++) // Á¤º¸ Ãß°¡
1196        {
1197                if (db_ett[i].crc) continue;
1198                db_ett[i].rf = rf;
1199                db_ett[i].source_id = (ett->ETM_id>>16) & 0xFFFF;
1200                db_ett[i].event_id = (ett->ETM_id>>2) & 0x3FFF ;
1201                char* title = mss2utf8(ett->extended_text_message_length,ett->extended_text_message);
1202                if (title && strlen(title))
1203                {
1204                        db_ett[i].title = (char*)DST_OS_Malloc(strlen(title)+1);
1205                        strcpy(db_ett[i].title, title);
1206                }
1207                db_ett[i].crc = crc;   
1208                break;
1209        }
1210        return true;
1211}
1212#endif
1213
1214// ä³Î½ºÄµ¿¡ ½ÇÆÐÇÑ °æ¿ì ÇØ´ç RF Á¦°Å
1215void JST_DB_Del(DS_U8 nRF)
1216{
1217        int i;
1218        DBLock(true);
1219#if EPG_SUPPORT
1220        for (i =0 ; i < DB_EIT_MAX; i++)
1221        {
1222                if (db_eit[i].rf != nRF) continue;
1223                memset(&db_eit[i], 0, sizeof(_DB_EIT_));
1224        }
1225        for (i =0 ; i < DB_EIT_SUB_MAX; i++)
1226        {
1227                if (db_eit_sub[i].rf != nRF) continue;
1228                if (db_eit_sub[i].title) DST_OS_Free(&db_eit_sub[i].title);
1229                memset(&db_eit_sub[i], 0, sizeof(_DB_EIT_SUB_));
1230        }
1231        for (i =0 ; i < DB_ETT_MAX; i++)
1232        {
1233                if (db_ett[i].rf != nRF) continue;
1234                if (db_ett[i].title) DST_OS_Free(&db_ett[i].title);
1235                memset(&db_ett[i], 0, sizeof(_DB_ETT_));
1236        }
1237#endif
1238        for (i =0 ; i < DB_PAT_MAX; i++)
1239        {
1240                if (db_pat[i].rf != nRF) continue;
1241                memset(&db_pat[i], 0, sizeof(_DB_PAT_));
1242        }
1243        for (i =0 ; i < DB_PMT_MAX; i++)
1244        {
1245                if (db_pmt[i].rf != nRF) continue;
1246                memset(&db_pmt[i], 0, sizeof(_DB_PMT_));
1247        }
1248        for (i =0 ; i < DB_TVCT_MAX; i++)
1249        {
1250                if (db_tvct[i].rf != nRF) continue;
1251                memset(&db_tvct[i], 0, sizeof(_DB_TVCT_));
1252        }
1253        for (i =0 ; i < DB_TVCT_SUB_MAX; i++)
1254        {
1255                if (db_tvct_sub[i].rf != nRF) continue;
1256                memset(&db_tvct_sub[i], 0, sizeof(_DB_TVCT_SUB_));
1257        }
1258#if CVCT_SUPPORT
1259        for (i =0 ; i < DB_CVCT_MAX; i++)
1260        {
1261                if (db_cvct[i].rf != nRF) continue;
1262                memset(&db_cvct[i], 0, sizeof(_DB_CVCT_));
1263        }
1264        for (i =0 ; i < DB_CVCT_SUB_MAX; i++)
1265        {
1266                if (db_cvct_sub[i].rf != nRF) continue;
1267                memset(&db_cvct_sub[i], 0, sizeof(_DB_CVCT_SUB_));
1268        }
1269#endif
1270        CT_ChMapUpdate();
1271        DBLock(false);
1272//      CDB db; NewCDB(&db);
1273//      db.Query(&db, "delete from eit where rf=%d", nRF);
1274//      db.Query(&db, "delete from eit_sub where rf=%d", nRF);
1275//      db.Query(&db, "delete from ett where rf=%d", nRF);
1276//      db.Query(&db, "delete from pat where rf=%d", nRF);
1277//      db.Query(&db, "delete from pmt where rf=%d", nRF);
1278////    db.Query("delete from signal where rf=%d", nRF);
1279//      db.Query(&db, "delete from tvct where rf=%d", nRF);
1280//      db.Query(&db, "delete from tvct_sub where rf=%d", nRF);
1281//      db.Query(&db, "delete from cvct where rf=%d", nRF);
1282//      db.Query(&db, "delete from cvct_sub where rf=%d", nRF);
1283//      db.Query(&db, "delete from channel_db where rf=%d", nRF);
1284//      db.Query(&db, "delete from channel_updn where rf=%d", nRF);
1285//      DeleteCDB(&db);
1286}
1287
1288#if 0
1289____CHANNEL_TASK___()
1290#endif
1291
1292static int gMsgQ = 0;
1293static int gSIMsgQ = 0;
1294
1295typedef struct  {
1296        DS_U8   Cmd;
1297        DHL_MODULATION_MODE demod;
1298        DS_U8 RF;
1299        DS_U16 program_number;
1300} CT_Msg;
1301
1302#define CMD_NULL               0
1303#define CMD_TUNE               1
1304#define CMD_SCAN                2
1305#define CMD_RF_UPDATE 3
1306#define CMD_CVT              4
1307#define CMD_OTC             5
1308#define CMD_OTC_STOP   6
1309#define CMD_STOP               7
1310#define CMD_CLOSE              8
1311
1312char* CT_GetMsgName(DS_U8 Cmd)
1313{
1314        static char strText[32];
1315        sprintf(strText, "Unknown");
1316        switch (Cmd)
1317        {
1318                case CT_RECEIVE_PAT:sprintf(strText, "CT_RECEIVE_PAT"); break;
1319                case CT_RECEIVE_PMT:sprintf(strText, "CT_RECEIVE_PMT"); break;
1320#if EPG_SUPPORT
1321                case CT_RECEIVE_MGT:sprintf(strText, "CT_RECEIVE_MGT"); break;
1322#endif
1323                case CT_CHMAP_UPDATE:sprintf(strText, "CT_CHMAP_UPDATE"); break;
1324                case CT_SIGNAL_INFO:sprintf(strText, "CT_SIGNAL_INFO"); break;
1325                case CT_AV_START:sprintf(strText, "CT_AV_START"); break;
1326                case CT_SCAN_PSIP_WAIT:sprintf(strText, "CT_SCAN_PSIP_WAIT"); break;
1327                case CT_SCAN_LOCK_WAIT:sprintf(strText, "CT_SCAN_LOCK_WAIT"); break;
1328                case CT_TUNE_START:sprintf(strText, "CT_TUNE_START"); break;
1329                case CT_SCAN_START:sprintf(strText, "CT_SCAN_START"); break;
1330                case CT_STOPPED:sprintf(strText, "CT_STOPPED"); break;
1331                case CT_RECEIVE_PMT_CC:sprintf(strText, "CT_RECEIVE_PMT_CC"); break;
1332                case CT_RECEIVE_PMT_AUDIO:sprintf(strText, "CT_RECEIVE_PMT_AUDIO"); break;
1333        }
1334        return strText;
1335}
1336
1337static jst_callback g_callback = 0;
1338
1339static 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*/)
1340{
1341        ////if (0) DST_Printf("Cmd = %s(%d) %d %d %d\n", CT_GetMsgName(Cmd), Cmd, p1, p2, p3);
1342        if (g_callback) g_callback(Cmd, p1, p2, p3, p4, p5, p6);
1343}
1344
1345static void DST_FreeAtscTable(void *tablePtrPtr)
1346{
1347        if (tablePtrPtr == NULL || *(void **) tablePtrPtr == NULL) return;
1348        DHL_PSI_FreeMpegSection(*(void **) tablePtrPtr);
1349        *(void **) tablePtrPtr = NULL;
1350}
1351
1352typedef struct  {
1353        DS_U32 RF;
1354        DHL_MODULATION_MODE demod;
1355        DS_U32 nRequestID;
1356        DS_U32 *SI;
1357        DS_U32 CRC32;
1358} CT_SI_Msg;
1359
1360typedef struct 
1361{
1362        DS_U16 pid;
1363        DS_U8  type;
1364        bool bKorean;
1365        bool bVI;
1366} MTS;
1367
1368static int CT_DB_GetAudioPidSub(MTS *mts, int mts_count)
1369{
1370//      for (int i = 0; i < mts_count; i++)
1371//      {
1372//              if (0) DST_Printf("mts[%d].bVI = %d mts[%d].bKorean = %d\n", i, mts[i].bVI, i, mts[i].bKorean);
1373//      }
1374        int i;
1375        // È­¸éÇØ¼³¹æ¼Û + Çѱ¹¾î
1376        if (DST_EEPROM_GetVI() == 1 && DST_EEPROM_GetAudioPref() == 0) // È­¸éÇØ¼³¹æ¼Û
1377        {
1378                // È­¸éÇØ¼³¹æ¼ÛÀ̸鼭 Çѱ¹¾î
1379                for ( i = 0; i < mts_count; i++) if (mts[i].bVI == true && mts[i].bKorean == true) return i;
1380                // ù¹øÂ° Çѱ¹¾î
1381                for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == true) return i;
1382                // ù¹øÀç Æ®·¢
1383                return 0;
1384        }
1385        // È­¸éÇØ¼³¹æ¼Û + ¿Ü±¹¾î
1386        if (DST_EEPROM_GetVI() == 1 && DST_EEPROM_GetAudioPref() == 1) // È­¸éÇØ¼³¹æ¼Û
1387        {
1388                // È­¸éÇØ¼³¹æ¼ÛÀ̸鼭 ¿Ü±¹¾î
1389                for ( i = 0; i < mts_count; i++) if (mts[i].bVI == true && mts[i].bKorean == false) return i;
1390                // ù¹øÂ° ¿Ü±¹¾î
1391                for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == false) return i;
1392                // µÎ¹øÀç Æ®·¢
1393                return 1;
1394        }
1395        // È­¸éÇØ¼³ ¹æ¼Û(x) + Çѱ¹¾î
1396        if (DST_EEPROM_GetAudioPref() == 0) // È­¸éÇØ¼³¹æ¼Û
1397        {
1398                // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ Çѱ¹¾î
1399                for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == true) return i;
1400                // ù¹øÂ° Çѱ¹¾î
1401                for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == true) return i;
1402                // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ ¿Ü±¹¾î
1403                for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == false) return i;
1404                // ù¹øÀç Æ®·¢
1405                return 0;
1406        }
1407        // È­¸éÇØ¼³ ¹æ¼Û(x) + ¿Ü±¹¾î
1408        // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ ¿Ü±¹¾î
1409        for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == false) return i;
1410        // ù¹øÂ° ¿Ü±¹¾î
1411        for ( i = 0; i < mts_count; i++) if (mts[i].bKorean == false) return i;
1412        // È­¸éÇØ¼³¹æ¼Û¾Æ´Ï¸é¼­ Çѱ¹¾î
1413        for ( i = 0; i < mts_count; i++) if (mts[i].bVI == false && mts[i].bKorean == true) return i;
1414        // µÎ¹øÀç Æ®·¢
1415        return 1;
1416}
1417
1418// ÀÔ·ÂµÈ ¹®ÀÚ¿­ÀÌ "kor"ÀÎÁö °Ë»çÇÑ´Ù.
1419// -1 unknown 0: ¿Ü±¹¾î 1: Çѱ¹¾î
1420static int isKOR(char* strText)
1421{
1422        if (strText == 0) return -1;
1423        int nLen = strlen(strText);
1424        if (nLen != 3) return -1;
1425        int i;
1426        for ( i= 0; i < nLen; i++) if (strText[i] >='A' && strText[i] <= 'Z') strText[i] -= ('A'-'a'); // tolower
1427        return (strcmp(strText, "kor") == 0) ? 1 : 0;
1428}
1429
1430
1431int CT_GetAudioCount(DS_U8 RF, DS_U16 program_number)
1432{
1433        int pmt_audio_count = 0;
1434        int i;
1435        DBLock(true);
1436        for ( i = 0; i < MAX_PMT_AUDIO_TABLE_COUNT; i++)
1437        {
1438                if (pmt_audio_table[i].program_number == 0) continue;
1439                if (pmt_audio_table[i].rf == (int)RF && pmt_audio_table[i].program_number == program_number)
1440                        pmt_audio_count++;
1441        }
1442        DBLock(false);
1443        return pmt_audio_count;
1444}
1445
1446static bool g_ReceivePMTAudio = false;
1447void CT_DB_GetAudioPid(DS_U8 RF, DS_U16 program_number, DS_U16* pid, DS_U8* type)
1448{
1449        static DS_U32 old_RF = 0;
1450        static DS_U16 old_program_number = 0;
1451        static DS_U16 old_pid = 0;
1452        static DS_U8 old_type = 0;
1453        if (program_number == 0) return;
1454        DBLock(true);
1455        if (g_ReceivePMTAudio == true || DST_g_AudioSettingChanged == true || old_RF != RF || old_program_number != program_number)
1456        {
1457                DST_g_AudioSettingChanged = false;
1458               
1459                int pmt_audio_count = 0;
1460                typedef struct 
1461                {
1462                        int pid;
1463                        int type;
1464                } PMT_AUDIO;
1465                PMT_AUDIO pmt_audio[32];
1466                memset(pmt_audio, 0, sizeof(pmt_audio));
1467                int i;
1468                for ( i = 0; i < MAX_PMT_AUDIO_TABLE_COUNT; i++)
1469                {
1470                        if (pmt_audio_table[i].program_number == 0) continue;
1471                        if (pmt_audio_table[i].rf == (int)RF && pmt_audio_table[i].program_number == program_number)
1472                        {
1473                                pmt_audio[pmt_audio_count].pid = pmt_audio_table[i].pid;
1474                                pmt_audio[pmt_audio_count].type = pmt_audio_table[i].type;
1475                                pmt_audio_count++;
1476                        }
1477                        if (pmt_audio_count == 32) break;
1478                }
1479                if (pmt_audio_count < 1)
1480                {
1481                        *pid = 0; *type = 0;
1482                }
1483                else
1484                {
1485                        if (pmt_audio_count == 1)
1486                        {
1487                                *pid = pmt_audio[0].pid;
1488                                *type = pmt_audio[0].type;
1489                        }
1490                        else
1491                        {
1492                                int mts_count = pmt_audio_count;
1493                                MTS *mts = (MTS*)DST_OS_Malloc(sizeof(MTS)*mts_count);
1494                                int i;
1495                                for ( i = 0; i < mts_count; i++)
1496                                {
1497                                        mts[i].pid = pmt_audio[i].pid;
1498                                        mts[i].type = pmt_audio[i].type;
1499                                        mts[i].bKorean = true;
1500                                        mts[i].bVI = false;
1501                                        int nKorean[3] = {-1, -1, -1}; // unknown
1502                                        // AC-3 Audio Descriptor °¡ ¿ì¼± ¼øÀ§°¡ ³ô´Ù
1503                                        int j;
1504                                        for ( j = 0; j < MAX_PMT_ISO_TABLE_COUNT; j++)
1505                                        {
1506                                                if (pmt_iso_table[j].rf == (int)RF && pmt_iso_table[j].program_number == program_number && pmt_iso_table[j].pid == mts[i].pid)
1507                                                {
1508                                                DS_U8 audio_type = pmt_iso_table[j].type;
1509                                                mts[i].bVI = (audio_type == 0x03);
1510                                                nKorean[0] = isKOR(pmt_iso_table[j].lang);
1511                                                break;
1512                                        }
1513                                        }
1514                                        for ( j = 0; j < MAX_PMT_AC3_TABLE_COUNT; j++)
1515                                        {
1516                                                if (pmt_ac3_table[j].rf == (int)RF && pmt_ac3_table[j].program_number == program_number && pmt_ac3_table[j].pid == mts[i].pid)
1517                                                {
1518                                                        DS_U8 bsmod = pmt_ac3_table[j].bsmod;
1519                                                        DS_U8 full_svc = pmt_ac3_table[j].full_svc;
1520                                                        DS_U8 langcod = pmt_ac3_table[j].langcod;
1521                                                        mts[i].bVI = (bsmod == 0x02 && full_svc == 0x01);
1522                                                        nKorean[1] = (langcod == 0xFF) ? -1 : (langcod == 0x65) ? 1 : 0;
1523                                                        nKorean[2] = isKOR(pmt_ac3_table[j].language);
1524                                                        break;
1525                                                }
1526                                        }
1527//                                      if (0) DST_Printf("nKorean[0] = %d nKorean[1] = %d nKorean[2] = %d\n", nKorean[0], nKorean[1], nKorean[2]);
1528                                        if (nKorean[0] == 0 || nKorean[1] == 0 || nKorean[2] == 0) mts[i].bKorean = false; // µÑ ÁßÇϳª ¿Ü±¹¾îÀÎ °æ¿ì ¿Ü±¹¾î
1529                                        if (nKorean[0] == 1 || nKorean[1] == 1 || nKorean[2] == 1) mts[i].bKorean = true; // µÑ Áß Çϳª Çѱ¹¾îÀÎ °æ¿ì Çѱ¹¾î
1530                                        //isoÁ¤º¸  ac3Á¤º¸  °áÁ¤µÈ¾ð¾î
1531                                        //¾Ë¼ö¾øÀ½ ¾Ë¼ö¾øÀ½ Çѱ¹¾î
1532                                        //¾Ë¼ö¾øÀ½ ¿Ü±¹¾î   ¿Ü±¹¾î
1533                                        //¾Ë¼ö¾øÀ½ Çѱ¹¾î   Çѱ¹¾î
1534                                        //¿Ü±¹¾î   ¾Ë¼ö¾øÀ½ ¿Ü±¹¾î
1535                                        //¿Ü±¹¾î   ¿Ü±¹¾î   ¿Ü±¹¾î
1536                                        //¿Ü±¹¾î   Çѱ¹¾î   Çѱ¹¾î
1537                                        //Çѱ¹¾î   ¾Ë¼ö¾øÀ½ Çѱ¹¾î
1538                                        //Çѱ¹¾î   ¿Ü±¹¾î   Çѱ¹¾î
1539                                        //Çѱ¹¾î         Çѱ¹¾î   Çѱ¹¾î
1540                                }
1541                                int nPos = CT_DB_GetAudioPidSub(mts, mts_count);
1542                                *pid =  mts[nPos].pid;
1543                                *type = mts[nPos].type;
1544                                DST_OS_Free(&mts);                             
1545                        }
1546                }
1547                g_ReceivePMTAudio = false;
1548                old_RF = RF;
1549                old_program_number = program_number;
1550                old_pid = *pid;
1551                old_type = *type;
1552        }
1553        else
1554        {
1555                *pid = old_pid; *type = old_type;
1556        }
1557        DBLock(false);
1558}
1559
1560//static void CT_DB_GetCCPid(DS_U8 RF, DS_U16 sID,DS_U16 pid[8])
1561//{
1562//      CDB db;
1563//      db.GetTable("select pid from pmt_cc where rf=%d and program_number=%d", RF, sID);
1564//      memset(pid, 0, sizeof(DS_U16)*8);
1565//      for (int i = 0; i < db.GetRow(); i++) pid[i] = dst_atoi(db.GetResult(i+1));
1566//}
1567
1568void CT_DB_GetVideoPid(DS_U8 RF, DS_U16 sID,DS_U16* pcr, DS_U16* pid, DS_U8* type)
1569{
1570        //CDB db; NewCDB(&db);
1571        //db.GetTable(&db, "select pcr_pid, video_pid, video_type from pmt where rf=%d and program_number=%d", RF, sID);
1572        int i;
1573        DBLock(true);
1574        for (i=0; i < DB_PMT_MAX; i++)
1575        {
1576                if (db_pmt[i].program_number == 0) continue;
1577                if (db_pmt[i].rf != RF) continue;
1578                if (db_pmt[i].program_number != sID) continue; 
1579                if (pcr) *pcr = db_pmt[i].pcr_pid;
1580                if (pid) *pid = db_pmt[i].video_pid;
1581                if (type) *type = db_pmt[i].video_type;
1582                DBLock(false);
1583                return;
1584        }
1585        DBLock(false);
1586}
1587
1588#if 0 // Newcon3Kr¿¡¼­ »ç¿ë ¾ÈÇÔ
1589#define MAX_CRC_COUNT 400
1590class CheckCRC32
1591{
1592private:
1593        int nPos;
1594        DS_U32 CRC32[MAX_CRC_COUNT];
1595public:
1596        CheckCRC32()
1597        {
1598                memset(CRC32, 0, sizeof(CRC32));
1599                nPos = 0;
1600        }
1601        void Add(DS_U32 crc32)
1602        {
1603                for (int i = 0; i < MAX_CRC_COUNT; i++) if (CRC32[i] == crc32) return;
1604                CRC32[nPos] =  crc32;
1605                nPos++;
1606                if (nPos >= MAX_CRC_COUNT) nPos = 0;
1607        }
1608        bool IsDuplicate(DS_U32 crc32)
1609        {
1610                for (int i = 0; i < MAX_CRC_COUNT; i++) if (CRC32[i] == crc32) return true;
1611                return false;
1612        }
1613        // CRC LIST¿¡ ¾ø´Â CRC´Â Áö¿î´Ù.
1614        void Clear(DS_U32 *crclist, int nCount)
1615        {
1616                for (int i = 0; i < MAX_CRC_COUNT; i++)
1617                {
1618                        if (CRC32[i] == 0) continue;
1619                        bool bFind = false;
1620                        for (int j=0; j <nCount;j++)
1621                        {
1622                                if (CRC32[i] != crclist[j]) continue;
1623                                bFind = true;
1624                                break;
1625                        }
1626                        if (bFind == false) CRC32[i] = 0;
1627                }
1628        }
1629};
1630
1631static CheckCRC32 check_crc;
1632#endif
1633
1634static DS_U32 CalcCRC(DS_U8* buff)
1635{
1636        DS_U32 len = (((DS_U32)buff[1]&0x0F) << 8) + (DS_U32)buff[2]-1;
1637        return ((DS_U32)buff[len] << 24) + ((DS_U32)buff[len+1] << 16) + ((DS_U32)buff[len+2] << 8) + (DS_U32)buff[len+3];
1638}
1639
1640static void CT_TunePSIP(DS_U8 RF /*= 0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_8VSB*/, 
1641                        DS_U16 program_number /*= 0*/, DS_U16 source_id /*= 0*/, bool bOn /*= false*/)
1642{
1643        static bool bStart = false;
1644
1645        static DHL_HANDLE hTVCT = 0;
1646#if CVCT_SUPPORT
1647        static DHL_HANDLE hCVCT = 0;
1648#endif
1649        static DHL_HANDLE hSTT = 0;
1650#if EPG_SUPPORT
1651        static DHL_HANDLE hMGT = 0;
1652        static DHL_HANDLE hEIT[MAX_EIT_COUNT];
1653        static DHL_HANDLE hETT[MAX_EIT_COUNT];
1654#endif
1655        static DHL_HANDLE hPAT = 0;
1656        static DHL_HANDLE hPMT[MAX_PMT_COUNT];
1657#if EPG_SUPPORT
1658        static DS_U16 eit_pid[MAX_EIT_COUNT];
1659        static DS_U16 ett_pid[MAX_EIT_COUNT];
1660#endif
1661#if EPG_SUPPORT
1662        bool g_bReceiveMGT = false;
1663#endif
1664        static bool bReceivePMT =  false; // PMT¸¦ »¡¸® ¹Þ±â À§ÇØ PMT ¹Þ±â Àü¿¡ ´Ù¸¥ ¸ð´ÏÅ͸µÀº ¸ØÃá´Ù.
1665        if (bOn)
1666        {
1667                if (bStart)
1668                {
1669                        CT_SI_Msg msg;
1670                        DS_U32 retLen = 0;
1671                        while (DST_OS_ReceiveMessage_NoWait(gSIMsgQ, (DS_U32*)&msg, sizeof(CT_SI_Msg), &retLen) == noError)
1672                        {
1673                                if (RF == msg.RF) 
1674                                {
1675                                        if (msg.nRequestID == POS_TVCT)
1676                                        {
1677                                                bool bFind = true;
1678                                                if (CT_ChMapUpdateTVCT(RF, (TVCT*)msg.SI, msg.CRC32)) 
1679                                                {
1680                                                        bFind = false;
1681                                                        CT_ChMapUpdate();
1682                                                        // program_number°¡ ä³Î¸Ê¿¡ ÀÖ´ÂÁö È®ÀÎ
1683                                                        DBLock(true);
1684                                                        int i;
1685                                                        for (i = 0; i < DB_CHANNEL_DB_MAX; i++)
1686                                                        {
1687                                                                if (db_channel_db[i].rf != RF) continue;
1688                                                                if (db_channel_db[i].program_number !=  program_number) continue;
1689                                                                bFind = true;
1690                                                                break;
1691                                                        }
1692                                                        DBLock(false);
1693                                                }
1694                                                CT_CallBack(CT_RECEIVE_TVCT, RF, bFind ? 0 : 1, 0, 0, 0, 0);
1695                                        }
1696#if CVCT_SUPPORT
1697                                        if (msg.nRequestID == POS_CVCT)
1698                                        {
1699                                                if (CT_ChMapUpdateCVCT(RF, (CVCT*)msg.SI, msg.CRC32)) CT_ChMapUpdate();
1700                                                CT_CallBack(CT_RECEIVE_CVCT, RF, 0,0,0,0,0);
1701                                        }
1702#endif
1703#if EPG_SUPPORT
1704                                        if (msg.nRequestID == POS_MGT)
1705                                        {
1706                                                g_bReceiveMGT = true;
1707                                                MGT *mgt = (MGT*)msg.SI;
1708                                                if (0) DST_Printf("mgt->tables_defined = %d\n", mgt->tables_defined);
1709                                                int i;
1710                                                for( i = 0 ; i< mgt->tables_defined ; i++)
1711                                                {
1712                                                        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);
1713                                                        if (mgt->table[i].table_type >= 0x100 && mgt->table[i].table_type <0x100 + MAX_EIT_COUNT)
1714                                                        {
1715                                                                T();
1716                                                                int pos = mgt->table[i].table_type - 0x100;
1717                                                                if (eit_pid[pos] == mgt->table[i].table_type_PID) continue;
1718                                                                eit_pid[pos] = mgt->table[i].table_type_PID;
1719                                                                //DHL_SI_MonitorStop(&hEIT[pos]);
1720                                                                //hEIT[pos] = DHL_SI_MonitorEIT(RF, POS_EIT+pos, eit_pid[pos]);
1721                                                        }
1722                                                        if (mgt->table[i].table_type >= 0x200 && mgt->table[i].table_type <0x200 + MAX_EIT_COUNT)
1723                                                        {
1724                                                                T();
1725                                                                int pos = mgt->table[i].table_type - 0x200;
1726                                                                if (ett_pid[pos] == mgt->table[i].table_type_PID) continue;
1727                                                                ett_pid[pos] = mgt->table[i].table_type_PID;
1728                                                                //DHL_SI_MonitorStop(&hETT[pos]);
1729                                                                //hETT[pos] = DHL_SI_MonitorETT(RF, POS_ETT+pos, ett_pid[pos]);
1730                                                        }
1731                                                }
1732                                                CT_CallBack(CT_RECEIVE_MGT, RF, 0,0,0,0,0);
1733                                        }
1734                                        if (msg.nRequestID >= POS_EIT && msg.nRequestID < POS_EIT+MAX_EIT_COUNT)
1735                                        {
1736                                                EIT *eit = (EIT*)msg.SI;
1737                                                if (eit->source_id == source_id)
1738                                                {
1739                                                        CT_ChMapUpdateEIT(RF, eit, msg.nRequestID - POS_EIT, msg.CRC32);
1740                                                        CT_CallBack(CT_RECEIVE_EIT, RF, 0,0,0,0,0);
1741                                                }
1742                                        }
1743                                        if (msg.nRequestID >= POS_ETT && msg.nRequestID < POS_ETT+MAX_EIT_COUNT)
1744                                        {
1745                                                ETT *ett = (ETT*)msg.SI;
1746                                                if ((ett->ETM_id >> 16) == source_id)
1747                                                {
1748                                                        CT_ChMapUpdateETT(RF, ett, msg.CRC32);
1749                                                        CT_CallBack(CT_RECEIVE_ETT, RF, 0,0,0,0,0);
1750                                                }
1751                                        }
1752#endif
1753                                        if (msg.nRequestID == POS_PAT)
1754                                        {
1755                                                MPEG_PAT *pat = (MPEG_PAT*)msg.SI;
1756                                                CT_ChMapUpdatePAT(RF, pat, msg.CRC32);
1757                                                int nPos = 0;
1758                                                int i;
1759                                                for ( i = 0; i < MAX_PMT_COUNT; i++)
1760                                                {
1761                                                        if (hPMT[i]) DHL_SI_MonitorStop(&hPMT[i]);
1762                                                }
1763                                                for ( i = 0; i < pat->numPrograms; i++)
1764                                                {
1765                                                        if (pat->programs[i].program_map_PID == 0) continue;
1766                                                        if (pat->programs[i].program_map_PID == 0x1FFF) continue;
1767                                                        hPMT[nPos] = DHL_SI_MonitorPMT(RF, POS_PMT+nPos, pat->programs[i].program_map_PID, pat->programs[i].program_number);
1768                                                        nPos++;
1769                                                        if (nPos >= MAX_PMT_COUNT) break;
1770                                                }
1771                                                CT_CallBack(CT_RECEIVE_PAT, RF, 0,0,0,0,0);
1772                                        }
1773                                        if (msg.nRequestID >= POS_PMT && msg.nRequestID < POS_PMT+MAX_PMT_COUNT)
1774                                        {
1775                                                bReceivePMT = true;
1776                                                MPEG_PMT *pmt = (MPEG_PMT*)msg.SI;
1777                                                if (CT_ChMapUpdatePMT(RF, pmt, msg.nRequestID - POS_PMT+1, msg.CRC32))
1778                                                {
1779                                                        CT_ChMapUpdate();
1780                                                }
1781                                                CT_CallBack(CT_RECEIVE_PMT, RF, pmt->program_number, 0,0,0,0);
1782                                                g_ReceivePMTAudio = true;
1783                                                CT_CallBack(CT_RECEIVE_PMT, RF, 0,0,0,0,0);
1784                                        }
1785                                }
1786                                DST_FreeAtscTable(&msg.SI); // ¸Þ¸ð¸® ÇØÁ¦´Â ¿©±â¿¡¼­
1787                        } // while
1788                        { // CC µð½ºÅ©¸³ÅÍ ¸ð´ÏÅ͸µ
1789                                static DS_U32 old_RF = 0;
1790                                static DS_U16 old_program_number = 0;
1791                                if (old_RF != RF || old_program_number != program_number || g_bReceiveCCDescriptor == true)
1792                                {
1793                                        old_RF = RF;
1794                                        old_program_number = program_number;
1795                                        g_bReceiveCCDescriptor = false;
1796                                        bool bFind = false;
1797                                        int i;
1798                                        for ( i=0; i < MAX_PMT_CC_TABLE_COUNT; i++)
1799                                        {
1800                                                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) 
1801                                                {
1802                                                        DST_g_CC_bCCKorean = (strcmp(pmt_cc_table[i].language, "kor") != 0 && strcmp(pmt_cc_table[i].language, "KOR") != 0) ? false : true;
1803                                                        DST_g_CC_bWideScreen = pmt_cc_table[i].wide_aspect_ratio ? true : false;
1804                                                        DST_g_CC_bUnicode = pmt_cc_table[i].korean_code ? true : false;
1805                                                        bFind = true;
1806                                                        break;
1807                                                }
1808                                        }
1809                                        if (bFind == false)
1810                                        {
1811                                                DST_g_CC_bCCKorean = true;
1812                                                DST_g_CC_bWideScreen = true;
1813                                                DST_g_CC_bUnicode = false;
1814                                        }
1815                                }
1816                        }
1817#if EPG_SUPPORT
1818                        { // EIT ETT ¸ð´ÏÅ͸µ
1819                                static DS_U8 old_RF = 0;
1820                                static DS_U16 old_source_id = 0;
1821                                if (old_RF != RF || old_source_id != source_id || g_bReceiveMGT == true)
1822                                {
1823                                        old_RF = RF;
1824                                        old_source_id = source_id;
1825                                        int i;
1826                                        for ( i = 0; i < MAX_EIT_COUNT; i++)
1827                                        {
1828                                                if (hEIT[i]) DHL_SI_MonitorStop(&hEIT[i]);
1829                                                if (hETT[i]) DHL_SI_MonitorStop(&hETT[i]);
1830                                        }
1831                                        for ( i = 0; i < MAX_EIT_COUNT; i++)
1832                                        {
1833                                                if (eit_pid[i]) hEIT[i] = DHL_SI_MonitorEIT(RF, POS_EIT+i, eit_pid[i], source_id);
1834                                                if (ett_pid[i]) hETT[i] = DHL_SI_MonitorETT(RF, POS_ETT+i, ett_pid[i], source_id);
1835                                        }
1836                                }
1837                        }
1838#endif
1839                        if (bReceivePMT) // PMT  ¹ÞÀº ÈÄ ´Ù¸¥ ¸ð´ÏÅ͸µ ½ÃÀÛÇÏÀÚ
1840                        {
1841#if EPG_SUPPORT
1842                                if (hMGT== 0) hMGT = DHL_SI_MonitorMGT(RF, POS_MGT);
1843#endif
1844#if CVCT_SUPPORT
1845                                if (hCVCT== 0) hCVCT = DHL_SI_MonitorCVCT(RF, POS_CVCT);
1846#endif
1847                                if (hSTT == 0) hSTT = DHL_SI_MonitorSTT(RF, POS_STT);
1848                                if (hTVCT == 0) hTVCT = DHL_SI_MonitorTVCT(RF, POS_TVCT);
1849                        }
1850                }
1851                else // bStart == false
1852                {
1853                        CT_TunePSIP(0, DHL_MODULATION_8VSB, 0, 0, false);
1854                        bStart = true;
1855                        hPAT = DHL_SI_MonitorPAT(RF, POS_PAT); // PMT¸¦ »¡¸® ¹Þ±â À§ÇØ ´Ù¸¥ SI´Â ´Ê°Ô ¹Þ´Â´Ù.
1856                }
1857        }
1858        else
1859        {
1860                if (bStart)
1861                {
1862                        DHL_SI_MonitorStop(&hTVCT);
1863//                      DHL_SI_MonitorStop(&hCVCT);
1864                        DHL_SI_MonitorStop(&hSTT);
1865#if EPG_SUPPORT
1866                        DHL_SI_MonitorStop(&hMGT);
1867#endif
1868                        int i;
1869#if EPG_SUPPORT
1870                        for ( i = 0; i < MAX_EIT_COUNT; i++) 
1871                        {
1872                                DHL_SI_MonitorStop(&hEIT[i]);
1873                                eit_pid[i] = 0;
1874                                DHL_SI_MonitorStop(&hETT[i]);
1875                                ett_pid[i] = 0;
1876                        }
1877#endif
1878                        DHL_SI_MonitorStop(&hPAT);
1879                        for ( i = 0; i < MAX_PMT_COUNT; i++) 
1880                        {
1881                                DHL_SI_MonitorStop(&hPMT[i]);
1882                        }
1883                        CT_SI_Msg msg;
1884                        DS_U32 retLen = 0;
1885                        while (DST_OS_ReceiveMessage_NoWait(gSIMsgQ, (DS_U32*)&msg, sizeof(CT_SI_Msg), &retLen) == noError)
1886                        {
1887                                if (0) DST_Printf("Remove msg.nRequestID == %d\n", (int)msg.nRequestID);
1888                                DST_FreeAtscTable(&msg.SI);
1889                        }
1890                        bStart = false;
1891                        bReceivePMT = false;
1892                }
1893        }
1894}
1895
1896static void CT_VideoAudio(DS_U16 pcr /*= 0*/, DS_U16 vpid /*= 0*/, DS_U8 vtype /*= 0*/, DS_U16 apid /*= 0*/, DS_U8 atype /*= 0*/)
1897{
1898        static DS_U16 _pcr  = 0;
1899        static DS_U16 _vpid  = 0;
1900        static DS_U8  _vtype = 0;
1901        static DS_U16 _apid = 0;
1902        static DS_U8  _atype = 0;
1903        if (pcr == _pcr && vpid == _vpid && vtype == _vtype && apid == _apid && atype == _atype) return;
1904        if (vpid != _vpid)
1905        {
1906                if (vpid)
1907                {
1908                        DHL_VIDEO_TYPE VidStreamType = DHL_VIDEO_NONE;
1909                        switch (vtype) // ABNT NBR 15602-3:2007 Table 5 ? Strem_type
1910                        {
1911                                case 0x01: VidStreamType = DHL_VIDEO_MPEG1; break;
1912                                case 0x02: VidStreamType = DHL_VIDEO_MPEG2; break;
1913                                case 0x1B: VidStreamType = DHL_VIDEO_MPEG4; break;
1914                        };
1915                        if (DHL_VID_Start(vpid, pcr, VidStreamType) != 0) return;
1916                        DST_g_LastVideoStartTime = DST_OS_GetTickCount();
1917                        _apid = 0; // ºñµð¿À º¯°æ ½Ã ¿Àµð¿Àµµ ´Ù½Ã ½ÃÀÛÇϱâ À§Çؼ­ ÀÌÀü ¿Àµð¿À »óŸ¦ Áö¿î´Ù.
1918                }
1919                else
1920                {
1921//                      CT_ChannelChangeVideoMute(true);
1922                        DHL_VID_Stop();
1923                        DST_g_LastVideoStartTime = 0;
1924                }
1925        }
1926        if (apid != _apid)
1927        {
1928                if (apid)
1929                {
1930                        DHL_AUDIO_TYPE AudStreamType = DHL_AUDIO_NONE;
1931                       
1932                        switch (atype) // ABNT NBR 15602-3:2007 Table 5 ? Strem_type
1933                        {
1934                                case 0x03: AudStreamType = DHL_AUDIO_MPEG1; break;
1935                                case 0x04: AudStreamType = DHL_AUDIO_MPEG2; break;
1936                                case 0x0F: AudStreamType = DHL_AUDIO_AAC_ADTS; break;
1937                                case 0x11: AudStreamType = DHL_AUDIO_AAC_LATM; break;
1938                                case 0x81: AudStreamType = DHL_AUDIO_AC3; break;
1939                        };
1940                        DHL_AUD_Start(apid, pcr == 0 ? 0x1FFF : pcr, AudStreamType);
1941                        CT_ChannelChangeAudioMute(false);
1942                        DST_g_LastAudioStartTime = DST_OS_GetTickCount();
1943                }
1944                else
1945                {
1946                        CT_ChannelChangeAudioMute(true);
1947                        DHL_AUD_Stop();
1948                        DST_g_LastAudioStartTime = 0;
1949                }       
1950        }
1951        _pcr  = pcr;
1952        _vpid  = vpid;
1953        _vtype = vtype;
1954        _apid = apid;
1955        _atype = atype;
1956}
1957
1958static void CT_AV(DS_U8 RF /*= 0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_8VSB*/, 
1959                        DS_U16 program_number /*= 0*/, DS_U16 source_id /*= 0*/, bool bOn /*= false*/)
1960{
1961        if (bOn)
1962        {
1963                // ½ÅÈ£ Á¤º¸
1964                bool bLock = false;
1965                int ss = 0, power = 0, snr = 0;
1966                DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr);
1967                CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0);
1968       
1969                // ¼Ò½º¾ÆÀ̵𿡠µû¶ó AV¸¦ ½ÃÀÛÇÑ´Ù.
1970                DS_U16 PcrPid = 0;
1971                DS_U16 VideoPid = 0;
1972                DS_U8  VideoType = 0;
1973                DS_U16 AudioPid = 0;
1974                DS_U8  AudioType = 0;
1975                CT_DB_GetVideoPid(RF, program_number, &PcrPid, &VideoPid, &VideoType);
1976               
1977                // if (0) DST_Printf("VideoPid = %d\n", VideoPid);
1978               
1979                CT_DB_GetAudioPid(RF, program_number, &AudioPid, &AudioType);
1980               
1981                 //if (0) DST_Printf("AudioPid = %d\n", AudioPid);
1982               
1983                CT_VideoAudio(PcrPid, VideoPid, VideoType, AudioPid, AudioType);
1984                CT_CallBack(CT_AV_START, RF, program_number,  source_id, 0,0,0);
1985                CT_CallBack(CT_AV_INFO, RF, PcrPid, VideoPid, AudioPid, VideoType, AudioType);         
1986                // CC ¸ð´ÏÅ͸µÀ» ½ÃÀÛÇÑ´Ù.
1987               
1988                // AV »óÅ Á¤º¸ Äݹé
1989                CT_CallBack(CT_SIGNAL, RF, program_number, VideoPid ? DHL_VID_Alive() : 0, AudioPid ? DHL_AUD_Alive() : 0, 0,0);
1990                CT_CallBack(CT_AUDIO_MODE, DHL_AUD_GetMode(),0,0,0,0, 0);
1991                CT_TunePSIP(RF, demod, program_number, source_id, bOn);
1992        }
1993        else
1994        {
1995                CT_TunePSIP(0, DHL_MODULATION_8VSB, 0, 0, false); // PSIP ¸ð´ÏÅ͸µ ÁßÁö
1996                CT_VideoAudio(0,0,0,0,0);
1997        }
1998}
1999
2000static void CT_Tune(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_8VSB*/, 
2001                        DS_U16 program_number/*=0*/, DS_U16 source_id /*= 0*/, bool bOn/*= false*/)
2002{
2003        static bool bStart = false;
2004        static DS_U8 CurrentRF = 0;
2005        static DHL_MODULATION_MODE CurrentDemod = DHL_MODULATION_NULL;
2006        if (bOn)
2007        {
2008                if (bStart == false || CurrentRF != RF || CurrentDemod != demod)
2009                {
2010                        CT_AV(0, DHL_MODULATION_8VSB, 0, 0, false);
2011                        DHL_TUN_Start(RF, demod);
2012                        DST_g_LastTuneTime = DST_OS_GetTickCount();
2013                        CurrentRF = RF;
2014                        CurrentDemod = demod;
2015                        bStart = true;
2016                }
2017                CT_AV(RF, demod, program_number, source_id, bOn);
2018        }
2019        else
2020        {
2021                CT_AV(0, DHL_MODULATION_8VSB, 0,0,false);
2022                if (bStart)
2023                {
2024                        DST_g_LastTuneTime = 0;
2025                        DHL_TUN_Stop();
2026                        bStart = false;
2027                }
2028        }
2029}
2030
2031typedef struct 
2032{
2033        DS_U8  vendor_id[3];
2034        DS_U8  hardware_version_id[4];
2035        DS_U8  software_version_id[4];
2036        DS_U8  so_id[2];
2037        DS_U8  download_type; /* 4bits */
2038        DS_U8  download_command; /* 4bits */
2039        DS_U16 frequency_vector; /* 16bits */
2040        DS_U8  modulation_type;
2041        DS_U16 PID;
2042} AirCodeCVT;
2043
2044static bool DST_SCTESI_ParseAirCodeCVT(DS_U8 *p, AirCodeCVT *cvt)
2045{
2046        if (p == 0 || cvt == 0) return false;
2047        if (p[0] != 0x90) return false; // invalid table
2048        memset(cvt, 0, sizeof(AirCodeCVT));
2049        DS_U8 number_of_descriptor = p[8];
2050        int nPos = 9;
2051        if (0) DST_Printf("number_of_descriptor = %d", number_of_descriptor);
2052        int i;
2053        for ( i = 0; i < number_of_descriptor; i++)
2054        {
2055                DS_U8 tag = p[nPos];
2056                DS_U8 length = p[nPos+1];
2057                if (0) DST_Printf("tag = %d\n", tag);
2058                if (0) DST_Printf("length = %d\n", length);
2059                switch (tag)
2060                {
2061                        case 0: // vendor_id
2062//                              T();
2063                                if (length == 3) memcpy(cvt->vendor_id, &p[nPos+2], length);
2064                                break;
2065                        case 1: // hardware_version_id
2066//                              T();
2067                                if (length == 4) memcpy(cvt->hardware_version_id, &p[nPos+2], length);
2068                                break;
2069                        case 2: // softeware_version_id
2070//                              T();
2071                                if (length == 4) memcpy(cvt->software_version_id, &p[nPos+2], length);
2072                                break;
2073                        case 0x80:
2074//                              T();
2075                                if (length == 2) memcpy(cvt->so_id, &p[nPos+2], length);
2076                                break;
2077                }
2078                nPos = nPos + length + 2;               
2079        }
2080        cvt->download_type = (p[nPos]&0xF0) >> 4;
2081        cvt->download_command = (p[nPos]&0x0F);
2082        cvt->frequency_vector = p[nPos+1]*256 + p[nPos+2];
2083        cvt->modulation_type = p[nPos+3];
2084        cvt->PID = (p[nPos+4]&0x1F)*256 + p[nPos+5];
2085        return true;
2086}
2087
2088static void CT_SI_Proc(DS_U32 RF, DS_U32 nRequestID, DS_U8** buff, DS_U32 nBuffLength)
2089{
2090        if (0) DST_Printf("%s | RF = %d | nRequestID = %d %s\n", __func__, (int)RF, (int)nRequestID, GetSiName(nRequestID));
2091        CT_SI_Msg msg;
2092        msg.RF = RF;
2093        msg.nRequestID = nRequestID;
2094        msg.SI = 0;
2095        msg.CRC32 =  CalcCRC(buff[0]);
2096
2097#if 1
2098        if (msg.CRC32 != DST_CRC32(buff[0], (*(buff[0]+1)&0x0F) * 256 + *(buff[0]+2) - 1)) 
2099        {
2100                DST_Printf("%s|Invalid CRC nRequestID =%d %s\n", __func__, nRequestID, GetSiName(nRequestID));
2101                return;
2102        }
2103#endif
2104
2105        if (nRequestID == POS_TVCT)
2106        {
2107                if (DHL_PSI_ParseTVCT(buff, (TVCT **)&msg.SI)) if (0) DST_Printf("%s|%d|TVCT Parse Error\n", __func__, __LINE__);
2108        }
2109#if CVCT_SUPPORT
2110        if (nRequestID == POS_CVCT)
2111        {
2112                if (DHL_PSI_ParseCVCT(buff, (CVCT **)&msg.SI)) if (0) DST_Printf("%s|%d|CVCT Parse Error\n", __func__, __LINE__);
2113        }
2114#endif
2115        if (nRequestID == POS_STT)
2116        {
2117                DS_U8* p = buff[0];
2118                CT_CallBack(CT_RECEIVE_STT,  RF, p[9] * 0x1000000 + p[10] * 0x10000 + p[11] * 0x100 + p[12] ,  p[13], DST_OS_GetTickCount(), 0,0);
2119        }
2120#if EPG_SUPPORT
2121        if (nRequestID == POS_MGT)
2122        {
2123                if (DHL_PSI_ParseMGTSection(buff[0], (MGT **)&msg.SI)) if (0) DST_Printf("%s|%d|MGT Parse Error\n", __func__, __LINE__);
2124        }
2125        if (nRequestID >= POS_EIT && nRequestID < POS_EIT+MAX_EIT_COUNT)
2126        {
2127                if (DHL_PSI_ParseEIT(buff, (EIT **)&msg.SI)) if (0) DST_Printf("%s|%d|EIT Parse Error\n", __func__, __LINE__);
2128        }
2129        if (nRequestID >= POS_ETT && nRequestID < POS_ETT+MAX_EIT_COUNT)
2130        {
2131                if (DHL_PSI_ParseETTSection(buff[0], (ETT **)&msg.SI)) if (0) DST_Printf("%s|%d|ETT Parse Error\n", __func__, __LINE__);
2132        }
2133#endif
2134        if (nRequestID == POS_PAT)
2135        {
2136                if (DHL_PSI_ParsePAT(buff, (MPEG_PAT **)&msg.SI)) if (0) DST_Printf("%s|%d|PAT Parse Error\n", __func__, __LINE__);
2137        }
2138        if (nRequestID >= POS_PMT && msg.nRequestID < POS_PMT+MAX_PMT_COUNT)
2139        {
2140                if (DHL_PSI_ParsePMT(buff[0], (MPEG_PMT **)&msg.SI)) if (0) DST_Printf("%s|%d|PMT Parse Error\n", __func__, __LINE__); 
2141        }
2142        if (nRequestID == POS_RFUPDATE)
2143        {
2144                CT_CallBack(CT_RECEIVE_RF_UPDATE, RF, (DS_U32)buff[0],0,0,0,0);
2145        }
2146        if (nRequestID == POS_CVT) // CVT
2147        {
2148//              DST_g_ReceiveCVT++;
2149               
2150                // CMB´Â DDBµ¥ÀÌÅÍ¿¡ ¹Ýº¹µÇ´Â CVT ½Ç·Á¿Â´Ù.
2151                // CVT ÆÄÀÏÀ» °ËÃâÇÏ¿© 0x90À¸·Î ½ÃÀÛÇÏ´Â Å×À̺í·Î º¯È¯ÇÑ´Ù.
2152                // CVT°¡ ¿¬¼ÓÇØ¼­ ¿À±â ¶§¹®¿¡ ¼ö½ÅÇÑ CVT´Â ÀúÀåÇÏ¿© µÎ¾î Áߺ¹ 󸮸¦ ¹æÁöÇÑ´Ù.
2153                static DS_U8 received_cvt[300]; 
2154                DS_U8 cvt_new[300];
2155                DS_U8* p = buff[0];
2156                DS_U16 section_length = (p[1] & 0x0F) * 256 + p[2];
2157                bool bFind = false;
2158                int i;
2159                for ( i = 26; i < section_length - 32; i++)  // CVT Å×ÀÌºí ¾ÕÀÇ 26¹ÙÀÌÆ®´Â ´õ¹Ì CVT Å×À̺íÀÇ ÃÖ¼Ò Å©±â´Â 32¹ÙÀÌÆ®
2160                {
2161                        if (p[i] == 0xD9 && p[i+1] == 0x30 && p[i+3] == 0x9F && p[i+4] == 0x9C && p[i+5] == 0x02)
2162                        {
2163                                if (i+p[i+6] > section_length) return; // ÀÔ·ÂµÈ µ¥ÀÌÅͱæÀ̺¸´Ù Å« °æ¿ì ¿¡·¯Ã³¸®
2164                                memset(cvt_new, 0, 300);
2165                                cvt_new[0] = 0x90;
2166                                memcpy(&cvt_new[1], &p[i], p[i+6] + 3);
2167                                if (!memcmp(cvt_new, received_cvt, 300)) return; // ÀÌ¹Ì ¹ÞÀ½
2168                                bFind = true;
2169                                break;
2170                        }
2171                }
2172
2173                if (bFind == false) 
2174                {
2175                        return;
2176                }
2177                static bool bReceiveValidCVT = false;
2178                if (bReceiveValidCVT == true) return;
2179                AirCodeCVT cvt;
2180                memset(&cvt, 0, sizeof(AirCodeCVT));
2181                if (DST_SCTESI_ParseAirCodeCVT(cvt_new, &cvt) == false) return;
2182#if 1
2183                if (1) DST_Printf("============================================\n");
2184                if (1) DST_Printf("Request ID = POS_CVT\n");
2185                if (1) DST_Printf("vendor_id %02X %02X %02X\n", cvt.vendor_id[0], cvt.vendor_id[1], cvt.vendor_id[2]);
2186                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]);
2187                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]);
2188                if (1) DST_Printf("so_id %02X %02X\n", cvt.so_id[0], cvt.so_id[1]);
2189                if (1) DST_Printf("download_type %d\n", cvt.download_type);
2190                if (1) DST_Printf("download_command %d\n", cvt.download_command);
2191                if (1) DST_Printf("frequency_vector %d\n", cvt.frequency_vector);
2192                if (1) DST_Printf("modulation_type %d\n", cvt.modulation_type);
2193                if (1) DST_Printf("PID 0x%X\n", cvt.PID);
2194                if (1) DST_Printf("============================================\n");
2195#endif
2196               
2197                // °¢ ÇÊµå °ªÀÇ À¯È¿¼º °Ë»ç             
2198                if (cvt.vendor_id[0] != 'D') return;
2199                if (cvt.vendor_id[1] != 'S') return;
2200                if (cvt.vendor_id[2] != 'T') return;
2201                if (cvt.hardware_version_id[0] != 'N') return;
2202                if (cvt.hardware_version_id[1] != '3') return;
2203                if (cvt.hardware_version_id[2] != 'K') return;
2204                if (cvt.hardware_version_id[3] != 'R') return;
2205//              if (cvt.so_id[0] != DST_g_SO_ID/256) return;
2206//              if (cvt.so_id[1] != DST_g_SO_ID%256) return;
2207               
2208                // º¥´õ¾ÆÀ̵ð¿Í H/W ¹öÀüÀÌ ÀÏÄ¡ÇÏÁö ¾Ê´Â Á¤º¸°¡ °°Àº PID·Î ¿Ã °¡´É¼º ´ëºñÇÏ¿© ¹é¾÷ À§Ä¡´Â H/W ¹öÀü üũ ÀÌÈÄ·Î
2209                memcpy(received_cvt, cvt_new, 300); // »õ·Î ¹ÞÀº µ¥ÀÌÅ͸¦ ¹é¾÷
2210               
2211                int major = 0, minor = DST_GetAppShortVersionNumber(); 
2212                if (1) DST_Printf("major = %d minor = %d\n", major, minor);
2213                int new_major = cvt.software_version_id[0]*256+cvt.software_version_id[1];
2214                int new_minor = cvt.software_version_id[2]*256+cvt.software_version_id[3];
2215                if (1) DST_Printf("new_major = %d new_minor = %d\n", new_major, new_minor);
2216                if ((major * 0x10000 + minor) >= (new_major * 0x10000 + new_minor))
2217                {
2218                        if (1) DST_Printf("Old or Same version. ignore it.\n");
2219                        return;
2220                }
2221                if (cvt.download_command > 2) 
2222                {
2223                        if (1) DST_Printf("download_command invalid(%d)\n", cvt.download_command);
2224                        return;
2225                }
2226                if (cvt.frequency_vector == 0)
2227                {
2228                        if (1) DST_Printf("frequency_vector invalid(%d)\n", cvt.frequency_vector);
2229                        return;
2230                }
2231                if (cvt.modulation_type < 1 || cvt.modulation_type > 2)
2232                {
2233                        if (1) DST_Printf("modulation_type invalid(%d)\n", cvt.modulation_type);
2234                         return;
2235                }
2236                if (cvt.PID == 0) 
2237                {
2238                        if (1) DST_Printf("PID invalid(%d)\n", cvt.PID);
2239                        return;
2240                }
2241                bReceiveValidCVT = true;
2242#if 1
2243                switch (cvt.download_command)
2244                {
2245                        case 0: if (1) DST_Printf("Download Now\n"); break;
2246                        case 1: if (1) DST_Printf("Deferred Download\n"); break;
2247                        case 2: if (1) DST_Printf("No Exception\n"); break;
2248                }
2249                if (1) DST_Printf("OTC RF = %dHz\n", cvt.frequency_vector * 250000);
2250                switch (cvt.modulation_type)
2251                {
2252                        case 1: if (1) DST_Printf("64QAM\n"); break;
2253                        case 2: if (1) DST_Printf("256QAM\n"); break;
2254                }
2255#endif
2256                SWinEventMsg event;
2257                memset(&event, 0, sizeof(SWinEventMsg));
2258                event.cmd = WM_CVT;
2259                memcpy(&event.data[0], &cvt.software_version_id[0], 16);
2260                event.data32[4] = cvt.download_command;
2261                event.data32[5] = cvt.modulation_type;
2262                event.data32[6] = cvt.frequency_vector * 250000;
2263                event.data32[7] = cvt.PID;
2264                DST_SendWindowEvent(event);
2265#ifdef DSTAR
2266                DST_g_OTC_Modulation_type = (event.data32[5]==1)?(DHL_MODULATION_64QAM):(DHL_MODULATION_256QAM);
2267                DST_g_OTC_RF = event.data32[6];
2268                DST_g_OTC_PID = event.data32[7];
2269//              DST_OTC_Start();
2270#endif
2271        }
2272        if (nRequestID == POS_OTC_DII) // OTC_DII
2273        {
2274                if (1) DST_Printf("################## Request ID = POS_OTC_DII\n");
2275                 // DST_OTC_ParseDsmcc(buff[0]);
2276                DS_U8 *p = buff[0];
2277                if (p[0] != 0x4B) return; // TABLE ID
2278                DS_U16 section_length = ((p[1]&0x0F) * 0x100) + p[2];
2279                if (section_length < 48) return; // SECTION TOO SHORT
2280                if (p[10] != 0x10 || p[11] != 0x02) return; // DSMCC_DM_MSG_DII 0x1002
2281                DS_U8 adaptationLength = p[17];
2282                if (section_length < 48 + adaptationLength) return; // SECTION TOO SHORT
2283                p += adaptationLength; // adaptationLength ±æÀ̸¸Å­ Æ÷ÀÎÅÍ À̵¿
2284                DS_U16 blockSize = p[24] * 0x100 + p[25];
2285                DS_U32 moduleSz = p[42]* 0x1000000 +    p[43]* 0x10000 + p[44]* 0x100 + p[45];
2286                if (1) DST_Printf("blockSize = %d moduleSz = %d\n", blockSize, (int)moduleSz);
2287                CT_CallBack(CT_OTC_RECEIVE_DII, moduleSz, blockSize,0,0,0,0);
2288        }
2289        if (nRequestID == POS_OTC_DDB) // OTC_DDB
2290        {
2291                //if (0) DST_Printf("############## Request ID = POS_OTC_DDB\n");
2292                //DST_OTC_ParseDsmcc(buff[0]);
2293                DS_U8 *p = buff[0];
2294                if (p[0] != 0x4C) return; // TABLE ID
2295                //DS_U16 section_length = ((p[1]&0x0F) * 0x100) + p[2];
2296                //if (section_length < 48) return; // SECTION TOO SHORT
2297                if (p[10] != 0x10 || p[11] != 0x03) return; // DSMCC_DM_MSG_DDB 0x1003
2298                DS_U8 adaptationLength = p[17];
2299                //if (section_length < 48 + adaptationLength) return; // SECTION TOO SHORT
2300                p += adaptationLength; // adaptationLength ±æÀ̸¸Å­ Æ÷ÀÎÅÍ À̵¿
2301                DS_U16 blockSize = p[18] * 0x100 + p[19];
2302                DS_U16 blockNumber = p[24]* 0x100 + p[25];
2303                //if (0) DST_Printf("blockSize = %d blockNumber = %d\n", blockSize-6, blockNumber);
2304                CT_CallBack(CT_OTC_RECEIVE_DDB, blockNumber, (DS_U32)&p[26], blockSize-6,0,0,0);
2305        }
2306        if (msg.SI) DST_OS_SendMessage(gSIMsgQ, (DS_U32 *)&msg, sizeof(CT_SI_Msg));
2307}
2308
2309
2310// ÇÑ RF¿¡ ´ëÇÑ ¿ÀÅ佺ĵÀÌ ³¡³ª°í ³ª¼­ ´ÙÀ½ ä³Î·Î °¥¶§ ÇöÀç RF¿¡¼­ SI¸¦ ¹Þ¾Ò´ÂÁö ¿©ºÎ¸¦ ÆÇ´ÜÇØ¼­
2311// ä³Î¸ÊÀ» Áö¿ö¾ß ÇÑ´Ù.
2312static bool g_bRemovedOldChannel = false; // PAT/CVCT/TVCT Áß Çϳª¸¦ ¹ÞÀ¸¸é ÀÌÀü ä³ÎÀ» Áö¿î´Ù.
2313bool CT_ScanFindChannel()
2314{
2315        return g_bRemovedOldChannel;
2316}
2317
2318static void CT_ScanPSIP(DS_U8 RF/*=0*/, bool bOn/*=false*/)
2319{
2320        static bool bStart = false;
2321        static DS_U32 startTick = 0;
2322        static DHL_HANDLE hTVCT = 0;
2323#if CVCT_SUPPORT
2324        static DHL_HANDLE hCVCT = 0;
2325#endif
2326        static DHL_HANDLE hPAT = 0;
2327        static DHL_HANDLE hPMT[MAX_PMT_COUNT];
2328        static int remain_pmt_count = 0;
2329       
2330       
2331        if (bOn)
2332        {
2333                if (bStart)
2334                {
2335                        CT_SI_Msg msg;
2336                        DS_U32 retLen = 0;
2337                        while (DST_OS_ReceiveMessage_NoWait(gSIMsgQ, (DS_U32*)&msg, sizeof(CT_SI_Msg), &retLen) == noError)
2338                        {
2339                                if (RF == msg.RF) 
2340                                {
2341                                         // PAT/CVCT/TVCT Áß Çϳª¸¦ ¹ÞÀ¸¸é ÀÌÀü ä³ÎÀ» Áö¿î´Ù.
2342                                        if (msg.nRequestID == POS_TVCT ||
2343#if CVCT_SUPPORT
2344                                                msg.nRequestID == POS_CVCT || 
2345#endif
2346                                                msg.nRequestID == POS_PAT)
2347                                        {
2348                                                if (g_bRemovedOldChannel == false)
2349                                                {
2350                                                        // JST_DB_Del(RF);
2351                                                        g_bRemovedOldChannel = true;
2352                                                }
2353                                        }
2354                                        if (msg.nRequestID == POS_TVCT)
2355                                        {
2356                                                TVCT *tvct = (TVCT*)msg.SI;
2357                                                if (CT_ChMapUpdateTVCT(RF, tvct, msg.CRC32))
2358                                                {
2359                                                        CT_ChMapUpdate();
2360                                                }
2361                                                CT_CallBack(CT_SCAN_RECEIVE_TVCT, msg.RF, (DS_U32)tvct,0,0,0,0);
2362                                        }
2363#if CVCT_SUPPORT
2364                                        if (msg.nRequestID == POS_CVCT)
2365                                        {
2366                                                CVCT *cvct = (CVCT*)msg.SI;
2367                                                if (CT_ChMapUpdateCVCT(RF, cvct, msg.CRC32))
2368                                                {
2369                                                        CT_ChMapUpdate();
2370                                                }
2371                                                CT_CallBack(CT_SCAN_RECEIVE_CVCT, msg.RF, (DS_U32)cvct,0,0,0,0);
2372                                        }
2373#endif
2374                                        if (msg.nRequestID == POS_PAT)
2375                                        {
2376                                                MPEG_PAT *pat = (MPEG_PAT*)msg.SI;
2377                                                if (CT_ChMapUpdatePAT(RF, pat, msg.CRC32)) // PAT°¡ °»½ÅµÇ¾ú´Ù
2378                                                {
2379                                                        // VCT°¡ ÀÖ´ø ä³Î¿¡¼­ VCT°¡ ¾ø´Â ä³Î·Î ½ºÆ®¸²ÀÌ º¯°æµÈ °æ¿ì ¹Ý¿µÇϱâ À§ÇÑ ÄÚµå
2380                                                        // VCT°¡ ¾ø´Â ä³ÎÀϼö ÀÖÀ¸´Ï VCT Á¤º¸¸¦ Áö¿ì°í »õ·Î ¹Þ¾Æº»´Ù.
2381                                                        DHL_SI_MonitorStop(&hTVCT);
2382//                                                      DHL_SI_MonitorStop(&hCVCT);
2383                                                        // VCT Á¤º¸¸¦ Á¦°ÅÇÑ´Ù
2384                                                        {
2385        //                                                      CDB db; NewCDB(&db);
2386        //                                                      db.Query(&db, "delete from tvct where rf = %d", RF);
2387        //                                                      db.Query(&db, "delete from tvct_sub where rf = %d", RF);
2388        //                                                      db.Query(&db, "delete from cvct where rf = %d", RF);
2389        //                                                      db.Query(&db, "delete from cvct_sub where rf = %d", RF);
2390        //                                                      DeleteCDB(&db);
2391                                                                int i;
2392                                                                DBLock(true);
2393                                                                for (i =0 ; i < DB_TVCT_MAX; i++)
2394                                                                {
2395                                                                        if (db_tvct[i].rf != RF) continue;
2396                                                                        memset(&db_tvct[i], 0, sizeof(_DB_TVCT_));
2397                                                                }
2398                                                                for (i =0 ; i < DB_TVCT_SUB_MAX; i++)
2399                                                                {
2400                                                                        if (db_tvct_sub[i].rf != RF) continue;
2401                                                                        memset(&db_tvct_sub[i], 0, sizeof(_DB_TVCT_SUB_));
2402                                                                }
2403#if CVCT_SUPPORT
2404                                                                for (i =0 ; i < DB_CVCT_MAX; i++)
2405                                                                {
2406                                                                        if (db_cvct[i].rf != RF) continue;
2407                                                                        memset(&db_cvct[i], 0, sizeof(_DB_CVCT_));
2408                                                                }
2409                                                                for (i =0 ; i < DB_CVCT_SUB_MAX; i++)
2410                                                                {
2411                                                                        if (db_cvct_sub[i].rf != RF) continue;
2412                                                                        memset(&db_cvct_sub[i], 0, sizeof(_DB_CVCT_SUB_));
2413                                                                }
2414#endif
2415                                                                DBLock(false);
2416                                                                CT_ChMapUpdate();
2417                                                        }
2418                                                        // VCT ¸ð´ÏÅ͸µ Àç½ÃÀÛ
2419                                                        hTVCT = DHL_SI_MonitorTVCT(RF, POS_TVCT);
2420#if CVCT_SUPPORT
2421                                                        hCVCT = DHL_SI_MonitorCVCT(RF, POS_CVCT);
2422#endif
2423                                                }
2424                                                int nPos = 0;
2425                                                int i;
2426                                                for ( i = 0; i < MAX_PMT_COUNT; i++)
2427                                                {
2428                                                        if (hPMT[i]) DHL_SI_MonitorStop(&hPMT[i]);
2429                                                }
2430                                                for ( i = 0; i < pat->numPrograms; i++)
2431                                                {
2432                                                        if (pat->programs[i].program_map_PID == 0) continue;
2433                                                        if (pat->programs[i].program_map_PID == 0x1FFF) continue;
2434                                                        hPMT[nPos] = DHL_SI_MonitorPMT(RF, POS_PMT+nPos, pat->programs[i].program_map_PID, pat->programs[i].program_number);
2435                                                        nPos++;
2436                                                        if (nPos >= MAX_PMT_COUNT) break;
2437                                                }
2438                                                remain_pmt_count = nPos;
2439                                        }
2440                                        if (msg.nRequestID >= POS_PMT && msg.nRequestID < POS_PMT+MAX_PMT_COUNT)
2441                                        {
2442                                                MPEG_PMT *pmt = (MPEG_PMT*)msg.SI;
2443                                                if (CT_ChMapUpdatePMT(RF, pmt, msg.nRequestID-POS_PMT+1, msg.CRC32))
2444                                                {
2445                                                        CT_ChMapUpdate();
2446                                                }
2447                                                remain_pmt_count--;
2448                                                CT_CallBack(CT_SCAN_RECEIVE_PMT, RF, pmt->program_number, remain_pmt_count,0,0,0);
2449                                                if (0) DST_Printf("remain_pmt_count = %d\n", remain_pmt_count);
2450                                        }
2451                                }
2452                                DST_FreeAtscTable(&msg.SI); // ¸Þ¸ð¸® ÇØÁ¦´Â ¿©±â¿¡¼­
2453                        } // while
2454                        if (startTick > DST_OS_GetTickCount()) startTick =  DST_OS_GetTickCount();
2455                        CT_CallBack(CT_SCAN_PSIP_WAIT, RF, (DST_OS_GetTickCount() - startTick) * 1000/DST_OS_GetTicksPerSecond(),0,0,0,0); // PSIP ¸ðµðÅ͸µ ½ÃÀÛ ÈÄ ¸î msÀÌ Áö³µ´ÂÁö
2456                }
2457                else // bStart == false
2458                {
2459                        T();
2460                        CT_ScanPSIP(0, false);
2461                        bStart = true;
2462                        g_bRemovedOldChannel = false; 
2463                        startTick = DST_OS_GetTickCount();
2464                        hTVCT = DHL_SI_MonitorTVCT(RF, POS_TVCT);
2465#if CVCT_SUPPORT
2466                        hCVCT = DHL_SI_MonitorCVCT(RF, POS_CVCT);
2467#endif
2468                        // hPAT = DHL_SI_MonitorPAT(RF, POS_PAT);
2469                }
2470        }
2471        else
2472        {
2473                if (bStart)
2474                {
2475                        T();
2476                        DHL_SI_MonitorStop(&hTVCT);
2477//                      DHL_SI_MonitorStop(&hCVCT);
2478                        DHL_SI_MonitorStop(&hPAT);
2479                        int i;
2480                        for ( i = 0; i < MAX_PMT_COUNT; i++) 
2481                        {
2482                                DHL_SI_MonitorStop(&hPMT[i]);
2483                        }
2484                        bStart = false;
2485                        g_bRemovedOldChannel = false; 
2486                        startTick = 0;
2487                        CT_SI_Msg msg;
2488                        DS_U32 retLen = 0;
2489                        while (DST_OS_ReceiveMessage_NoWait(gSIMsgQ, (DS_U32*)&msg, sizeof(CT_SI_Msg), &retLen) == noError)
2490                        {
2491                                if (0) DST_Printf("Remove msg.nRequestID == %d\n", (int)msg.nRequestID);
2492                                DST_FreeAtscTable(&msg.SI);
2493                        }
2494                }
2495        }
2496}
2497
2498static void CT_Scan(DS_U8 RF/*=0*/, bool bOn/*=false*/)
2499{
2500        static bool bStart = false;
2501        static DS_U8 CurrentRF = 0;
2502        static DS_U32 startTick = 0;
2503        if (bOn)
2504        {
2505                if (bStart == false || CurrentRF != RF)
2506                {
2507                        CT_ScanPSIP(0, false);
2508                        DHL_TUN_Start(RF, DHL_MODULATION_8VSB);
2509                        DST_g_LastTuneTime = DST_OS_GetTickCount();
2510                        CurrentRF = RF;
2511                        //bLock = false;
2512                        bStart = true;
2513                        startTick = DST_OS_GetTickCount();
2514                }
2515                CT_ScanPSIP(RF, bOn);
2516                bool bLock = false;
2517                int ss = 0, power = 0, snr = 0;
2518                DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr);
2519                if (startTick > DST_OS_GetTickCount()) startTick = DST_OS_GetTickCount();
2520                CT_CallBack(CT_SCAN_LOCK_WAIT, RF, (DST_OS_GetTickCount() - startTick) * 1000/DST_OS_GetTicksPerSecond() , ss, power,0,0);
2521        }
2522        else
2523        {
2524                CT_ScanPSIP(0, false); // SCAN PSIP ¸ð´ÏÅ͸µ Ãë¼Ò
2525                if (bStart)
2526                {
2527                        DST_g_LastTuneTime = 0;
2528                        DHL_TUN_Stop();
2529                        bStart = false;
2530                        CurrentRF = 0;
2531                        startTick = 0;
2532                        //bLock = false;
2533                }
2534        }
2535}
2536
2537static void CT_RF_Update(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_256QAM*/,  bool bOn /*=false*/)
2538{
2539        static bool bStart = false;
2540        static DHL_HANDLE hRfUpdate = 0;
2541        if (bOn)
2542        {
2543                if (bStart == false)
2544                {
2545                        DHL_TUN_Start(RF, demod);
2546                        hRfUpdate = DHL_SI_MonitorRFUpdate(RF,  POS_RFUPDATE);
2547                        bStart = true;
2548                }
2549                else
2550                {
2551                        // ½ÅÈ£ Á¤º¸
2552                        bool bLock = false;
2553                        int ss = 0, power = 0, snr = 0;
2554                        DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr);
2555                        CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0);
2556                }
2557        }
2558        else
2559        {
2560                if (bStart == true)
2561                {
2562                        DHL_SI_MonitorStop(&hRfUpdate);
2563                        DHL_TUN_Stop();
2564                        bStart = false;
2565                }
2566        }
2567}
2568
2569// CMB OTC ¸¦ À§ÇØ ¸ÕÀú CVT¸¸ È®ÀÎÇÑ´Ù.
2570static void CT_CVT(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_256QAM*/,  bool bOn/*=false*/)
2571{
2572        static bool bStart = false;
2573        static DHL_HANDLE hCVT = 0;
2574        if (bOn)
2575        {
2576                if (bStart == false)
2577                {
2578                        DHL_TUN_Start(RF, demod);
2579                        hCVT = DHL_SI_MonitorSCTE_CVT(RF,  POS_CVT);
2580                        bStart = true;
2581                }
2582                else
2583                {
2584                        // ½ÅÈ£ Á¤º¸
2585                        bool bLock = false;
2586                        int ss = 0, power = 0, snr = 0;
2587                        DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr);
2588                        CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0);
2589                }
2590        }
2591        else
2592        {
2593                if (bStart == true)
2594                {
2595                        DHL_SI_MonitorStop(&hCVT);
2596                        DHL_TUN_Stop();
2597                        bStart = false;
2598                }
2599        }
2600}
2601
2602static void CT_OTC(DS_U8 RF/*=0*/, DHL_MODULATION_MODE demod /*= DHL_MODULATION_256QAM*/,  DS_U16 otc_pid /*= 0*/, bool bOn/*=false*/)
2603{
2604        static bool bStart = false;
2605        static DHL_HANDLE hDII = 0;
2606        static DHL_HANDLE hDDB = 0;
2607        if (bOn)
2608        {
2609                if (bStart == false)
2610                {
2611                        DHL_TUN_Start(RF, demod);
2612                        DST_g_LastTuneTime = DST_OS_GetTickCount();
2613                        //CT_CallBack(CT_OTC_START);
2614                        hDII = DHL_SI_MonitorSCTE_DII(RF,  POS_OTC_DII, otc_pid);
2615                        hDDB = DHL_SI_MonitorSCTE_DDB(RF, POS_OTC_DDB, otc_pid);
2616                        bStart = true;
2617                }
2618                else
2619                {
2620                        // ½ÅÈ£ Á¤º¸
2621                        bool bLock = false;
2622                        int ss = 0, power = 0, snr = 0;
2623                        DHL_TUNE_Info(RF, &ss, &bLock, &power, &snr);
2624                        CT_CallBack(CT_SIGNAL_INFO, RF, bLock, ss, power, snr,0);
2625                }
2626        }
2627        else
2628        {
2629                if (bStart == true)
2630                {
2631                        DST_g_LastTuneTime = 0;
2632                        DHL_SI_MonitorStop(&hDII);
2633                        DHL_SI_MonitorStop(&hDDB);
2634                        DHL_TUN_Stop();
2635                        bStart = false;
2636                }
2637        }
2638//      if(DST_OTC_GetStatus() == CD_INBAND_DOWNLOAD)
2639//      {
2640//              if(hDII)
2641//              {
2642//                      DHL_SI_MonitorStop(&hDII);
2643//                      hDII = 0;
2644//              }
2645//              if(hDDB == 0)
2646//              {
2647//                      hDDB = DHL_SI_MonitorSCTE_DDB(RF, POS_OTC_DDB, otc_pid);
2648//              }
2649//      }
2650//      if(DST_OTC_GetStatus() == CD_INBAND_DOWNLOAD_UPDATE)
2651//      {
2652//              if(hDDB)
2653//              {
2654//                      DHL_SI_MonitorStop(&hDDB);
2655//                      hDDB = 0;
2656//              }
2657//      }       
2658}
2659
2660
2661static void CT_VideoFreezeEndProc()
2662{
2663        if (0) DST_Printf("DST_VideoFreezeEndProc\n");
2664        CT_ChannelChangeVideoMute(false);
2665}
2666
2667static void CT_SignalInfoCallBack(int nWidth, int nHeight, int RefreshRate, bool bInterlaced,   DHL_SOURCE_ASEPCT Aspect)
2668{
2669        CT_CallBack(CT_VIDEO_RESOLUTION, nWidth, nHeight, RefreshRate, bInterlaced, Aspect,0);
2670}
2671
2672void DST_708_Callback(DS_U8 *bytearray,int size);
2673void DST_IrCallBack(DS_U32 key, DS_U32 repeat, DS_U32 tick);
2674
2675static bool g_VideoDisplay = true;
2676void JST_POWER_Display(bool bOn)
2677{
2678        g_VideoDisplay = bOn;
2679}
2680
2681static void tChannel(void)
2682{
2683        DHL_SYS_TV_Open(CT_SignalInfoCallBack, CT_VideoFreezeEndProc, 0, 
2684                CT_SI_Proc, DST_708_Callback, DST_IrCallBack);
2685        CT_Msg msg = {CMD_NULL, DHL_MODULATION_8VSB, 0,0};
2686        while (1)
2687        {
2688                DS_U32 retLen;
2689                CT_Msg tmp;
2690                bool bChanged = false;
2691                // ½×¿©ÀÖ´Â ¸ðµç ¸Þ½ÃÁö¸¦ °¡Á®¿Â´Ù.
2692#ifdef DSTAR
2693                DST_OS_Delay(50);
2694#else
2695                DST_OS_Delay(10);
2696#endif
2697                while (DST_OS_ReceiveMessage_NoWait(gMsgQ, (DS_U32*)&tmp, sizeof(CT_Msg), &retLen) == noError)
2698                {
2699                        if (0) DST_Printf("\n\n\n\n\nReceive Cmd = %d RF = %d demod = %d program_number = %d\n\n\n\n\n\n", 
2700                                        tmp.Cmd, tmp.RF, tmp.demod, tmp.program_number);
2701                        if (msg.Cmd != tmp.Cmd || msg.RF != tmp.RF || msg.demod != tmp.demod || msg.program_number != tmp.program_number)
2702                        { 
2703                                msg = tmp;
2704                                bChanged = true;
2705                        }
2706                }
2707                ////if (0) DST_Printf("Current Cmd = %d RF = %d Minor = %d Mode = %d\n", msg.Cmd, msg.RF, msg.Minor, msg.Mode);
2708
2709                static DS_U16 program_number = 0;
2710                static DS_U16 source_id = 0;
2711                if (msg.Cmd == CMD_TUNE)
2712                {
2713                        DBLock(true);
2714                        DS_U16 new_program_number = 0;
2715                        DS_U16 new_source_id = 0;
2716                        if (msg.program_number == 0) // RF Æ©´×ÀÎ °æ¿ì
2717                        {
2718                                int i;
2719                                int min_minor = 10000;
2720                                int min_minor_pos = -1;
2721                                for (i = 0; i < DB_CHANNEL_DB_MAX; i++)
2722                                {
2723                                        if (db_channel_db[i].program_number == 0) continue;
2724                                        if (db_channel_db[i].rf !=      msg.RF) continue;
2725                                        if (min_minor > db_channel_db[i].minor)
2726                                        {
2727                                                        min_minor = db_channel_db[i].minor;
2728                                                        min_minor_pos = i;
2729                                        } 
2730                                }
2731                                if (min_minor_pos >= 0)
2732                                {
2733                                        new_program_number = db_channel_db[min_minor_pos].program_number;
2734                                        new_source_id = db_channel_db[min_minor_pos].source_id;
2735                                }
2736                        }
2737                        else
2738                        {
2739                                int i;
2740                                for (i = 0; i < DB_CHANNEL_DB_MAX; i++)
2741                                {
2742                                        if (db_channel_db[i].program_number == 0) continue;
2743                                        if (db_channel_db[i].program_number != msg.program_number) continue;
2744                                        if (db_channel_db[i].rf !=      msg.RF) continue;
2745                                        new_program_number = db_channel_db[i].program_number;
2746                                        new_source_id = db_channel_db[i].source_id;
2747                                        break;
2748                                }
2749                        }
2750                        if (program_number != new_program_number || source_id != new_source_id)
2751                        {
2752                                program_number = new_program_number;
2753                                source_id = new_source_id;
2754                                bChanged = true;
2755                        }
2756                        DBLock(false);
2757                }
2758                else
2759                {
2760                        program_number = 0;
2761                        source_id = 0;
2762                }
2763
2764                switch (msg.Cmd)
2765                {
2766                        case CMD_NULL:
2767                                break;
2768                        case CMD_TUNE:
2769                                CT_Scan(0, false);
2770                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2771                                CT_RF_Update(0, DHL_MODULATION_256QAM, false);
2772                                CT_CVT(0, DHL_MODULATION_256QAM, false);
2773                                CT_Tune(msg.RF, msg.demod, program_number, source_id, true);
2774                                if (bChanged) CT_CallBack(CT_TUNE_START, msg.RF, program_number, source_id,0,0,0);
2775                                CT_AutoScanMute(false);
2776                                break;
2777                        case CMD_SCAN:
2778                                CT_AutoScanMute(true);
2779                                CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2780                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2781                                CT_RF_Update(0, DHL_MODULATION_256QAM, false);
2782                                CT_CVT(0, DHL_MODULATION_256QAM, false);
2783                                CT_Scan(msg.RF, true);
2784                                if (bChanged) CT_CallBack(CT_SCAN_START, msg.RF,0,0,0,0,0);
2785                                break;
2786                        case CMD_RF_UPDATE:
2787                                CT_AutoScanMute(true);
2788                                CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2789                                CT_Scan(0, false);
2790                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2791                                CT_CVT(0, DHL_MODULATION_256QAM, false);
2792                                CT_RF_Update(msg.RF, msg.demod, true);
2793                                if (bChanged) CT_CallBack(CT_RF_UPDATE_START, msg.RF,0,0,0,0,0);
2794                                break;
2795                       
2796                        case CMD_CVT:
2797                                CT_AutoScanMute(true);
2798                                CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2799                                CT_Scan(0, false);
2800                                CT_RF_Update(0, DHL_MODULATION_256QAM, false);
2801                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2802                                CT_CVT(msg.RF, msg.demod, true);
2803                                if (bChanged) CT_CallBack(CT_CVT_START, msg.RF, msg.program_number,0,0,0,0);
2804                                break;
2805                               
2806                        case CMD_OTC:
2807                                CT_AutoScanMute(true);
2808                                CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2809                                CT_Scan(0, false);
2810                                CT_RF_Update(0, DHL_MODULATION_256QAM, false);
2811                                CT_CVT(0, DHL_MODULATION_256QAM, false);
2812                                CT_OTC(msg.RF, msg.demod, msg.program_number, true);
2813                                if (bChanged) CT_CallBack(CT_OTC_START, msg.RF, msg.program_number,0,0,0,0);
2814                                break;
2815                               
2816                        case CMD_OTC_STOP:
2817                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2818                                break;
2819                               
2820                        case CMD_STOP:
2821                                CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2822                                CT_Scan(0, false);
2823                                CT_OTC(0, DHL_MODULATION_256QAM, 0, false);
2824                                CT_RF_Update(0, DHL_MODULATION_256QAM, false);
2825                                if (bChanged) CT_CallBack(CT_STOPPED,0,0,0,0,0,0);
2826                                break;
2827                }
2828               
2829                DHL_POWER_Display(g_VideoDisplay);
2830                if (msg.Cmd == CMD_CLOSE) break;
2831        }
2832        CT_Tune(0, DHL_MODULATION_8VSB, 0, 0, false);
2833        CT_Scan(0, false);
2834        DHL_SYS_TV_Close();
2835        CT_CallBack(CT_CLOSE, 0, 0, 0, 0,0,0);
2836        DST_OS_DeleteMessageQueue(gMsgQ);
2837        DST_OS_DeleteMessageQueue(gSIMsgQ);
2838        gMsgQ = 0;
2839        gSIMsgQ = 0;
2840//      DST_DB_Close();
2841        g_callback = 0;
2842        DST_OS_SelfDeleteTask();
2843}
2844
2845static void CT_Init()
2846{
2847        static int taskID = 0;
2848        // ŽºÅ©¿Í ¸Þ½ÃÁöÅ¥ »ý¼º
2849        if (taskID == 0)
2850        {
2851                gMsgQ = DST_OS_CreateMessageQueue("qChannelTask", 0, 100, sizeof(CT_Msg));
2852                gSIMsgQ = DST_OS_CreateMessageQueue("qChannelTask", 0, 100, sizeof(CT_SI_Msg));
2853                taskID = DST_OS_SpawnTask((void (*)(void *)) tChannel, (char*)"tChannel", APP_TASK_PRIO_CHANNEL, WIN_MGR_TASK_STACKSIZE, 0);
2854        }
2855}
2856
2857// jstack open
2858void JST_Open(jst_callback callcack)
2859{
2860        g_callback = callcack;
2861        CT_Init();
2862}
2863
2864static void JST_SendMsg(int Cmd /*= CMD_NULL*/, DS_U32 RF /*= 0*/, 
2865                DHL_MODULATION_MODE demod /*= DHL_MODULATION_8VSB*/, DS_U16 program_number /*= 0*/)
2866{
2867        switch (demod)
2868        {
2869                case    DHL_MODULATION_64QAM:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|64QAM|%d\n", __func__, Cmd, RF, program_number);break;
2870                case    DHL_MODULATION_256QAM:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|256QAM|%d\n", __func__, Cmd, RF, program_number);break;
2871                case    DHL_MODULATION_8VSB:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|8VSB|%d\n", __func__, Cmd, RF, program_number);break;
2872                case    DHL_MODULATION_16VSB:if (0) DST_Printf("%s|Cmd = %d|RF=%ld|16VSB|%d\n", __func__, Cmd, RF, program_number);break;
2873                default:
2874                        break;
2875        }
2876        CT_Init();
2877        CT_Msg msg;
2878        msg.Cmd = Cmd;
2879        msg.RF = RF;
2880        msg.demod =  demod;
2881        msg.program_number = program_number;
2882        if (gMsgQ) DST_OS_SendMessage(gMsgQ, (DS_U32 *)&msg, sizeof(CT_Msg));
2883} 
2884
2885// jstack close
2886void JST_Close()
2887{
2888        JST_SendMsg(CMD_CLOSE, 0, DHL_MODULATION_8VSB, 0);
2889}
2890
2891// Channel Task Start
2892void JST_Tune(DS_U8 RF, DHL_MODULATION_MODE demod, DS_U16 program_number)
2893{
2894        JST_SendMsg(CMD_TUNE, RF, demod, program_number);
2895}
2896
2897// Channel Task Start
2898void JST_Scan(DS_U8 RF)
2899{
2900        DST_Printf("JST_Scan %d\n", RF);
2901        JST_SendMsg(CMD_SCAN, RF, DHL_MODULATION_8VSB, 0);
2902}
2903
2904void JST_RFUpdate(DS_U8 RF)
2905{
2906        T();
2907        JST_SendMsg(CMD_RF_UPDATE, RF, DHL_MODULATION_8VSB, 0);
2908}
2909
2910void JST_CVT(DS_U8 RF, DHL_MODULATION_MODE demod)
2911{
2912        JST_SendMsg(CMD_CVT, RF, demod, 0);
2913}
2914
2915void JST_OTC(DS_U8 RF, DHL_MODULATION_MODE demod, DS_U16 otc_pid)
2916{
2917        JST_SendMsg(CMD_OTC, RF, DHL_MODULATION_256QAM, otc_pid);
2918}
2919
2920void JST_OTC_STOP()
2921{
2922        JST_SendMsg(CMD_OTC_STOP, 0, DHL_MODULATION_8VSB, 0);
2923}
2924
2925// Channel Task Stop
2926void JST_Stop(void)
2927{
2928        JST_SendMsg(CMD_STOP, 0, DHL_MODULATION_8VSB, 0);
2929}
Note: See TracBrowser for help on using the repository browser.