source: svn/newcon3bcm2_21bu/dst/app/src/Function/App_Fnc_ChTune.c

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

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

  • Property svn:executable set to *
File size: 99.5 KB
Line 
1/****************************************************************************
2* NAME: App_Fnc_ChTune.c
3*----------------------------------------------------------------------------
4* Copyright (c) DIGITAL STREAM Technology Inc.
5*----------------------------------------------------------------------------
6* CREATED_BY: Chan Hun Jeon
7* CREATION_DATE: 2009/09/02
8* $Author: chjeon $
9* $Revision: 1.1 $
10* $Date: 2009/07/08 15:08:26 $
11*----------------------------------------------------------------------------
12* PURPOSE:
13*       - Channel tuning API (Chup, Chdown, Major-Minor tune, RF-tune)
14*****************************************************************************/
15
16/*_____ I N C L U D E __________________________________________*/
17
18#include "App_Main.h"
19#include "App_Fnc_Common.h"
20
21// include Fnc
22#include "App_Fnc_ChTune.h"
23#include "App_Fnc_Rating.h"
24#include "App_Fnc_DigitKeyProc.h"
25#include "App_Fnc_EA2.h"
26#include "App_Fnc_CC.h"
27#include "App_Fnc_Video.h"
28#include "App_Fnc_Audio.h"
29#include "App_Fnc_EPG.h"
30#include "App_Fnc_SignalMonitor.h"
31#include "App_Fnc_EA2.h"
32#include "App_Fnc_Ucm.h"
33#include "App_Fnc_Time.h"
34#include "App_Fnc_Power.h"
35#include "App_Fnc_AutoScan.h"
36#include "App_Fnc_Pod.h"
37#include "App_Fnc_Sdds.h"
38
39#include "App_Res_Resources.h"
40
41#include "DMG_Menu.h"
42
43
44
45
46/*_____ D E F I N I T I O N ____________________________________*/
47
48#if COMMENT
49_____DbgPrint_____(){}
50#endif
51
52DHL_MODULE("@f_cht", 0);
53
54
55
56#if COMMENT
57____Config___(){}
58#endif
59
60#define NEO_REGISTER_DEBUG_SYMBOL 0
61
62#define APP_CH_TUNE_POLICY SET_CH_TUNE_POLICY
63
64
65#define STOP_EA_BEFORE_STOP_VIDEO 1
66        // 0À¸·Î ÇØ¾ß ¸Â´Âµ¥
67        // ¾à°£ÀÇ ¹®Á¦°¡ À־ ÀÏ´Ü 1·Î ÇØµÒ.
68
69#define DRAW_SAME_CH_BANNER 1
70        // ch up, ch down ÇÑ °á°ú°¡ ÇöÀç ä³Î°ú µ¿ÀÏÇÒ °æ¿ì banner Ç¥½Ã ¿©ºÎ.
71        // 0 -> 1..
72
73#define USE_EDGE_COLOR_CHAGE 0
74
75
76#define USE_PRESCAN_PID 1
77        // in case of UDCP prescan_pid is not used because of some bugs. below is reasons
78        // arzhna, 100407
79        // udcp demo¿¡¼­´Â prescan pid¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù.
80        // ½Ã°£ÀÌ Á¶±Ý ´õ °É¸®´õ¶óµµ »õ·Î ¹Þµµ·Ï ÇÏÀÚ.
81        /*      cafrii 100409, comment
82        ÇöÀç 3114 DST API¿¡¼­ tuner°¡ ½ÇÁ¦·Î lockÀÌ µÇÁö ¾Ê¾ÒÀ½¿¡µµ
83        tune success·Î reportµÇ´Â ¹®Á¦°¡ ÀÖ´Ù. (¿øÀÎ ºÒ¸í..)
84        prescan pid¸¦ »ç¿ëÇÏ°Ô µÇ¸é AV¸¦ ¹Ù·Î ½ÃÀÛÇϹǷÎ, ÀÌ·± ¹®Á¦°¡ ½±°Ô µå·¯³ªÁö ¾Ê°í
85        ±×³É blank È­¸é°ú °°Àº °á°ú·Î¸¸ ³ª¿Â´Ù.
86        psi, psipÀ» ¸Å¹ø ¹Þµµ·Ï Çϸé download failÀÌ ³ª¿À±â ¶§¹®¿¡
87        ¹º°¡ ¿¹¿Ü 󸮸¦ ÇÒ ¼ö ÀÖ´Â ±âȸ°¡ »ý±ä´Ù.
88        3114 ÂÊ ¼öÁ¤ÀÌ µÇ¸é ÀÌ ºÎºÐÀº ¿ø»ó º¹±ÍÇÏ´Â °ÍÀÌ ÁÁ°ÚÀ½.
89        */
90
91
92#if COMMENT
93____Types____(){}
94#endif
95
96// ÀÌÀü ä³Î Æ©´×À» À§ÇÑ Á¤º¸
97static struct
98{
99        // DRF Æ©´×ÀÎ °æ¿ì..
100        UINT8 nRF;
101        //UINT16 nProgramNumber;
102        // cafrii 060804 delete,
103        //   ÀÌÀü ä³Î Æ©´×¿¡ ´õÀÌ»ó »ç¿ëµÇÁö ¾ÊÀ½.
104       
105        // Uid Æ©´×ÀÎ °æ¿ì..
106        UINT16 nUid;
107
108} g_App_PrevChannel;
109
110
111
112#if COMMENT
113____Variables____(){}
114#endif
115
116// ÇöÀç ½Ãû ÁßÀΠä³ÎÀÇ ¸ðµç Á¤º¸.
117
118
119STATUS g_App_LastTuneResult = statusError;
120static tApp_UcmShortInfo *c_chinfo = NULL;
121
122#if USE_PRESCAN_PID
123BOOL g_App_UsePrescanPidInfo = 1;
124#else
125BOOL g_App_UsePrescanPidInfo = 0;
126#endif
127
128BOOL bPrevCH = FALSE;
129
130static struct
131{
132        UINT8 nChannelType;   // 0: Air, 1: CableSTD
133
134        // Air RF & Pn
135        UINT8 air_rf;
136        UINT32 air_pn;
137       
138        // Cable RF & Pn
139        UINT8 cable_rf;
140        UINT32 cable_fn;
141
142        // Card OOB »óÅ¿¡¼­ÀÇ ¸¶Áö¸· ½Ãû ä³Î
143        UINT8 oob_rf;
144        UINT32 oob_pn;
145
146        BOOL enable_force_aircable;
147        BOOL enable_qam;
148
149        UINT8 ch_sort_mode;
150} p_chtune_nvm_param;
151
152
153
154
155/*_____ F U N C T I O N ________________________________________*/
156
157#if COMMENT
158____Channel_Info___(){}
159#endif
160
161
162
163
164
165
166
167#if COMMENT
168____Sub__API___(){}
169#endif
170
171int FindUIDbyRF(UINT16 nRF)
172{
173        int i = 0;
174        int nReturn = -1;
175       
176        DMW_MSC_LockUcm();
177        if(g_UCM_number)
178        {
179                while(TRUE)
180                {
181                        if(nRF == g_UCM[i].RF)
182                        {       
183                                nReturn = DMW_MSC_Index2Uid(i);
184                                break;
185                        }
186                       
187                        i++;
188                        if(i == g_UCM_number)
189                                break;
190                }
191        }
192        DMW_MSC_UnlockUcm();   
193       
194        return nReturn;
195}
196
197
198// ÇØ´ç Uid ä³ÎÀÌ Hidden ä³ÎÀ̸é TRUE¸¦ ¸®ÅÏ.
199//
200BOOL App_IsHiddenChannel(int nUid)
201{
202        BOOL bHidden = FALSE;
203        int idx;
204       
205        DMW_MSC_LockUcm();
206
207        idx = DMW_MSC_Uid2Index(nUid);
208        if (idx >= 0)
209                bHidden = g_UCM[idx].hidden;
210       
211        DMW_MSC_UnlockUcm();
212       
213        return bHidden;
214}
215
216
217// cafrii 060804 add
218//   runtime ½Ã¿¡ pmt º¯°æ½Ã pidµµ º¯°æµÉ ¼ö Àִµ¥,
219//   ÀÌ ³»¿ëÀ» Áï°¢ DB¿¡ Àû¿ëÇÏ´Â ÄÚµå Ãß°¡.
220static void PmtChangeCallback(int uid, const ProgramAVInfo *av)
221{
222        int index;
223       
224        if (uid <= 0 || av == NULL)
225                return;
226
227        DMW_MSC_LockUcm();     
228
229        index = DMW_MSC_Uid2Index(uid);
230
231        if (index >= 0 && index < g_UCM_number)
232        {
233                if (g_UCM[index].Pcr_pid != av->pcr_pid ||
234                        g_UCM[index].Video_pid != av->video_pid ||
235                        g_UCM[index].Audio_pid != av->audio_pid ||
236                        g_UCM[index].Video_type != av->video_type ||
237                        g_UCM[index].Audio_type != av->audio_type ||
238                        0)
239                {
240                        g_UCM[index].Pcr_pid = av->pcr_pid;
241                        g_UCM[index].Video_pid = av->video_pid;
242                        g_UCM[index].Audio_pid = av->audio_pid;
243                        g_UCM[index].Video_type = av->video_type;
244                        g_UCM[index].Audio_type = av->audio_type;
245
246                //      dprint(0, "    PID/StreamType changed, pva %x %x %x, vtat %x %x. DB update and saved\n",
247                //              av->pcr_pid, av->video_pid, av->audio_pid, av->video_type, av->audio_type);
248
249                        // cafrii 081218 delete
250                        // pid ´Â nvram¿¡ ÀúÀåµÇÁöµµ ¾ÊÀ» »Ó´õ·¯ ±»ÀÌ Áö±Ý ÀúÀåÇÒ Çʿ䵵 ¾ø´Ù.
251                        //App_SaveUcm();
252                }
253                else
254                {
255                        //dprint(0, "    same PID. no update\n");
256                }
257        }
258        else
259                dprint(0, "!! uid %d invalid. index %d resulted\n", uid, index);
260        DMW_MSC_UnlockUcm();
261}
262
263
264// cafrii 060609 add
265static void _ChannelNotificationCallback(UINT32 event, UINT32 param)
266{
267        if (0) ;
268
269#if SUPPORT_POD
270        else if (event == DMC_NOTIFY_CaPmt)
271        {
272                PSIChangeNotifyInfo *pcni = (PSIChangeNotifyInfo *)param;
273       
274                // arzhna, 100129
275                // PMT Change¸¦ POD·Î Àü´Þ
276                // NULL °ªÀÌ µé¾î¿Ã °æ¿ìµµ ±×´ë·Î Àü´ÞÇÑ´Ù.
277               
278                // arzhna, 100406
279                // CARD À¯¹«¿Í »ó°ü¾øÀÌ Ç×»ó PMT¸¦ Àü´ÞÇÑ´Ù.
280                //if(APP_POD_IsPodInserted()){
281                        dprint(0, "\t Report CaPmt\n");         
282                        APP_POD_NotifyPmtChange(pcni->pmt);
283                //}
284        }
285        else if(event == DMC_NOTIFY_IsPodInserted)
286        {
287                PodStatusParam *podInfo = (PodStatusParam*)param;
288
289                if(APP_POD_IsPodInserted())
290                        podInfo->isPodInserted = TRUE;
291                else
292                        podInfo->isPodInserted = FALSE;
293        }
294
295#else
296        else if(event == DMC_NOTIFY_IsPodInserted)
297        {
298                PodStatusParam *podInfo = (PodStatusParam*)param;
299                podInfo->isPodInserted = FALSE;
300        }
301#endif // #if SUPPORT_POD
302       
303        else if (event == DMC_NOTIFY_ScreenAdjustment) 
304        {
305                ScreenAdjustmentParam *sap = (ScreenAdjustmentParam *)param;
306                if (sap)
307                        App_VideoScreenAdjustCallback(sap);
308                       
309                // TODO: After FNC CC Porting
310                //App_CC_Restart();
311               
312                // neverdai 090120 screenÀÌ º¯°æµÈ °æ¿ìµµ CCÀÇ aspect ratio¸¦ º¯°æÇÔ.
313                // cc¸¦ Àç½ÃÀÛÇÏ´Â °ÍÀÌ ÁÁÀ»µí. ¾È±×·¯¸é CC°¡ ¿Àµ¿ÀÛÇÒ ¼ö ÀÖÀ½.
314                dprint(0, "----> APP Notify callback [Screen Ratio]\n");
315                // TODO: After FNC CC Porting
316                //App_CC_SetScreenRatio();
317        }
318        else if (event == DMC_NOTIFY_PMTChanged || event == DMC_NOTIFY_PATChanged) 
319        {
320                PSIChangeNotifyInfo *pcni = (PSIChangeNotifyInfo *)param;
321
322                //dprint(0, "----> APP Notify callback [PSIChanged]\n");
323
324#if 1 //PSI_WO_CHVIEW
325                // cafrii 110331 add, chview°¡ ¾Æ´Ñ »óÅ¿¡¼­ psi event°¡ ¿À¸é ¾Æ·¡ ÄÚµå ÁøÇàÇÏÁö ¾ÊÀ½.
326                // stby »óÅ¿¡¼­ psi load¸¸ ÇÏ´Â °æ¿ì¸¦ À§ÇÔ.
327                if (pcni && pcni->av && pcni->av->active==FALSE) {
328                        dprint(2, "  psi event w/o chview\n");
329                        return;
330                }
331#endif
332
333                // Closed_Caption Notify Function       add 050615      Probability     
334                // PMT¿¡ Á¸Àç ÇÒ °æ¿ì. ¸ÕÀú Àû¿ëÇÑ´Ù.   
335                // ¸¸¾à. epgEventNotifyProgramChange°¡ ºÒ¸±°æ¿ì, EIT Descriptors¿¡µµ ÀÖ´Ù¸é
336                // PMT´Â ¹«½ÃµÇ°í EIT Descriptors°¡ Àû¿ëµÈ´Ù.
337
338                // cafrii 070907 add
339                // TODO: After FNC CC Porting
340                //App_CC_SetScreenRatio();
341               
342                if (event == DMC_NOTIFY_PMTChanged)
343                {
344                        PSIChangeNotifyInfo *pcni = (PSIChangeNotifyInfo *)param;
345
346                        UINT16 uid = (pcni->userParam >> 16) & 0xffff;   // »óÀ§ 16 bit
347                        //APP_TUNE_METHOD method = (pcni->userParam & 0xffff); // ÇÏÀ§ 16 bit
348                       
349                        if (uid > 0 && pcni->av) 
350                        {
351                                PmtChangeCallback(uid, (const ProgramAVInfo *)pcni->av);
352                        }
353                        //iskang 071116. add. rating check.
354                       
355                        AppRating_CheckRatingBlock(3000); //¿ø·¡ 0ÃÊ¿´À¸³ª, »ç¿ëÀÚÀÇ ¿ä±¸¿¡ ÀÇÇÑ °ÍÀÌ ¾Æ´Ï¸é 3ÃÊ·Î º¯°æ
356                }
357        }
358
359        else if (event == DMC_NOTIFY_AllPsiReceived)
360        {
361                AllPsiRxNotifyInfo *a = (AllPsiRxNotifyInfo *)param;
362               
363                // trigger checking dynamic channel update..
364                //dprint(0, "############## all psi rx\n");
365
366                if (a && a->av && a->av->active)
367                        App_CheckDynamicChUpdate();
368        }
369       
370        // cafrii 050617 add, MultiLingual 󸮸¦ À§ÇØ AudioSelection ºÎºÐ °¡·Îè
371        else if (event == DMW_NOTIFY_SelectAudio)
372        {
373                if (param)
374                        App_AudioSelectAudioStream((AudioPidSelectParam *) param);
375        }
376
377        else if (event == DMW_NOTIFY_AudioDecodeStop)
378        {
379                if (param)
380                        App_AudioNotifyStop((AudioDecodeStopParam *)param);
381        }
382
383        // Updated by Chjeon 2007.09.17
384        // MTS 󸮽ÿ¡ Start ½Ã¿¡ ¿Àµð¿ÀÀÇ PID ¼³Á¤Çϱâ À§ÇÑ ¸Þ½ÃÁö Àü´Þ
385        else if (event == DMW_NOTIFY_AudioDecodeStart)
386        {
387                if (param)
388                        App_AudioNotifyStart((AudioDecodeStartParam *)param);
389        }
390}
391
392
393// cafrii 060609 add
394void App_RegisterChannelNotifyCallback()
395{
396        Dmc_RegisterNotificationCallback(_ChannelNotificationCallback);
397}
398
399
400//  App_FindInfoFromVct
401//
402//  VCT·ÎºÎÅÍ °¢Á¾ Á¤º¸¸¦ ÃßÃâÇÑ´Ù.
403//  DRF Æ©´×ÀÇ °æ¿ì rf, pn ¸¸À¸·Î Æ©´×À» Ç߱⠶§¹®¿¡
404//  ¿©·¯°¡Áö Ãß°¡ Á¤º¸°¡ ÇÊ¿äÇÔ. (banner Ç¥½Ã µî..)
405//
406STATUS App_FindInfoFromVct(xvctPtr_t vct, int program_number,
407                UINT16 *pMajor, UINT16 *pMinor, UINT16 *pSourceId, UINT16 *pShortName)
408{
409        int i;
410        int major, minor;
411       
412        if (vct == NULL || program_number <= 0) 
413                return statusNotFound;
414
415        for (i=0; vct->channel && i<vct->numChannels; i++)
416        {
417                if (vct->channel[i].program_number == program_number)
418                {
419                        major = vct->channel[i].major_channel_number;
420                        minor = vct->channel[i].minor_channel_number;
421
422                        if (vct->is_cvct && IsOnePartChannelNumber(major))
423                        {
424                                major = ConvertToOnePartChannelNumber(major, minor);
425                                minor = ONE_PART_CHANNEL_INDICATOR;
426                        }
427
428                        if (pMajor)
429                                *pMajor = major;
430                        if (pMinor)
431                                *pMinor = minor;
432                        if (pSourceId)
433                                *pSourceId = vct->channel[i].source_id;
434
435                        if (pShortName)
436                                memcpy(pShortName, vct->channel[i].short_name, sizeof(vct->channel[i].short_name));
437                       
438                        return statusOK;
439                }
440        }
441        return statusNotFound;
442}
443
444
445static void VideoResolutionUpdateHandler(UINT32 nIDTimer, UINT32 param)
446{
447        //5ÃÊ µ¿¾È Á¤º¸¸¦ ¼öÁýÇÔ
448        //Á¤º¸°¡ Á¦´ë·Î ¼öÁýµÇ¸é ±×¸¸µÒ.->À߸øµÈ Á¤º¸°¡ ÀÐÈúÁöµµ ¸ð¸£±â ¶§¹®¿¡
449        //°è¼Ó ¼öÁýÇÔ.
450        tDHL_VideoSeqHdr seq;
451        tDHL_DispFormat disp=eDHL_DISP_720x480i;
452        static UINT32 prev_param=0;
453        static UINT32 first_ms=0;
454        int idx;
455       
456        if(prev_param==0 || prev_param!=param) first_ms=DHL_OS_GetMsCount();
457       
458        prev_param=param;
459       
460        if(DHL_OS_GetMsCount()-first_ms>=5000) {
461                DMW_SYS_KillTimer(TIMER_ID_UPDATE_VIDSEQ);
462                return;
463        }
464       
465        if(DHL_AV_VideoSeqInfo(0, &seq)!=DHL_OK) return;
466
467        if(seq.vertical_size>=1080)     disp=eDHL_DISP_1920x1080i;
468        else if(seq.vertical_size>=720) disp=eDHL_DISP_1280x720p;
469        else                            disp=eDHL_DISP_720x480i;
470       
471        DMW_MSC_LockUcm();
472       
473        idx=DMW_MSC_Uid2Index(APP_CUR_CH.nUid);
474       
475        if(idx>=0) {
476                g_UCM[idx].video_format=disp;
477        }
478       
479        DMW_MSC_UnlockUcm();
480       
481        //DMW_SYS_KillTimer(TIMER_ID_UPDATE_VIDSEQ);
482                //Á¤º¸°¡ ¾÷µ¥ÀÌÆ®µÇ¾úÀ¸¹Ç·Î timer¸¦ Á×ÀÓ.
483}
484
485
486void App_UpdateVideoResolution()
487{
488        DMW_SYS_SetTimer(TIMER_ID_UPDATE_VIDSEQ, 1000, 
489                        VideoResolutionUpdateHandler, DHL_OS_GetMsCount(), FALSE);
490}
491
492
493
494
495
496
497/*
498        cafrii 070608 merge APRO1 code
499                remove DRF related code
500                add analog stuff (not used yet)
501*/
502static void _ChannelTuneCallback(STATUS status, UINT32 userParam , AppRfTuneCallbackParam *param)
503{
504        // cafrii 060608 comment
505        // userParam Àº APP_TUNE_METHOD tuning method¸¦ °£Á÷Çϰí ÀÖÀ¸´Ï ÇÊ¿äÇϸé Ȱ¿ë.
506        //
507        UINT16 uid = (userParam >> 16) & 0xffff;   // »óÀ§ 16 bit
508        APP_TUNE_METHOD method = (APP_TUNE_METHOD)(userParam & 0xffff); // ÇÏÀ§ 16 bit
509        int idx;
510
511        ProgramAVInfo *program;
512        BOOL bAnalog;
513       
514#if DELETE_CHBANNER_AFTER_TUNNING
515        BOOL bTuneSuccess = FALSE;
516#endif
517
518        if (status)
519        {
520                dprint(0, "**************************************\n");
521                dprint(0, "  !! Tuning ERROR !! %d (%s)\n", status, DMW_CDB_ErrString(status));
522                dprint(0, "**************************************\n");
523               
524                // cafrii 060609, tune err status¸¦ ±×´ë·Î ±â¾ïÇÑ´Ù.
525                // satusError -> status
526                g_App_LastTuneResult = status;
527
528                // cafrii 091221 bugfix
529                // Dmc MsgQ ³»¿¡¼­ ¹Ù·Î cancel µÈ °æ¿ì¶ó¸é paramÀÌ NULL ÀÏ ¼ö ÀÖÀ½.
530                // ¾Æ·¡ bAnalog ¶ó´Â º¯¼ö´Â »ç¿ëÇÏÁöµµ ¾Ê´Â °Í °°À¸¹Ç·Î ¾Æ¿¹ Á¦°ÅÇÔ.
531                //bAnalog = (param->tuneParam->type == Modulation_NTSC) ? TRUE : FALSE;
532
533                // cafrii 060724 bugfix
534                // autoscan µîÀÇ ÀÛ¾÷À» ½ÃÀÛÇϱâ À§ÇØ cancel µÈ °Í¿¡ ÀÇÇØ¼­
535                // SigMonÀÌ ´Ù½Ã RestartµÉ ¼ö ÀÖÀ½.
536                // cancel ÀÎ °æ¿ì´Â È®½ÇÇÏ°Ô STOP!
537                //
538                if (status != statusCancelled) 
539                {
540                        App_Restart_SMTask(FALSE, FALSE); // No program ÀÎÁö Low signal ÀÎÁö ¾Ë ¼ö ¾øÀ½.
541                }
542               
543#if DELETE_CHBANNER_AFTER_TUNNING
544                bTuneSuccess = FALSE;
545                goto label_banner_delete;
546#else
547                return;
548#endif
549        }
550
551#if USE_EDGE_COLOR_CHAGE               
552                App_VideoSetEdgeColor(App_VideoGetEdgeColor(), FALSE);
553#endif
554
555        //-------- tune success ----------
556       
557        program = param->program;
558        bAnalog = program->analog;
559       
560        dprint(0, "**************************************\n");
561        dprint(0, "       %s Tuning Completed\n", bAnalog ? "Analog" : "Digital");
562        dprint(0, "**************************************\n");
563       
564        g_App_LastTuneResult = statusOK;
565
566#if DELETE_CHBANNER_AFTER_TUNNING
567        bTuneSuccess = TRUE;
568#endif //DELETE_CHBANNER_AFTER_TUNNING
569
570        // now, this is UID tune..
571
572        //if (method == APP_TUNE_UID || method == APP_TUNE_SIGMON)
573
574        if (param->vct == NULL && param->pat == NULL && param->pmt == NULL) {
575                // pid·Î¸¸ tuningµÈ °æ¿ìÀÌ´Ù.
576                //   ¾ÆÁ÷ vct ¼ö½ÅÀÌ ¾ÈµÇ¾ú°í, psiµµ ¼ö½ÅÀÌ ¾ÈµÈ »óÅÂ..
577                // ¹Ýµå½Ã DB based tuning À̹ǷΠuid·Î Á¤º¸¸¦ ¾Ë¾Æ³»¸é µÈ´Ù.
578        }
579        else if (param->vct) {
580                // psip channel ÀÎ °æ¿ì..
581        }
582        else {
583                // psi channel ÀÎ °æ¿ì.. ¶Ç´Â vct download ½ÇÆÐÀÎ °æ¿ì..
584        }
585
586        if (bAnalog) {
587                dprint(0, "Analog (%s, rf %d, uid %d)\n",
588                        method == APP_TUNE_UID ? "Uid" : 
589                        method == APP_TUNE_SIGMON ? "SigMon" : "??",
590                        program->rf, uid);
591                APP_CUR_CH.uPcrPid = APP_CUR_CH.uVidPid = APP_CUR_CH.uAudPid = 0;
592        }
593        else {
594                dprint(0, "Digital (%s, rf %d, %d-%d #%d, uid %d, pva %x/%x/%x %x/%x)\n",
595                        method == APP_TUNE_UID ? "Uid" : 
596                        method == APP_TUNE_SIGMON ? "SigMon" : "??",
597                                program->rf, program->major, program->minor, program->program_number, 
598                        uid,
599                        program->pcr_pid, program->video_pid, program->audio_pid,
600                        program->video_type, program->audio_type);
601
602                APP_CUR_CH.uPcrPid = program->pcr_pid;
603                APP_CUR_CH.uVidPid = program->video_pid;
604                APP_CUR_CH.uAudPid = program->audio_pid;
605
606                APP_CUR_CH.VideoType = program->video_type;
607                APP_CUR_CH.AudioType = program->audio_type;
608        }
609       
610        g_App_LastTuneResult = statusOK;
611       
612        if (APP_CUR_CH.nUid != uid) {
613                dprint(0, "!! err, uid mismatch? %d != %d\n", APP_CUR_CH.nUid, uid);
614        }
615       
616        // cafrii 060630 add
617        //  Á¤È®ÇÑ pid data ¸¦ DB¿¡ updateÇÑ´Ù.
618        DMW_MSC_LockUcm();
619
620        idx = DMW_MSC_Uid2Index(uid);
621        if (idx >= 0) {
622                g_UCM[idx].Pcr_pid = program->pcr_pid;
623                g_UCM[idx].Video_pid = program->video_pid;
624                g_UCM[idx].Audio_pid = program->audio_pid;
625                g_UCM[idx].Video_type = program->video_type;
626                g_UCM[idx].Audio_type = program->audio_type;
627        }
628       
629        DMW_MSC_UnlockUcm();
630
631        if (idx < 0)
632                dprint(0, "!! uid %d invalid, cannot update pid!\n", uid);
633               
634               
635        if (!bAnalog) 
636        {
637                // card µ¿ÀÛ Áß¿¡µµ stt¿¡ ÀÇÇÑ time sync ±â´ÉÀº ¿©ÀüÈ÷ ÇÊ¿äÇÔ.
638                // ´Ù¸¸ psip stt°¡ ¾Æ´Ñ oob si stt¿¡ ÀÇÇØ sync°¡ µÇ¾î¾ß ÇÑ´Ù.
639                // fnc_time ¸ðµâ ³»¿¡¼­ card µ¿ÀÛ ¿©ºÎ¿¡ µû¶ó ó¸®Çϵµ·Ï ÇÑ´Ù.
640                App_DeferredSyncSTT();
641
642#if SUPPORT_POD
643                // cablecard °¡ µ¿ÀÛ Áß¿¡´Â epg ½ÃÀÛÇÏ¸é ¾ÈµÊ. oob si Á¤º¸¸¸À» Ȱ¿ëÇØ¾ß ÇÔ.
644                if (!App_Op_IsOobMode())
645#endif
646                {
647                        dprint(0, "Start EpgUpdate..\n");
648                        App_EpgUpdateStart();
649                }
650               
651                // cafrii 060609 add
652                // ¾à 4ÃÊ ÈÄ¿¡.. ¹«Á¶°Ç rating check¸¦ 1ȸ ÇÑ´Ù.
653                // Missing rating¿¡ ´ëÇÑ Ã³¸®¸¦ ÇØ¾ß ÇÒ °æ¿ì Çʼö.
654                // Missing rating 󸮰¡ ¾ø´Â Á¦Ç°Àº »ó°ü¾øÀ½.
655                AppRating_CheckRatingBlock(3000); 
656        }
657       
658        // cafrii 070608 add argument
659        App_Restart_SMTask(bAnalog, TRUE);
660
661        // cafrii 060714
662        // OSD Ãæµ¹Àº OSD mgrÀÌ °ü¸®ÇϹǷΠCC´Â ¹«Á¶°Ç ½ÃÀÛÇÑ´Ù.
663        // CC OptionÀº ³»ºÎ¿¡¼­ ÆÄ¾ÇÇÑ´Ù.
664        // ´Ü CC°¡ °¡Àå OSD priority°¡ ³·¾Æ¾ß ÇÑ´Ù.
665        // TODO: Aftter FNC CC
666        //App_CC_Start();
667       
668        App_UpdateVideoResolution();
669
670        if (!bAnalog) 
671        {
672                //neverdai 0714 add
673                App_EAMonStart();       
674        }
675       
676#if DELETE_CHBANNER_AFTER_TUNNING
677
678label_banner_delete:
679
680#endif//DELETE_CHBANNER_AFTER_TUNNING
681}
682
683
684//  ÀÌÀü ä³Î Æ©´×À» À§ÇÑ Á¤º¸
685//
686//  App_ResetPrevChannelInfo : ÀÌÀü ä³Î Á¤º¸ »èÁ¦
687//  App_SetPrevChannelInfo : ÀÌÀü ä³Î Á¤º¸ ÀúÀå
688//
689void App_ResetPrevChannelInfo(void)
690{
691        memset(&g_App_PrevChannel, 0, sizeof(g_App_PrevChannel));
692}
693
694
695void App_SetPrevChannelInfo(void)
696{
697        // ÀÌÀü ä³Î Æ©´×À» À§ÇÑ Á¤º¸´Â ChannelType¿¡ »ó°ü ¾ø´Ù.
698        //
699        // cafrii 060804 change
700        //
701        if (APP_CUR_CH.nUid > 0)  // UID ä³Î
702        {
703                dprint(0, "backup to prev channel uid %d\n", APP_CUR_CH.nUid);
704
705                g_App_PrevChannel.nRF = 0;
706                g_App_PrevChannel.nUid = APP_CUR_CH.nUid;
707        }
708        else if (APP_CUR_CH.nRF > 0) // Quick scan ä³Î
709        {
710                dprint(0, "backup to prev channel, rf %d\n", APP_CUR_CH.nRF);
711               
712                g_App_PrevChannel.nRF = APP_CUR_CH.nRF;
713                g_App_PrevChannel.nUid = 0;
714        }
715        else 
716        {
717                dprint(0, "!! cur channel invalid. keep prev ch: uid %d, rf %d\n", 
718                                                g_App_PrevChannel.nUid, g_App_PrevChannel.nRF);
719        }
720}
721
722
723//  App_SaveLastChannelInfo
724//
725//  Uid tune, or DRF tune Çϱâ Á÷Àü¿¡,
726//  channel recovery ±â´ÉÀ» À§ÇØ ÇÊ¿äÇÑ Á¤º¸¸¦ NVM¿¡ ÀúÀåÇÑ´Ù.
727//  previous channel tuning°ú´Â °³³äÀÌ ´Ù¸§.
728//
729void App_SaveLastChannelInfo(int rf, int program_number, int uid)
730{
731        // »õ·Î Æ©´×ÇÒ Ã¤³Î, ¶Ç´Â ¹æ±Ý Àü¿¡ Æ©´×Çß´ø ä³ÎÀÇ Á¤º¸ÀÌ´Ù.
732        // ä³Î º¹±¸ ±â´ÉÀ» À§ÇØ NVM¿¡ ÀúÀåÀ» ÇÑ´Ù.
733       
734        // Note!
735        // °¢ °ªµéÀÌ -1À̸é ÇØ´ç °ªÀº ÀúÀåÇÏÁö ¾Ê°í ±×³É skipÇÑ´Ù.
736        // °¢ °ªµéÀÌ 0À̸é À¯È¿ÇÏÁö ¾ÊÀº Á¤º¸¶ó´Â Àǹ̷ΠNVM¿¡ ÀúÀåÇÑ´Ù.
737        //
738
739        if (uid > 0)
740        {
741                // uid ÀÔ·ÂÀ» Áö¿øÇÏ´Â °ÍÀº ´Ü¼ø ÆíÀǸ¦ À§Çؼ­ÀÓ.
742                // °á±¹Àº rf/pnÀ¸·Î º¯È¯µÇ¾î¼­ ÀúÀåµÈ´Ù. uid·Î ÀúÀå ¾ÈµÊ¿¡ À¯ÀÇ..
743                int index;
744                DMW_MSC_LockUcm();
745
746                index = DMW_MSC_Uid2Index(uid);
747                if (index >= 0) {
748                        rf = g_UCM[index].RF;
749                        program_number = g_UCM[index].Prog_number;
750                }
751                DMW_MSC_UnlockUcm();
752        }
753
754        dprint(0, "save last channel info rf %d, #%d (uid %d)\n", rf, program_number, uid);
755       
756        if (APP_CUR_CH.nChannelType == ChannelType_Air) 
757        {
758                if (rf >= 0)
759                        p_chtune_nvm_param.air_rf = rf;
760               
761                if (program_number >= 0)
762                        p_chtune_nvm_param.air_pn= program_number;
763
764                App_NVM_SaveModuleParam(eAPP_NVR_CHTUNE, &p_chtune_nvm_param);
765        }
766#if SUPPORT_POD
767        else if (App_Op_IsOobMode())
768        {
769                dprint(0, "  save last ch info in oob mode\n");
770                if (rf >= 0)
771                        p_chtune_nvm_param.oob_rf = rf;
772                if (program_number >= 0)
773                        p_chtune_nvm_param.oob_pn= program_number;
774
775                App_NVM_SaveModuleParam(eAPP_NVR_CHTUNE, &p_chtune_nvm_param);
776        }
777#endif // #if SUPPORT_POD
778       
779        else
780        {
781                if (rf >= 0)
782                        p_chtune_nvm_param.cable_rf = rf;
783                if (program_number >= 0)
784                        p_chtune_nvm_param.cable_fn= program_number;
785
786                App_NVM_SaveModuleParam(eAPP_NVR_CHTUNE, &p_chtune_nvm_param);
787        }
788}
789
790
791void App_UpdateQuickScanChannelParam(int rf)
792{
793        // QuickScanÀ» ½ÃÀÛÇϱâ Àü¿¡ ºÒ¸°´Ù.
794        //
795        APP_CUR_CH.nRF = rf;
796       
797        APP_CUR_CH.nUid = 0;
798
799        // ¹è³Ê Ç¥½Ã¸¦ À§Çؼ­ ¾Æ·¡¿Í °°ÀÌ ¼³Á¤ÇÑ´Ù.
800        APP_CUR_CH.nMajor = rf;
801        APP_CUR_CH.nMinor = ONE_PART_CHANNEL_INDICATOR;
802
803        APP_CUR_CH.nServiceType = 1;
804        APP_CUR_CH.nProgramNumber = 0;
805        APP_CUR_CH.nSourceId = 0;
806        APP_CUR_CH.ShortName[0] = 0;
807        APP_CUR_CH.bPSIChannel = 0;
808}
809
810
811void App_UpdateUidChannelParam(int uid)
812{
813        // ºÒ¸®´Â °÷:
814        //  UID tuning ÇÔ¼ö¿¡¼­ Tuning API ºÎ¸£±â ¹Ù·Î Àü.
815        //  ¿©·¯ Uid tuning ÇÏ´Â °÷¿¡¼­ tuning Çϱâ Á÷Àü ȤÀº Á÷ÈÄ (Á÷ÀüÀÌ ±ÇÀåµÊ!!)
816        //
817        int i;
818        char name[40];
819
820        DMW_MSC_LockUcm();
821        i = DMW_MSC_Uid2Index(uid);
822        if (i >= 0)
823        {
824                // ÇöÀç ä³Î Çʼö Á¤º¸ ±â¾ï..
825                APP_CUR_CH.nUid = uid;
826                APP_CUR_CH.nRF = g_UCM[i].RF;
827                APP_CUR_CH.nServiceType = g_UCM[i].Service_type;
828                APP_CUR_CH.nProgramNumber = g_UCM[i].Prog_number;
829
830                // ºÎ°¡ Á¤º¸ ±â¾ï.. ³ªÁß¿¡ ´Ù½Ã Á¤È®ÇÑ ³»¿ëÀ» update ÇÒ °ÍÀÓ.
831                APP_CUR_CH.nMajor = g_UCM[i].Major;
832                APP_CUR_CH.nMinor = g_UCM[i].Minor;
833                        // OnePartChannel system¿¡ °æ¿ì¶ó¸é decodingµÈ ä³Î¹øÈ£°¡ ±â¾ïµÇ¾î ÀÖ´Ù.
834
835                APP_CUR_CH.nSourceId = g_UCM[i].source_id;
836                APP_CUR_CH.bPSIChannel = g_UCM[i].VctFlag ? 0 : 1;
837               
838                memcpy(APP_CUR_CH.ShortName, g_UCM[i].ShortName, sizeof(g_UCM[i].ShortName));
839
840                dprint(0, "(%02d) %d-%d %d type %d #%d [uid %03d] '%s' is selected.\n",
841                                i, g_UCM[i].Major, g_UCM[i].Minor, g_UCM[i].RF, 
842                                g_UCM[i].Service_type, g_UCM[i].Prog_number, uid,
843                                ShortNameString(g_UCM[i].ShortName, name));
844        }
845        else
846                dprint(0, "!! Updating invalid UID %d\n", uid);
847
848        DMW_MSC_UnlockUcm();
849}
850
851
852void App_UpdateDRFChannelParam(int rf, int program_number)
853{
854        // DRF¿¡ ÀÇÇÑ Æ©´×ÀÓÀ» ¾Ë¸®±â À§ÇØ invalid uid ¼³Á¤.
855        APP_CUR_CH.nUid         = 0;
856       
857        APP_CUR_CH.nRF = rf;
858        APP_CUR_CH.nProgramNumber = program_number;
859
860        // ¹è³Ê Ç¥½Ã¸¦ À§ÇØ Á¤È®ÇÏÁø ¾ÊÁö¸¸ rf, pnÀ» ÀúÀåÇÏÀÚ.
861        // - »ç¿ëÀÚÀÇ digit entry ÀÔ·ÂÀÇ °æ¿ì¿¡´Â
862        //     µÎ¹øÂ° ¼ýÀÚ°¡ ¹«½ÃµÇ¾î 0ÀÌ µÇ¹Ç·Î Ç¥½Ã¸¦ ÇÏÁö ¸»¾Æ¾ß ÇÑ´Ù.
863        // - program number¸¦ ÁöÁ¤Çؼ­ Á÷Á¢ Æ©´×ÇÏ´Â °æ¿ì¿¡´Â Minor±îÁö Ç¥½Ã.
864        //
865        APP_CUR_CH.nMajor = rf; 
866        APP_CUR_CH.nMinor = 
867                program_number >= 1 ? DMW_ASC_ProgramNumberToMinor(program_number) : 
868                        ONE_PART_CHANNEL_INDICATOR;
869
870        APP_CUR_CH.nSourceId = 0;
871        APP_CUR_CH.nServiceType = 0;
872       
873        APP_CUR_CH.bPSIChannel = 1;
874
875        APP_CUR_CH.ShortName[0] = 0;
876}
877
878
879//iskang 071113. add
880//get channel skipped status..
881void App_GetChannelSkippedInfo(int *pAdd)
882{
883        int idx=0;
884        //BOOL bDRF = TRUE;
885        *pAdd=0;
886
887        if(APP_CUR_CH.nUid>0)
888        {
889                DMW_MSC_LockUcm();     
890                idx = DMW_MSC_Uid2Index(APP_CUR_CH.nUid);
891                if (idx < 0) {
892                        dprint(0, "!! cur channel uid %d is invalid. treat as DRF %d\n", 
893                                APP_CUR_CH.nUid, APP_CUR_CH.nRF);
894                                //bDRF = TRUE;
895
896                }
897                else {
898                        //g_UCM[idx].Skipped = g_UCM[idx].Skipped ? 0 : 1;
899                        *pAdd = g_UCM[idx].Skipped? 0 : 1;
900                       
901                        //if(!bAdd && g_UCM[idx].SurfIndex)
902                        //      g_UCM[idx].SurfIndex = 0;
903       
904                        dprint(0, " Get channel skipped status: %d \n", g_UCM[idx].Skipped);
905                       
906                        //bDRF = FALSE;
907                        //*pAdd = 1;
908                }
909                DMW_MSC_UnlockUcm();
910        }
911        //return bDRF;
912}
913
914
915
916
917
918#if COMMENT
919____Tuning__API1___(){}
920#endif
921
922void App_ChTuneStopTV(void)
923{
924        App_ChTuneStopTVEx(FALSE);
925}
926
927
928// cafrii 070608 add for extended Stop
929void App_ChTuneStopTVEx(BOOL bFromSigMon)
930{
931        dprint(0, "Stop TV\n");
932
933        DMW_SYS_KillTimer(TIMER_ID_DEFERRED_UID_TUNE);
934        DMW_SYS_KillTimer(TIMER_ID_TUNE_AFTER_SCAN);
935
936        App_CancelDynamicChUpdate();
937
938        // À§ timer¿Ü¿¡µµ ¸î°³ÀÇ timerµéÀÌ ´õ ÀÖÀ½.
939        // Ưº°È÷ ¹®Á¦¸¦ ÀÏÀ¸Å°Áö´Â ¾Ê°í ÀÖÁö¸¸
940        // ºÒÇÊ¿äÇÑ ÄÚµåÀ̹ǷΠtimer cancelÇϵµ·Ï ÇÔ.
941        AppRating_CancelCheckRatingBlock(); // cafrii 060919 add
942       
943        App_ForceDisableFreeze();//iskang 070514 channel u/downµî¿¡ ÀÖ¾î freeze Ç®±â
944
945#if 0
946        // ÀÌ ÄÚµåµéÀ» stop video ÀÌÈÄ·Î À̵¿.
947        App_CancelSyncSTT();
948        App_EpgUpdateCancel();
949
950        // OSD´Â ³·Àº priority ºÎÅÍ Áö¿ì´Â°Ô ÁÁ´Ù.
951        App_CC_Stop();
952#endif // #if 0
953
954        //App_ForceDisableFreeze();
955        // cafrii 060808 delete
956        //   ÀÌ freeze disable ±â´ÉÀº ÀÌÀü µ¿ÀÛÀ» cancel ÇÏÁö ¾Ê±â ¶§¹®¿¡
957        //   AV decoding Áß¿¡ stopÇÏ´Â µ¿ÀÛÀÌ ´Ê¾îÁö´Â ¹®Á¦°¡ ÀÖ´Ù.
958
959        if (!bFromSigMon) {
960                // cafrii 060713 comment, Ç×»ó pause sm ÇÏ°í ³ª¼­ stop video¸¦ ÇÑ´Ù.   
961                App_Pause_SMTask();
962        }
963
964#if USE_EDGE_COLOR_CHAGE               
965                App_VideoSetEdgeColor(APP_VIDEO_EDGE_BLACK, FALSE);
966#endif 
967
968        Dmc_StopVideo(); // cafrii 060710 add
969
970#if SUPPORT_AFD
971        // stop afd monitor.
972        App_VideoAfdStartMonitor(FALSE);
973#endif
974        // tune callback¿¡¼­ ´Ù½Ã re-start¸¦ ½ÃÄѹö¸± ¼ö ÀÖ´Â °ÍµéÀº
975        // dmc stop ÇÑ ´ÙÀ½¿¡ Á¾·á¸¦ ÇØ¾ß ÇÑ´Ù.
976        //
977        // ´Ü SigMonÀº ¿¹¿Ü·Î StopVideo Çϱâ Àü°ú ÈÄ, µÎ ¹ø stop ÇØ¾ß ÇÑ´Ù.
978        // sigmon ÀÚü¿¡¼­ video start/stopÀ» ÇØ ¹ö¸®´Â ±â´ÉÀÌ ÀÖÀ¸¹Ç·Î.
979        //
980
981        App_CancelSyncSTT();
982
983        App_EpgUpdateCancel();
984
985        // OSD´Â ³·Àº priority ºÎÅÍ Áö¿ì´Â°Ô ÁÁ´Ù.
986        // TODO: After CC
987        //App_CC_Stop();
988
989        App_EAExit();
990        App_EAMonStop();
991
992#if SUPPORT_SDDS
993        // Á» ´õ È¿À²ÀûÀ¸·Î ÇÏ·Á¸é sdds ä³ÎÀÎ °æ¿ì¿¡¸¸ stop ÇØÁÖ¸é µÊ.
994        // ±×·¯³ª ±»ÀÌ ±×·² ÇÊ¿ä ±îÁö´Â ¾øÀ» µí ÇÏ´Ù.
995        // blocking callÀÌ ¾Æ´Ï¹Ç·Î ±×¸® ¹«°Å¿î ÇÔ¼ö´Â ¾Æ´Ï´Ù.
996        App_SddsStop();
997#endif
998
999        AppRating_BlockForceOff();
1000        if (!bFromSigMon) 
1001        {
1002                App_Pause_SMTask();
1003
1004                // cafrii 060718 add
1005                // ÀÌ ÄÚµå´Â stop video ÇÑ ´ÙÀ½¿¡ ÇØ¾ß ÇÑ´Ù.
1006                // ±×·¸Áö ¾ÊÀ¸¸é Àá±ñ È­¸éÀÌ ³ª¿Í¹ö¸± ¼ö ÀÖÀ½.
1007                //
1008
1009                AppRating_BlockForceOff();
1010
1011                // TODO: After Banner Porting
1012                //App_ClearPopupBanner(); // cafrii 060714 add
1013                        // MTS µîÀÇ ³»¿ëÀÌ ¹Ù²ð ¼ö ÀÖÀ¸¹Ç·Î..
1014
1015                // cafrii 060623 add
1016                // ÀÌÀü ä³Î Æ©´×À» À§ÇÑ Á¤º¸ ÀúÀåÇÑ´Ù.
1017                //
1018                // cafrii 070713, change policy.
1019                // ÀÌÀü ä³Î Á¤º¸´Â ÇÊ¿äÇÑ °æ¿ì¿¡ caller°¡ Á÷Á¢ ÀúÀåÇϵµ·Ï ÇÑ´Ù.
1020                // StopTV Çϱâ Àü¿¡ ºÒ·¯¾ß ÇÔ.
1021                //--App_SetPrevChannelInfo();
1022
1023                APP_CUR_CH.nUid = APP_CUR_CH.nRF = 0;
1024        }
1025        g_App_LastTuneResult = statusError;
1026}
1027
1028
1029//  DeferredChannelTuneHandler
1030//
1031//  AutoscanÀÌ Á¾·áµÇ°í Æ©´×À» ÇÏ´Â timer handler
1032//  Æ©´×À» ÇÒ rf, uid¸¦ paramÀ¸·Î ³Ñ°ÜÁØ´Ù.
1033//
1034static void DeferredUidTuneHandler(UINT32 nIDTimer, UINT32 param)
1035{
1036        UINT16 uid, flag;
1037       
1038        if (nIDTimer != TIMER_ID_DEFERRED_UID_TUNE)
1039                return;
1040
1041        uid = (param & 0xffff);
1042        flag = ((param >> 16) & 0xffff);
1043       
1044        if (uid > 0)
1045                App_TuneChannelByUidEx(uid, (APP_UID_TUNE_FLAG)flag);
1046        else
1047                dprint(0, "!! Deferred tune uid %d flag %x err\n", uid, flag);
1048}
1049
1050
1051int App_TuneChannelByUid(int uid)
1052{
1053        return App_TuneChannelByUidEx(uid, APP_UID_TUNE_NORMAL);
1054}
1055
1056
1057int App_TuneChannelByUidEx(int uid, APP_UID_TUNE_FLAG flag)
1058{
1059        int nReturn = 0;
1060        UINT32 tuneflag; // cafrii 050724 add
1061        STATUS status;
1062
1063#if SUPPORT_ALANG_RECOVERY     
1064        //iskang 081208.
1065        //»õ·Ó°Ô tunningÀ» ½ÃµµÇϸé user°¡ ¼±ÅÃÇÑ audio¸¦ resetÇÑ´Ù.
1066        if(flag!=APP_UID_TUNE_FROM_SIGMON)
1067                App_ResetCurALANG();
1068#endif
1069
1070        dprint(0, "%s: uid %d, flag 0x%x\n", __FUNCTION__, uid, flag);
1071       
1072        if (uid <= 0 || uid > 0xffff) { // cafrii 06069, uid validity check
1073                dprint(0, "!! invalid UID %d\n", uid);
1074                return -1;
1075        }
1076
1077        if ((flag & APP_UID_TUNE_INCLUDE_HIDDEN) == 0 &&
1078                App_IsHiddenChannel(uid)) 
1079        {
1080                dprint(0, "!! uid %d is hidden channel\n", uid);
1081                return -1;
1082        }
1083
1084
1085        // cafrii 060701 add case called in DMC task
1086        //
1087        if (Dmc_IsDmcTask()) 
1088        {
1089                // dmc task¿¡¼­ dmc task·Î command¸¦ º¸³¾ ¼ö ¾øÀ¸¹Ç·Î deferred call ¼öÇà..
1090                //
1091                UINT32 param;
1092               
1093                dprint(0, "deferred tune channel, uid %d flag 0x%x\n", uid, flag);
1094
1095                // deferred uid tune param:
1096                //
1097                //  MSB                 LSB
1098                //   31      16 15       0
1099                //  +----------+----------+
1100                //  |   flag   |   uid    |
1101                //  +----------+----------+
1102                //
1103
1104                param = ((flag & 0xffff) << 16) | (uid & 0xffff);
1105               
1106                DMW_SYS_KillTimer(TIMER_ID_DEFERRED_UID_TUNE);
1107                status = DMW_SYS_SetTimer(TIMER_ID_DEFERRED_UID_TUNE, 0, 
1108                                        DeferredUidTuneHandler, param, TRUE); // one shot mode
1109
1110                if (status) {
1111                        dprint(0, "!! cannot auto tune after scan\n");
1112                        return -1;
1113                }
1114                return 0;
1115        }
1116
1117
1118        // cafrii 070608 add
1119        //  use same tuning api in case of sigmon retune also   
1120        if (flag & APP_UID_TUNE_FROM_SIGMON)  // Signal Monitor¿¡¼­ tuning retryÇÏ´Â °æ¿ìÀÓ.
1121        {
1122                //dprint(0, " called from SigMon..\n");
1123               
1124                tuneflag = 0;
1125
1126#if SUPPORT_NEWBY
1127                tuneflag |= CTF_ShowHiddenChannelAlso;
1128#endif
1129                tuneflag |= CTF_SkipPrescanPidInfo;
1130                        // ´çºÐ°£ ÀÌ flag¸¦ Ű´Â°Ô ³ªÀ» µíÇÔ
1131                        // cafrii 070608 remove
1132                        // Àç Æ©´× ¼Óµµ¸¦ ºü¸£°Ô Çϱâ À§ÇØ ¸·ÀÚ.
1133                        // À߸øµÈ pid Á¤º¸¿´´Ù¸é ÀÏ¹Ý Æ©´×¿¡¼­µµ ¾îÂ¥ÇÇ ¹®Á¦°¡ µÈ´Ù.
1134               
1135                tuneflag |= CTF_ForceSetTuner;  // °­Á¦·Î Æ©³Ê¸¦ ´Ù½Ã Çѹø ´õ ¼³Á¤.
1136                //tuneflag |= CTF_UseQamAutoMode; // cafrii 061221 remove for test
1137               
1138                //tuneflag |= CTF_SkipQamModulation; // cafrii 091123, QAM should be supported
1139
1140        #if SUPPORT_NTSC_AFC
1141                tuneflag |= CTF_TunerAutoFreqAdjust; // cafrii 070517 add for AFC
1142        #endif
1143
1144                g_App_LastTuneResult = statusInvalidState;
1145               
1146                DMW_TUN_TuneChannelByUidAndFlag(
1147                                uid, 
1148                                tuneflag, // cafrii 070420 bugfix! flag->tuneflag
1149                                FALSE, 
1150                                _ChannelTuneCallback, 
1151                                APP_TUNE_SIGMON | ((uid & 0xffff)<<16));
1152                        // skip prescan pid!, no wait mode..
1153        }
1154
1155        // cafrii 060609 add condition
1156        // ¹Ù·Î Á÷Àü¿¡ Æ©´× Çß´ø °á°ú°¡ ½ÇÆÐÀÌ¸é ´Ù½Ã ½ÃµµÇØ¾ß ÇÑ´Ù.
1157        //
1158        else if (uid != APP_CUR_CH.nUid || g_App_LastTuneResult != statusOK)
1159        {
1160                dprint(0, "*************************************\n");
1161                dprint(0, "   Channel Tune: UID %d, flag %x\n", uid, flag);
1162                dprint(0, "*************************************\n");
1163
1164                if ((flag & APP_UID_TUNE_DONT_SAVE_PREV) == 0) {
1165                        // Ưº°ÇÑ °æ¿ì¿¡´Â Prev Ch ÀúÀåÀ» ÇÏ¸é ¾ÈµÇ¹Ç·Î Ã¼Å© ÇÊ¿ä.
1166                        App_SetPrevChannelInfo();
1167                }
1168               
1169                App_ChTuneStopTV();
1170               
1171                // ä³Î º¹±¸¸¦ À§ÇØ Á¤º¸¸¦ NVM¿¡ ÀúÀåÇÑ´Ù.
1172                // ÁÖÀÇ:
1173                //   ÀÌ UidTune ÇÔ¼ö°¡ »ç¿ëÀÚÀÇ Àǵµ¿¡ ÀÇÇØ È£ÃâµÈ °æ¿ì¿¡¸¸ ÀúÀåÇÑ´Ù.
1174                //   ¿¹¸¦ µé¾î EA force tuneÀÇ °æ¿ì¿¡´Â ÀúÀåÇÏ¸é ¾ÈµÈ´Ù. (ÀÌ ÇÔ¼ö »ç¿ë ºÒ°¡)
1175                //   Signal monitor¿¡¼­ Æ©´×ÇÏ´Â °æ¿ì¿¡´Â ±»ÀÌ ÇÒ ÇÊ¿ä´Â ¾ø´Ù.
1176                //   Ã¤³Î º¹±¸ÀÇ Æ©´×Àº µ¿ÀÏÇÑ Á¤º¸¸¦ ±×´ë·Î ¶Ç ÀúÀåÇÏ´Â ²ÃÀε¥, ¹®Á¦´Â ¾ÈµÈ´Ù.
1177                //      ¿¹: last channel uid°¡ 3, ºÎÆÃÇϸ鼭 3À» Æ©´×Çϴµ¥ À̶§ 3À» ¶Ç ÀúÀå.
1178                //   ÀÌÀü ä³Î Æ©´×À» ÇÏ´Â °æ¿ì¿¡´Â Æ©´×ÇÏ°Ô µÉ ä³ÎÀÌ ÀÌÀü ä³ÎÀÌ´Ù. ¹®Á¦ ¾øÀ½.
1179                //
1180                App_SaveLastChannelInfo(0, 0, uid);
1181
1182                // todo
1183                //  Ȥ½Ã DB°¡ ¸Á°¡Áú °æ¿ì¸¦ ´ëºñÇØ¼­ RF, PN µîµµ ÀúÀåÇÏ´Â°Ô ÁÁÀ» µí..
1184
1185                // ¼ø¼­ Áß¿ä. ¸ÕÀú À§¿¡¼­ ÇöÀç/ÀÌÀü ä³Î ÀúÀåÇϰí,
1186                // ±× ´ÙÀ½¿¡ Æ©´×ÇÒ Ã¤³Î ¼³Á¤.
1187                App_UpdateUidChannelParam(uid);
1188               
1189                g_App_LastTuneResult = statusInvalidState;
1190                // ÀÌ º¯¼ö´Â tuneÀÌ ¿ÏÀüÈ÷ ³¡³­ ÈÄ callback¿¡¼­ updateµÈ´Ù.
1191               
1192                // cafrii 060609, add callback param
1193                // cafrii 060622, pass actual uid value to callback
1194                // cafrii 060630, option¿¡ µû¶ó prescan pid¸¦ »ç¿ëÇϱ⵵ ÇÑ´Ù.
1195                // cafrii 060724, flag¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Â API·Î º¯°æ.
1196                //
1197                tuneflag = 0;
1198#if SUPPORT_NEWBY
1199                tuneflag |= CTF_ShowHiddenChannelAlso;
1200#endif
1201                //tuneflag = CTF_UseQamAutoMode; // LG tuner not support QAM auto
1202                if (g_App_UsePrescanPidInfo == 0)
1203                        tuneflag |= CTF_SkipPrescanPidInfo;
1204
1205                //tuneflag |= CTF_SkipQamModulation; // cafrii 091123, QAM should be supported
1206
1207        #if SUPPORT_NTSC_AFC   
1208                tuneflag |= CTF_TunerAutoFreqAdjust; // cafrii 070517 add for AFC
1209        #endif
1210                DMW_EPG_DeleteAll(); // ¾ÈÀü¼º Çâ»óÀ» À§ÇØ Ã¤³Î Æ©´× Àü¿¡ ¸ðµç EPG¸¦ Áö¿î´Ù. 2012.12.09 megakiss
1211                DMW_TUN_TuneChannelByUidAndFlag(
1212                                        uid,                   // uid of channel to tune
1213                                        tuneflag,              // tune flag
1214                                        FALSE,                  // wait complete
1215                                        _ChannelTuneCallback,    // tune callback
1216                                        APP_TUNE_UID | ((uid&0xffff)<<16));  // userparam
1217
1218
1219                // ±âÁ¸ ÄÚµå´Â ¹ö±×!! ch banner°¡ Á¸ÀçÇÏÁö ¾Ê´Â »óÅ¿¡¼­´Â UD ¸Þ½ÃÁö¸¦ º¸³» ºÁ¾ß 󸮰¡ ¾ÈµÈ´Ù.
1220                // ±×³É »õ·Ó°Ô ch banner¸¦ ½ÃÀÛÇϵµ·Ï ÇØ¾ß ÇÑ´Ù.
1221                // ±×¸®°í MenuStart º¸´Ù´Â MenuUpdate°¡ ´õ °³¼±µÈ ¹æ¹ýÀÌ´Ù.
1222                DMG_MenuUpdate(MID_CH_BANNER, 0);
1223                // ±âÁ¸ ÄÚµå: DMG_SetUserDefined(UD_ID_TUNE_COMPLETED, uid, 0);
1224                dprint(0, "[INFORM] App_TuneChannelByUid (%d) Complete!!!\n", uid);             
1225        }
1226        else   
1227        {
1228                dprint(0, "channel uid %d already tuned\n", uid);
1229
1230                // ¹è³Ê¸¦ ¶ç¿ìÀÚ.
1231                DMG_MenuUpdate(MID_CH_BANNER, 0);
1232        }
1233       
1234        return nReturn;
1235}
1236
1237
1238void App_ChTuneByDigitKey(int nMajor, int nMinor)
1239{
1240        int nUid, uidFound = -1;
1241        int flag = 0;
1242       
1243        if (nMinor < 0 || nMinor > 999)
1244                nMinor = ONE_PART_CHANNEL_INDICATOR;
1245       
1246        dprint(0, "[App] ChannelTuneMajorMinor (%d,%d)\n", nMajor, nMinor);
1247       
1248        //SkippedµÈ ä³ÎÀº direct tunnig¿¡¼­ Á¦¿ÜÇÑ´Ù. iskang 070831.
1249        //
1250        // cafrii 070903, ¹«Á¶°Ç Á¦¿ÜÇÏ¸é ¾ÈµÊ..
1251        //  ¸ÕÀú 1Â÷·Î enabled ä³Î °Ë»öÇϰí, ¾øÀ¸¸é ´Ù½Ã skipped ä³Î Æ÷ÇÔ °Ë»öÀ» ÇÑ´Ù.
1252        //
1253        flag = APP_CH_TUNE_POLICY & ~CSF_Include_Skipped;
1254
1255        if (nMinor == ONE_PART_CHANNEL_INDICATOR)
1256        {
1257                if (nMajor < 0 || nMajor > 16383)
1258                {
1259                        dprint(0, "  one part channel %d is invalid\n", nMajor);       
1260                        goto EXIT;
1261                }
1262       
1263                // ¸ÕÀú OnePart channel X °¡ DB¿¡ Á¸ÀçÇÏ´ÂÁö °Ë»ç
1264               
1265                // note!
1266                //  DMW_MSC_FindChannelMajorMinor API´Â
1267                //  CSF_Include_Hidden µîÀÇ flag°¡ Àß µ¿ÀÛÇÏÁö ¾Ê±â ¶§¹®¿¡ hidden ä³Îµµ °Ë»öÀÌ µÈ´Ù. ÁÖÀÇ!!
1268
1269                nUid = DMW_MSC_FindChannelMajorMinor(nMajor, ONE_PART_CHANNEL_INDICATOR, flag, 1, &uidFound);
1270               
1271                if (nUid >= 1 || uidFound > 0)
1272                {
1273                        if (App_IsHiddenChannel(uidFound)) {
1274                                dprint(0, "  !! channel uid [%d] is hidden. skip\n", uidFound);
1275                                //goto EXIT;
1276                                // exit ÇÏÁö ¸»°í, 2nd try search¿¡ Âü¿©ÇÑ´Ù.
1277                        }
1278                        else {
1279                                App_TuneChannelByUid(uidFound);
1280                                return; 
1281                        }
1282                }
1283
1284                dprint(0, "  search skipped channel also..\n");
1285
1286                // skipped ä³Î Æ÷ÇÔÇÏ¿© ´Ù½Ã °Ë»ö.
1287                flag |= CSF_Include_Skipped;
1288                nUid = DMW_MSC_FindChannelMajorMinor(nMajor, ONE_PART_CHANNEL_INDICATOR, flag, 1, &uidFound);
1289               
1290                if (nUid >= 1 || uidFound > 0)
1291                {
1292                        if (App_IsHiddenChannel(uidFound)) {
1293                                dprint(0, "  !! channel uid [%d] is hidden. skip\n", uidFound);
1294                                //goto EXIT;
1295                                // exit ÇÏÁö ¸»°í, ±× ´ÙÀ½ ¼ø¼­·Î °è¼Ó ÁøÇàÇÑ´Ù.
1296                        }
1297                        else {
1298                                App_TuneChannelByUid(uidFound);
1299                                return; 
1300                        }
1301                }
1302                dprint(0, "  OnePart %d not found\n", nMajor);
1303        }
1304        else if (nMinor <= 0 || nMinor > 999)
1305        {
1306                // minor 0´Â ¾Æ³¯·Î±×·Î ¿¹¾à µÇ¾î ÀÖÀ¸¸ç, ÃÖ´ë °ªÀº 999ÀÌ´Ù.
1307                dprint(0, "  minor %d is invalid\n", nMinor);
1308                goto MAJOR_ONLY;
1309        }
1310        else if (nMajor <= 0 || nMajor >= 1008) 
1311        {
1312                // two part ä³Î ¹øÈ£¿¡¼± major °ªÀÌ 0ÀÏ ¼ö ¾øÀ¸¸ç, 1008 ÀÌ»óÀº one part·Î ÇØ¼®µÈ´Ù.
1313                dprint(0, "  major %d is invalid\n", nMajor);
1314                goto EXIT;     
1315        }
1316        else 
1317        {
1318                nUid = DMW_MSC_FindChannelMajorMinor(nMajor, nMinor, flag, 1, &uidFound);
1319               
1320                // cafrii 070906 bugfix!
1321                // two part ch tuningÀÇ °æ¿ì¿¡µµ skip channel ó¸® ÇÊ¿äÇÔ.
1322                //
1323                if (nUid >= 1 || uidFound > 0)
1324                {
1325                        if (App_IsHiddenChannel(uidFound)) {
1326                                dprint(0, "  !! channel uid [%d] is hidden. skip\n", uidFound);
1327                                //goto EXIT;
1328                                // exit ÇÏÁö ¸»°í, 2nd try search¿¡ Âü¿©ÇÑ´Ù.
1329                        }
1330                        else {
1331                                App_TuneChannelByUid(uidFound);
1332                                return;
1333                        }
1334                }
1335
1336                dprint(0, "  search skipped channel also..\n");
1337
1338                // skipped ä³Î Æ÷ÇÔÇÏ¿© ´Ù½Ã °Ë»ö.
1339                flag |= CSF_Include_Skipped;
1340
1341                nUid = DMW_MSC_FindChannelMajorMinor(nMajor, nMinor, flag, 1, &uidFound);
1342
1343                if (nUid >= 1 || uidFound > 0)
1344                {
1345                        if (App_IsHiddenChannel(uidFound)) {
1346                                dprint(0, "  !! channel uid [%d] is hidden. skip\n", uidFound);
1347                                //goto EXIT;
1348                                // exit ÇÏÁö ¸»°í, ±× ´ÙÀ½ ¼ø¼­·Î °è¼Ó ÁøÇàÇÑ´Ù.
1349                        }
1350                        else {
1351                                App_TuneChannelByUid(uidFound);
1352                                return;
1353                        }
1354                }
1355               
1356                dprint(0, "  channel %d,%d not found\n", nMajor, nMinor);
1357        }
1358
1359MAJOR_ONLY:             // X.* Çü½ÄÀ¸·Î µÇ¾î Àִ ä³ÎÀ» Çϳª ã´Â´Ù. Áï major¶óµµ ÀÏÄ¡Çϴ ä³Î..
1360       
1361        nUid = DMW_MSC_FindChannelMajor(nMajor, flag, 1, &uidFound);
1362
1363        if (nUid >= 1 || uidFound > 0)
1364        {
1365                if (App_IsHiddenChannel(uidFound))
1366                {
1367                        dprint(0, "  !! channel uid [%d] is hidden. skip\n", uidFound);
1368                        goto RF_ONLY;
1369                }
1370                else
1371                {
1372                        App_TuneChannelByUid(uidFound);
1373                        return;
1374                }
1375        }
1376
1377        dprint(0, "  channel %d-* not found\n", nMajor);
1378
1379RF_ONLY:         // X °¡ RF ¹øÈ£°¡ µÉ ¼ö ÀÖ´ÂÁö °Ë»çÇÑ´Ù.
1380       
1381        if ((g_CurChannelType == ChannelType_Air && (nMajor < 2 || nMajor > 69)) ||
1382                (g_CurChannelType == ChannelType_Cable && (nMajor < 1 || nMajor > 135)) )
1383        {
1384                dprint(0, "  channel number %d cannot be RF\n", nMajor);
1385                goto EXIT;
1386        }
1387       
1388        uidFound = FindUIDbyRF(nMajor);
1389       
1390        if(uidFound > 0)
1391        {
1392                if (App_IsHiddenChannel(uidFound))
1393                {
1394                        dprint(0, "  !! channel uid [%d] is hidden. skip\n", uidFound);
1395                        goto EXIT;
1396                }
1397                else
1398                {
1399                        App_TuneChannelByUid(uidFound);
1400                        return;
1401                }
1402
1403        }
1404
1405#if !SUPPORT_POD
1406
1407        dprint(0, "  channel tune only by RF %d\n", nMajor);
1408
1409
1410        // cafrii 060801 add quickscan
1411        //     tune any channel in this rf
1412        App_ChTuneQuickScanAndTune(nMajor, 0, APP_QUICKSCAN_DRF);
1413
1414#endif // #if !SUPPORT_POD
1415
1416
1417EXIT:   // Æ©´× ¿¡·¯ÈÄ ÈÄó¸® ÀÛ¾÷À» À§Çؼ­ returnÇÏÁö ¾Ê°í ¿©±â·Î ÀÏ´Ü ´ëÇǽÃÄѵÒ
1418        return;
1419}
1420
1421
1422
1423
1424
1425#if COMMENT
1426____Tuning__API2___(){}
1427#endif
1428
1429/********************************************************************************
1430                App_ChTuneMinorUp
1431
1432        - Function that increase only the minor number by 1.
1433        - If there is no upper minor channel, do nothing.
1434*********************************************************************************/
1435int App_ChTuneMinorUp()
1436{
1437        int newUid;
1438
1439        if (APP_CUR_CH.nUid <= 0) // DRF ä³Î..
1440        {
1441                // cafrii 060623 up/down ¹æ½Ä º¯°æ. ½ÇÁ¦ major/minor ±âÁØ..
1442                //
1443                int start = -(((APP_CUR_CH.nMajor&0x7fff)<<16)|(APP_CUR_CH.nMinor&0xffff));
1444
1445                dprint(0, "search up from %d-%d\n", APP_CUR_CH.nMajor, APP_CUR_CH.nMinor);
1446               
1447                if (DMW_MSC_FindMinorUp(start, APP_CH_TUNE_POLICY, 1, &newUid) >= 1)
1448                {
1449                        return App_TuneChannelByUid(newUid);
1450                }
1451
1452        }
1453        else
1454        {
1455                if(DMW_MSC_FindMinorUp(APP_CUR_CH.nUid, APP_CH_TUNE_POLICY, 1, &newUid) >= 1)
1456                {
1457                        return App_TuneChannelByUid(newUid);
1458                }
1459        }
1460
1461#if DRAW_SAME_CH_BANNER
1462        DMG_MenuUpdate(MID_CH_BANNER, 0);
1463#endif
1464
1465        return statusOK;
1466}
1467
1468
1469/********************************************************************************
1470                App_ChTuneMinorDown
1471
1472        - Function that increase only the major number by 1.
1473        - If there is no smaller minor channel, do nothing.
1474*********************************************************************************/
1475int App_ChTuneMinorDown()
1476{
1477        int newUid;
1478       
1479        if (APP_CUR_CH.nUid <= 0) // DRF ä³Î..
1480        {
1481                // cafrii 060623 up/down ¹æ½Ä º¯°æ. ½ÇÁ¦ major/minor ±âÁØ..
1482                //
1483                int start = -(((APP_CUR_CH.nMajor&0x7fff)<<16)|(APP_CUR_CH.nMinor&0xffff));
1484
1485                dprint(0, "search down from %d-%d\n", APP_CUR_CH.nMajor, APP_CUR_CH.nMinor);
1486               
1487                if (DMW_MSC_FindMinorDown(start, APP_CH_TUNE_POLICY, 1, &newUid) >= 1)
1488                {
1489                        return App_TuneChannelByUid(newUid);
1490                }
1491        }
1492        else 
1493        {
1494                if (DMW_MSC_FindMinorDown(APP_CUR_CH.nUid, APP_CH_TUNE_POLICY, 1, &newUid) >= 1)
1495                {
1496                        return App_TuneChannelByUid(newUid);
1497                }
1498        }
1499
1500#if DRAW_SAME_CH_BANNER
1501        DMG_MenuUpdate(MID_CH_BANNER, 0);
1502#endif
1503       
1504        return statusOK;
1505}
1506
1507
1508int App_ChTuneSortUp()
1509{
1510        int newUid;
1511
1512        if (APP_CUR_CH.nUid <= 0) // DRF ä³Î..
1513        {
1514                // cafrii 060623 up/down ¹æ½Ä º¯°æ. ½ÇÁ¦ major/minor ±âÁØ..
1515                //
1516                int start = -(((APP_CUR_CH.nMajor&0x7fff)<<16)|(APP_CUR_CH.nMinor&0xffff));
1517
1518                dprint(0, "search up from %d-%d\n", APP_CUR_CH.nMajor, APP_CUR_CH.nMinor);
1519               
1520                if (DMW_MSC_FindMinorUp(start, APP_CH_TUNE_POLICY, 1, &newUid) >= 1)
1521                {
1522                        return App_TuneChannelByUid(newUid);
1523                }
1524        }
1525        else
1526        {
1527                int i;
1528                int start_uid=APP_CUR_CH.nUid;
1529                int mode;
1530                tApp_UcmShortInfo ucm_info;
1531                tApp_ChSelParam ch_sel_param={TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
1532               
1533                App_GetUcmShortInfo(APP_CUR_CH.nUid, &ucm_info);
1534               
1535                if(ucm_info.vid_pid==0 && ucm_info.aud_pid!=0) mode=2;
1536                else if(ucm_info.video_format>=eDHL_DISP_1280x720p) mode=0;
1537                else mode=1;
1538               
1539                for(i=0; i<4; i++) //ÃÖ´ë 4¹ø check ÇÔ. ¿¹) sd(1)->audio(2)->hd(3)->sd(4)
1540                {
1541                        switch(mode) {
1542                                case 0:
1543                                        ch_sel_param.exc_hd=FALSE;
1544                                        ch_sel_param.exc_sd=TRUE;
1545                                        ch_sel_param.exc_audio=TRUE;
1546                                        break;
1547                                       
1548                                case 1:
1549                                        ch_sel_param.exc_hd=TRUE;
1550                                        ch_sel_param.exc_sd=FALSE;
1551                                        ch_sel_param.exc_audio=TRUE;
1552                                        break;
1553                                       
1554                                case 2:
1555                                        ch_sel_param.exc_hd=TRUE;
1556                                        ch_sel_param.exc_sd=TRUE;
1557                                        ch_sel_param.exc_audio=FALSE;
1558                                        break;
1559                        }
1560                       
1561                        newUid=App_Ucm_GetNextChannel(start_uid, &ch_sel_param);
1562                       
1563                        if(newUid==APP_CUR_CH.nUid) {
1564                                //ÇöÀç ä³ÎÀÌ ´Ù½Ã °Ë»öµÇ¾ú´Ù´Â °ÍÀº ¾Æ¹« ä³Îµµ ¾ø´Ù´Â Áõ°ÅÀÓ..
1565                                newUid=-1;
1566                        }
1567                        if(newUid==-1) {
1568                                start_uid=0;
1569                                if(++mode==3) mode=0;
1570                        }
1571                        else if(newUid==APP_CUR_CH.nUid) {
1572                                //ÇöÀç ä³ÎÀÌ ´Ù½Ã °Ë»öµÇ¾ú´Ù´Â °ÍÀº ¾Æ¹« ä³Îµµ ¾ø´Ù´Â Áõ°ÅÀÓ..
1573                                newUid=-1;
1574                                break;
1575                        }
1576                        else { //¹ß°ßµÊ...
1577                                break;
1578                        }
1579                }
1580               
1581                if(newUid>0)
1582                        App_TuneChannelByUid(newUid);
1583        }
1584
1585#if DRAW_SAME_CH_BANNER
1586        DMG_MenuUpdate(MID_CH_BANNER, 0);
1587#endif
1588
1589        return statusOK;
1590}
1591
1592
1593int App_ChTuneSortDown()
1594{
1595        int newUid;
1596       
1597        if (APP_CUR_CH.nUid <= 0) // DRF ä³Î..
1598        {
1599                // cafrii 060623 up/down ¹æ½Ä º¯°æ. ½ÇÁ¦ major/minor ±âÁØ..
1600                //
1601                int start = -(((APP_CUR_CH.nMajor&0x7fff)<<16)|(APP_CUR_CH.nMinor&0xffff));
1602
1603                dprint(0, "search down from %d-%d\n", APP_CUR_CH.nMajor, APP_CUR_CH.nMinor);
1604               
1605                if (DMW_MSC_FindMinorDown(start, APP_CH_TUNE_POLICY, 1, &newUid) >= 1)
1606                {
1607                        return App_TuneChannelByUid(newUid);
1608                }
1609        }
1610        else 
1611        {
1612                int i;
1613                int start_uid=APP_CUR_CH.nUid;
1614                int mode;
1615                tApp_UcmShortInfo ucm_info;
1616                tApp_ChSelParam ch_sel_param={TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE};
1617               
1618                App_GetUcmShortInfo(APP_CUR_CH.nUid, &ucm_info);
1619               
1620                if(ucm_info.vid_pid==0 && ucm_info.aud_pid!=0) mode=2;
1621                else if(ucm_info.video_format>=eDHL_DISP_1280x720p) mode=0;
1622                else mode=1;
1623               
1624                for(i=0; i<4; i++) //ÃÖ´ë 4¹ø check ÇÔ. ¿¹) sd(1)->audio(2)->hd(3)->sd(4)
1625                {
1626                        switch(mode) {
1627                                case 0:
1628                                        ch_sel_param.exc_hd=FALSE;
1629                                        ch_sel_param.exc_sd=TRUE;
1630                                        ch_sel_param.exc_audio=TRUE;
1631                                        break;
1632                                       
1633                                case 1:
1634                                        ch_sel_param.exc_hd=TRUE;
1635                                        ch_sel_param.exc_sd=FALSE;
1636                                        ch_sel_param.exc_audio=TRUE;
1637                                        break;
1638                                       
1639                                case 2:
1640                                        ch_sel_param.exc_hd=TRUE;
1641                                        ch_sel_param.exc_sd=TRUE;
1642                                        ch_sel_param.exc_audio=FALSE;
1643                                        break;
1644                        }
1645                       
1646                        newUid=App_Ucm_GetPrevChannel(start_uid, &ch_sel_param);
1647                       
1648                        if(newUid==APP_CUR_CH.nUid) {
1649                                //ÇöÀç ä³ÎÀÌ ´Ù½Ã °Ë»öµÇ¾ú´Ù´Â °ÍÀº ¾Æ¹« ä³Îµµ ¾ø´Ù´Â Áõ°ÅÀÓ..
1650                                newUid=-1;
1651                        }
1652                        if(newUid==-1) {
1653                                start_uid=0;
1654                                if(--mode==-1) mode=2;
1655                        }
1656                        else if(newUid==APP_CUR_CH.nUid) {
1657                                //ÇöÀç ä³ÎÀÌ ´Ù½Ã °Ë»öµÇ¾ú´Ù´Â °ÍÀº ¾Æ¹« ä³Îµµ ¾ø´Ù´Â Áõ°ÅÀÓ..
1658                                newUid=-1;
1659                                break;
1660                        }
1661                        else { //¹ß°ßµÊ...
1662                                break;
1663                        }
1664                }
1665               
1666                if(newUid>0)
1667                        App_TuneChannelByUid(newUid);
1668        }
1669
1670#if DRAW_SAME_CH_BANNER
1671        DMG_MenuUpdate(MID_CH_BANNER, 0);
1672#endif
1673       
1674        return statusOK;
1675}
1676
1677int App_GetChUid(int idx)
1678{
1679        return c_chinfo[idx].uid;
1680}
1681
1682int App_SaveChSortNumber(void /*tApp_UcmShortInfo *c_chinfo*/)
1683{
1684        int i;
1685        int idx;
1686        int uid = 0;
1687        int numCh = 0;
1688        int TotalUcmCount = 0;
1689        tApp_UcmShortInfo ucm_info;
1690        DST_CURCHANNEL ChannelInfo;
1691       
1692        TotalUcmCount = App_Ucm_GetTotalUcmCount();
1693       
1694        if(c_chinfo) {
1695                DHL_OS_Free((void **)&c_chinfo);
1696                c_chinfo=NULL;
1697        }
1698       
1699        c_chinfo = DHL_OS_Malloc(sizeof(tApp_UcmShortInfo)*TotalUcmCount);
1700        memset(c_chinfo, 0, sizeof(tApp_UcmShortInfo)*TotalUcmCount);
1701        App_Ucm_GetCurChInfo(&ChannelInfo);
1702
1703        DMW_MSC_LockUcm();
1704
1705        numCh=App_Ucm_GetChannelNum(FALSE);
1706
1707        for(i=0, idx=-1; i<numCh; i++) {
1708               
1709                idx=App_Ucm_GetNextChannelNumber(idx, FALSE, FALSE);
1710               
1711                if(idx<0) break;
1712               
1713                App_Ucm_GetShortInfobyIndex(idx, &c_chinfo[i]);
1714        }
1715       
1716        DMW_MSC_UnlockUcm();
1717       
1718        return numCh;
1719}
1720
1721int App_ChTuneSortNumberUp(void)
1722{
1723        int nUid = -1;
1724        int i, k, idx, index;
1725        int TotalUcmCount = 0;
1726        BOOL bFind = FALSE;
1727
1728//      DHL_OS_Delay(500);
1729
1730        DMW_MSC_LockUcm();
1731        index = DMW_MSC_Uid2Index(APP_CUR_CH.nUid);
1732        TotalUcmCount=App_SaveChSortNumber();
1733        /*
1734                no program case:
1735                        current RF 5: "No program"             
1736                                2-1
1737                                2-2  fav
1738                                    <-- RF 5 is thought to be here.
1739                                7-1
1740                                7-2
1741                                7-3  fav
1742                                7-4  fav
1743
1744                        if user press fav in RF 5, 2-2 is first visited. (go back one step).
1745                        and start searching from 7-1 to 2-2 (wrap around).
1746                        finally 7-3 fav is tuned.
1747
1748                channel db empty:
1749                        this is drf case, and just cur ch banner will be shown.
1750        */
1751
1752        if (index < 0) // this is DRF channel. find greatest lower channel number.
1753        {
1754                int start = -(((APP_CUR_CH.nMajor&0x7fff)<<16)|(APP_CUR_CH.nMinor&0xffff));
1755
1756                if (DMW_MSC_FindMinorDown(start, APP_CH_TUNE_POLICY, 1, &nUid) >= 1) {
1757                        index = DMW_MSC_Uid2Index(nUid);
1758                        dprint(0, "drf: search dn from %d-%d -> uid %d, idx %d\n", 
1759                                APP_CUR_CH.nMajor, APP_CUR_CH.nMinor, nUid, index);
1760                }
1761                else
1762                        nUid = -1;
1763        }
1764       
1765        if (index >= 0) // valid channel
1766        {
1767                nUid = APP_CUR_CH.nUid;
1768
1769                for (i = 0; i < g_UCM_number; i++)
1770                {
1771                        if (nUid == c_chinfo[i].uid)
1772                        {
1773                                idx = i;
1774                                break;
1775                        }
1776                }
1777
1778                if (idx == TotalUcmCount-1)
1779                        nUid = c_chinfo[0].uid;
1780                else nUid = c_chinfo[idx+1].uid;
1781        }
1782        DMW_MSC_UnlockUcm();
1783        // we selected channel 'nUid' as a next surf channel.
1784        // if no other surf channel exist,
1785        // or this is the only surf channel, just draw banner only without tuning.
1786        if (nUid <= 0 ||
1787                nUid == APP_CUR_CH.nUid)
1788        {
1789                dprint(0, "upper surf major from uid %d not found!\n", APP_CUR_CH.nUid);
1790
1791#if DRAW_SAME_CH_BANNER
1792                DMG_MenuUpdate(MID_CH_BANNER, 0);
1793#endif
1794
1795                return statusOK;
1796        }
1797       
1798        return App_TuneChannelByUid(nUid);
1799}
1800
1801int App_ChTuneSortNumberDown(void)
1802{
1803        int nUid = -1;
1804        int i, k, idx, index;
1805        int TotalUcmCount = 0;
1806        BOOL bFind = FALSE;
1807
1808//      DHL_OS_Delay(500);
1809
1810        TotalUcmCount = App_SaveChSortNumber();
1811
1812        DMW_MSC_LockUcm();
1813        index = DMW_MSC_Uid2Index(APP_CUR_CH.nUid);
1814        /*
1815                no program case:
1816                        current RF 5: "No program"             
1817                                2-1
1818                                2-2  fav
1819                                    <-- RF 5 is thought to be here.
1820                                7-1
1821                                7-2
1822                                7-3  fav
1823                                7-4  fav
1824
1825                        if user press fav in RF 5, 2-2 is first visited. (go back one step).
1826                        and start searching from 7-1 to 2-2 (wrap around).
1827                        finally 7-3 fav is tuned.
1828
1829                channel db empty:
1830                        this is drf case, and just cur ch banner will be shown.
1831        */
1832
1833        if (index < 0) // this is DRF channel. find greatest lower channel number.
1834        {
1835                int start = -(((APP_CUR_CH.nMajor&0x7fff)<<16)|(APP_CUR_CH.nMinor&0xffff));
1836
1837                if (DMW_MSC_FindMinorDown(start, APP_CH_TUNE_POLICY, 1, &nUid) >= 1) {
1838                        index = DMW_MSC_Uid2Index(nUid);
1839                        dprint(0, "drf: search dn from %d-%d -> uid %d, idx %d\n", 
1840                                APP_CUR_CH.nMajor, APP_CUR_CH.nMinor, nUid, index);
1841                }
1842                else
1843                        nUid = -1;
1844        }
1845       
1846        if (index >= 0) // valid channel
1847        {
1848                nUid = APP_CUR_CH.nUid;
1849
1850                for (i = 0; i < g_UCM_number; i++)
1851                {
1852                        if (nUid == c_chinfo[i].uid)
1853                        {
1854                                idx = i;
1855                                break;
1856                        }
1857                }
1858
1859                if (idx == 0)
1860                        nUid = c_chinfo[TotalUcmCount-1].uid;
1861                else nUid = c_chinfo[idx-1].uid;
1862        }
1863        DMW_MSC_UnlockUcm();
1864        // we selected channel 'nUid' as a next surf channel.
1865        // if no other surf channel exist,
1866        // or this is the only surf channel, just draw banner only without tuning.
1867        if (nUid <= 0 ||
1868                nUid == APP_CUR_CH.nUid)
1869        {
1870                dprint(0, "upper surf major from uid %d not found!\n", APP_CUR_CH.nUid);
1871
1872#if DRAW_SAME_CH_BANNER
1873                DMG_MenuUpdate(MID_CH_BANNER, 0);
1874#endif
1875
1876                return statusOK;
1877        }
1878       
1879        return App_TuneChannelByUid(nUid);
1880}
1881
1882/********************************************************************************
1883                App_ChTuneSurfUp
1884
1885        - Function that search and tune next surf-selected channel.
1886       
1887        Surf field´Â On/Off ÀÇ Àǹ̷θ¸ ÇØ¼®µÈ´Ù. ¹«¼øÀ§ Á¤º¸ÀÌ´Ù.
1888*********************************************************************************/
1889int App_ChTuneSurfUp(void)
1890{
1891        int nUid = -1;
1892        int i, k, index;
1893       
1894        bPrevCH = TRUE;
1895        DMW_MSC_LockUcm();
1896        index = DMW_MSC_Uid2Index(APP_CUR_CH.nUid);
1897
1898        /*
1899                no program case:
1900                        current RF 5: "No program"             
1901                                2-1
1902                                2-2  fav
1903                                    <-- RF 5 is thought to be here.
1904                                7-1
1905                                7-2
1906                                7-3  fav
1907                                7-4  fav
1908
1909                        if user press fav in RF 5, 2-2 is first visited. (go back one step).
1910                        and start searching from 7-1 to 2-2 (wrap around).
1911                        finally 7-3 fav is tuned.
1912
1913                channel db empty:
1914                        this is drf case, and just cur ch banner will be shown.
1915        */
1916
1917        if (index < 0) // this is DRF channel. find greatest lower channel number.
1918        {
1919                int start = -(((APP_CUR_CH.nMajor&0x7fff)<<16)|(APP_CUR_CH.nMinor&0xffff));
1920
1921                if (DMW_MSC_FindMinorDown(start, APP_CH_TUNE_POLICY, 1, &nUid) >= 1) {
1922                        index = DMW_MSC_Uid2Index(nUid);
1923                        dprint(0, "drf: search dn from %d-%d -> uid %d, idx %d\n", 
1924                                APP_CUR_CH.nMajor, APP_CUR_CH.nMinor, nUid, index);
1925                }
1926                else
1927                        nUid = -1;
1928        }
1929       
1930        if (index >= 0)  // valid channel
1931        {
1932                // if surf ch not found, we should keep current channel.
1933                // so, remember current channel.
1934                // if cur channel is DRF ch, then nUid will be wrong value. that's ok.
1935                //
1936                int found_index = -1;
1937                nUid = APP_CUR_CH.nUid;
1938       
1939                for (k=0; k<g_UCM_number; k++)
1940                {
1941                        // search start from next channel and wrap around to current channel.
1942                        i = (index + 1 + k) % g_UCM_number;
1943                        if (!g_UCM[i].Skipped && g_UCM[i].SurfIndex && !g_UCM[i].disabled) {
1944                                        found_index = i;
1945                                break; // ok! we found one.
1946                        }
1947                }
1948                if (found_index < 0)
1949                        dprint(0, "!! not found any other surf channel! keep uid %d\n", nUid);
1950                else {
1951                        nUid = g_UCM[found_index].Uid;
1952                        dprint(0, "found idx %d, uid %d\n", found_index, nUid);
1953                }
1954        }
1955
1956        DMW_MSC_UnlockUcm();
1957
1958        // we selected channel 'nUid' as a next surf channel.
1959        // if no other surf channel exist,
1960        // or this is the only surf channel, just draw banner only without tuning.
1961        if (nUid <= 0 ||
1962                nUid == APP_CUR_CH.nUid)
1963        {
1964                dprint(0, "upper surf major from uid %d not found!\n", APP_CUR_CH.nUid);
1965
1966#if DRAW_SAME_CH_BANNER
1967                DMG_MenuUpdate(MID_CH_BANNER, 0);
1968#endif
1969
1970                return statusOK;
1971        }
1972       
1973        return App_TuneChannelByUid(nUid);
1974}
1975
1976int App_ChTuneSortSurfUp(void)
1977{
1978        int start_uid, newUid = -1;
1979        int i, k, index;
1980
1981        /*
1982                no program case:
1983                        current RF 5: "No program"             
1984                                2-1
1985                                2-2  fav
1986                                    <-- RF 5 is thought to be here.
1987                                7-1
1988                                7-2
1989                                7-3  fav
1990                                7-4  fav
1991
1992                        if user press fav in RF 5, 2-2 is first visited. (go back one step).
1993                        and start searching from 7-1 to 2-2 (wrap around).
1994                        finally 7-3 fav is tuned.
1995
1996                channel db empty:
1997                        this is drf case, and just cur ch banner will be shown.
1998        */
1999       
2000        bPrevCH = TRUE;
2001
2002        if(APP_CUR_CH.nUid <= 0) // this is DRF channel. find greatest lower channel number.
2003        {
2004                int start = -(((APP_CUR_CH.nMajor&0x7fff)<<16)|(APP_CUR_CH.nMinor&0xffff));
2005
2006                if (DMW_MSC_FindMinorDown(start, APP_CH_TUNE_POLICY, 1, &start_uid) >= 1) {
2007                        tApp_UcmShortInfo ucm_info;
2008                        App_GetUcmShortInfo(start_uid, &ucm_info);
2009                       
2010                        if(ucm_info.bFav) { //Æ©´×ÇÔ..
2011                                goto label_tune;
2012                        }
2013                }
2014                else
2015                        start_uid = -1;
2016        }
2017        else {
2018                start_uid=APP_CUR_CH.nUid;
2019        }
2020       
2021        if(start_uid ==-1) { //
2022               
2023        }
2024        else {
2025                int i;
2026                int mode;
2027                tApp_UcmShortInfo ucm_info;
2028                tApp_ChSelParam ch_sel_param={TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE};
2029               
2030                App_GetUcmShortInfo(APP_CUR_CH.nUid, &ucm_info);
2031               
2032                if(ucm_info.vid_pid==0 && ucm_info.aud_pid!=0) mode=2;
2033                else if(ucm_info.video_format>=eDHL_DISP_1280x720p) mode=0;
2034                else mode=1;
2035               
2036                for(i=0; i<4; i++) //ÃÖ´ë 4¹ø check ÇÔ. ¿¹) sd(1)->audio(2)->hd(3)->sd(4)
2037                {
2038                        switch(mode) {
2039                                case 0:
2040                                        ch_sel_param.exc_hd=FALSE;
2041                                        ch_sel_param.exc_sd=TRUE;
2042                                        ch_sel_param.exc_audio=TRUE;
2043                                        break;
2044                                       
2045                                case 1:
2046                                        ch_sel_param.exc_hd=TRUE;
2047                                        ch_sel_param.exc_sd=FALSE;
2048                                        ch_sel_param.exc_audio=TRUE;
2049                                        break;
2050                                       
2051                                case 2:
2052                                        ch_sel_param.exc_hd=TRUE;
2053                                        ch_sel_param.exc_sd=TRUE;
2054                                        ch_sel_param.exc_audio=FALSE;
2055                                        break;
2056                        }
2057                       
2058                        newUid=App_Ucm_GetNextChannel(start_uid, &ch_sel_param);
2059                       
2060                        if(newUid==APP_CUR_CH.nUid) {
2061                                //ÇöÀç ä³ÎÀÌ ´Ù½Ã °Ë»öµÇ¾ú´Ù´Â °ÍÀº ¾Æ¹« ä³Îµµ ¾ø´Ù´Â Áõ°ÅÀÓ..
2062                                newUid=-1;
2063                        }
2064                        if(newUid==-1) {
2065                                start_uid=0;
2066                                if(++mode==3) mode=0;
2067                        }
2068                        else if(newUid==APP_CUR_CH.nUid) {
2069                                //ÇöÀç ä³ÎÀÌ ´Ù½Ã °Ë»öµÇ¾ú´Ù´Â °ÍÀº ¾Æ¹« ä³Îµµ ¾ø´Ù´Â Áõ°ÅÀÓ..
2070                                newUid=-1;
2071                                break;
2072                        }
2073                        else { //¹ß°ßµÊ...
2074                                break;
2075                        }
2076                }
2077        }
2078
2079label_tune :
2080               
2081        if(newUid>0)
2082                App_TuneChannelByUid(newUid);
2083
2084#if DRAW_SAME_CH_BANNER
2085        DMG_MenuUpdate(MID_CH_BANNER, 0);
2086#endif 
2087       
2088        return statusOK;
2089}
2090
2091int App_ChTuneSortNumberSurfUp(void)
2092{
2093        int nUid = -1;
2094        int i, k, idx, index;
2095        int TotalUcmCount = 0;
2096        BOOL bFind = FALSE;
2097
2098//      DHL_OS_Delay(500);
2099        bPrevCH = TRUE;
2100        TotalUcmCount = App_Ucm_GetTotalUcmCount();
2101
2102        DMW_MSC_LockUcm();
2103        index = DMW_MSC_Uid2Index(APP_CUR_CH.nUid);
2104        App_SaveChSortNumber();
2105        /*
2106                no program case:
2107                        current RF 5: "No program"             
2108                                2-1
2109                                2-2  fav
2110                                    <-- RF 5 is thought to be here.
2111                                7-1
2112                                7-2
2113                                7-3  fav
2114                                7-4  fav
2115
2116                        if user press fav in RF 5, 2-2 is first visited. (go back one step).
2117                        and start searching from 7-1 to 2-2 (wrap around).
2118                        finally 7-3 fav is tuned.
2119
2120                channel db empty:
2121                        this is drf case, and just cur ch banner will be shown.
2122        */
2123
2124        if (index < 0) // this is DRF channel. find greatest lower channel number.
2125        {
2126                int start = -(((APP_CUR_CH.nMajor&0x7fff)<<16)|(APP_CUR_CH.nMinor&0xffff));
2127
2128                if (DMW_MSC_FindMinorDown(start, APP_CH_TUNE_POLICY, 1, &nUid) >= 1) {
2129                        index = DMW_MSC_Uid2Index(nUid);
2130                        dprint(0, "drf: search dn from %d-%d -> uid %d, idx %d\n", 
2131                                APP_CUR_CH.nMajor, APP_CUR_CH.nMinor, nUid, index);
2132                }
2133                else
2134                        nUid = -1;
2135        }
2136       
2137        if (index >= 0) // valid channel
2138        {
2139                nUid = APP_CUR_CH.nUid;
2140
2141                for (i = 0; i < g_UCM_number; i++)
2142                {
2143                        if (nUid == c_chinfo[i].uid)
2144                        {
2145                                idx = i+1;
2146                                break;
2147                        }
2148                }
2149
2150                if (idx == TotalUcmCount-1)
2151                {
2152                        for (i = 0; i <TotalUcmCount; i++)
2153                        {
2154                                if (c_chinfo[i].bFav)
2155                                {
2156                                        nUid = c_chinfo[i].uid;
2157                                        break;
2158                                }
2159                        }
2160                }
2161                else
2162                {
2163                        for (i = idx; i < TotalUcmCount; i++)
2164                        {
2165                                if (c_chinfo[i].bFav)
2166                                {
2167                                        nUid = c_chinfo[i].uid;
2168                                        bFind = TRUE;
2169                                        break;
2170                                }
2171                        }
2172
2173                        if (!bFind)
2174                        {
2175                                for (i = 0; i < idx; i++)
2176                                {
2177                                        if (c_chinfo[i].bFav)
2178                                        {
2179                                                nUid = c_chinfo[i].uid;
2180                                                bFind = TRUE;
2181                                                break;
2182                                        }
2183                                }
2184                        }
2185                }
2186        }
2187        DMW_MSC_UnlockUcm();
2188        // we selected channel 'nUid' as a next surf channel.
2189        // if no other surf channel exist,
2190        // or this is the only surf channel, just draw banner only without tuning.
2191        if (nUid <= 0 ||
2192                nUid == APP_CUR_CH.nUid)
2193        {
2194                dprint(0, "upper surf major from uid %d not found!\n", APP_CUR_CH.nUid);
2195
2196#if DRAW_SAME_CH_BANNER
2197                DMG_MenuUpdate(MID_CH_BANNER, 0);
2198#endif
2199
2200                return statusOK;
2201        }
2202
2203        return App_TuneChannelByUid(nUid);
2204}
2205
2206
2207
2208
2209#if COMMENT
2210____Tuning__API3___(){}
2211#endif
2212
2213//
2214// Quick Scan by DRF
2215//
2216static STATUS QuickScanEventProc(ChannelScanEventType evt, UINT32 evparam)
2217{
2218        if (evt == evtScanTunerSet)
2219        {
2220                ScanTunerSetCbParam *param = (ScanTunerSetCbParam *)evparam;
2221
2222                App_AutoScan_TunerSet(param);
2223        }
2224        else if (evt == evtNewChannel)
2225        {
2226                // 2010.03.25 foxhunt : quick scanÀ¸·Î new channelÀ» ¹ß°ßÇßÀ» ¶§, guide¸¦ ¾ø¾ÖÁØ´Ù.
2227                DMG_SetUserDefined(UD_ID_NO_CH_GUIDE, 0, 0);
2228        }
2229        else
2230                dprint(0, "!! unsupported scan event %d\n", evt);
2231
2232        return statusOK;
2233}
2234
2235
2236//------------------------------
2237//  QuickScanCompletedCallback
2238//
2239//   Callback of QuickScanAndTune
2240//   process result of quick scan and tune channel
2241//
2242static void QuickScanCompletedCallback(STATUS status, UINT32 userParam, 
2243                                void *pAdditionalParam)
2244{
2245        int i, idx;
2246        OneChannelScanCompleteParam *param = pAdditionalParam;
2247        APP_QUICKSCAN_TYPE type;
2248        int program_number;
2249        int uidToTune;
2250
2251        // quickscan user param:
2252        //
2253        //  MSB                 LSB
2254        //   31      16 15       0
2255        //  +----------+----------+
2256        //  |   type   | prog_num |
2257        //  +----------+----------+
2258
2259        type = (APP_QUICKSCAN_TYPE)((userParam >> 16) & 0xffff);
2260        program_number = userParam & 0xffff;
2261       
2262        dprint(0, "Quick scan complete: status %d, #%d, type %d %s\n", 
2263                                        status, program_number, 
2264                                        type, APP_QUICKSCAN_TYPE_STR(type));
2265
2266
2267        // DHL_ASSERT(param, "QuickScan add param NULL");
2268        // Updated by chjeon 080304
2269        if(!param)
2270        {
2271                dprint(0, "QuickScan add param NULL\n");
2272                status = statusError;
2273                goto label_tune_failed;
2274        }
2275       
2276       
2277        if (status != statusOK) {
2278                // out of memory
2279                // cancelled
2280                // µîµî..
2281                dprint(0, "!! quick scan failed\n");
2282                goto label_tune_failed;
2283        }
2284
2285        dprint(0, "  rf %d, flag 0x%x, %d uids scanned\n", 
2286                        param->rf, param->flag, param->nUid);
2287
2288        DMW_MSC_LockUcm();
2289
2290        for (i=0; i<param->nUid && param->uidBuf; i++)
2291        {
2292                idx = DMW_MSC_Uid2Index(param->uidBuf[i]);
2293                if (idx >= 0 && idx < g_UCM_number) {
2294                        g_UCM[idx].Skipped = 0; // RF ƪÀ¸·Î Ãß°¡µÈ ÆÄÀÏÀº Unskipped·Î megakiss 2012.11.15
2295                        dprint(0, "     uid %d, %c(%02d) %d-%d, #%d %s\n", 
2296                                        param->uidBuf[i],
2297                                        g_UCM[idx].Skipped ? ' ' : '+',
2298                                        idx,
2299                                        g_UCM[idx].Major, g_UCM[idx].Minor,
2300                                        g_UCM[idx].Prog_number, g_UCM[idx].scrambled ? "scrambled" : "");
2301                }
2302                else
2303                        dprint(0, "     uid %d, --\n"); 
2304                        // Ãß°¡ µÇ¾ú´Ù°í Çϴµ¥ DB¿¡¼­ ¸ø ãÀ½? ÀÌ·±°Ô ÀÖÀ¸¸é ¾ÈµÊ..
2305        }
2306
2307        // tuning ÇÒ uid¸¦ ã´Â´Ù.
2308        uidToTune = -1;
2309
2310        // 1. non-hidden, non-scrambled µÈ program_number ä³ÎÀ» ã´Â´Ù.
2311
2312        for (i=0; i<param->nUid && param->uidBuf; i++)
2313        {
2314                idx = DMW_MSC_Uid2Index(param->uidBuf[i]);
2315                if (idx < 0) continue;
2316                if (g_UCM[idx].Prog_number == program_number &&
2317                        g_UCM[idx].hidden == 0 &&
2318                        g_UCM[idx].scrambled == 0) {
2319                        uidToTune = param->uidBuf[i];
2320                        dprint(0, "  uid %d is selected in 1st pass\n", uidToTune);
2321                        break;
2322                }
2323        }
2324
2325        // 2. non-hidden, non-scrambled µÈ ÀÓÀÇ Ã¤³ÎÀ» ã´Â´Ù.
2326        for (i=0; uidToTune<0 && i<param->nUid && param->uidBuf; i++)
2327        {
2328                idx = DMW_MSC_Uid2Index(param->uidBuf[i]);
2329                if (idx < 0) continue;
2330                if (g_UCM[idx].hidden == 0 &&
2331                        g_UCM[idx].scrambled == 0) {
2332                        uidToTune = param->uidBuf[i];
2333                        dprint(0, "  uid %d is selected in 2nd pass\n", uidToTune);
2334                        break;
2335                }
2336        }
2337
2338        // 3. non-hidden ä³ÎÀ» ã´Â´Ù.
2339        for (i=0; uidToTune<0 && i<param->nUid && param->uidBuf; i++)
2340        {
2341                idx = DMW_MSC_Uid2Index(param->uidBuf[i]);
2342                if (idx < 0) continue;
2343                if (g_UCM[idx].hidden == 0) {
2344                        uidToTune = param->uidBuf[i];
2345                        dprint(0, "  uid %d is selected in 3rd pass\n", uidToTune);
2346                        break;
2347                }
2348        }
2349       
2350        DMW_MSC_UnlockUcm();
2351        App_NVM_SaveUcm();
2352       
2353
2354        if (uidToTune > 0) 
2355        {
2356                // cafrii 070713 change
2357                //   Quick scan ÈÄ¿¡ Æ©´×ÇÏ´Â °æ¿ì¿¡´Â ÀÌÀüä³Î Á¤º¸¸¦ update ÇÏ¸é ¾ÈµÈ´Ù.
2358                //
2359                //App_TuneChannelByUid(uidToTune);
2360                App_TuneChannelByUidEx(uidToTune, APP_UID_TUNE_DONT_SAVE_PREV);
2361               
2362                /* menu¿¡ drf tuneÀÌ Á¾·áµÇ¾ú´Ù´Â °ÍÀ» ¾Ë·ÁÁÖ±â À§ÇÑ ¸ñÀûÀÓ */
2363                DMG_SetUserDefined(UD_ID_TUNE_COMPLETED, uidToTune, 0);
2364                return;
2365        }
2366
2367        dprint(0, "!! no channel to tune.\n");
2368        status = statusChannelNotFound;
2369
2370label_tune_failed:
2371
2372        /* menu¿¡ drf tuneÀÌ Á¾·áµÇ¾ú´Ù´Â °ÍÀ» ¾Ë·ÁÁÖ±â À§ÇÑ ¸ñÀûÀÓ, -1Àº fail */
2373                DMG_SetUserDefined(UD_ID_TUNE_COMPLETED, (UINT32)-1, 0);
2374
2375        g_App_LastTuneResult = status;
2376
2377        // Digit tuneÀ» ÇÏ°í ³ª¼­ quick scanÀÌ failÀ̸é SMÀ» ±âµ¿½ÃŲ´Ù.
2378
2379        // cancelÀÌ µÈ °æ¿ì´Â ´ÙÀ½ tuning µ¿ÀÛÀÌ queue¿¡ ÀÖ´Ù´Â °ÍÀ» ÀǹÌÇϹǷÎ
2380        // SM µ¿ÀÛ ½Ãų ÇÊ¿ä ¾ø´Ù.
2381        //
2382
2383        if (status != statusCancelled)
2384                App_Restart_SMTask(FALSE, FALSE); 
2385                // No program ÀÎÁö Low signal ÀÎÁö ¾Ë ¼ö ¾øÀ¸³ª, tuning¿¡ ½ÇÆÐÇÑ °ÍÀº »ç½Ç..
2386}
2387
2388
2389//------------------------------
2390// App_ChTuneQuickScanAndTune
2391//
2392// µÎ ±ºµ¥¼­ ºÒ¸± ¼ö ÀÖÀ½.
2393//   1. digit key ¿¡ ÀÇÇÑ quick scan
2394//   2. 1¹ø ÀÛ¾÷Áß low signal¿¡¼­ sigmon retry°¡ µÇ´Â °æ¿ì.
2395//
2396// quick scan banner (animation) µîÀº caller°¡ ÀÛ¾÷À» ½ÃÀÛÇØ ³õ¾Æ¾ß ÇÑ´Ù.
2397// À̰÷¿¡¼­ banner 󸮴 ÇÏÁö ¾Ê´Â´Ù.
2398//
2399STATUS App_ChTuneQuickScanAndTune(int rf, int program_number, APP_QUICKSCAN_TYPE type)
2400{
2401        UINT32 scan_flag;
2402        STATUS status;
2403        UINT32 param;
2404
2405        dprint(0, "start quick scan.. rf %d, #%d\n", rf, program_number);
2406       
2407        if (type != APP_QUICKSCAN_SIGMON)
2408        {
2409                // banner Ç¥½Ã..
2410                // todo
2411                //   Áö±ÝÀº ÀÏ¹Ý banner·Î Ç¥½ÃÇÏÁö¸¸,
2412                //   ¾à°£ÀÇ animationÀÌ µé¾î°£ banner·Î º¯°æ °¡´ÉÇѰ¡?
2413                // iskang 3¹øÂ° arg FALSE->CH_NO_SHORTNAME·Î º¯°æ.
2414                // TODO: After Banner Porting (OSD)
2415                //App_DrawChBannerMajorMinor(rf, FALSE, 0, NO_SHORTNAME);
2416
2417                // cafrii 070713 change
2418                //   º°µµ·Î ÀÌÀü ä³Î Á¤º¸ ÀúÀå.
2419                App_SetPrevChannelInfo();
2420               
2421                App_ChTuneStopTV();
2422
2423                // ÀÌ ±â°£µ¿¾È info banner¿¡´Â ÃÖ¼ÒÇÑÀÇ Á¤º¸ 'rf' ¸¸ º¸¿©ÁÙ °ÍÀÓ.
2424                //
2425                App_UpdateQuickScanChannelParam(rf);
2426                App_SaveLastChannelInfo(rf, 0, 0);
2427        }
2428
2429        // quickscan user param:
2430        //
2431        //  MSB                 LSB
2432        //   31      16 15       0
2433        //  +----------+----------+
2434        //  |   type   | prog_num |
2435        //  +----------+----------+
2436
2437        param = ((type & 0xffff) << 16) | (program_number & 0xffff);
2438       
2439        scan_flag = (g_CurChannelType == ChannelType_Air ? CBTF_Air : CBTF_Cable);
2440        scan_flag |= (CBTF_ForcePSI | CBTF_IgnoreNtscInVct);
2441        // scan_flag |= CBTF_CheckScrambleByVideoContext
2442       
2443        status = DMW_ASC_ScanChannel(rf, 
2444                                        scan_flag,          // scan flag
2445                                        FALSE,              // wait for complete
2446                                        QuickScanEventProc,   // event callback
2447                                        QuickScanCompletedCallback, (UINT32)param, // complete callback
2448                                        TRUE);  // cancel prev commands
2449
2450        if (status == statusOK) 
2451        {
2452                dprint(0, "quick scan started\n");
2453                return statusOK;
2454        }
2455        else
2456        {
2457                // update cannot start..
2458                dprint(0, "!! quick scan cannot start, err %d\n", status);
2459
2460
2461                // digit key¿¡ ÀÇÇÑ quick scanÀ̶ó¸é ¹è³Ê°¡ ÀÖÀ» ¼ö ÀÖ´Ù.
2462                // banner°¡ ¾ø´Âµ¥ ¶Ç Áö¿ì´Â°Ô ¹®Á¦´Â ¾ÈµÇ¹Ç·Î ¹«Á¶°Ç È£Ãâ.
2463                //
2464               
2465                g_App_LastTuneResult = statusChannelNotFound;
2466               
2467                if (status != statusCancelled)
2468                        App_Restart_SMTask(FALSE, FALSE); // No program ÀÎÁö Low signal ÀÎÁö ¾Ë ¼ö ¾øÀ½.
2469        }
2470
2471        return status;
2472}
2473
2474
2475
2476
2477
2478#if COMMENT
2479____Tuning__API4___(){}
2480#endif
2481
2482/*
2483        manual scan °úÁ¤ ÁßÀÇ °¢Á¾ event ó¸®.
2484*/
2485static STATUS ManualScanEventProc(ChannelScanEventType evt, UINT32 evparam)
2486{
2487        if (evt == evtScanTunerSet)
2488        {
2489                ScanTunerSetCbParam *param = (ScanTunerSetCbParam *)evparam;
2490
2491                App_AutoScan_TunerSet(param);
2492        }
2493        else if (evt == evtNewChannel)
2494        {
2495                // 2010.03.25 foxhunt : RF scanÀ¸·Î new channelÀ» ¹ß°ßÇßÀ» ¶§, guide¸¦ ¾ø¾ÖÁØ´Ù.
2496                DMG_SetUserDefined(UD_ID_NO_CH_GUIDE, 0, 0);
2497        }
2498        else
2499                dprint(0, "!! unsupported scan event %d\n", evt);
2500
2501        return statusOK;
2502}
2503
2504
2505/*
2506        manual scan Á¾·á ÈÄ Ã³¸®.
2507        ä³ÎÀÌ °Ë»öÀÌ µÇ¾ú´Ù¸é °Ë»öµÈ ä³Î Áß ÀÓÀÇ Ã¤³Î·Î Æ©´×.
2508        °Ë»ö¿¡ ½ÇÆÐ Çß´Ù¸é manual scan Çϱâ Á÷ÀüÀÇ Ã¤³Î·Î ´Ù½Ã º¹±Í.
2509*/
2510static void ManualScanCompletedCallback(STATUS status, UINT32 userParam, 
2511                                void *pAdditionalParam)
2512{
2513        int i;
2514        OneChannelScanCompleteParam *param = pAdditionalParam;
2515        int uidToTune;
2516       
2517        dprint(0, "manual scan complete: status %d, user param %d\n", 
2518                                        status, userParam);
2519
2520        if (!param) {
2521                dprint(0, "!! manual scan add.param NULL\n");
2522                status = statusError;
2523                goto label_scan_failed;
2524        }
2525
2526        if (status != statusOK) {
2527                // out of memory, cancelled, µîµî..
2528                dprint(0, "!! manual scan failed %d\n", status);
2529                goto label_scan_failed;
2530        }
2531
2532        dprint(0, "  rf %d, flag 0x%x, %d uids scanned\n", 
2533                        param->rf, param->flag, param->nUid);
2534
2535        /*
2536                MW ¿¡¼­´Â »õ·Ó°Ô Ãß°¡µÈ ä³Îµé¿¡ ´ëÇØ¼­´Â ±âº»ÀûÀ¸·Î skipped »óÅ·Π¸¸µç´Ù.
2537                ±âÁ¸¿¡ ÀÌ¹Ì Á¸ÀçÇß´ø ä³ÎµéÀº ±âÁ¸ÀÇ enable/skip »óŰ¡ À¯ÁöµÈ´Ù.
2538               
2539                »ç¿ëÀÚ ÆíÀǸ¦ À§ÇØ ¸ðµç ä³ÎµéÀ» enable »óÅ·ΠÇÑ´Ù.
2540                ±âÁ¸¿¡ »ç¿ëÀÚ°¡ skipÀ¸·Î ¼³Á¤µÇ¾ú´ø Á¤º¸ ¸ðµÎ enable »óÅ·ΠoverwriteµÇ´Âµ¥,
2541                ¾î´À ¹æ½ÄÀÌ ´õ ³ªÀºÁö´Â ³í¶õÀÌ ÀÖÀ»¼ö ÀÖ´Ù.
2542               
2543                ÀÌ manual scan ±â´ÉÀÌ ÀÚÁÖ »ç¿ëµÇÁö ¾ÊÀº ±â´ÉÀ̹ǷΠū ¹®Á¦´Â ¾ÈµÉ °ÍÀ¸·Î º¸ÀÓ.
2544        */
2545       
2546        for (i=0; i<param->nUid; i++)
2547                DMW_MSC_EnableChannel(param->uidBuf[i], TRUE);
2548
2549        App_NVM_SaveUcm();
2550       
2551        {
2552                tApp_UcmSelectParam ucmSelParam;
2553                ucmSelParam.nUid = param->nUid;
2554                ucmSelParam.uidBuf = param->uidBuf;
2555               
2556                uidToTune = App_Ucm_SelectChannels(&ucmSelParam);
2557        }
2558
2559        if (uidToTune < 0) {
2560                dprint(0, "!! no channel to tune.\n");
2561                status = statusChannelNotFound;
2562                goto label_scan_failed;
2563        }
2564
2565        DMG_SetUserDefined(UD_ID_SCAN_BANNER_OPERATION, UD_ID_SCAN_BANNER_OPERATION_STOP, 0);
2566
2567        // cafrii 070713 change
2568        //   Quick scan ÈÄ¿¡ Æ©´×ÇÏ´Â °æ¿ì¿¡´Â ÀÌÀüä³Î Á¤º¸¸¦ update ÇÏ¸é ¾ÈµÈ´Ù.
2569        App_TuneChannelByUidEx(uidToTune, APP_UID_TUNE_DONT_SAVE_PREV);
2570       
2571        return;
2572
2573label_scan_failed:
2574
2575        if (status != statusCancelled) {
2576                // cancel ÀÌ µÈ °æ¿ì´Â ¹Ù·Î À̾ Æ©´× ÀÛ¾÷ÀÌ ÁøÇà µÉ °ÍÀ̹ǷÎ
2577                // Æ©´×À» ÇÏÁö ¾ÊÀ½.
2578                DMG_SetUserDefined(UD_ID_SCAN_BANNER_OPERATION, UD_ID_SCAN_BANNER_OPERATION_START, (UINT32)-1);
2579                DHL_OS_Delay(500);
2580                DMG_SetUserDefined(UD_ID_SCAN_BANNER_OPERATION, UD_ID_SCAN_BANNER_OPERATION_STOP, 0);
2581
2582                dprint(0, "  recover prev channel.. uid %d\n", userParam);
2583                App_TuneChannelByUidEx(userParam, (APP_UID_TUNE_FLAG)0);
2584        }
2585        else {
2586                DMG_SetUserDefined(UD_ID_SCAN_BANNER_OPERATION, UD_ID_SCAN_BANNER_OPERATION_STOP, 0);
2587        }
2588}
2589
2590
2591//------------------------------
2592// App_ChTuneQuickScanAndTune
2593//
2594STATUS App_ChTuneManualScan(int rf)
2595{
2596        UINT32 scan_flag;
2597        STATUS status;
2598        UINT32 uid;
2599
2600        dprint(0, "start manual scan.. rf %d\n", rf);
2601
2602        // progress ¹è³Ê Ç¥½Ã.
2603        DMG_SetUserDefined(UD_ID_SCAN_BANNER_OPERATION, UD_ID_SCAN_BANNER_OPERATION_START, rf);
2604
2605        // ÀÌÀü ä³Î Á¤º¸¸¦ ÀúÀåÇÏ¸é ¾ÈµÈ´Ù.
2606        // manual scanÀÌ ½ÇÆÐÇßÀ» °æ¿ì¿¡µµ ÀÌÀü ä³ÎÀÌ Á¦´ë·Î µ¿ÀÛÇØ¾ß Çϱ⠶§¹®.
2607        // App_SetPrevChannelInfo();
2608
2609        // ¾Æ·¡ ÇÔ¼ö¸¦ ºÎ¸£´Â ¼ø°£ ÇöÀç ½ÃûÁßÀΠä³Î Á¤º¸°¡ reset µÇ¾î ¹ö¸°´Ù.
2610        // µû¶ó¼­ manual scanÀÌ ½ÇÆÐÇÒ °æ¿ì¸¦ ´ëºñÇÏ¿© backupÀ» ÇØ µÎ¾î¾ß ÇÑ´Ù.
2611        //
2612        uid = APP_CUR_CH.nUid; // ÇöÀç ä³Î UID¸¦ user paramÀ¸·Î º¸Á¸.
2613        dprint(0, "  cur uid: %d\n", uid);
2614       
2615        App_ChTuneStopTV();
2616       
2617        //
2618        //App_UpdateQuickScanChannelParam(rf);
2619
2620        // nvm ÀúÀå ±â´Éµµ ¼öÇàÇÏÁö ¾ÊÀ½. manual scanÀÌ ¼º°øÇÑ ÈÄ¿¡ tuning ÇÒ ¶§ ¼öÇà.
2621        //App_SaveLastChannelInfo(rf, 0, 0);
2622       
2623        scan_flag = (g_CurChannelType == ChannelType_Air ? CBTF_Air : CBTF_Cable);
2624        scan_flag |= (CBTF_ForcePSI | CBTF_IgnoreNtscInVct);
2625        // scan_flag |= CBTF_CheckScrambleByVideoContext
2626       
2627        status = DMW_ASC_ScanChannel(rf, 
2628                                        scan_flag,          // scan flag
2629                                        FALSE,              // wait for complete
2630                                        ManualScanEventProc,   // event callback
2631                                        ManualScanCompletedCallback, (UINT32)uid, // complete callback
2632                                        TRUE);  // cancel prev commands
2633
2634        if (status == statusOK) 
2635        {
2636                dprint(0, "manual scan started\n");
2637                return statusOK;
2638        }
2639        else
2640        {
2641                // update cannot start..
2642                dprint(0, "!! manual scan cannot start, err %d\n", status);
2643                dprint(0, "  recover prev channel.. uid %d\n", uid);
2644                App_TuneChannelByUidEx(uid, (APP_UID_TUNE_FLAG)0);
2645        }
2646
2647        return status;
2648}
2649
2650
2651
2652
2653
2654#if COMMENT
2655____Tuning__API5___(){}
2656#endif
2657
2658#if USE_EPG_MW_PSI_DOWNLOAD
2659/*
2660        channel mw °¡ ¾Æ´Ñ epg mw ¿¡¼­ psi °ü¸®¸¦ ÇÏ´Â °æ¿ì¿¡´Â
2661        Á» ´Ù¸¥ ±¸ÇöÀÌ ÇÊ¿äÇÏ´Ù.
2662        ÀÏ´Ü ³ªÁßÀ¸·Î ¹Ì·ë.
2663*/
2664STATUS App_ChTuneAddDelChannel(BOOL bAdd, BOOL bScanOtherChannel)
2665{
2666        dprint(0, "!! %s: not implemented yet\n", __func__);
2667}
2668
2669#else // !USE_EPG_MW_PSI_DOWNLOAD
2670
2671//------------------------------
2672//  UpdateChannelCompleted
2673// 
2674//  CH_ADD Ű¿¡ ÀÇÇØ update¸¦ ½ÃÀÛÇÏ°í ³ª¼­ Á¾·áµÈ ´ÙÀ½¿¡ ºÒ¸®´Â callback.
2675// 
2676static void UpdateChannelCompleted(STATUS status, UINT32 userParam, 
2677                                void *pAdditionalParam)
2678{
2679        int i, idx;
2680        OneChannelScanCompleteParam *param = pAdditionalParam;
2681        BOOL bWaitCompleteMode = userParam;
2682       
2683        dprint(0, "Update Channel Complete: status %d\n", status);
2684
2685        if (param == NULL || status != statusOK)
2686                return;
2687
2688        dprint(0, "  rf %d, flag 0x%x, %d uids scanned\n", 
2689                        param->rf, param->flag, param->nUid);
2690
2691        DMW_MSC_LockUcm();
2692
2693        // ÇöÀç g_App_ChannelÀÇ Á¤º¸¸¦ »õ DB¿¡ ¸Â°Ô Á¶Á¤.
2694        //
2695        for (i=0; i<g_UCM_number; i++) {
2696                if (g_UCM[i].RF == APP_CUR_CH.nRF &&
2697                        g_UCM[i].Prog_number == APP_CUR_CH.nProgramNumber) {
2698                        APP_CUR_CH.nUid = g_UCM[i].Uid;
2699                        //g_UCM[i].Skipped = 0;  // ÀÌ Ã¤³Î¸¸ ÀÚµ¿À¸·Î add »óÅ·Π¼öÁ¤.
2700                        // cafrii 060629 fix
2701                        // add »óÅ¿¡¼­ skipÀ¸·ÎÀÇ º¯°æÀÎ °æ¿ì¿¡µµ ÀÌ callbackÀÌ ºÒ¸®¹Ç·Î
2702                        // ¼³Á¤ÇÏ¸é ¾ÈµÈ´Ù.
2703                        // caller¿¡¼­ ¸ÕÀú add/skip ¼³Á¤ ÇÑ ÈÄ¿¡ scanÀ» Çϵµ·Ï ÇÏÀÚ..
2704                        break;
2705                }
2706        }
2707
2708        for (i=0; i<param->nUid; i++) {
2709                idx = DMW_MSC_Uid2Index(param->uidBuf[i]);
2710                if (idx >= 0 && idx < g_UCM_number)
2711                        dprint(0, "     uid %d, %c(%02d) %d-%d, #%d\n", 
2712                                        param->uidBuf[i],
2713                                        g_UCM[idx].Skipped ? ' ' : '+',
2714                                        idx,
2715                                        g_UCM[idx].Major, g_UCM[idx].Minor,
2716                                        g_UCM[idx].Prog_number);
2717                else
2718                        dprint(0, "     uid %d, --\n"); 
2719                        // Ãß°¡ µÇ¾ú´Ù°í Çϴµ¥ DB¿¡¼­ ¸ø ãÀ½? ÀÌ·±°Ô ÀÖÀ¸¸é ¾ÈµÊ..
2720        }
2721               
2722        DMW_MSC_UnlockUcm();
2723
2724        dprint(0, "  current uid is set to %d\n", APP_CUR_CH.nUid);
2725
2726        // cafrii 060808, last channel Á¤º¸¿¡¼­ uid°¡ ºüÁö¹Ç·Î ´Ù½Ã ÀúÀå ºÒÇÊ¿ä.
2727        //App_SaveLastChannelInfo(0, 0, APP_CUR_CH.nUid);
2728
2729        App_NVM_SaveUcm();
2730
2731        if (bWaitCompleteMode == FALSE) {
2732                dprint(0, "recover from update..\n");
2733               
2734                Dmc_PausePsiMonitor(FALSE); // resume..
2735
2736                App_Resume_SMTask();
2737        }
2738       
2739}
2740
2741
2742//------------------------------
2743//  App_ChTuneAddDelChannel
2744//
2745//  ¸®¸ðÄÁ CH_ADD Ű ó¸®
2746//  Ch Edit³ª, EPG¿¡ µé¾î°¡±â Àü¿¡ ÇöÀç ä³ÎÀ» Àӽ÷Πµî·ÏÇÏ·Á¸é
2747//  bScanOtherChannel¸¦ FALSE·Î »ç¿ëÇÏ¸é µÈ´Ù.
2748// 
2749//  mightwar, add 'bAdd' variable
2750//
2751STATUS App_ChTuneAddDelChannel(BOOL bAdd, BOOL bScanOtherChannel)
2752{
2753        // ÇöÀç ä³ÎÀÌ DB¿¡ ÀÖ°í skipped À̸é add·Î..
2754
2755        // ÇöÀç ä³ÎÀÌ DB¿¡ ÀÖ°í add À̸é skipped·Î..
2756
2757        // ÇöÀç ä³ÎÀÌ DB¿¡ ¾øÀ¸¸é
2758        //   ÀÏ´Ü ÇöÀç Á¤º¸¸¦ ÀÌ¿ëÇÏ¿© DB entry Çϳª¸¦ add·Î Ãß°¡Çϰí,
2759        //   »õ·Î °Ë»ö ÀÛ¾÷À» ½ÃÀÛÇØ¼­ ´Ù¸¥ subchannel±îÁö skipped·Î Ãß°¡.
2760
2761        STATUS status;
2762        int idx;
2763        int rf;
2764        UINT32 scan_flag = 0;
2765        tDHL_Demod mod;
2766
2767        BOOL bWaitCompleteMode = FALSE;
2768
2769        dprint(0, "%s:\n", __FUNCTION__);
2770       
2771        if (APP_CUR_CH.nUid > 0)
2772        {
2773                DMW_MSC_LockUcm();
2774               
2775                idx = DMW_MSC_Uid2Index(APP_CUR_CH.nUid);
2776                if (idx < 0) {
2777                        dprint(0, "!! cur channel uid %d is invalid. treat as DRF %d\n", 
2778                                APP_CUR_CH.nUid, APP_CUR_CH.nRF);
2779                }
2780                else {
2781
2782                        //g_UCM[idx].Skipped = g_UCM[idx].Skipped ? 0 : 1;
2783                        g_UCM[idx].Skipped = bAdd ? 0 : 1;
2784                       
2785                        if(!bAdd && g_UCM[idx].SurfIndex)
2786                                g_UCM[idx].SurfIndex = 0;
2787                       
2788                          // todo
2789                          // º¯°æ»çÇ×ÀÌ ¾ø´Â °æ¿ì¿¡´Â Ucm save¸¦ ¾ÈÇØµµ µÇ´Âµ¥,
2790                          // ÀÏ´Ü ³ªÁß¿¡..
2791                        dprint(0, "  'skip' changed to %d\n", g_UCM[idx].Skipped);
2792                }
2793                DMW_MSC_UnlockUcm();
2794
2795                if (idx >= 0) { // Á¦´ë·Î º¯È¯¿¡ ¼º°øÇÑ °æ¿ì..
2796                        App_NVM_SaveUcm();
2797
2798                        if (bScanOtherChannel)
2799                                goto label_background_scan;
2800                               
2801                        return statusOK;
2802                }
2803                // º¯È¯ÀÌ ¾ÈµÈ °æ¿ì´Â DB¿¡ ¹®Á¦°¡ ÀÖ´Â °æ¿ì.. DRF·Î °£ÁÖÇÏ°í µ¿ÀÛÇÑ´Ù.
2804        }
2805
2806        // ÇöÀç DRF ä³ÎÀ̰ųª, UID°¡ invalid ÇÑ °æ¿ì.. ´Ù½Ã °Ë»öÀÌ ÇÊ¿äÇÔ.
2807
2808        dprint(0, "!! cur channel (rf %d, #%d) not in DB\n", 
2809                                APP_CUR_CH.nRF, APP_CUR_CH.nProgramNumber);
2810
2811        // ¸ÕÀú ÇöÀç Á¤º¸¸¸À» ÀÌ¿ëÇÏ¿© ÀúÀå..
2812       
2813        DMW_MSC_LockUcm();
2814
2815        DHL_FE_GetModFormat(DEFAULT_TUNER_ID, &mod);
2816       
2817        if (mod != eDHL_DEMOD_8VSB && mod != eDHL_DEMOD_64QAM && mod != eDHL_DEMOD_256QAM)
2818                mod = APP_CUR_CH.nChannelType == ChannelType_Air ? eDHL_DEMOD_8VSB : eDHL_DEMOD_64QAM;
2819                       
2820                       
2821        rf = 0;
2822        if (IS_VALID_RF(APP_CUR_CH.nChannelType, APP_CUR_CH.nRF)) {
2823                rf = APP_CUR_CH.nRF;
2824        }
2825        else {
2826                if (IS_VALID_RF(APP_CUR_CH.nChannelType, APP_CUR_CH.nMajor)) {
2827                        dprint(0, "!! cur rf %d invalid. use major %d instead\n", APP_CUR_CH.nMajor);
2828                        rf = APP_CUR_CH.nMajor;
2829                }
2830                else
2831                        dprint(0, "!! cur rf %d invalid\n", APP_CUR_CH.nRF);
2832        }
2833
2834#if 1
2835        idx = DMW_CDB_MakeNewUcm(rf, 1, rf, FALSE, (int)mod);
2836
2837#else
2838        // cafrii, Ȥ½Ã program number°¡ invalidÇÒ °æ¿ì 1·Î ÇÒ´ç.
2839        if (APP_CUR_CH.bPSIChannel) {
2840                idx = DMW_CDB_MakeNewUcm(APP_CUR_CH.nRF, 
2841                                APP_CUR_CH.nProgramNumber >= 1 ?
2842                                DMW_ASC_ProgramNumberToMinor(APP_CUR_CH.nProgramNumber) : 1,
2843                                APP_CUR_CH.nRF, FALSE, (int)mod);
2844        }
2845        else {
2846                idx = DMW_CDB_MakeNewUcm(APP_CUR_CH.nMajor, APP_CUR_CH.nMinor, 
2847                                APP_CUR_CH.nRF, TRUE, (int)mod);
2848        }
2849#endif // #if 1
2850
2851        // cafrii add
2852        // Ȥ½Ã ¸Þ¸ð¸®°¡ ºÎÁ·Çؼ­ make¸¦ ¸øÇÒ °æ¿ì¿¡ ´ëÇÑ Ã¼Å© Ãß°¡.
2853        if (idx >= 0) {
2854                g_UCM[idx].source_id = APP_CUR_CH.nSourceId;
2855                g_UCM[idx].Skipped = bAdd ? 0 : 1;
2856                g_UCM[idx].Prog_number = APP_CUR_CH.nProgramNumber;
2857                memcpy(g_UCM[idx].ShortName, APP_CUR_CH.ShortName, sizeof(g_UCM[idx].ShortName));
2858
2859                if (g_App_LastTuneResult == statusOK) {
2860                        g_UCM[idx].Pcr_pid = APP_CUR_CH.uPcrPid;
2861                        g_UCM[idx].Video_pid = APP_CUR_CH.uVidPid;
2862                        g_UCM[idx].Audio_pid = APP_CUR_CH.uAudPid;
2863                }
2864                else {
2865                        g_UCM[idx].Pcr_pid = DMW_PID_NO_INFO;
2866                        g_UCM[idx].Video_pid = DMW_PID_NO_INFO;
2867                        g_UCM[idx].Audio_pid = DMW_PID_NO_INFO;
2868                }
2869                APP_CUR_CH.nUid = g_UCM[idx].Uid;
2870        }
2871        else
2872                dprint(0, "  make new ucm err!\n");
2873       
2874        DMW_MSC_UnlockUcm();
2875
2876        dprint(0, "  current uid set to %d\n", APP_CUR_CH.nUid);
2877
2878        // cafrii 060808, last channel Á¤º¸¿¡¼­ uid°¡ ºüÁö¹Ç·Î ´Ù½Ã ÀúÀå ºÒÇÊ¿ä.
2879        //App_SaveLastChannelInfo(0, 0, APP_CUR_CH.nUid);
2880
2881        App_NVM_SaveUcm(); // ÀÏ´Ü ÇöÀç ¼öÁ¤ »çÇ× ±îÁö¸¸ÀÌ¶óµµ ÀúÀå.
2882       
2883        // ÇöÀç ½Ãû ä³Î¸¸ °£´ÜÈ÷ µî·ÏÇÏ´Â °ÍÀ̶ó¸é ¿©±â¼­ Á¾·á.
2884        if (bScanOtherChannel == FALSE)
2885                return statusOK;
2886               
2887
2888label_background_scan:
2889
2890        // background update ½ÃÀÛ..
2891        dprint(0, "start background scan.. %s mode\n", bWaitCompleteMode ? "wait" : "nowait");
2892               
2893        // SigMon¿¡¼­ low signal¿¡ ÀÇÇØ disable/enable TV¸¦ ¼öÇàÇØ ¹ö¸± °¡´É¼º ÀÖÀ½.
2894        // ±×·¯³ª ¹Ù·Î ¾Æ·¡¿¡¼­ update°¡ Àß ¾ÈµÉ ¼ö ÀÖ´Ù. ¾îµð±îÁö³ª ¿î¿¡ µû¸§.
2895        App_Pause_SMTask();
2896       
2897        // ÇöÀç signal monitor¿¡ ÀÇÇØ stopÀÌ µÇ¾î ÀÖÀ» ¼öµµ ÀÖÀ½.
2898        // µµÁß¿¡ SMÀÌ µ¿ÀÛÇÏ´Â °ÍÀ» ¸·±â À§ÇØ ÀÏ´Ü SMÀ» hold ½ÃŲ´Ù.
2899        Dmc_PausePsiMonitor(TRUE);
2900       
2901        scan_flag = (g_CurChannelType == ChannelType_Air ? CBTF_Air : CBTF_Cable);
2902        scan_flag |= (CBTF_8VSB | CBTF_QAM); // cafrii 060814, digital only
2903        scan_flag |= CBTF_SkipTunerSet;
2904
2905        status = DMW_ASC_UpdateChannel(APP_CUR_CH.nRF, scan_flag, 
2906                                bWaitCompleteMode, 
2907                                UpdateChannelCompleted, bWaitCompleteMode, 
2908                                FALSE);
2909
2910        if (bWaitCompleteMode) 
2911        {
2912                dprint(0, "update channel completed. err %d\n", status);
2913                goto label_recover_from_update;
2914        }
2915        else
2916        {
2917                if (status == statusOK) {
2918                        dprint(0, "update channel started\n");
2919                        return statusOK;
2920                }
2921                else
2922                {
2923                        // update cannot start..
2924                        dprint(0, "!! update channel cannot start, err %d\n", status);
2925                        goto label_recover_from_update;
2926                }
2927        }
2928
2929label_recover_from_update:
2930
2931        // wait mode°¡ ¾Æ´Ñ °æ¿ì callback¿¡µµ ÀÌ¿Í µ¿ÀÏÇÑ Äڵ尡 Ãß°¡µÇ¾î¾ß ÇÑ´Ù.
2932        Dmc_PausePsiMonitor(FALSE); // resume..
2933
2934        App_Resume_SMTask();
2935       
2936        return statusOK;
2937}
2938
2939#endif // USE_EPG_MW_PSI_DOWNLOAD
2940
2941
2942
2943// bAddOrDel : TRUE -> ADD / FALSE -> FALSE
2944void App_ChTuneAddDelSurfCurChannel(BOOL bAddOrDel)
2945{
2946        int i = -1;
2947
2948        DMW_MSC_LockUcm();
2949       
2950        if(APP_CUR_CH.nUid > 0)
2951                i = DMW_MSC_Uid2Index(APP_CUR_CH.nUid);
2952        else
2953        {
2954                DMW_MSC_UnlockUcm();
2955                return;
2956        }
2957
2958        if(i >= 0)
2959        {
2960                if(bAddOrDel)   //Add
2961                {
2962                        if(g_UCM[i].Skipped)    //Add À϶§´Â skipÀ» ÇØÁ¦
2963                                g_UCM[i].Skipped = FALSE;
2964                }
2965                g_UCM[i].SurfIndex = bAddOrDel;
2966        }
2967        DMW_MSC_UnlockUcm();
2968
2969        App_NVM_SaveUcm();     
2970        return;
2971}
2972
2973
2974// App_ChTunePrevChannel
2975//
2976// ÀÌÀü ä³Î ۰¡ ´­·ÈÀ» ¶§ ºÒ¸°´Ù.
2977// ÀÌÀü ä³Î Æ©´× ±â´ÉÀº autoscan ¼öÇà½Ã, ¸®ºÎÆÃ½Ã, Air/Cable º¯È¯½Ã¿¡´Â resetµÈ´Ù.
2978// Channel DBÀÇ ³»¿ëÀÌ º¯°æ µÇÁö ¾Ê´Â ¾ÈÀüÇÑ »óȲ¿¡¼­¸¸ µ¿ÀÛÇÏ´Â ±â´ÉÀÌ´Ù.
2979//
2980// ±×·¡¼­ ÀÌÀü ä³Î Á¤º¸¸¦ UID·Î ±â¾ïÇØµµ µÈ´Ù.
2981// No program channelÀ̾ú´ø °æ¿ì¿¡´Â rf·Î ±â¾ïÀ» ÇÑ´Ù.
2982// program number Á¤º¸´Â ÇÊ¿ä ¾ø´Ù.
2983//
2984// todo..
2985// ChADD¿Í °°ÀÌ ÀϺΠDB update µ¿ÀÛÀÌ ¼öÇàµÈ °æ¿ì¿¡´Â
2986// ÀÌÀü ä³Î ±â´ÉÀÌ µ¿ÀÛÇÏÁö ¾ÊÀ» ¼öµµ ÀÖ´Ù.
2987// DB°¡ ´Ü¼øÈ÷ update¸¸ µÇ¸é ¹®Á¦ ¾øÁö¸¸ overwrite µÇ¸é uid°¡ º¯°æµÉ ¼ö Àֱ⠶§¹®.
2988//
2989STATUS App_ChTunePrevChannel(void)
2990{
2991        int uid = g_App_PrevChannel.nUid;
2992        int rf = g_App_PrevChannel.nRF;
2993        //int pn = g_App_PrevChannel.nProgramNumber;
2994       
2995        bPrevCH = TRUE;
2996       
2997        if (uid > 0)
2998        {
2999                dprint(0, "PrevChannel: uid %d\n", uid);
3000                App_TuneChannelByUid(uid);
3001        }
3002        else if (rf > 0)
3003        {
3004                dprint(0, "PrevChannel: rf %d\n", rf);
3005                App_ChTuneQuickScanAndTune(rf, 0, APP_QUICKSCAN_DRF);
3006        }
3007        else 
3008        {
3009                dprint(0, "No PrevChannelInfo rf %d, uid %d\n", rf, uid);
3010        }
3011
3012        return statusOK;
3013}
3014
3015
3016// cafrii 060814 add
3017//  App_SearchMostCloseChannel
3018//
3019//  °¡Àå ±ÙÁ¢ÇÑ Ã¤³ÎÀ» °Ë»öÇÑ´Ù.
3020//  °Ë»öµÈ ä³ÎÀÇ UID °ªÀ» ¸®ÅÏÇÑ´Ù.
3021//
3022int App_SearchMostCloseChannel(int major, int minor)
3023{
3024        int uidFound = -1;
3025
3026        UINT32 flag = CSF_Include_Skipped | CSF_ATSC_Only | CSF_Include_PSI | CSF_DontWrapAround;
3027
3028        int MajorMinor;
3029        int nFound;     
3030
3031        dprint(0, "Search most close channel from %d-%d..\n", major, minor);
3032       
3033        // 1. ¸ÕÀú Á¤È®ÇÏ°Ô ÀÏÄ¡Çϴ ä³ÎÀ» ã´Â´Ù.
3034        //
3035        nFound = DMW_MSC_FindChannelMajorMinor(major, minor, flag, 1, &uidFound);
3036        if (nFound > 0)
3037                goto label_end;
3038               
3039        // 2. upper side·Î ±ÙÁ¢ÇÑ Ã¤³Î °Ë»ö.
3040        //
3041        MajorMinor = -(((major & 0x3fff) << 16) | (minor & 0xffff));
3042
3043        nFound = DMW_MSC_FindMinorUp(MajorMinor, flag, 1, &uidFound);
3044        if (nFound > 0)
3045                goto label_end;
3046
3047        // 3. lower side·Î ±ÙÁ¢ÇÑ Ã¤³Î °Ë»ö.
3048        //
3049        nFound = DMW_MSC_FindMinorDown(MajorMinor, flag, 1, &uidFound);
3050        if (nFound > 0)
3051                goto label_end;
3052
3053        dprint(0, "!! close channel search err\n");
3054        return -1;
3055       
3056label_end:
3057        dprint(0, "    uid %d is most close channel\n", uidFound);
3058       
3059        return uidFound;
3060}
3061
3062
3063// SelectAnyValidChannel
3064//
3065//  ÀÓÀÇ Ã¤³ÎÀ» ¼±ÅÃÇÑ´Ù. ¼±ÅÃµÈ Ã¤³ÎÀÇ uid¸¦ ¸®ÅÏÇÑ´Ù.
3066//  Æ©´×ÇÒ Ã¤³ÎÀ» ãÁö ¸øÇϸé -1 ¸®ÅÏ.
3067//
3068static int SelectAnyValidChannel(void)
3069{
3070        int i;
3071        int uidToTune = -1;
3072       
3073        DMW_MSC_LockUcm();
3074       
3075        // 1. non-hidden, non-scrambled µÈ ä³ÎÀ» ã´Â´Ù.
3076
3077        for (i=0; g_UCM && i<g_UCM_number; i++)
3078        {
3079                if (g_UCM[i].hidden == 0 &&
3080                        g_UCM[i].scrambled == 0) {
3081                        uidToTune = g_UCM[i].Uid;
3082                        break;
3083                }
3084        }
3085
3086        // 2. non-hidden ä³ÎÀ» ã´Â´Ù.
3087        for (i=0; uidToTune<0 && g_UCM && i<g_UCM_number; i++)
3088        {
3089                if (g_UCM[i].hidden == 0) {
3090                        uidToTune = g_UCM[i].Uid;
3091                        break;
3092                }
3093        }
3094       
3095        DMW_MSC_UnlockUcm();
3096
3097        return uidToTune;
3098}
3099
3100
3101// App_ChTuneRecoverLastChannel
3102//
3103// 1. ºÎÆÃ °úÁ¤ ¸¶Áö¸· ´Ü°è¿¡¼­ ºÒ¸°´Ù.
3104// 2. Air/Cable Àüȯ½Ã¿¡ ºÒ¸°´Ù.
3105// 3. Autoscan ÈÄ¿¡µµ ºÒ¸°´Ù.
3106//
3107// APP_CUR_CH.nChannelType º¯¼ö´Â ¿Ã¹Ù¸£°Ô ¼³Á¤µÇ¾î ÀÖ¾î¾ß ÇÑ´Ù.
3108//
3109STATUS App_ChTuneRecoverLastChannel(void)
3110{
3111        int i, rf, pn, uid;
3112        //BOOL bUidOK;
3113        UINT8 data8;
3114        UINT32 data32;
3115
3116        // cafrii 060808 change
3117        // uid´Â NvRam¿¡¼­ ÀÐ¾î ¿Ã ¶§ resetµÇ´Â °ªÀ̹ǷΠ½Å·Ú ÇÒ ¼ö ¾ø´Ù.
3118        // uid¸¦ ÀÌ¿ëÇÑ ¹æ¹ýÀº ¸ðµÎ »èÁ¦ÇÑ´Ù.
3119
3120        if (APP_CUR_CH.nChannelType == ChannelType_Air) {
3121                App_NVM_LoadModuleParam(eAPP_NVR_CHTUNE, &p_chtune_nvm_param);         
3122                rf = p_chtune_nvm_param.air_rf;
3123                pn = p_chtune_nvm_param.air_pn;
3124        }
3125#if SUPPORT_POD
3126        else if (App_Op_IsOobMode()) {
3127                App_NVM_LoadModuleParam(eAPP_NVR_CHTUNE, &p_chtune_nvm_param);         
3128                rf = p_chtune_nvm_param.oob_rf;
3129                pn = p_chtune_nvm_param.oob_pn;
3130        }
3131#endif
3132        else {
3133                App_NVM_LoadModuleParam(eAPP_NVR_CHTUNE, &p_chtune_nvm_param);         
3134                rf = p_chtune_nvm_param.cable_rf;
3135                pn = p_chtune_nvm_param.cable_fn;
3136        }
3137
3138        dprint(0, "try last channel recevery, %s, rf %d, #%d\n",
3139                        APP_CUR_CH.nChannelType == ChannelType_Air ? "Air" : "Cable", rf, pn);
3140       
3141
3142        // Æ©´× µµÁß¿¡ g_App_PrevChannel <-- APP_CUR_CH backupÀÌ ÀÌ·ç¾îÁø´Ù.
3143        // ÃÖÃÊ ºÎÆÃ ÈÄ¿¡´Â prev channel tuneÀÌ ¾ÈµÇ¾î¾ß ÇϹǷÎ
3144        // ÇÊ¿äÇÑ Á¤º¸¸¦
3145
3146        APP_CUR_CH.nRF = 0;
3147        APP_CUR_CH.nProgramNumber = 0;
3148        APP_CUR_CH.nUid = 0;
3149
3150        // STEP 1
3151        // rf, pnÀ¸·Î Channel DB °Ë»ö
3152
3153        uid = 0;
3154        DMW_MSC_LockUcm();
3155        for (i=0; i<g_UCM_number; i++)
3156        {
3157                if (g_UCM[i].RF == rf && g_UCM[i].Prog_number == pn && 
3158                        g_UCM[i].hidden == 0) {
3159                        uid = g_UCM[i].Uid;
3160                        break;
3161                }
3162        }
3163        DMW_MSC_UnlockUcm();
3164
3165        if (uid > 0) {
3166                dprint(0, "  channel uid %d found..\n", uid);
3167                return (STATUS)App_TuneChannelByUid(uid);
3168        }
3169
3170
3171#if SUPPORT_POD
3172        if (1)
3173        {
3174                dprint(0, "\n!! channel not found.. try to tune any channel \n");
3175               
3176                // ÀÓÀÇ Ã¤³Î Æ©´×..
3177                //uid = App_Ucm_SelectChannels(NULL);
3178                uid = SelectAnyValidChannel();
3179                if (uid > 0)
3180                        return (STATUS)App_TuneChannelByUid(uid);
3181
3182                // Æ©´×ÇÒ Ã¤³ÎÀÌ ¾øÀ¸¸é ¾ÈÇÏ¸é µÊ.
3183                // caller´Â ÀûÀýÇÑ Á¶Ä¡¸¦ ÃëÇØ¾ß ÇÑ´Ù.
3184                //
3185                // ex: no channel banner µî..
3186        }
3187
3188#else
3189        // STEP 2
3190        // rf, pnÀ¸·Î quick scan
3191
3192        dprint(0, "  using rf/pn quickscan..\n");
3193
3194        if (APP_CUR_CH.nChannelType == ChannelType_Air)
3195        {
3196                // 1. rf °ªÀÌ À¯È¿ÇÑ °æ¿ì quickscan ½Ãµµ..
3197                //
3198                if (rf >= APP_CHTUNE_AIR_RF_MIN && rf <= APP_CHTUNE_AIR_RF_MAX) {
3199                        return App_ChTuneQuickScanAndTune(rf, pn, APP_QUICKSCAN_DRF);
3200                }
3201
3202                // 2. DB°¡ Á¸ÀçÇÏ´Â °æ¿ì, ÀÓÀÇ À¯È¿ ä³Î Æ©´×
3203                //
3204                uid = SelectAnyValidChannel();
3205                if (uid > 0)
3206                        return (STATUS)App_TuneChannelByUid(uid);
3207               
3208                // 3. DB¿¡¼­µµ º° Á¤º¸°¡ ¾ø´Â °æ¿ì
3209                //
3210                dprint(0, " scan default rf %d..\n", APP_CHTUNE_AIR_RF_DEFAULT);
3211
3212                return App_ChTuneQuickScanAndTune(APP_CHTUNE_AIR_RF_DEFAULT, 0, APP_QUICKSCAN_DRF);
3213        }
3214        else // ChannelType_Cable
3215        {
3216                if (rf >= APP_CHTUNE_CABLE_RF_MIN && rf <= APP_CHTUNE_CABLE_RF_MAX) {
3217                        return App_ChTuneQuickScanAndTune(rf, pn, APP_QUICKSCAN_DRF);
3218                }
3219
3220                dprint(0, " rf %d invalid. tune any valid channel\n", rf);
3221               
3222                uid = SelectAnyValidChannel();
3223                if (uid > 0)
3224                        return (STATUS)App_TuneChannelByUid(uid);
3225
3226                return App_ChTuneQuickScanAndTune(APP_CHTUNE_CABLE_RF_DEFAULT, 0, APP_QUICKSCAN_DRF);
3227        }
3228
3229#endif // #if SUPPORT_POD
3230}
3231
3232
3233
3234
3235
3236#if COMMENT
3237____TunerMode____(){}
3238#endif
3239
3240STATUS App_ChangeChannelType(ChannelType nType)
3241{
3242        STATUS status = statusOK;
3243
3244        dprint(0, "App_ChangeChannelType (%d, %s)\n", nType, ChannelTypeString(nType));
3245
3246        // cafrii 060609 add err check
3247        if (nType != ChannelType_Air && nType != ChannelType_Cable)
3248                return statusInvalidArgument;
3249
3250#if SUPPORT_ONLY_CABLE
3251        if (nType != ChannelType_Cable && !p_chtune_nvm_param.enable_force_aircable) {
3252                dprint(0, "!! support only cable chtype. forced to set Cable!\n");
3253                nType = ChannelType_Cable;
3254        }
3255#elif SUPPORT_ONLY_AIR
3256        if (nType != ChannelType_Air && !p_chtune_nvm_param.enable_force_aircable) {
3257                dprint(0, "!! support only cable chtype. forced to set Cable!\n");
3258                nType = ChannelType_Air;
3259        }
3260#endif
3261
3262        if(APP_CUR_CH.nChannelType == nType)
3263                return statusInvalidArgument;
3264       
3265        App_ChTuneStopTV();
3266
3267        App_EpgDeleteAll();
3268
3269#if SUPPORT_SDDS
3270        App_SddsDeleteAll();
3271//      DHL_ASSERT(FALSE, "just check..\n");
3272#endif
3273       
3274        status = DMW_CDB_InitializeChannelLib((ChannelType)nType, 0);
3275       
3276        if(status) {
3277                dprint(0, "!! error : init ch lib failed(err code : %d)\n", status);
3278        }
3279
3280        // cafrii 060609, servicetype -> channeltype
3281        APP_CUR_CH.nChannelType = nType;
3282
3283        // cafrii 060609, remember last channel type
3284        p_chtune_nvm_param.nChannelType = APP_CUR_CH.nChannelType;
3285        App_NVM_SaveModuleParam(eAPP_NVR_CHTUNE, &p_chtune_nvm_param);
3286
3287        App_ResetPrevChannelInfo();     // ÀÌÀü ä³Î Á¤º¸´Â »èÁ¦ÇÑ´Ù.
3288
3289        App_NVM_LoadUcm();
3290
3291        App_ChTuneRecoverLastChannel();
3292
3293        return statusOK;
3294}
3295
3296
3297
3298#if COMMENT
3299____DynChUpdate____(){}
3300#endif
3301
3302
3303void App_PreProcessDynamicUpdateChannel(void)
3304{
3305        int i;
3306
3307        // fresh bit¸¦ Ȱ¿ëÇϱâ À§Çؼ­ ¸ÕÀú reset.
3308        DMW_MSC_LockUcm();
3309        for (i=0; i<g_UCM_number; i++) {
3310                g_UCM[i].fresh = FALSE;
3311        }
3312        DMW_MSC_UnlockUcm();
3313}
3314
3315static BOOL bRunDynamicChannelUpdate = FALSE; //2012.12.06 megakiss
3316static BOOL bCancelDynamicChUpdate = FALSE; //2012.12.06 megakiss
3317
3318void App_PostProcessDynamicUpdateChannel(int nUid, int *uidBuf)
3319{
3320        int i, idx;
3321        int rf = 0;
3322        int n_disabled = 0;
3323        int bSeeked;
3324        int bUCMLocked = 1;
3325        int uid = 1;
3326        DMW_MSC_LockUcm();
3327        // 1Â÷ ó¸®:
3328        // À̹ø¿¡ »õ·Ó°Ô Ãß°¡µÈ ä³ÎÀº ¸ðµÎ ´Ù enable ·Î ¼³Á¤.
3329        // ±âÁ¸¿¡ »ç¿ëÀÚ°¡ ÀϺη¯ skip ó¸®ÇÑ Ã¤³ÎÀº ±×´ë·Î µÒ.
3330        for (i=0; i<nUid; i++) {
3331                idx = DMW_MSC_Uid2Index(uidBuf[i]);
3332
3333#if INCLUDE_SPECIAL_HIDDEN             
3334                if(g_UCM[idx].hidden) {
3335                        g_UCM[idx].hidden=FALSE;
3336                }
3337#endif
3338
3339                if (g_UCM[idx].fresh)
3340                        g_UCM[idx].Skipped = 0;
3341
3342                // ¾Æ·¡¿¡¼­ 2Â÷ üũ¸¦ Çϴµ¥, ÀÌ flag¸¦ Ȱ¿ëÇϹǷΠtrue ¼³Á¤.
3343                g_UCM[idx].fresh = TRUE;
3344                // ÀÌ Àü¿¡ »èÁ¦ ¿¹Á¤ ä³ÎÀ̾úÀ¸³ª ´Ù½Ã Ãß°¡µÈ ä³ÎÀÎ °æ¿ì..
3345                g_UCM[idx].disabled = FALSE;
3346
3347                // ÇöÀç rf ä³Î Á¤º¸¸¦ ¿©±â¿¡¼­..
3348                rf = g_UCM[idx].RF;
3349        }
3350        dprint(2, " dynch post proc: rf %d\n", rf);
3351
3352
3353#if 1 //neverdai 110105 ä³ÎÀ» »èÁ¦ÇÏÁö ¾Ê°í ±×´ë·Î µÒ.->ä³Î »èÁ¦ÇÔ
3354        // 2Â÷ ó¸®:
3355        // ÇöÀç rf¿Í ´Ù¸¥ ¸ðµç ä³ÎµéÀº »èÁ¦!!
3356        for (i=0; i<g_UCM_number; i++) {
3357                if (g_UCM[i].RF == rf && g_UCM[i].fresh == FALSE) {
3358                        // ÀÌ Ã¤³ÎÀº À̹ø update¿¡¼­ »ç¶óÁø(?) ä³ÎÀÌ´Ù.
3359                        g_UCM[i].disabled = TRUE;
3360                        dprint(0, "!! ucm[%d] %d-%d rf %d v%d #%u will be removed\n", 
3361                                i, g_UCM[i].Major, g_UCM[i].Minor, g_UCM[i].RF, 
3362                                g_UCM[i].VctFlag, g_UCM[i].Prog_number);
3363                        n_disabled++;
3364                }
3365        }
3366        if (n_disabled)
3367                dprint(0, "!! %d channels becomes disabled\n", n_disabled);
3368#elif 0 //neverdai 110105 ä³ÎÀ» »èÁ¦ÇÏÁö ¾Ê°í skip »óÅ·ΠµÒ. --> ±×³É add »óÅ·ΠµÒ.
3369        for (i=0; i<g_UCM_number; i++) {
3370                if (g_UCM[i].RF == rf && g_UCM[i].fresh == FALSE) {
3371                        // ÀÌ Ã¤³ÎÀº À̹ø update¿¡¼­ »ç¶óÁø(?) ä³ÎÀÌ´Ù.
3372                        g_UCM[i].Skipped = TRUE;
3373                        dprint(0, "!! ucm[%d] %d-%d rf %d v%d #%u will be skipped\n", 
3374                                i, g_UCM[i].Major, g_UCM[i].Minor, g_UCM[i].RF, 
3375                                g_UCM[i].VctFlag, g_UCM[i].Prog_number);
3376                }
3377        }
3378#endif
3379       
3380       
3381        //neverdai 110105, ÇöÀç ä³ÎÀÌ ¾øÀ» °æ¿ì(major, minor ±âÁØ) RFÀÇ ÃÖ¼Ò minor·Î Æ©´×
3382        //¹®Á¦, »èÁ¦µÇ
3383        for(i=0, bSeeked=FALSE; i<nUid; i++) {
3384                idx=DMW_MSC_Uid2Index(uidBuf[i]);
3385                if(g_UCM[idx].Major==APP_CUR_CH.nMajor && 
3386                        g_UCM[idx].Minor==APP_CUR_CH.nMinor) {
3387                       
3388                        if(uidBuf[i]!=APP_CUR_CH.nUid)
3389                        {
3390                                uid = uidBuf[i];
3391                                DMW_MSC_UnlockUcm(); // Æ©´× Àü¿¡ Lock Ǭ´Ù.
3392                                bUCMLocked = 0;
3393                                bRunDynamicChannelUpdate = FALSE;
3394                                if (bCancelDynamicChUpdate == TRUE) 
3395                                {
3396                                        dprint(0, "%s|%d|bCancelDynamicChUpdate = %d\n", __func__, __LINE__, bCancelDynamicChUpdate);
3397                                        return;
3398                                } 
3399                                App_TuneChannelByUid(uid);
3400                                return;
3401                        }
3402                        bSeeked=TRUE;
3403                        break;
3404                }
3405        }
3406       
3407        if(!bSeeked) {
3408                int min_minor=1024;
3409                int min_idx=-1;
3410               
3411                for(i=0; i<nUid; i++) {
3412                       
3413                        idx=DMW_MSC_Uid2Index(uidBuf[i]);
3414                       
3415                        if(g_UCM[idx].Minor<min_minor) {
3416                                min_minor=g_UCM[idx].Minor;
3417                                min_idx=idx;
3418                        }
3419                }
3420               
3421                if(min_idx>=0) {
3422                        uid = g_UCM[min_idx].Uid;
3423                        DMW_MSC_UnlockUcm(); // Æ©´× Àü¿¡ Lock Ǭ´Ù.
3424                        bUCMLocked = 0;
3425                        bRunDynamicChannelUpdate = FALSE;
3426                        if (bCancelDynamicChUpdate == TRUE) 
3427                        {
3428                                dprint(0, "%s|%d|bCancelDynamicChUpdate = %d\n", __func__, __LINE__, bCancelDynamicChUpdate);
3429                                return;
3430                        } 
3431                        App_TuneChannelByUid(uid);
3432                        return;
3433                }
3434        }
3435        if (bUCMLocked == 1) DMW_MSC_UnlockUcm(); // ä³Î Æ©´×ÀÌ ¾È µÈ °æ¿ì lock Ǭ´Ù.
3436}
3437
3438
3439void App_CheckCurChannelChange()
3440{
3441        int i, j;
3442        STATUS status;
3443
3444        DmcChannelInfo *chInfo;
3445        ProgramAVInfo *av = Dmc_LockAVMutex();
3446
3447        xvctPtr_t vct = NULL;
3448        MPEG_PAT *pat;
3449        MPEG_PMT *pmtlist[100] = {0, };
3450       
3451        int nScanFlags;
3452        int rf;
3453        int nUid = 0, *uidBuf = NULL;
3454
3455        rf = APP_CUR_CH.nRF;
3456
3457        dprint(2, "dynamic ch update, rf %d\n", rf);
3458
3459        Dmc_EpgLockCoreDB(TRUE);
3460
3461        // vct È®ÀÎ..
3462        chInfo = Dmc_GetChannelInfo(g_EpgDB, rf);
3463        if (chInfo == NULL) {
3464                dprint(0, "!! dyn ch up rf %d err\n", rf);
3465                goto label_end;
3466        }
3467        else if (chInfo->cvct && g_CurChannelType == ChannelType_Cable) {
3468                status = Dmc_TranslateCvct(chInfo->cvct, &vct);
3469                //dprint(2, "\tCVCT found. total %d channels\n", vct->numChannels);
3470        }
3471        else if (chInfo->tvct) {
3472                status = Dmc_TranslateTvct(chInfo->tvct, &vct);
3473                //dprint(2, "\tTVCT found. total %d channels\n", vct->numChannels);
3474        }
3475        else {
3476                dprint(0, "!! no vct info\n");
3477                // ÀÏ´Ü psi channelÀº °í·ÁÇÏÁö ¾Ê´Â´Ù..
3478                goto label_end;
3479        }
3480
3481        // pat, pmtlist È®ÀÎ..
3482        // ¸ÕÀú pat..
3483        if (!(av->pat && av->pat->numPrograms && av->pmtList)) {
3484                dprint(0, "!! not enough psi info: %x %d\n", av->pat, av->pat ? av->pat->numPrograms : 0);
3485                goto label_end;
3486        }
3487        pat = av->pat;
3488
3489        // pmt Á¤º¸µé ÃëÇÕ..
3490        // ¸ðµç pmtµéÀÌ ´Ù ÀÖ´ÂÁö È®ÀÎ. ÁÖÀÇ! ÇöÀç ½Ãû ä³ÎÀÇ pmt´Â µû·Î ÀÖÀ½! program number üũ Çʼö!!
3491        for (i=0; i<pat->numPrograms; i++) {
3492                if (av->pmtList[i])
3493                        pmtlist[i] = av->pmtList[i];
3494                else if (pat->programs[i].program_number == av->program_number && av->pmt)
3495                        pmtlist[i] = av->pmt;
3496                else
3497                        pmtlist[i] = NULL;
3498        }
3499
3500        for (i=0; i<pat->numPrograms; i++) {
3501                if (pmtlist[i] == NULL) {
3502                        dprint(0, "!! pmt[%d] not ready!\n", i);
3503                        goto label_end;
3504                        // ; // ¾î¶»°Ô ÇÏÁö??
3505                        //
3506                }
3507        }
3508
3509        {
3510                int idx;
3511                int TotalUcmCount;
3512                int numChannels = 0;
3513                int numCh = 0;
3514                UINT16 major, minor;
3515                BOOL bsame=TRUE;
3516                BOOL bDisabled;
3517               
3518                int num_ch_exist_rf=0;
3519                int ch_list_exist_rf[128];
3520               
3521                int num_vct_ch=vct->numChannels;
3522                int num_hidden=0;
3523
3524                TotalUcmCount = App_Ucm_GetTotalUcmCount();
3525               
3526                DMW_MSC_LockUcm();
3527
3528                num_ch_exist_rf=App_Ucm_FindChannelByRF(rf, 128, ch_list_exist_rf);
3529
3530                //hidden exists.
3531                for(i=0; i<num_vct_ch; i++) 
3532                {
3533                        //show stream type, and check validity
3534                        if(vct->channel[i].hidden) {
3535                                if(!pmtlist[i]) num_hidden++;
3536                                else {
3537                                       
3538                                        #define StreamTypeToAudioType(t) ( \
3539                                                (t) == StreamType_AC3Audio   ? eDHL_AUDIO_TYPE_AC3 : \
3540                                                (t) == StreamType_MPEG2Audio ? eDHL_AUDIO_TYPE_MPEG_2 : \
3541                                                (t) == StreamType_AACAudioADTS ? eDHL_AUDIO_TYPE_AAC_ADTS : \
3542                                                (t) == StreamType_AACAudioLATM ? eDHL_AUDIO_TYPE_AAC_LATM : \
3543                                                        eDHL_AUDIO_TYPE_UNKNOWN )
3544                                       
3545                                        #define StreamTypeToVideoType(t) ( \
3546                                                (t) == StreamType_MPEG2Video ? eDHL_VIDEO_TYPE_MPEG2 : \
3547                                                (t) == StreamType_DC2Video   ? eDHL_VIDEO_TYPE_MPEG2 : \
3548                                                (t) == StreamType_MPEG1Video ? eDHL_VIDEO_TYPE_MPEG1 : \
3549                                                (t) == StreamType_H264       ? eDHL_VIDEO_TYPE_H264 : \
3550                                                        eDHL_VIDEO_TYPE_UNKNOWN )
3551                                       
3552                                        int j;
3553                                        UINT32 val1, val2;
3554                                        BOOL bvalidity=FALSE;
3555                                       
3556                                        DHL_AV_Query(eDHL_AV_QUERY_VIDEO_CAP, &val1);
3557                                        DHL_AV_Query(eDHL_AV_QUERY_AUDIO_CAP, &val2);
3558                                       
3559                                        for(j=0; j<pmtlist[i]->numStreams; j++) {
3560                                               
3561                                                if((1<<StreamTypeToVideoType(pmtlist[i]->streams[j].stream_type))&val1) {
3562                                                        bvalidity=TRUE;
3563                                                        break;
3564                                                }
3565                                               
3566                                                if((1<<StreamTypeToAudioType(pmtlist[i]->streams[j].stream_type))&val2) {
3567                                                        bvalidity=TRUE;
3568                                                        break;
3569                                                }
3570                                        }
3571                                       
3572                                        if(!bvalidity) num_hidden++;
3573                                }
3574                        }
3575                }
3576                                               
3577                if(num_vct_ch-num_hidden!=num_ch_exist_rf) {
3578                        bsame=FALSE;
3579                        goto label_check;
3580                }
3581               
3582                for(i=0; i<num_vct_ch; i++) 
3583                {
3584                        BOOL bseek=FALSE;
3585                       
3586                        if(vct->channel[i].hidden) continue;
3587                       
3588                        major=vct->channel[i].major_channel_number;
3589                        minor=vct->channel[i].minor_channel_number;
3590                       
3591                        for(j=0; j<num_ch_exist_rf; j++) {
3592                                int idx=DMW_MSC_Uid2Index(ch_list_exist_rf[j]);
3593                               
3594                                if(g_UCM[idx].Major==major && g_UCM[idx].Minor==minor) {
3595                                        bseek=TRUE;
3596                                        break;
3597                                }
3598                        }
3599                       
3600                        if(!bseek) {
3601                                bsame=FALSE;
3602                                goto label_check;
3603                        }
3604                }
3605
3606
3607label_check:           
3608                DMW_MSC_UnlockUcm();
3609       
3610                if (!bsame)
3611                {
3612                        //ÇöÀç ä³ÎÀÇ major, minor°¡ ¾ø±â ¶§¹®¿¡
3613                        //ÀÏ´Ü »õ·Î¿î ä³ÎÀÌ ¹ß°ßµÉ ¶§±îÁö ¸Þ½ÃÁö¸¦ ¶ç¿ö¾ß ÇÔ
3614                        DMG_SetUserDefined(UD_ID_AUTO_CH_UPDATING, TRUE, 0);
3615                }
3616        }
3617       
3618label_end:
3619
3620        // ¸ÕÀú table, mutex µîºÎÅÍ ´ÝÀÚ.
3621        if (vct)
3622                Dmc_FreeAtscTable(&vct);
3623
3624        Dmc_UnlockAVMutex();
3625        Dmc_EpgLockCoreDB(FALSE);
3626
3627        if (uidBuf)
3628                DHL_OS_Free((void **)&uidBuf);
3629}
3630
3631
3632
3633/*
3634
3635*/
3636
3637// Dynamic Channel Update°¡ ³¡³¯¶§±îÁö ŸÀ̸Ӹ¦ ¿¬ÀåÇÏÁö ¾Êµµ·Ï ÇÔ
3638static BOOL bNeedDynamicChannelUpdate = FALSE; //2012.11.22 megakiss
3639
3640void App_DoDynamicChUpdate(void)
3641{
3642        int i;
3643        STATUS status;
3644
3645        DmcChannelInfo *chInfo;
3646        ProgramAVInfo *av = Dmc_LockAVMutex();
3647        bRunDynamicChannelUpdate = TRUE;
3648       
3649        xvctPtr_t vct = NULL;
3650        MPEG_PAT *pat;
3651        MPEG_PMT *pmtlist[100] = {0, };
3652       
3653        int nScanFlags;
3654        int rf;
3655        int nUid = 0, *uidBuf = NULL;
3656        UINT16 VCT_TSID = 0;
3657        UINT16 PAT_TSID = 0;
3658        if (bCancelDynamicChUpdate == TRUE) 
3659        {
3660                dprint(0, "%s|%d|bCancelDynamicChUpdate = %d\n", __func__, __LINE__, bCancelDynamicChUpdate);
3661                goto label_end;
3662        }
3663        DMG_SetUserDefined(UD_ID_AUTO_CH_UPDATING, FALSE, 0);
3664
3665        rf = APP_CUR_CH.nRF;
3666
3667        dprint(0, "dynamic ch update, rf %d start\n", rf);
3668       
3669        DHL_OS_Delay(1000);
3670       
3671        Dmc_EpgLockCoreDB(TRUE);
3672        if (bCancelDynamicChUpdate == TRUE)
3673        {
3674                dprint(0, "%s|%d|bCancelDynamicChUpdate = %d\n", __func__, __LINE__, bCancelDynamicChUpdate);
3675                goto label_end;
3676        }
3677        // vct È®ÀÎ..
3678        chInfo = Dmc_GetChannelInfo(g_EpgDB, rf);
3679        if (chInfo == NULL) {
3680                dprint(0, "!! dyn ch up rf %d err\n", rf);
3681                goto label_end;
3682        }
3683        else if (chInfo->cvct && g_CurChannelType == ChannelType_Cable) {
3684                status = Dmc_TranslateCvct(chInfo->cvct, &vct);
3685                //dprint(2, "\tCVCT found. total %d channels\n", vct->numChannels);
3686        }
3687        else if (chInfo->tvct) {
3688                status = Dmc_TranslateTvct(chInfo->tvct, &vct);
3689                //dprint(2, "\tTVCT found. total %d channels\n", vct->numChannels);
3690        }
3691        else {
3692                dprint(0, "!! no vct info\n");
3693                // ÀÏ´Ü psi channelÀº °í·ÁÇÏÁö ¾Ê´Â´Ù..
3694//              goto label_end; // 2012.11.23 nonVCT support
3695        }
3696
3697        // pat, pmtlist È®ÀÎ..
3698        // ¸ÕÀú pat..
3699        if (!(av->pat && av->pat->numPrograms && av->pmtList)) {
3700                dprint(0, "!! not enough psi info: %x %d\n", av->pat, av->pat ? av->pat->numPrograms : 0);
3701                goto label_end;
3702        }
3703        pat = av->pat;
3704
3705        // pmt Á¤º¸µé ÃëÇÕ..
3706        // ¸ðµç pmtµéÀÌ ´Ù ÀÖ´ÂÁö È®ÀÎ. ÁÖÀÇ! ÇöÀç ½Ãû ä³ÎÀÇ pmt´Â µû·Î ÀÖÀ½! program number üũ Çʼö!!
3707        for (i=0; i<pat->numPrograms; i++) {
3708                if (av->pmtList[i])
3709                        pmtlist[i] = av->pmtList[i];
3710                else if (pat->programs[i].program_number == av->program_number && av->pmt)
3711                        pmtlist[i] = av->pmt;
3712                else
3713                        pmtlist[i] = NULL;
3714        }
3715
3716        for (i=0; i<pat->numPrograms; i++) {
3717                if (pmtlist[i] == NULL) {
3718                        dprint(0, "!! pmt[%d] not ready!\n", i);
3719                        //goto label_end;
3720                        // ; // ¾î¶»°Ô ÇÏÁö??
3721                        //ÀÏ´Ü ±×´ë·Î ÁøÇàÇÔ.
3722                        //
3723                }
3724        }
3725
3726        nScanFlags = CBTF_8VSB | CBTF_IgnoreNtscInVct | CBTF_ForcePSI; 
3727        nScanFlags |= (g_CurChannelType == ChannelType_Air) ? CBTF_Air : CBTF_Cable;
3728
3729        dprint(2, "rf %d, vct %x, pat %x, %d pmts, update channel..\n", 
3730                                rf, vct, pat, pat ? pat->numPrograms : 0);
3731        if (bCancelDynamicChUpdate == TRUE)
3732        {
3733                dprint(0, "%s|%d|bCancelDynamicChUpdate = %d\n", __func__, __LINE__, bCancelDynamicChUpdate);
3734                goto label_end;
3735        }
3736        App_PreProcessDynamicUpdateChannel();
3737        if (bCancelDynamicChUpdate == TRUE)
3738        {
3739                dprint(0, "%s|%d|bCancelDynamicChUpdate = %d\n", __func__, __LINE__, bCancelDynamicChUpdate);
3740                goto label_end;
3741        }
3742        // 2012.11.23 nonVCT support
3743        // Ch30.trp´Â VCT TSID = 0x17F PAT TSID=0x17E ÀÓ
3744        // ÀÌ ¹®Á¦ ȸÇǸ¦ À§ÇØ 0¹øºñÆ®´Â ¹«½ÃÇϵµ·Ï ÇÔ
3745        if (vct) dprint(0,"vct->transport_stream_id = 0x%x\n", vct->transport_stream_id);
3746        dprint(0,"pat->transport_stream_id = 0x%x\n", pat->transport_stream_id);
3747
3748        uidBuf = NULL;
3749       
3750        VCT_TSID = 0xFFFF;
3751        if (vct) VCT_TSID = vct->transport_stream_id & 0xFFFE;
3752        PAT_TSID = 0xFFFF;
3753        if (pat) PAT_TSID = pat->transport_stream_id & 0xFFFE;
3754        // VCT°¡ ¾ø°Å³ª ÀÌÀü ½ºÆ®¸²ÀÇ VCTÀÎ °æ¿ì¿¡´Â VCT ¾ø´Â°É·Î °£ÁÖÇÑ´Ù
3755        if (bCancelDynamicChUpdate == TRUE)
3756        {
3757                dprint(0, "%s|%d|bCancelDynamicChUpdate = %d\n", __func__, __LINE__, bCancelDynamicChUpdate);
3758                goto label_end;
3759        }
3760        status = DMW_CDB_UpdateChannel(
3761                (VCT_TSID == 0xFFFE || VCT_TSID != PAT_TSID) ? 0 :vct, 
3762                pat, pmtlist,
3763                                                rf, nScanFlags, 
3764                                                &nUid, &uidBuf);
3765        if (status) {
3766                dprint(0, "!! update ucm vct err %d\n", status);
3767                goto label_end;
3768        }
3769        dprint(2, "---- %d uids are added \n", nUid);
3770        for (i=0; i<nUid; i++) {
3771                dprint(2, "(%d) uid %d\n", i, uidBuf[i]);
3772        }
3773
3774label_end:
3775
3776        // ¸ÕÀú table, mutex µîºÎÅÍ ´ÝÀÚ.
3777        if (vct)
3778                Dmc_FreeAtscTable(&vct);
3779
3780        Dmc_UnlockAVMutex();
3781        Dmc_EpgLockCoreDB(FALSE);
3782
3783        // Ȥ½Ã ÇÊ¿äÇÑ ÈÄó¸® ÀýÂ÷°¡ ÀÖ´Ù¸é ¿©±â¼­..
3784        if (nUid) {
3785                App_PostProcessDynamicUpdateChannel(nUid, uidBuf);
3786        }
3787
3788        if (uidBuf)
3789                DHL_OS_Free((void **)&uidBuf);
3790        dprint(0, "dynamic ch update, rf %d end\n", rf);
3791        bNeedDynamicChannelUpdate = FALSE;
3792        bRunDynamicChannelUpdate = FALSE;
3793}
3794
3795
3796/*
3797        ÀÌ ÇÔ¼ö´Â psi, psip º¯°æ event°¡ ¹ß»ýÇÒ ¶§ ¸¶´Ù È£ÃâµÈ´Ù.
3798        ÀÌ ÇÔ¼ö°¡ ºÒ¸®´Â task´Â ÀÓÀÇ taskÀ̹ǷΠ(ISR ÀÏ °æ¿ìµµ ¹èÁ¦ ¸øÇÔ)
3799        µ¿±âÈ­¿¡ ÁÖÀÇ ÇÊ¿äÇÔ.
3800*/
3801void App_CheckDynamicChUpdate(void)
3802{
3803#if SUPPORT_DYN_CH_UPDATE
3804        // psip °ú psi °¡ ¸ðµÎ ´Ù ¹Þ¾ÆÁ®¾ß ÇÑ´Ù.
3805
3806        // üũ´Â ¾Æ·¡ ÇÔ¼ö¿¡¼­ vct, psi À¯¹«¸¦ üũÇϹǷÎ,
3807        // ¹«Á¶°Ç trigger Çϵµ·Ï ÇÏÀÚ..
3808        // if (bNeedDynamicChannelUpdate == TRUE) return; // hack stream ó¸® Á¦°Å
3809        //¸ÕÀú ä³Î Á¤º¸¸¦ ¼ö½ÅÇϰí, ÇöÀç ä³ÎÀÌ À¯ÁöµÇ±â Èûµç °æ¿ì¸é ¹è³Ê¸¦ ¶ç¿ò
3810       
3811        App_CheckCurChannelChange();
3812                //ÇöÀç ä³ÎÀ» À¯Áö½Ãų ¼ö ¾ø´Â °æ¿ì ä³Î Á¤º¸°¡ ¾÷µ¥ÀÌÆ® ÁßÀ̶ó´Â Á¤º¸¸¦ ¶ç¿ò
3813               
3814        DMW_SYS_SetTimer(TIMER_ID_DCU, 3000, (DMW_TIMER_PROC)App_DoDynamicChUpdate, 0, TRUE);
3815        bNeedDynamicChannelUpdate = TRUE;
3816#endif
3817}
3818
3819
3820void App_CancelDynamicChUpdate(void)
3821{
3822        int i;
3823        bCancelDynamicChUpdate = TRUE;
3824        dprint(0, "%s|%d|bCancelDynamicChUpdate = %d\n", __func__, __LINE__, bCancelDynamicChUpdate);
3825        for (i=0; i < 20; i++)
3826        {
3827                dprint(0, "%s|%d|bCancelDynamicChUpdate = %d bRunDynamicChannelUpdate = %d\n", __func__, __LINE__, bCancelDynamicChUpdate, bRunDynamicChannelUpdate);
3828                if (bRunDynamicChannelUpdate == FALSE) break;
3829                DHL_OS_Delay(100);
3830        }
3831        // DMW_SYS_KillTimer(TIMER_ID_DCU);
3832        DMW_SYS_SetTimer(TIMER_ID_DCU, 0xFFFFFFFF, (DMW_TIMER_PROC)App_DoDynamicChUpdate, 0, TRUE);
3833        bNeedDynamicChannelUpdate = FALSE;
3834        bCancelDynamicChUpdate = FALSE;
3835        dprint(0, "%s|%d|bCancelDynamicChUpdate = %d\n", __func__, __LINE__, bCancelDynamicChUpdate);
3836}
3837
3838
3839#if COMMENT
3840____Debug____(){}
3841#endif
3842
3843void App_ChannelUp(void)
3844{
3845        // TODO: After RCU
3846        // App_SimulateRcuKey(APP_VK_CH_UP); // App_Debug.c »ç¿ë½Ã »ç¿ëÇÏÀÚ.
3847}
3848
3849void App_ChannelDown(void)
3850{
3851        // App_SimulateRcuKey(G2H_CH_DOWN);
3852}
3853
3854void chskip(int index, int bSkip)
3855{
3856        if (index < 0 || index >= g_UCM_number)
3857                return;
3858       
3859        g_UCM[index].Skipped = bSkip;
3860}
3861
3862
3863
3864
3865void p_set_def_cfg()
3866{
3867#if SUPPORT_ONLY_CABLE
3868        p_chtune_nvm_param.nChannelType = ChannelType_Cable;
3869#else
3870        p_chtune_nvm_param.nChannelType = ChannelType_Air;
3871#endif
3872
3873        // default
3874        p_chtune_nvm_param.air_rf = 2;
3875        p_chtune_nvm_param.air_pn = 0;
3876       
3877        p_chtune_nvm_param.cable_rf = 1;
3878        p_chtune_nvm_param.cable_fn = 0;
3879
3880#if SUPPORT_ONLY_AIR || SUPPORT_ONLY_CABLE
3881        p_chtune_nvm_param.enable_force_aircable=FALSE;
3882#else
3883        p_chtune_nvm_param.enable_force_aircable=TRUE;
3884#endif
3885
3886        p_chtune_nvm_param.ch_sort_mode=(UINT8)APP_CH_SORT_CH_NUM;
3887
3888        p_chtune_nvm_param.enable_qam=FALSE;
3889       
3890        App_NVM_SaveModuleParam(eAPP_NVR_CHTUNE, &p_chtune_nvm_param);
3891}
3892
3893
3894
3895
3896
3897#if COMMENT
3898____Symbol____(){}
3899#endif
3900
3901#if NEO_REGISTER_DEBUG_SYMBOL
3902
3903static DHL_SymbolTable _ChTuneSymbolx[] =
3904{
3905        DHL_FNC_SYM_ENTRY2("chtype", App_ChangeChannelType),
3906        DHL_FNC_SYM_ENTRY2("ch", App_ChTuneByDigitKey),
3907        DHL_FNC_SYM_ENTRY2("stop", App_ChTuneStopTV),
3908        DHL_FNC_SYM_ENTRY2("chup", App_ChannelUp),
3909        DHL_FNC_SYM_ENTRY2("chdn", App_ChannelDown),
3910       
3911        DHL_VAR_SYM_ENTRY(g_App_UsePrescanPidInfo),
3912};
3913
3914static void RegisterSymbols(void)
3915{
3916        DHL_DBG_RegisterSymbols(_ChTuneSymbolx, DHL_NUMSYMBOLS(_ChTuneSymbolx));
3917
3918        // cafrii 091123 add. it is CRUCIAL in testing!!!
3919        Dmc_RegisterChannelSymbols();
3920}
3921
3922#else
3923static void RegisterSymbols(void) { }
3924#endif  /* NEO_REGISTER_DEBUG_SYMBOL */
3925
3926
3927
3928
3929
3930#if COMMENT
3931____Init____(){}
3932#endif
3933
3934void App_ChTuneInit(void)       
3935{
3936        dprint(0, "%s:\n", __FUNCTION__);
3937
3938        RegisterSymbols();
3939
3940        /* load nv param */
3941        App_NVM_LoadModuleParam(eAPP_NVR_CHTUNE, &p_chtune_nvm_param);
3942
3943        /* apply nv param */
3944        APP_CUR_CH.nChannelType = p_chtune_nvm_param.nChannelType;
3945               
3946#if SUPPORT_ONLY_CABLE
3947/* arzhna, 100422
3948        air·Î ¼³Á¤µÇ´Â °ÍÀ» ¸·±â À§ÇØ °­Á¦·Î cable ¼³Á¤ ±Ùº»ÀûÀÎ ÇØ°á¹æ¹ý ¾Æ´Ô */
3949        if(APP_CUR_CH.nChannelType == 0  && !p_chtune_nvm_param.enable_force_aircable){
3950                dprint(0,"only cable mode is supported in this project!!\n");
3951                App_ChangeChannelType(ChannelType_Cable);
3952               
3953        }
3954#elif SUPPORT_ONLY_AIR
3955        if(APP_CUR_CH.nChannelType == 1  && !p_chtune_nvm_param.enable_force_aircable){
3956                dprint(0,"only air mode is supported in this project!!\n");
3957                App_ChangeChannelType(ChannelType_Air);
3958        }
3959#endif 
3960               
3961        // cafrii 060609, register channel noti.. callback
3962        App_RegisterChannelNotifyCallback();
3963
3964#if SUPPORT_POD
3965        // because of low 3114 qam reception capability..
3966        g_Timeout_SignalLock = 5000;
3967#endif
3968}
3969
3970
3971void App_ChTuneParamInit(void)
3972{
3973        App_NVM_RegisterModule(eAPP_NVR_CHTUNE, sizeof(p_chtune_nvm_param), p_set_def_cfg);
3974}
3975
3976
3977void App_ForceEnableAirCable(BOOL is_enable)
3978{
3979        p_chtune_nvm_param.enable_force_aircable=is_enable;
3980        App_NVM_SaveModuleParam(eAPP_NVR_CHTUNE, &p_chtune_nvm_param);
3981        if(!is_enable)
3982                App_ChangeChannelType(APP_CUR_CH.nChannelType==0?ChannelType_Air:ChannelType_Cable);
3983}
3984
3985BOOL App_IsForceEnableAirCable(void)
3986{
3987        return p_chtune_nvm_param.enable_force_aircable;
3988}
3989
3990/*Cable ä³Î Æ©´×½Ã VSB¿Ü¿¡ QAM ä³Îµµ Æ©´×ÇÏ´ÂÁö ¿©ºÎ ¼³Á¤.*/
3991void App_SetEnableCableQam(BOOL setting)
3992{
3993        p_chtune_nvm_param.enable_qam=setting;
3994        App_NVM_SaveModuleParam(eAPP_NVR_CHTUNE, &p_chtune_nvm_param);
3995}
3996
3997BOOL App_GetEnableCableQam(void)
3998{
3999        return p_chtune_nvm_param.enable_qam;
4000}
4001
4002
4003void App_SetChSortMode(tAppChSortMode mode)
4004{
4005        p_chtune_nvm_param.ch_sort_mode=(UINT8)mode;
4006}
4007
4008
4009
4010tAppChSortMode App_GetChSortMode()
4011{
4012        return (tAppChSortMode)p_chtune_nvm_param.ch_sort_mode;
4013}
4014
4015#if 0
4016// cafrii 060920 add
4017// PR192 ÀçÇöÀ» À§ÇÑ Å×½ºÆ® ÄÚµå.
4018//
4019void App_TestScanOverload(int rf, BOOL bStop)
4020{
4021        STATUS status;
4022        UINT32 scan_flag;
4023        int count = 0;
4024       
4025        static BOOL bStopTest = FALSE;
4026       
4027        if (bStop) {
4028                bStopTest = TRUE;
4029                return;
4030        }
4031
4032        App_ChTuneStopTV();
4033
4034        bStopTest = FALSE;
4035       
4036        scan_flag = (g_CurChannelType == ChannelType_Air ? CBTF_Air : CBTF_Cable);
4037        scan_flag |= (CBTF_ForcePSI | CBTF_IgnoreNtscInVct);
4038        //scan_flag |= CBTF_CheckScrambleByVideoContext;
4039        scan_flag |= CBTF_SkipTunerSet;
4040
4041        while (bStopTest == FALSE)
4042        {
4043                status = DMW_ASC_ScanChannel(rf,
4044                                                scan_flag,          // scan flag
4045                                                TRUE,              // wait for complete
4046                                                NULL,   // event callback
4047                                                NULL, 0, // complete callback
4048                                                TRUE);  // cancel prev commands
4049                dprint(0, "\n========== scan test [%d] result %d ===========\n\n", count, status);
4050                count++;
4051                DHL_OS_Delay(1000);
4052        }
4053
4054        dprint(0, "test end\n");
4055       
4056}
4057
4058#endif // #if 0
4059
4060
4061
4062
4063
4064/* end of file */
Note: See TracBrowser for help on using the repository browser.