source: svn/newcon3bcm2_21bu/dst/dmw/src/Channel/DMW_Mcm.c @ 22

Last change on this file since 22 was 22, checked in by phkim, 11 years ago
  1. phkim
  2. newcon3sk 를 kctv 로 브랜치 함
  • Property svn:executable set to *
File size: 34.4 KB
Line 
1/*******************************************************************
2 * DMW_Mcm.c
3 *
4 * Private routines to be used in M/W
5 *
6 * Copyright 2003 Digital STREAM Technology, Inc.
7 * All Rights Reserved
8 *
9 * $Id: DMW_Mcm.c,v 1.? 2003/03/24 cafrii Exp $
10 *
11 ********************************************************************/
12
13
14
15
16
17#include "DMW_Platform.h"
18
19#include "DHL_DBG.h"
20
21
22#include "DMW_Config.h"
23#include "DMW_ChannelAPI.h"
24#include "DMW_DebugUtil.h"
25#include "dmw_mcm_priv.h"
26#include "dmw_ucm_priv.h"
27
28#include "DMW_Mutex.h"
29
30//#include <string.h>
31
32DHL_MODULE("$mcm", 0);
33
34
35
36#define USE_STATIC_MCM 1 //static mcmÀ» »ç¿ëÇÔ->memory fragmentationÀ» ¹æÁöÇϱâ À§ÇÔ
37
38
39#define equiv_mcm_major_minor(a, b) \
40        ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor )
41                        // && (a)->RF==(b)->RF && (a)->VctFlag==(b)->VctFlag)
42#define equiv_mcm_major_minor_rf(a, b) \
43        ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor && (a)->RF==(b)->RF)
44#define equiv_mcm_major_minor_vf(a, b) \
45        ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor && (a)->VctFlag==(b)->VctFlag)
46#define equiv_mcm_major_minor_rf_vf(a, b) \
47        ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor && (a)->RF==(b)->RF && (a)->VctFlag==(b)->VctFlag)
48        //     
49        // a ~= b ÀÎÁö¸¦ üũÇÏ´Â ¸ÅÅ©·Î.
50        // ´ëÇ¥ mcm itemÀ» ¼±ÅÃÇϱâ À§Çؼ­ Áߺ¹µÇ´Â ä³Î Á¤º¸¸¦ ¾Ë¾Æ³»±â À§ÇÑ ºñ±³ ±¸¹®¿¡¼­ »ç¿ëÇÑ´Ù.
51        // ÇöÀç ¹æÄ§Àº Major/Minor/Vf °ªÀÌ ÀÏÄ¡Çϴ ä³Î Áß¿¡¼­ ½ÅÈ£ ¼¼±â°¡ °¡Àå Å« Á¤º¸¸¦ »ç¿ëÇÑ´Ù.
52
53/*
54#define not_ordered(a1, a2, a3, a4, b1, b2, b3, b4) \
55        (((a1)>(b1)) || ((a1)==(b1) && (a2)>(b2)) || ((a1)==(b1) && (a2)==(b2) && (a3)>(b3)) \
56         ((a1)==(b1) && (a2)==(b2) && (a3)==(b3) && (a4)>(b4)) )
57#define require_mcm_swap(a, b) \
58        not_ordered((a)->Major, (a)->Minor, (a)->RF, (a)->VctFlag, (b)->Major, (b)->Minor, (b)->RF, (b)->VctFlag)
59*/
60
61#define require_mcm_swap(a, b)  \
62        (((a)->Major>(b)->Major) || \
63         ((a)->Major==(b)->Major && (a)->Minor>(b)->Minor) || \
64         ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor && (a)->RF>(b)->RF) || \
65         ((a)->Major==(b)->Major && (a)->Minor==(b)->Minor && (a)->RF==(b)->RF &&   \
66          (a)->VctFlag<(b)->VctFlag) )
67        // MCM Á¤·Ä¿¡¼­ a¿Í b µÎ MCM item À§Ä¡¸¦ ¹Ù²ã¾ß µÇ´ÂÁö üũÇÏ´Â ¸ÅÅ©·Î.
68        // ±âº»ÀûÀ¸·Î Major/Minor/RF/VctFlag ¼ø¼­·Î ¼øÀ§¸¦ µÎ°í, Major/Minor/Rf´Â ¿À¸§Â÷¼ø,
69        // VctFlag´Â ³»¸²Â÷¼øÀ¸·Î Á¤·ÄÇØ¾ß ÇÑ´Ù.
70
71
72
73//-----------------------------------------------------
74
75#define IMPLEMENT_MCM_ARRAY 1
76        // 1À̸é 1Â÷¿ø array·Î MCMÀ» ±¸Çö.
77        // 0À̸é linked list·Î ±¸Çö..
78
79
80
81
82
83
84
85//=======================================================================
86// MCM °ü¸® ·çƾ.
87//
88// MCM °ü·Ã ÆíÀÇ ÇÔ¼öµé..
89
90// MCMÀÇ ±¸Á¶´Â Çì´õ ÆÄÀÏ¿¡ °ø°³µÇ¾î ÀÖÁö¸¸, MCM DB ÀÚü´Â AutoScan °úÁ¤¿¡¼­¸¸ ÇÊ¿äÇÑ
91// Àӽà µ¥ÀÌÅÍÀ̱⠶§¹®¿¡ ³»ºÎ static º¯¼ö·Î Á¤ÀÇÇÑ´Ù.
92//
93// °Ë»öµÈ ä³Î Á¤º¸´Â Áß°£Áß°£¿¡ callback ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© applicationÀ¸·Î º¸°íµÈ´Ù.
94// À̶§ Àü´ÞµÇ´Â µ¥ÀÌÅÍ´Â MCM DB itemÀÇ ¹øÁöÀÌ´Ù.
95// ±×·¯³ª callback ÇÔ¼ö ¾È¿¡¼­¸¸ »ç¿ëÇØ¾ß ÇÑ´Ù´Â Á¦¾àÁ¶°ÇÀÌ ÀÖÀ¸¹Ç·Î
96// "Àӽà µ¥ÀÌÅÍ"·Î¼­ÀÇ MCMÀ̶ó´Â ¿ø·¡ Á¤Ã¥À» À§¹ÝÇÏÁö´Â ¾Ê°ÔµÈ´Ù.
97//
98// MCMÀº Çʿ信 µû¶ó óÀ½ ÇÒ´çµÈ Å©±â ÀÌ»óÀ¸·Î Áõ°¡µÉ ¼ö ÀÖ´Ù. (¸Þ¸ð¸® ÀçÇÒ´ç)
99//
100//
101
102
103
104
105
106//   Mutex = { SemID, Owner, lockCnt, FailCnt, UseOsMutex, Name, flag,        traceLvl }
107//
108DMW_MUTEX
109  mcmMutex = { 0,     0,     0,       0,       FALSE,  "McmMtx", OS_SEM_PRIO, FALSE, };
110
111STATUS lock_mcm(int timeout)
112{
113        return DMW_LockMutexWait(&mcmMutex, timeout);
114}
115
116void unlock_mcm()
117{
118        DMW_UnlockMutex(&mcmMutex);
119}
120
121DHL_OS_TASK_ID get_mcm_owner()
122{
123        return DMW_GetOwnerTaskId(&mcmMutex);
124}
125
126
127//=======================================================================
128
129
130#if IMPLEMENT_MCM_ARRAY
131
132#if 0
133______New_Code________()
134#endif
135
136#if USE_STATIC_MCM
137#define MAX_MCM_SIZE 512 //ÃÖ´ë 512°³±îÁö mcm Áö¿øÇÔ.
138        //140bytes*512=70k. ´ë·« 70k Á¤µµÀÓ.
139
140static MCM_DB_T  static_mcm[MAX_MCM_SIZE];
141static MCM_DB_T *g_MCM = static_mcm;      // MCM DB pointer
142#else
143static MCM_DB_T *g_MCM = NULL;      // MCM DB pointer
144static UINT32    g_MCM_max = 0;     // ÇöÀç ÀúÀå °¡´ÉÇÑ ÃÖ´ë MCM item °¹¼ö. DB Å©±â.
145#endif
146
147// MCM DB¿¡ ÀúÀåµÇ¾î Àִ ä³Î Á¤º¸ °¹¼ö.
148static UINT32    g_MCM_number = 0;
149
150// MCMÀº ÀÏÂ÷¿ø ¹è¿­ ±¸Á¶¸¦ °®´Â´Ù.
151// MCM È®ÀåÀÌ ÇÊ¿äÇÒ °æ¿ì, ¸Þ¸ð¸®¸¦ Reallocation ÇØ¾ß ÇÑ´Ù.
152//
153
154#if USE_STATIC_MCM==0
155
156STATUS prepare_mcm_space(int margin)
157{
158        // MCM 1°³¸¦ À§ÇÑ °ø°£À» ÇÒ´çÀ» ÇÑ´Ù. margin ¸¸Å­ È®ÀåÇÏ´Â°Ô ¾Æ´Ô!!
159        //  marginÀÇ Àǹ̺¸´Ù increse_stepÀÇ °³³äÀ¸·Î ÀÌÇØÇØ¾ß ÇÑ´Ù.
160        // ¸¸¾à 1°³¸¦ À§ÇÑ °ø°£ÀÌ ¾øÀ» °æ¿ì margin ¸¸Å­ÀÇ Ãß°¡ °ø°£À» È®º¸ÇÑ´Ù. (¹è¿­À» È®Àå)
161        //
162       
163        if (g_MCM_number >= g_MCM_max) // °ø°£ÀÌ ºÎÁ·Çϸé,
164        {
165                g_MCM_number = g_MCM_max; // for safety..
166
167                if (margin < 8) margin = 8;
168
169                dprint(1, "prepare_mcm_space: increase mcm +%d, -> total %d \n", 
170                                margin, g_MCM_max+margin);
171                                                       
172                if (g_MCM) 
173                {
174                       
175                #if 0
176                        // ¸Þ¸ð¸® ÀçÇÒ´ç..
177                        if (OS_Realloc(&g_MCM, g_MCM_max * sizeof(MCM_DB_T),
178                                        (g_MCM_max + margin)*sizeof(MCM_DB_T))) {
179                                g_MCM_max += margin;
180                        }
181                        else
182                                // OS_Realloc()ÀÌ ½ÇÆÐÇØµµ g_MCM¿¡´Â º¯È­°¡ ¾ø´Ù.
183                                return statusOutOfMemory;
184
185                #else // cafrii 031112 TL_OS bugfix..
186                       
187                        MCM_DB_T *tmpMcm = DHL_OS_Malloc(sizeof(MCM_DB_T) * (g_MCM_max + margin));
188                        if (tmpMcm == NULL)
189                                return statusOutOfMemory;
190                               
191                        memcpy(tmpMcm, g_MCM, sizeof(MCM_DB_T) * g_MCM_number);
192                       
193                        DHL_OS_Free((void**)&g_MCM);
194                        g_MCM = tmpMcm;
195                        g_MCM_max += margin;
196               
197                #endif
198                       
199                }
200                else
201                {
202                        // ¸Þ¸ð¸® ½Å±Ô ÇÒ´ç.
203                        g_MCM_number = 0;
204                        g_MCM_max = margin;
205                        g_MCM = DHL_OS_Malloc(sizeof(MCM_DB_T) * g_MCM_max);
206                       
207                        if (g_MCM == NULL) {
208                                g_MCM_max = 0;
209                                return statusOutOfMemory;
210                        }
211                }
212        }
213        return statusOK;
214}
215
216
217
218MCM_DB_T *new_mcm()
219{
220        // MCM Çϳª¸¦ ÁغñÇÑ´Ù.
221        //
222        MCM_DB_T *m;
223
224        if (prepare_mcm_space(32) != statusOK) {
225                dprint(0, "new_mcm: !! out of memory!\n");
226                return NULL;
227        }
228
229        #if DEVELOPMENT_BUILD
230        DHL_ASSERT(g_MCM_number < g_MCM_max, "MCM corrupt! g_MCM_number >= g_MCM_max"); // Àû¾îµµ Çϳª ÀÌ»óÀÇ °ø°£ÀÌ ÀÖ´ÂÁö È®ÀÎ.
231                // post-check ¿¡¼­ pre-check·Î º¯°æÇÔ.
232        #endif
233       
234        m = &g_MCM[g_MCM_number++];
235
236        memset(m, 0, sizeof(MCM_DB_T)); // ÃʱâÈ­..
237
238        return m;
239}
240
241void free_mcm(MCM_DB_T *m)
242{
243        // MCM Çϳª¸¦ »èÁ¦ÇÑ´Ù.
244        // mÀÌ MCM array»ó¿¡ ÀÖ´Â À¯È¿ÇÑ Æ÷ÀÎÅÍÀÎÁö È®ÀÎÇϰí,
245        // m ÀÌÈÄÀÇ ¸ðµç MCM itemÀ» Çϳª¾¿ ¾ÕÀ¸·Î shiftÇÑ´Ù.
246        //
247        // ½ÇÁ¦·Î ÀÌ ÇÔ¼ö¸¦ »ç¿ëÇÒ ÇÊ¿ä´Â °ÅÀÇ ¾ø´Ù. ÇÊ¿ä½Ã È®Àå (prepare_mcm_space) Çϰí
248        // ¸Þ¸ð¸® 'Ãà¼Ò'´Â ÇÏÁö ¾Ê´Â ¹æ½ÄÀ» äÅÃÇϱ⠶§¹®ÀÌ´Ù.
249        // MCM Çϳª¸¦ deleteÇÒ °æ¿ì¿¡´Â ´ëºÎºÐ caller¿¡¼­ ¾Ë¾Æ¼­ shift½Ã۰í ÀÖ´Ù.
250        //
251        unsigned int i;
252        int k;
253        for (i=0; i<g_MCM_number; i++)
254        {
255                if (&g_MCM[i] == m)
256                        goto delete_it;
257        }
258
259        return;  // not found!!  'm' cannot be freed.
260
261delete_it:
262       
263        // cafrii 041126 add
264        if (1) {
265                dprint(2, "delete CSD of MCM[%d], 0x%x, %d/%d csds\n", i, g_MCM[i].csd, g_MCM[i].num_csd, g_MCM[i].max_csd);
266               
267                for (k=0; k<g_MCM[i].num_csd; k++) {
268                        DHL_OS_Free((void**)&g_MCM[i].csd[k].ptr);
269                }
270                DHL_OS_Free((void**)&g_MCM[i].csd);
271               
272                g_MCM[i].num_csd = g_MCM[i].max_csd = 0;
273        }
274       
275        i++;
276        for (; i<g_MCM_number; i++)
277        {
278                g_MCM[i-1] = g_MCM[i];
279        }
280        g_MCM_number--;
281}
282
283void free_all_mcm()
284{
285        int i, k;
286       
287        // MCM Àüü¸¦ ´Ù »èÁ¦..
288        //
289        dprint(2, "free_all_mcm()\n");
290       
291        // cafrii 041126 add
292        //
293        for (i=g_MCM_number-1; i>=0; i--) {
294
295                dprint(3, "  delete csd of mcm[%d], 0x%x, %d csds\n", i, g_MCM[i].csd, g_MCM[i].num_csd);
296               
297                for (k=0; k<g_MCM[i].num_csd; k++) {
298                        DHL_OS_Free((void**)&g_MCM[i].csd[k].ptr);
299                }
300                DHL_OS_Free((void**)&g_MCM[i].csd);
301                g_MCM[i].num_csd = g_MCM[i].max_csd = 0;
302        }
303       
304       
305        if (g_MCM)
306                DHL_OS_Free((void**)&g_MCM);
307        g_MCM_max = g_MCM_number = 0;
308
309        reset_mcm_id_counter(); // cafrii 060726 add
310}
311
312#else
313
314MCM_DB_T *new_mcm()
315{
316        // MCM Çϳª¸¦ ÁغñÇÑ´Ù.
317        //
318        MCM_DB_T *m;
319       
320        if(g_MCM_number>=MAX_MCM_SIZE) {
321                DHL_ASSERT(g_MCM_number<MAX_MCM_SIZE, 
322                        "MCM number is over MAX_MCM_SIZE(MAX_MCM_SIZE:512)\n");
323        }
324       
325        m = &g_MCM[g_MCM_number++];
326
327        memset(m, 0, sizeof(MCM_DB_T)); // ÃʱâÈ­..
328
329        return m;
330}
331
332
333void free_mcm(MCM_DB_T *m)
334{
335        //useless
336        DHL_ASSERT(FALSE, "Can't call this func(free_mcm)\n");
337}
338
339
340void free_all_mcm()
341{
342        int i, k;
343       
344        // MCM Àüü¸¦ ´Ù »èÁ¦..
345        //
346        dprint(2, "free_all_mcm()\n");
347       
348        // cafrii 041126 add
349        //
350        for (i=g_MCM_number-1; i>=0; i--) {
351
352                dprint(3, "  delete csd of mcm[%d], 0x%x, %d csds\n", i, g_MCM[i].csd, g_MCM[i].num_csd);
353               
354                for (k=0; k<g_MCM[i].num_csd; k++) {
355                        DHL_OS_Free((void**)&g_MCM[i].csd[k].ptr);
356                }
357                DHL_OS_Free((void**)&g_MCM[i].csd);
358                g_MCM[i].num_csd = g_MCM[i].max_csd = 0;
359        }
360       
361        //if (g_MCM)
362        //      DHL_OS_Free((void**)&g_MCM);
363        g_MCM_number = 0;
364
365        reset_mcm_id_counter(); // cafrii 060726 add
366}
367
368
369#endif
370
371// cafrii 060726 add
372static UINT16 g_current_mcm_id = 1;  // 0 is not used.
373UINT16 get_new_mcm_id(void)
374{
375        unsigned int i;
376        int original_id = g_current_mcm_id ? g_current_mcm_id : 1;
377        // 0Àº »ç¿ëÇÏÁö ¾Ê±â·Î ÇßÀ¸´Ï±î..
378       
379        while (1)
380        {
381                for (i=0; i<g_MCM_number; i++) {
382                        if (g_MCM[i].Uid == g_current_mcm_id)
383                                break;
384                }
385                if (i == g_MCM_number)
386                        return g_current_mcm_id;  // ÀÏÄ¡ÇÏ´Â °ÍÀÌ ¾øÀ¸¹Ç·Î ¾ÈÀüÇÏ°Ô »ç¿ë °¡´ÉÇÔ.
387                       
388                g_current_mcm_id++;
389                if (g_current_mcm_id == 0) // 0°ªÀº »ç¿ëÇÏÁö ¾Ê±â·Î ÇÏÀÚ.
390                        g_current_mcm_id++;
391                       
392                if (g_current_mcm_id == original_id)
393                        dprint(0, "!! mcm id counter is full???\n");
394        }
395}
396
397void reset_mcm_id_counter(void)
398{
399        // UID »ý¼º ¹øÈ£¸¦ ¸®¼ÂÇÑ´Ù. 0 °ªÀº »ç¿ëµÇÁö ¾Ê°í 1ºÎÅÍ »ç¿ëÇÑ´Ù.
400        g_current_mcm_id = 1;
401}
402
403
404MCM_DB_T *get_mcm_by_id(UINT16 id)
405{
406        unsigned int i;
407        for (i=0; i<g_MCM_number; i++)
408                if (g_MCM[i].Uid == id)
409                        return &g_MCM[i];
410
411        return NULL;
412}
413
414MCM_DB_T *find_mcm_analog(int major, int rf)
415{
416        // analog À̸鼭 (minor == 0)
417        // Major == major, RF == rfÀΠä³ÎÀ» ã´Â´Ù.
418       
419        unsigned int i;
420        for (i=0; i<g_MCM_number; i++)
421        {
422                if (g_MCM[i].Major == major && g_MCM[i].Minor == 0 && g_MCM[i].RF == rf)
423                        return &g_MCM[i];
424        }       
425        return NULL;   
426}
427
428
429MCM_DB_T *find_mcm_major_minor(int major, int minor)
430{
431        // major, minor°¡ ÀÏÄ¡ÇÏ´Â MCMÀ» ã¾Æ ¸®ÅÏ.
432        //
433        unsigned int i;
434        for (i=0; i<g_MCM_number; i++)
435        {
436                if (g_MCM[i].Major == major && g_MCM[i].Minor == minor)
437                        return &g_MCM[i];
438        }
439        return NULL;
440}
441
442MCM_DB_T *find_mcm_major_minor_rf(int major, int minor, int rf)
443{
444        // major, minor, RF°¡ ¸ðµÎ ÀÏÄ¡ÇÏ´Â MCMÀ» ã¾Æ ¸®ÅÏ.
445        //
446        unsigned int i;
447        for (i=0; i<g_MCM_number; i++)
448        {
449                if (g_MCM[i].Major == major && g_MCM[i].Minor == minor && g_MCM[i].RF == rf)
450                        return &g_MCM[i];
451        }
452        return NULL;
453}
454
455MCM_DB_T *find_mcm_major_minor_rf_vf(int major, int minor, int rf, int vctFlag)
456{
457        // major, minor, RF°¡ ¸ðµÎ ÀÏÄ¡ÇÏ´Â MCMÀ» ã¾Æ ¸®ÅÏ.
458        //
459        unsigned int i;
460        vctFlag = vctFlag != 0 ? 1 : 0;  // zero or one.
461        for (i=0; i<g_MCM_number; i++)
462        {
463                if (g_MCM[i].Major == major && g_MCM[i].Minor == minor
464                                && g_MCM[i].RF == rf && g_MCM[i].VctFlag == vctFlag)
465                        return &g_MCM[i];
466        }
467        return NULL;
468}
469
470// cafrii 041130 add
471//
472MCM_DB_T *find_mcm_rf_prognum_vf(int rf, int program_number, int vctFlag)
473{
474        unsigned int i;
475       
476        vctFlag = vctFlag != 0 ? 1 : 0;  // zero or one.
477        for (i=0; i<g_MCM_number; i++)
478        {
479                if (g_MCM[i].RF == rf && 
480                        g_MCM[i].Prog_number == program_number &&
481                        g_MCM[i].VctFlag == vctFlag)
482                        return &g_MCM[i];
483        }
484        return NULL;
485}
486
487// cafrii 060725 add
488BOOL check_mcm_if_rf_prognum_exist(int rf, int program_number)
489{
490        unsigned int i;
491        for (i=0; i<g_MCM_number; i++)
492        {
493                if (g_MCM[i].RF == rf && 
494                        g_MCM[i].Prog_number == program_number &&
495                        g_MCM[i].fresh) // À̹ø scan¿¡ »õ·Ó°Ô Ãß°¡µÈ entry¸¸ ã´Â´Ù.
496                        return TRUE;
497        }
498        return FALSE;
499}
500
501
502int sort_mcm()
503{
504        // MCMÀ» Major/Minor/RF/Vf ¼øÀ¸·Î Á¤¸®ÇÑ´Ù. (¿À¸§Â÷¼ø. Vf¸¸ ³»¸²Â÷¼ø.)
505        //
506        MCM_DB_T tmp;
507        unsigned int i;
508        unsigned int k;
509       
510        if (g_MCM_number <= 0)
511                return 0;
512
513        for (i=0; i<g_MCM_number-1; i++)
514                if (g_MCM[i].VctFlag) 
515                        g_MCM[i].VctFlag = 1;  // TRUEÀÇ Á¤Àǰ¡ non-zero·Î Á» ¾Ö¸ÅÇϹǷΠÁ¤·ÄÇÒ¶§´Â 1·Î °íÁ¤½ÃŰ´Â°Ô ÆíÇÔ.
516               
517        for (i=0; i<g_MCM_number-1; i++)
518        {
519                for (k=i+1; k<g_MCM_number; k++)
520                {
521                        // i¿Í k¸¦ ºñ±³Çؼ­ i°¡ ´õ Å©¸é ±³È¯.
522                #if 1
523                        if (require_mcm_swap(&g_MCM[i], &g_MCM[k])) {
524                                // swap
525                                tmp = g_MCM[i];
526                                g_MCM[i] = g_MCM[k];
527                                g_MCM[k] = tmp;
528                        }
529                #else
530                        if (g_MCM[i].Major > g_MCM[k].Major)
531                        {
532                                // swap
533                                tmp = g_MCM[i];
534                                g_MCM[i] = g_MCM[k];
535                                g_MCM[k] = tmp;
536                        }
537                        else if (g_MCM[i].Major == g_MCM[k].Major)
538                        {
539                                if (g_MCM[i].Minor > g_MCM[k].Minor)
540                                {
541                                        // swap
542                                        tmp = g_MCM[i];
543                                        g_MCM[i] = g_MCM[k];
544                                        g_MCM[k] = tmp;
545                                }
546                                else if (g_MCM[i].Minor == g_MCM[k].Minor)
547                                {
548                                        if (g_MCM[i].RF > g_MCM[k].RF)
549                                        {
550                                                // swap
551                                                tmp = g_MCM[i];
552                                                g_MCM[i] = g_MCM[k];
553                                                g_MCM[k] = tmp;
554                                        }
555                                }
556                        }
557                #endif
558                }
559        }
560//compile warming Á¦°Å : return 0Ãß°¡           probability
561        return 0;
562}
563
564STATUS select_max_mcms()
565{
566        // MCM¿¡¼­ °°Àº ¹øÈ£¸¦ °®´Â ä³Îµé Áß¿¡¼­ "´ëǥä³Î"À» ¼±ÅÃÇÏ°í ±× Ã¤³Î¸¸À» enable½ÃŲ´Ù.
567        // ¿©±â¼­ °°Àº ¹øÈ£¶õ, ÇöÀç ¹æÄ§¿¡ µû¸£¸é major/minor/vf ÀÌ´Ù.
568
569        // ÇöÀç sortingµÇ¾î ÀÖ´Â »óÅÂÀ̹ǷΠÀÛÀº ¹øÈ£ÀÇ Ã¤³ÎºÎÅÍ ½ÃÀÛÇØ¼­
570        // µ¿ÀÏÇÑ Mj/Mn/Rf °ªÀ» °®´Â ä³Îµé Áß¿¡¼­ ½ÅÈ£ ¼¼±â°¡ °¡Àå Å« °ÍÀ» ¼±ÅÃÇϰí,
571        //     ³ª¸ÓÁö´Â skip flag¸¦ ¼¼ÆÃÇÑ´Ù.
572
573        int maxnd;
574        unsigned int n;
575
576        if (g_MCM == NULL || g_MCM_number <= 0)
577                return statusOK;
578
579        maxnd = -1;  // maxnd´Â ÇöÀç±îÁö ÃÖ´ë strength¸¦ °®´Â mcmÀÇ À妽º.
580
581        // mj/mn/rf/vctf ¸¸À¸·Î ÆÇ´ÜÇÑ´Ù.
582        //  À§ µ¥ÀÌÅͰ¡ ¸ðµÎ µ¿ÀÏÇϸ鼭 ntsc/8vsb/64qam/256qamÀÌ ¼­·Î ´Ù¸¥ °ÍµéÀº
583        //    Àû´çÇÑ °ÍÀ¸·Î ÀÌ¹Ì ¼±ÅõǾî ÅëÀÏ µÇ¾î ÀÖ´Ù°í °¡Á¤.
584        // 
585
586        // ¸ÕÀú VctFlag == 1ÀÎ °æ¿ìºÎÅÍ ½ÃÀÛÇÏÀÚ.
587        for (n=0; n<g_MCM_number; n++)
588        {
589                // examin n'th MCM  (g_MCM[n])
590                if (g_MCM[n].VctFlag == 0) continue;   // ÀÌ MCMµéÀº ´ÙÀ½ ·çÇÁ¿¡¼­ µû·Î ó¸®.
591               
592                g_MCM[n].Skipped = TRUE;  // ±âº»À¸·Î ¸ðµÎ skipÀ¸·Î ¼³Á¤Çϰí, ³ªÁß¿¡ ƯÁ¤ÇÑ MCM¸¸ activateÇÑ´Ù.
593
594#if 0 // neverdai 101013 hidden 󸮴 post_process_mcm¿¡¼­ ó¸®µÉ °ÍÀ̹ǷΠ¿©±â¼­ ½Å°æ¾µ ÇÊ¿ä ¾øÀ½.
595                if (g_MCM[n].hidden) continue;  // hiddenÀº Ç×»ó Skip.
596#endif
597
598                if (maxnd == -1)  // ¾ÆÁ÷±îÁö ´ëǥä³ÎÀÌ ¾ø´Â °æ¿ì..
599                        maxnd = n;   // ÀÌ Ã¤³ÎÀ» ´ëÇ¥ ä³Î·Î ÁöÁ¤.
600               
601                if (equiv_mcm_major_minor_vf(&g_MCM[maxnd], &g_MCM[n])) {
602                        // ºñ±³ ´Ü°è °è¼Ó ÁøÇàÁß...
603                        // Áö±Ý±îÁöÀÇ ¿ì½ÂÈĺ¸(ÃÖ´ë strengthÀÇ ³ëµå)ÀÎ 'maxnd'¿Í 'n'°ú °æÀï..
604
605                        if (g_MCM[maxnd].signal_strength < g_MCM[n].signal_strength)
606                                maxnd = n;      // »õ·Î¿î ¿ì½ÂÀÚ 'n' ź»ý.. maxnd·Î ½Â°Ý.
607                }
608                else {
609                        // ºñ±³ ´Ü°è ³¡.. ¿©±â¼­ºÎÅÍ´Â »õ·Î¿î ¹øÈ£¸¦ °®´Â ä³Î ÁýÇÕ ½ÃÀÛÀÓ.
610                        // ±× Àü¿¡ ¾Õ ´Ü°è "´ëǥä³Î" ¼±ÅÃ.
611                        //
612                        if (maxnd >= 0)
613                                g_MCM[maxnd].Skipped = FALSE;  // <-- "´ëǥä³Î·Î ¼±ÅÃ!!!"
614                                // ÀÌ Àü±îÁöÀÇ ÁýÇÕµé Áß¿¡¼­ "´ëǥä³Î"À» enable ÇÑ´Ù.
615                                // ÀÌ Àü ä³ÎµéÀÌ ¸ðµÎ hiddenÀÎ °æ¿ì¿¡´Â        maxnd°¡ ¾øÀ» ¼öµµ ÀÖ´Ù.
616                               
617                        // »õ ºñ±³ ´Ü°è ½ÃÀÛ.
618                        maxnd = n;
619                }
620        }
621
622        if (maxnd >= 0 && g_MCM[maxnd].VctFlag
623#if 0
624                 && !g_MCM[maxnd].hidden
625#endif
626                 )
627                g_MCM[maxnd].Skipped = FALSE; // <-- "¼±ÅÃ!!!"
628                        // ¸¶Áö¸· maxnode´Â ¼±ÅÃÀÌ ¾ÈµÈ »óÅ¿¡¼­ loop ÀÌÅ»ÇßÀ¸¹Ç·Î ¿©±â¼­ "¼±ÅÃ".
629
630        // VctFlag == 0ÀΠä³ÎÁ¤º¸¿¡ ´ëÇØ¼­ ¹Ýº¹.
631        for (n=0; n<g_MCM_number; n++)
632        {
633                // examin n'th MCM  (g_MCM[n])
634                if (g_MCM[n].VctFlag) continue;   // ÀÌ MCMµéÀº ¾Õ ·çÇÁ¿¡¼­ ÀÌ¹Ì Ã³¸®Çß´Ù.
635
636                g_MCM[n].Skipped = TRUE;  // ±âº»À¸·Î ¸ðµÎ skipÀ¸·Î ¼³Á¤Çϰí, ³ªÁß¿¡ ƯÁ¤ÇÑ MCM¸¸ activateÇÑ´Ù.
637                g_MCM[n].hidden = FALSE;  // Vct¿¡¼­ ¿Â Á¤º¸°¡ ¾Æ´Ï¹Ç·Î hiddenÀ̶õ ¾ø´Ù.
638
639                if (maxnd == -1)  // ¾ÆÁ÷±îÁö ´ëǥä³ÎÀÌ ¾ø´Â °æ¿ì..
640                        maxnd = n;   // ÀÌ Ã¤³ÎÀ» ´ëÇ¥ ä³Î·Î ÁöÁ¤.
641               
642                if (equiv_mcm_major_minor_vf(&g_MCM[maxnd], &g_MCM[n])) {
643                        // ºñ±³ ´Ü°è °è¼Ó ÁøÇàÁß...
644                        // Áö±Ý±îÁöÀÇ ¿ì½ÂÈĺ¸(ÃÖ´ë strengthÀÇ ³ëµå)ÀÎ 'maxnd'¿Í 'n'°ú °æÀï..
645
646                        if (g_MCM[maxnd].signal_strength < g_MCM[n].signal_strength)
647                                maxnd = n;      // »õ·Î¿î ¿ì½ÂÀÚ 'n' ź»ý.. maxnd·Î ½Â°Ý.
648                }
649                else {
650                        // ºñ±³ ´Ü°è ³¡.. ¿©±â¼­ºÎÅÍ´Â »õ·Î¿î ¹øÈ£¸¦ °®´Â ä³Î ÁýÇÕ ½ÃÀÛÀÓ.
651                        // ±× Àü¿¡ ¾Õ ´Ü°è "´ëǥä³Î" ¼±ÅÃ.
652                        //
653                        if (maxnd >= 0)
654                                g_MCM[maxnd].Skipped = FALSE;  // <-- "¼±ÅÃ!!!"
655                                // ÀÌ Àü±îÁöÀÇ ÁýÇÕµé Áß¿¡¼­ "´ëǥä³Î"À» enable ÇÑ´Ù.
656                                // ÀÌ Àü ä³ÎµéÀÌ ¸ðµÎ hiddenÀÎ °æ¿ì¿¡´Â        maxnd°¡ ¾øÀ» ¼öµµ ÀÖ´Ù.
657                               
658                        // »õ ºñ±³ ´Ü°è ½ÃÀÛ.
659                        maxnd = n;
660                }
661        }
662       
663        if (maxnd >= 0 && g_MCM[maxnd].VctFlag == 0)
664                g_MCM[maxnd].Skipped = FALSE; // <-- "¼±ÅÃ!!!"
665                        // ¸¶Áö¸· maxnode´Â ¼±ÅÃÀÌ ¾ÈµÈ »óÅ¿¡¼­ loop ÀÌÅ»ÇßÀ¸¹Ç·Î ¿©±â¼­ "¼±ÅÃ".
666
667        return statusOK;
668}
669
670
671
672void ucm_to_mcm()
673{
674        // ucm Á¤º¸¸¦ Àо mcmÀ¸·Î ¸¸µç´Ù.
675        //
676        // »ç¿ëÀÚ°¡ ÀÚµ¿ ä³Î °Ë»öÀ» ¼±ÅÃÇÒ ¶§ "update ¸ðµå"·Î ÇÏ´Â °æ¿ì,
677        // ±âÁ¸ÀÇ Á¤º¸(ucm)´Â »èÁ¦ÇÏ¸é ¾ÈµÇ°í, ä³Î °Ë»öÀ» ¼öÇàÇÑ ÈÄ updateÇØ¾ß ÇÑ´Ù.
678        // ÀÌ °æ¿ì ucm Á¤º¸¸¦ mcmÀ¸·Î º¯È¯ÇÏ´Â ÀÛ¾÷ÀÌ ÇÊ¿äÇÏ´Ù.
679       
680        int i;
681        MCM_DB_T *m;
682        UCM_DB_T *u;
683
684        dprint(2, "ucm_to_mcm()..\n"); 
685        free_all_mcm();  // mcmÀº »õ·Î ¸¸µé °ÍÀ̹ǷΠ´Ù »èÁ¦..
686
687        //dprint(2, "mcm freed. lock ucm..\n");
688        DMW_MSC_LockUcm();
689
690        if (g_bReserveUcmIndex0) {
691                // UCMÀÇ Ã¹¹øÂ° ºÎºÐÀº Reserved ¿µ¿ªÀ̹ǷΠMCMÀ¸·Î º¹»çÇÏÁö ¾Ê´Â´Ù.
692                i = 1;
693        }
694        else
695                i = 0;
696       
697        for (; i<g_UCM_number; i++)
698        {
699                m = new_mcm();
700                if (m == NULL) break;
701                u = &g_UCM[i];
702               
703                memcpy(m, u, sizeof(MCM_DB_T)); // UCM È®Àå ºÎºÐÀº º¹»çÇÏ¸é ¾ÈµÈ´Ù.
704                m->fresh = 0; // cafrii 060725 add
705                        // ±âÁ¸¿¡ ÀÖ´ø DB´Â ¸ðµÎ 'old' À̰í, Ãß°¡µÉ DB°¡ freshÀ̹ǷÎ.
706
707                m->Uid = get_new_mcm_id(); // cafrii 060726 add
708               
709                // cafrii 041126 add
710                if (u->csd && u->max_csd > 0 && u->num_csd > 0)
711                {
712                        dprint(3, "  copy ucm[%d].csd to mcm, %d csds\n", i, u->num_csd);
713                       
714                        m->csd = DMW_CDB_DuplicateCsd(u->csd, u->num_csd, u->max_csd);
715                       
716                        if (m->csd) {
717                                m->num_csd = u->num_csd;
718                                m->max_csd = u->max_csd;
719                        }
720                        else {
721                                dprint(0, "!! ucm[%d].csd duplicate err\n", i);
722                                m->num_csd = m->max_csd = 0;
723                        }
724                }
725                else {
726                        m->csd = NULL;
727                        m->num_csd = m->max_csd = 0;
728                }
729        }
730
731        //dprint(2, "now, unlock umc..\n");
732        DMW_MSC_UnlockUcm();
733
734}
735
736
737void copy_to_ucm()  // mcm -> ucm
738{
739        // mcmÀ» óÀ½ºÎÅÍ Çϳª¾¿ Àо ucm¿¡ º¹»ç¸¸ ÇÏ¸é µÈ´Ù.
740        // mcmÀº Á¤·ÄµÈ »óÅÂÀ̾î¾ß Çϸç,
741        // ucm¿¡ »ç¿ëµÉ ¸ðµç Çʵå´Â ÃʱâÈ­ µÇ¾î ÀÖ¾î¾ß ÇÑ´Ù.
742        // skip flagµµ Á¤»óÀûÀ¸·Î ÃʱâÈ­ µÇ¾î ÀÖ¾î¾ß ÇÔ.
743       
744        // »ç¿ë ¿¹)
745        //   1. ucm_to_mcm();
746        //   2. gather_mcm_from_autoscan();
747        //   3. sort_mcm();
748        //   4. select_max_mcms();
749        //   5. copy_to_ucm();
750        //   6. free_all_mcm();
751       
752        unsigned int i;
753        MCM_DB_T *m;
754        UCM_DB_T *u;
755
756        DMW_CDB_ClearAll(); // ¸ÕÀú ±âÁ¸ UCMÀ» ¸ðµÎ »èÁ¦ÇÑ´Ù.
757
758        DMW_MSC_LockUcm();
759
760        reset_ucm_uid_counter();
761
762        prepare_ucm_space(g_MCM_number + 8);
763                // ¿©±â¼­ ¿¡·¯°¡ ³¯ ¼öµµ ÀÖÀ½. mcm°¹¼ö°¡ ³Ê¹« ¸¹¾Æ ¸Þ¸ð¸®°¡ ºÎÁ·ÇÒ °æ¿ì.
764                // ÀÌ °æ¿ì °è¼Ó ÁøÇàÇϵµ·Ï ÇÔ. ¸î°³¸¸ÀÌ¶óµµ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇÏ´Â°Ô ³´±â ¶§¹®.
765
766        if (g_bReserveUcmIndex0) {
767                memset(&g_UCM[0], 0, sizeof(g_UCM[0]));
768                g_UCM_number++;
769        }
770       
771        for (i=0; i<g_MCM_number; i++)
772        {
773                if (prepare_ucm_space(8) != statusOK)
774                        break;
775
776                u = &g_UCM[g_UCM_number];  // active ucm
777                m = &g_MCM[i];             // active mcm
778               
779                memset(u, 0, UcmItemMemorySize());  // UCMÀ» ¸ÕÀú clearÇϰí,
780                memcpy(u, m, sizeof(MCM_DB_T));     // MCM¿¡ »ó´çÇÏ´Â ºÎºÐ¸¸ º¹»çÇÑ´Ù. Áï UCM È®Àå Á¤º¸´Â »èÁ¦µÈ´Ù.
781               
782                // cafrii 041126 add
783                if (m->csd && m->max_csd > 0 && m->num_csd > 0)
784                {
785                        dprint(3, "  copy mcm[%d].csd to ucm\n", i);
786                       
787                        u->csd = DMW_CDB_DuplicateCsd(m->csd, m->num_csd, m->max_csd);
788                       
789                        if (u->csd) {
790                                u->num_csd = m->num_csd;
791                                u->max_csd = m->max_csd;
792                        }
793                        else {
794                                dprint(0, "!! mcm[%d].csd dup err\n", i);
795                                u->num_csd = u->max_csd = 0;
796                        }
797                }
798                else {
799                        u->csd = NULL;
800                        u->num_csd = u->max_csd = 0;
801                }
802               
803                u->Uid = make_new_ucm_uid_counter();
804                g_UCM_number++;
805        }
806
807        DMW_MSC_UnlockUcm();
808}
809
810int *update_to_ucm(BOOL bGetUidData, int *pnUid, BOOL bEnableNewChannel) // mcm ++> ucm
811{
812        // UpdateDB API¿¡¼­ ÇöÀç ä³Î updateÈÄ ¾òÀº MCM Á¤º¸¸¦ UCM¿¡ updateÇÏ´Â ÇÔ¼ö.
813        //
814        // mcmÀº Á¤·ÄµÈ »óÅÂÀÏ ÇÊ¿ä´Â ¾ø´Ù. updateÇϸ鼭 ´Ù½Ã Á¤·ÄÀ» ½Ã۱⠶§¹®.
815        //  ±×·¯³ª mcmÀº Á¤·ÄÀÌ µÇ¾î ÀÖ´Â°Ô º¸ÅëÀÌ´Ù.
816        // ÇÑ Ã¤³Î (¶Ç´Â ÀϺΠä³Î)¸¸ channel scanÀ» ÇÒ °æ¿ì »ç¿ëµÉ °ÍÀÓ.
817        //
818        // »ç¿ë ¿¹)
819        //   1. gather_mcm();
820        //   2. sort_mcm();
821        //   3. update_to_mcm(0, 0); // <- ³»ºÎ¿¡¼­ selectionÀ» ÇÏÁö ¾Ê´Â´Ù.
822        //   4. free_all_mcm();
823        //
824        // bGetUidData:  TRUEÀ̸é updateµÈ ä³Î Á¤º¸¸¦ pnUid ¹öÆÛ¸¦ ÅëÇØ µÇµ¹·ÁÁØ´Ù.
825        //               FALSEÀ̸é update¸¸ Çϰí caller´Â ¾î¶² ä³ÎÀÌ updateµÇ¾ú´ÂÁö´Â ¸ð¸¥´Ù.
826        // pnUid:        UpdateµÈ ä³Î Á¤º¸¸¦ ¸®ÅÏÇÏ´Â ¹öÆÛ.
827        //               Caller°¡ OS_Free ½ÃÄÑ¾ß ÇÑ´Ù.
828        // bEnableNewChannel: TRUEÀÌ¸é ±âº»À¸·Î updateµÈ ä³ÎµéÀ» ¸ðµÎ enable·Î ¸¸µç´Ù.
829        //
830        // »ç¿ë¿¹)
831        // ¸¸¾à updateµÈ uid Á¤º¸¸¦ ¹ÞÀ»·Á¸é ¾Æ·¡¿Í °°ÀÌ ÇÑ´Ù.
832        // int nUid, *uidBuf;
833        // uidBuf = update_to_ucm(TRUE, &nUid);
834        // if (nUid > 0 && uidBuf)
835        //       OS_DbgPrintf("%[%03d] ...\n", uidBuf[0], ...);  // uid Á¤º¸¸¦ »ç¿ëÇÑ´Ù.
836        // if (uidBuf) DHL_OS_Free((void**)&uidBuf);
837        //
838       
839        unsigned int i;
840        int idx, err;
841        MCM_DB_T *m;
842        UCM_DB_T *u;
843       
844        int *uidBuf, nUid=0;
845
846        dprint(1, "update_to_ucm():\n");
847       
848        DMW_MSC_LockUcm();
849       
850        if (g_UCM_number == 0)
851                reset_ucm_uid_counter();
852               
853        if (bGetUidData && g_MCM_number)
854                uidBuf = DHL_OS_Malloc(sizeof(int) * g_MCM_number);  // out of mem Àϼöµµ ÀÖ´Ù.
855        else
856                uidBuf = NULL; // cafrii 060627 add
857               
858        for (i=0; i<g_MCM_number; i++)
859        {
860
861                if (prepare_ucm_space(8) != statusOK)
862                        break;
863
864                m = &g_MCM[i];             // active mcm
865                idx = find_ucm_mj_mn_rf_vf(m->Major, m->Minor, m->RF, m->VctFlag);
866               
867                //if (idx > 0) { bugbug..
868                if (idx >= 0) { // cafrii, 030506
869                       
870                        // something exist. update mode.
871                        // ÀÌ·± °æ¿ì¿¡´Â uid_counterµµ ±âÁ¸ÀÇ °ª ±×´ë·Î À¯ÁöµÈ´Ù.
872                        u = &g_UCM[idx];
873                        memcpy(u->ShortName, m->ShortName, 14);
874                        u->Pcr_pid   = m->Pcr_pid;
875                        u->Video_pid = m->Video_pid;
876                        u->Audio_pid = m->Audio_pid;
877                        u->pmt_pid = m->pmt_pid;
878                        u->Prog_number  = m->Prog_number;
879                        u->Service_type = m->Service_type;
880                        //u->Skipped      = m->Skipped;   // ÀÌ Çʵå´Â ¿øº»À» º¸°üÇØ¾ß ÇÑ´Ù.
881                        //u->SurfIndex    = m->SurfIndex; // ÀÌ Çʵå´Â ¿øº»À» º¸°üÇØ¾ß ÇÑ´Ù.
882                        //u->Uid;    // ÀÌ Çʵå´Â update ´ë»óÀÌ ¾Æ´Ï´Ù.
883                        //u->pEpgDB; // ÀÌ Çʵå´Â update ´ë»óÀÌ ¾Æ´Ï´Ù.
884                        u->signal_strength = m->signal_strength;
885                        u->TSID = m->TSID;
886                        u->source_id = m->source_id;
887                        u->channel_tsid = m->channel_tsid;
888                        u->hidden = m->hidden;
889                        //u->video_format = m->video_format; //ÀÌ Çʵå´Â ¿øº»À» º¸°üÇÔ.
890                       
891                        // cafrii 041126 add
892                        // partially update.. user channel name µîÀº udpate ÇÏ¸é ¾ÈµÈ´Ù.
893                        // ±×·±µ¥ ÇöÀç mcm ¿¡´Â ExtendedChannelName tag ¿Í °°Àº Á¤º¸¸¸ ÀÖÀ» °ÍÀ¸·Î »ý°¢µÇ¹Ç·Î
894                        // user Á¤º¸´Â ¾øÀ» °ÍÀÌ´Ù.
895                        //
896                        if (m->csd && m->max_csd > 0 && m->num_csd > 0)
897                        {
898                                dprint(2, "  csd update: ucm[%d] (%d/%d) <-- mcm[%d] (%d/%d)\n", 
899                                                                idx, u->num_csd, u->max_csd, i, m->num_csd, m->max_csd);
900                       
901                                err = DMW_CDB_UpdateCsd(&u->csd, &u->num_csd, &u->max_csd, m->csd, m->num_csd);
902                       
903                                if (err) {
904                                        dprint(0, "!! update_to_ucm: UpdateCsd err\n");
905                                        // ±×³É ±×´ë·Î µÎ¸é µÈ´Ù.  »õ csd´Â updateµÇÁö ¾Ê¾ÒÀ½..
906                                }
907                        }
908                        if (uidBuf)
909                                uidBuf[nUid++] = u->Uid;
910                }
911                else {
912                        // none. newly insert.
913                        u = insert_ucm_ptr(m->Major, m->Minor, m->RF, m->VctFlag);
914                        if (u) {
915                                // u´Â 0À¸·Î clearµÇ¾î¼­ ¸®ÅϵȴÙ.
916                                memcpy(u, m, sizeof(MCM_DB_T)); // cafrii 030326. MCM »ó´ç ºÎºÐ¸¸ º¹»ç.
917                               
918                                // duplicate..  u.csd <-- m.csd
919                                //
920                                // cafrii 041126 add
921                                if (m->csd && m->max_csd > 0 && m->num_csd > 0) 
922                                {
923                                        dprint(3, "  duplicate mcm[%d].csd to ucm\n", i);
924                                       
925                                        u->csd = DMW_CDB_DuplicateCsd(m->csd, m->num_csd, m->max_csd);
926                                       
927                                        if (u->csd) {
928                                                u->num_csd = m->num_csd;
929                                                u->max_csd = m->max_csd;
930                                        }
931                                        else {
932                                                dprint(0, "!! mcm[%d].csd dup err\n", i);
933                                                u->num_csd = u->max_csd = 0;
934                                        }
935                                }
936                                else {
937                                        u->csd = NULL;
938                                        u->num_csd = u->max_csd = 0;
939                                }
940                                               
941                                if (bEnableNewChannel)
942                                        u->Skipped = 0;  // enable, if user want to.
943                                else
944                                        u->Skipped = 1;  // disable by default.
945                               
946                                u->SurfIndex    = 0;
947                                u->Uid          = make_new_ucm_uid_counter();
948                                u->pEpgDB       = NULL;
949
950                                // cafrii 101208 add, »õ·Ó°Ô Ãß°¡µÈ ä³ÎÀÓÀ» Ç¥½Ã.
951                                u->fresh        = TRUE;
952                               
953                                if (uidBuf)
954                                        uidBuf[nUid++] = u->Uid;
955                        }
956                        else dprint(0, "!! out of memory for additional ucm.\n");
957                }
958        }
959       
960#if 0
961        // NOTE!! cafrii, 030322
962        //    »õ Á¤Ã¥¿¡ µû¶ó updateÇÏ´Â °æ¿ì´Â Àüü autoscanÀÇ °æ¿ì¿Í ´Þ¸® ´ëǥä³Î ¼±ÅÃÀ» ÇÏÁö ¾Ê´Â´Ù.
963       
964        // max channelÀ» ã¾Æ 'skipped' flag¸¦ ¼¼ÆÃÇÑ´Ù.
965        dprint(2, "update_to_ucm(): updated. now activate max channel...\n");
966        for (i=0; i<g_MCM_number; i++) {
967                select_max_ucm(g_MCM[i].Major, g_MCM[i].Minor, g_MCM[i].VctFlag);
968                // Todo...
969                // mcmÁß¿¡´Â Áߺ¹µÈ ä³ÎÀÌ ¸¹Àºµ¥, ÀÌ È½¼ö¸¸Å­ ´Ù select_max_ucm()À» callÇϴ°ÍÀº
970                // ³¶ºñÀÌ´Ù.
971                // ³ªÁß¿¡ ½Ã°£ÀÌ µÇ¸é °³¼±ÇÏÀÚ..-_-;;
972                //
973                // todo2
974                //  »ç¿ëÀÚ°¡ °­Á¦·Î forced active½ÃŲ ä³Î Á¤º¸°¡ ´Ù½Ã disableµÇ´Â °æ¿ì°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù.
975        }
976#endif
977
978        DMW_MSC_UnlockUcm();
979       
980        if (pnUid) *pnUid = nUid; 
981                // ÁÖÀÇ!
982                // nUid != g_MCM_number ÀÏ ¼ö ÀÖ´Ù. (out of mem µî)
983        return uidBuf;
984}       
985
986void print_mcm()
987{
988        unsigned int i;
989
990        if (dprintable(2) == FALSE) // cafrii 060724 add
991                return;
992       
993        dprint(2, "print_mcm(): total %d item. array mode\n  ", g_MCM_number);
994        for (i=0; i<g_MCM_number; i++) {
995
996                if (i%5 == 0)
997                        dprint(2, "  ");
998                if (g_MCM[i].Minor == ONE_PART_CHANNEL_INDICATOR) // one part channel number
999                        dprint(2, " %d:[%d,%d%s%s]", i, g_MCM[i].Major, g_MCM[i].RF, 
1000                                        g_MCM[i].VctFlag ? "v" : "",g_MCM[i].Skipped ? "-" : "");
1001                else
1002                        dprint(2, " %d:[%d-%d,%d%s%s]", i, g_MCM[i].Major, g_MCM[i].Minor, g_MCM[i].RF, 
1003                                        g_MCM[i].VctFlag ? "v" : "",g_MCM[i].Skipped ? "-" : "");
1004
1005                if (i%5 == 4)
1006                        dprint(2, "\n");
1007        }
1008        if (i%5 != 0)
1009                dprint(2, "\n");
1010}
1011
1012
1013
1014
1015
1016#else  // ==========================================================
1017
1018#if 0
1019______Old_Code________()
1020#endif
1021
1022
1023
1024#error not tested. "New Channel Tuning Policy" is not applied to these code.
1025
1026// linked list·Î ±¸Çö.
1027
1028// array¿¡ ºñÇØ¼­ sorting °úÁ¤¿¡ µå´Â ºñ¿ë(¸Þ¸ð¸® º¹»ç)ÀÌ Àû´Ù.
1029// ÀϹÝÀûÀ¸·Î analog ä³Î ¹øÈ£È­ digital major ä³Î ¹øÈ£°¡ »ó°ü °ü°è°¡ ¾ø±â ¶§¹®¿¡
1030// UCMÀ» ¸¸µå´Â °úÁ¤¿¡ ¹Ýµå½Ã 'Á¤·Ä' °úÁ¤ÀÌ ÇÊ¿äÇÏ´Ù. ±×·¡¼­ list ±¸ÇöÀÌ Á» ´õ È¿À²ÀûÀÌ´Ù.
1031//
1032// ƯÈ÷ ±âÁ¸ UCM¿¡ updateÇϴ ä³Î °Ë»öÀÇ °æ¿ì, ±âÁ¸ ucm list »çÀÌ»çÀÌ¿¡ »õ·Î °Ë»öµÈ
1033// ä³Î Á¤º¸°¡ Ãß°¡µÉ °ÍÀ̹ǷΠlist°¡ ´õ ºûÀ» ¹ßÇÒ ¼ö ÀÖ´Ù.
1034
1035
1036#define RECYCLE_NODE 0
1037        // 1À̸é freeÇϱâ Àü¿¡ free list¸¦ µÎ¾î ³ëµå¸¦ Àç»ç¿ëÇÑ´Ù.
1038        // 0À̸é freeÇÒ¶§ OS_Free()·Î ½ÇÁ¦·Î free½ÃŲ´Ù.
1039        //
1040        // ½ÇÁ¦·Î MCMÀº AutoScanÇÒ ¶§¸¸ ÇÊ¿äÇÑ 1ȸ¼º µ¥ÀÌÅͱ¸Á¶À̹ǷÎ
1041        // Malloc/Free°¡ ºó¹øÇÏ°Ô ¹ß»ýÇÏÁö´Â ¾Ê°í µû¶ó¼­
1042        // ÀÌ ¿É¼ÇÀÌ ±×´ÙÁö Å« ¼º´É Çâ»óÀ» º¸¿©ÁÖÁö´Â ¾ÊÀ» °Å¶ó°í »ý°¢µÊ.
1043
1044
1045typedef struct Node_t
1046{
1047        struct Node_t *prev;
1048        struct Node_t *next;
1049        UINT32 key;    // nothing special.
1050        MCM_DB_T mcm;
1051
1052} Node, *NodePtr;
1053
1054
1055#define MCMKEY      0x14159265  // any value.
1056
1057#define MCMOFFSET   ((UINT32)&(((NodePtr)0)->mcm))
1058#define MCM2NODE(m) (NodePtr)((UINT32)m - MCMOFFSET)
1059
1060
1061static NodePtr g_list = NULL;   // MCM DB list
1062
1063#if RECYCLE_NODE
1064        static NodePtr g_free = NULL;   // free list
1065#endif
1066
1067
1068
1069
1070//---------------------------
1071// list specific routines..
1072
1073static NodePtr get_tail(NodePtr n)
1074{
1075        while (n && n->next)
1076                n = n->next;
1077
1078        return n;
1079}
1080
1081static void append_list(NodePtr head, NodePtr new_node)
1082{
1083        NodePtr tail = get_tail(head);
1084        if (tail && new_node)
1085        {
1086                TLASSERT(tail->next == NULL, "tail->next is non-NULL");
1087                tail->next = new_node;
1088                new_node->prev = tail;
1089                new_node->next = NULL;
1090        }
1091}
1092
1093static list_size(NodePtr head) // return the number of MCM node.
1094{
1095        int number = 0;
1096        NodePtr n = head;
1097        while (n)
1098        {
1099                number++;
1100                n = n->next;
1101        }
1102
1103        return number;
1104}
1105
1106//---------------------------
1107// the externals..
1108
1109MCM_DB_T *new_mcm()
1110{
1111        // allocate new mcm and "APPEND" to mcm list.
1112        // return mcm pointer as connected to g_list, not as isolated one.
1113        //
1114        // MCM item Çϳª¸¦ »õ·Î ÇÒ´çÇÏ¿© ¸®½ºÆ®ÀÇ ¸Ç ³¡¿¡ Ãß°¡ÇÑ´Ù.
1115        // ¸®½ºÆ®¿¡ Ãß°¡µÈ »óÅ·Π¸®ÅÏÇÑ´Ù.
1116
1117        NodePtr n;
1118
1119#if RECYCLE_NODE
1120
1121        if (g_free)
1122        {
1123                n = g_free;
1124                g_free = g_free->next;
1125
1126                memset(n, 0, sizeof(Node));
1127        }
1128        else
1129#endif
1130        {
1131                n = DHL_OS_Malloc(sizeof(Node));
1132                if (n == NULL)
1133                        return NULL;
1134        }
1135
1136
1137        if (g_list)
1138                append_list(g_list, n);
1139        else
1140        {
1141                g_list = n;
1142                n->next = n->prev = NULL;
1143        }
1144
1145        n->key = MCMKEY;
1146        return &(n->mcm);
1147}
1148
1149void free_mcm(MCM_DB_T *m)
1150{
1151        NodePtr n;
1152
1153        if (m == NULL) return;
1154
1155        // check if m is in mcm_list..
1156
1157        n = g_list;
1158        while (n && n->next)
1159        {
1160                if (&n->mcm == m)
1161                        goto free_it;   // ok.. 'm' is valid mcm node.
1162                n = n->next;
1163        }
1164
1165        // Note!!!
1166        // Once 'm' is treated that it is not in the list,
1167        //  we cannot free it on our way. do as it is now.
1168        return;
1169
1170
1171free_it:
1172
1173        n = MCM2NODE(m);
1174
1175        // break link.
1176        if (n->prev)
1177                n->prev->next = n->next;
1178        if (n->next)
1179                n->next->prev = n->prev;
1180
1181        if (g_list == n)
1182                g_list = n->next;
1183
1184#if RECYCLE_NODE
1185        append_list(g_free, n);
1186#else
1187        DHL_OS_Free((void**)&n);
1188#endif
1189}
1190
1191
1192void free_all_mcm()
1193{
1194        NodePtr n = g_list;
1195        NodePtr p;
1196        while (n)
1197        {
1198                p = n->next;
1199                DHL_OS_Free((void**)&n);
1200                n = p;
1201        }
1202#if RECYCLE_NODE  // free listµµ ¿ÏÀüÈ÷ »èÁ¦ÇÔ.
1203        n = g_free;
1204        while (n)
1205        {
1206                p = n->next;
1207                DHL_OS_Free((void**)&n);
1208                n = p;
1209        }
1210#endif
1211}
1212
1213
1214
1215MCM_DB_T *find_mcm_major_minor(int major, int minor)
1216{
1217        NodePtr n;
1218        n = g_list;
1219
1220        while (n)
1221        {
1222                if (n->mcm.Major == major && n->mcm.Minor == minor)
1223                        return &n->mcm;
1224                n = n->next;
1225        }
1226        return NULL;
1227}
1228
1229MCM_DB_T *find_mcm_major_minor_rf(int major, int minor, int rf, int vctFlag)
1230{
1231        NodePtr n;
1232        n = g_list;
1233
1234        vctFlag = vctFlag != 0 ? 1 : 0;
1235        while (n)
1236        {
1237                if (n->mcm.Major == major && n->mcm.Minor == minor && n->mcm.RF == rf && n->mcm.VctFlag == vctFlag)
1238                        return &n->mcm;
1239                n = n->next;
1240        }
1241        return NULL;
1242}
1243
1244
1245int sort_mcm()
1246{
1247        NodePtr sorted_list = NULL;
1248        NodePtr n, mn;
1249
1250        while (g_list)
1251        {
1252                // find minimum node in g_list.
1253                TLASSERT(g_list, "");
1254
1255                mn = g_list;
1256                n = g_list->next; // start of search.
1257                while (n)
1258                {
1259                #if 1
1260                        if (require_mcm_swap(&(mn->mcm), &(n->mcm)))
1261                                mn = n;
1262                #else
1263                        if (mn->mcm.Major > n->mcm.Major ||
1264                                (mn->mcm.Major == n->mcm.Major && mn->mcm.Minor > n->mcm.Minor) ||
1265                                (mn->mcm.Major == n->mcm.Major && mn->mcm.Minor == n->mcm.Minor && mn->mcm.RF > n->mcm.RF))
1266                        {
1267                                mn = n;
1268                        }
1269                #endif
1270                        n = n->next;
1271                }
1272
1273                // detach the minimum node from g_list.
1274                TLASSERT(mn, "");
1275                n = mn;
1276                if (n->prev)
1277                        n->prev->next = n->next;
1278                if (n->next)
1279                        n->next->prev = n->prev;
1280
1281                if (g_list == n)
1282                        g_list = n->next;
1283
1284                // append to new sorted list.
1285
1286                append_list(sorted_list, n);
1287        }
1288
1289        TLASSERT(g_list == NULL, "");
1290
1291        g_list= sorted_list;
1292}
1293
1294
1295STATUS select_max_mcms()
1296{
1297        // MCMÀ» Á¤¸®Çؼ­ UCMÀ¸·Î ¸¸µç´Ù.
1298
1299        // µ¿ÀÏÇÑ Mj/Mn/Rf Á¶ÇÕÀÌ ÀÖÀ¸¸é ½ÅÈ£ ¼¼±â°¡ °¡Àå Å« °ÍÀ» ¼±ÅÃÇϰí,
1300        //     ³ª¸ÓÁö´Â skip flag¸¦ ¼¼ÆÃÇÑ´Ù.
1301
1302        // choose maximum one..
1303        NodePtr n;
1304        NodePtr maxnd = NULL;
1305
1306        n = g_list;
1307        maxnd = n;    // default: ½ÃÀÛ°ªÀÌ ÇöÀç±îÁöÀÇ ÃÖ´ë°ª.
1308
1309        // mj/mn/rf ¼¼°¡Áö¸¸À¸·Î ÆÇ´ÜÇÑ´Ù.
1310        // analog/8vsb/qamÀº ±¸ºÐÇÏÁö ¾Ê´Â´Ù.
1311        //   analog´Â ¸ðµÎ minor 0À¸·Î °¡Á¤Çϰí,
1312        //   ÇÑ mcm¿¡¼­ 8vsb¿Í qamÀÌ °øÁ¸ÇÏÁö ¾Ê´Â´Ù´Â °¡Á¤À» ÇÏ¸é ¹®Á¦µÇÁö´Â ¾Ê´Â´Ù.
1313
1314        while (n)
1315        {
1316                // examin NODE 'n'..
1317
1318                n->mcm.Skipped = TRUE;  // ±âº»À¸·Î ¸ðµÎ skip..
1319
1320                if (equiv_mcm(&maxnd->mcm, &n->mcm))
1321                {
1322                        // ºñ±³ ´Ü°è °è¼Ó ÁøÇàÁß...
1323                        // Áö±Ý±îÁöÀÇ ¿ì½ÂÈĺ¸(ÃÖ´ë strengthÀÇ ³ëµå)¿Í 'n'°ú °æÀï..
1324
1325                        if (maxnd->mcm.signal_strength < n->mcm.signal_strength)
1326                        {
1327                                // »õ·Î¿î ¿ì½ÂÀÚ Åº»ý..
1328                                maxnd = n;
1329                        }
1330                }
1331                else
1332                {
1333                        // ºñ±³ ´Ü°è ³¡. ¿©±â¼­ºÎÅÍ´Â »õ·Î¿î ä³ÎÀÓ.
1334                        //
1335                        maxnd->mcm.Skipped = FALSE;  // <-- "¼±ÅÃ!!!"
1336
1337                        maxnd = n;
1338                }
1339
1340                n = n->next;
1341        }
1342
1343        if (maxnd)
1344                maxnd->mcm.Skipped = FALSE;
1345                // ¸¶Áö¸· maxnode´Â ¼±ÅÃÀÌ ¾ÈµÈ »óÅ¿¡¼­ loop ÀÌÅ»ÇßÀ¸¹Ç·Î ¿©±â¼­ "¼±ÅÃ".
1346
1347        return statusOK;
1348}
1349
1350void ucm_to_mcm()
1351{
1352        // ucm Á¤º¸¸¦ Àо mcmÀ¸·Î ¸¸µç´Ù.
1353        //
1354        // »ç¿ëÀÚ°¡ ÀÚµ¿ ä³Î °Ë»öÀ» ¼±ÅÃÇÒ ¶§ "update ¸ðµå"·Î ÇÏ´Â °æ¿ì,
1355        // ±âÁ¸ÀÇ Á¤º¸´Â ±×´ë·Î µÎ°í ä³Î °Ë»öÀ» ¼öÇàÇØ¾ß ÇÑ´Ù.
1356        // ÀÌ °æ¿ì ucm Á¤º¸¸¦ mcmÀ¸·Î º¯È¯ÇÏ´Â ÀÛ¾÷ÀÌ ÇÊ¿äÇÏ´Ù.
1357       
1358        int i;
1359        MCM_DB_T *m;
1360        UCM_DB_T *u;
1361       
1362        free_all_mcm();  // mcmÀº »õ·Î ¸¸µé °ÍÀ̹ǷΠ´Ù »èÁ¦..
1363
1364        DMW_MSC_LockUcm();
1365
1366        for (i=0; i<g_UCM_number; i++)
1367        {
1368                m = new_mcm();
1369                if (m == NULL) break;
1370
1371                u = &g_UCM[i];
1372
1373                memcpy(m, u, sizeof(MCM_DB_T));  // MCM¿¡ »ó´çÇÏ´Â ºÎºÐ¸¸ º¹»çÇÑ´Ù.
1374        }
1375
1376        DMW_MSC_UnlockUcm();
1377
1378}
1379
1380void copy_to_ucm()
1381{
1382        // mcmÀ» óÀ½ºÎÅÍ Çϳª¾¿ Àо ucm¿¡ º¹»ç¸¸ ÇÏ¸é µÈ´Ù.
1383        // mcmÀº Á¤·ÄµÈ »óÅÂÀ̾î¾ß Çϸç,
1384        // ucm¿¡ »ç¿ëµÉ ¸ðµç Çʵå´Â ÃʱâÈ­ µÇ¾î ÀÖ¾î¾ß ÇÑ´Ù.
1385        // skip flagµµ Á¤»óÀûÀ¸·Î ÃʱâÈ­ µÇ¾î ÀÖ¾î¾ß ÇÔ.
1386
1387        int totalsize;
1388        NodePtr n;
1389        MCM_DB_T *m;
1390        UCM_DB_T *u;
1391
1392
1393        DMW_CDB_ClearAll(); // ¸ÕÀú ±âÁ¸ UCMÀ» ¸ðµÎ »èÁ¦ÇÑ´Ù.
1394
1395        DMW_MSC_LockUcm();
1396
1397        reset_ucm_uid_counter();
1398
1399        totalsize = list_size(g_list);
1400        prepare_ucm_space(totalsize + 8);
1401                // ¿©±â¼­ ¿¡·¯°¡ ³¯ ¼öµµ ÀÖÀ½. mcm°¹¼ö°¡ ³Ê¹« ¸¹¾Æ ¸Þ¸ð¸®°¡ ºÎÁ·ÇÒ °æ¿ì.
1402                // ÀÌ °æ¿ì °è¼Ó ÁøÇàÇϵµ·Ï ÇÔ. ¸î°³¸¸ÀÌ¶óµµ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇÏ´Â°Ô ³´±â ¶§¹®.
1403
1404        if (g_bReserveUcmIndex0) {
1405                memset(&g_UCM[0], 0, sizeof(g_UCM[0]);
1406                g_UCM_number++;
1407        }
1408
1409        n = g_list;
1410        while (n)
1411        {
1412                if (prepare_ucm_space(8) != statusOK)
1413                        break;
1414
1415                u = &g_UCM[g_UCM_number];  // active ucm
1416                m = &n->mcm;               // active mcm
1417
1418                memcpy(u, m, sizeof(MCM_DB_T)); // cafrii 030326, MCM¿¡ »ó´çÇÏ´Â ºÎºÐ¸¸ º¹»çÇÑ´Ù.
1419
1420                g_UCM_number++;
1421                n = n->next;
1422        }
1423
1424        DMW_MSC_UnlockUcm();
1425}
1426
1427void print_mcm()
1428{
1429        int i = 0;
1430        NodePtr n;
1431        dprint(2, "print_mcm(): total %d item. list mode\n", list_size(g_list));
1432       
1433        n = g_list;
1434        while (n) {
1435                if (n->mcm.Minor == ONE_PART_CHANNEL_INDICATOR)
1436                        dprint(2, " %d:[%d,%d%s]", i, n->mcm.Major, n->mcm.Minor, n->mcm.RF, n->mcm.VctFlag ? "+" : "");
1437                else
1438                        dprint(2, " %d:[%d-%d,%d%s]", i, n->mcm.Major, n->mcm.Minor, n->mcm.RF, n->mcm.VctFlag ? "+" : "");
1439                if (i%5 == 4)
1440                        dprint(2, "\n");
1441                i++;           
1442                n = n->next;
1443        }
1444        if (i%5 != 0)
1445                dprint(2, "\n");
1446        return NULL;
1447}
1448
1449
1450#endif
1451
1452
1453/********************************************************************
1454  $Log: DMW_Mcm.c,v $
1455
1456        1.23 2004/11/30   find_mcm_rf_prognum_vf Ãß°¡
1457        1.22 2004/11/26   ÀÚü debug Ãâ·Â ÇÔ¼ö ÀÛ¼º, debug level ¼öÁ¤
1458                          free_mcm, free_mcm_all ½Ã¿¡ csd »èÁ¦
1459                          mcm <--> ucm º¯È¯, update ucm ½Ã¿¡ csdµµ º¹»ç ¹× update
1460        1.21 2004/11/10   print_mcm: one_part_channel support
1461        1.2  2004/7/27    debug level added
1462        1.1  2003/3/24    update_to_ucm(), skipped flag set by default. 2003/03/24
1463        1.0  2003/02/00   Initial coding from ground
1464 ********************************************************************/
1465
Note: See TracBrowser for help on using the repository browser.