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

Last change on this file since 27 was 14, checked in by megakiss, 11 years ago

서경방송 TS 지원을 위한 수정
PID는 8160 1개만 사용하도록
image dii ddb 테이블아이디를 수정 4b 4c

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.