source: svn/newcon3bcm2_21bu/dst/dmw/src/Channel/DMW_ChannelDB.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: 38.9 KB
Line 
1/*******************************************************************
2 * DMW_ChannelDB.c
3 *
4 * Interface code to middle ware for DST Module/STB channel DB management
5 *   especially about NVRAM.
6 *
7 * some of DMW_CDB_XXX APIs are implemented in this module.
8 *
9 * Copyright 2003 Digital STREAM Technology, Inc.
10 * All Rights Reserved
11 *
12 * $Id: DMW_ChannelDB.c,v 1.31  2004 cafrii Exp $
13 *
14 ********************************************************************/
15
16
17
18
19
20#include "DMW_Platform.h"
21
22#include "DHL_OSAL.h"
23#include "DHL_DBG.h"
24
25#include "DMW_Config.h"
26
27#include "DMW_ChannelAPI.h"
28#include "DMW_DebugUtil.h"
29#include "dmw_ucm_priv.h"
30#include "dmw_nvram_priv.h"
31
32#if !USE_INCLUDED_CRC_CODE
33#include "DHL_UTL.h"
34#endif
35
36//#include <string.h>
37//#include <string.h>
38
39
40DHL_MODULE("$cdb", 0);
41
42
43//---------------------------------------------------------
44// Configurations..
45
46
47#undef STATIC
48#if 1
49        #define STATIC         // for test debugging..
50#else
51        #define STATIC static  // for release code..
52#endif
53
54
55
56
57
58
59//---------------------------------------------------------
60
61
62
63
64#if COMMENT
65_______Util______(){}
66#endif
67
68
69
70STATIC UINT32 _m2d(UINT8 *p, int bytesize)  // memory to digit
71{
72        UINT32 result = 0;
73        int i;
74
75        if (bytesize > 4) bytesize = 4;
76
77        for (i=0; i<bytesize; i++)
78                result = (result<<8) | p[i];
79       
80        return result;
81}
82
83STATIC STATUS _d2m(UINT8 *p, int bytesize, UINT32 data)  // digit to memory
84{
85        int i;
86
87        if (bytesize > 4) bytesize = 4; // 'data' is only 4 byte-sized variable at maximum.
88
89        for (i=0; i<bytesize; i++) {
90               
91                p[bytesize-1-i] = (data & 0xff);  // fill BYTE from rear to front..
92                data >>= 8;
93        }
94        return statusOK;       
95}
96
97
98
99
100
101#if COMMENT
102_______CRC______(){}
103#endif
104
105#if USE_INCLUDED_CRC_CODE
106
107static UINT32 crc_table[256];
108
109#define DEMUX_CRC_ADDER_MASK 0x04C11DB7
110
111void nvr_init_crc_table()
112{
113        int i, j;
114        UINT32 crc;
115        // Initialize CRC table
116        for (i=0; i<256; i++) {
117                crc = 0;
118                for (j=7; j>=0; j--) {
119                        if (((i >> j) ^ (crc >> 31)) & 1) {
120                                crc=(crc<<1)^DEMUX_CRC_ADDER_MASK;
121                        }
122                        else {
123                                crc<<=1;
124                        }
125                }
126                crc_table[i] = crc;
127        }
128}
129
130// cafrii 041109 add
131// crc32 ¸¦ °è»êÇÑ´Ù.
132//
133UINT32 nvr_calc_crc32(UINT32 crc_start, const UINT8 *data, UINT32 len)
134{
135        UINT32 crc = crc_start; // 0xFFFFFFFF;
136        UINT32 i;
137
138        if (crc_table[1] == 0) { // ¾ÆÁ÷ ÃʱâÈ­°¡ ¾ÈµÈ ¸ð¾çÀÌ´Ù.
139                dprint(2, "..initializing crc table..\n");
140                nvr_init_crc_table();
141        }
142
143        for (i = 0; i < len; ++i) {
144                crc = (crc << 8) ^ crc_table[(crc >> 24) ^ (*data++)];
145        }
146        return(crc);
147}
148
149#else
150UINT32 nvr_calc_crc32(UINT32 crc_start, const UINT8 *data, UINT32 len)
151{
152        return DHL_UTL_CalcCRC32(crc_start, data, len);
153}
154
155#endif
156
157
158#if COMMENT
159_______Level_1_______(){}
160#endif
161
162STATIC BOOL nvr_is_safe_area(UINT32 offset, UINT32 size)
163{
164        // NvRAM¿¡ Á¢±ÙÇϱâ Àü¿¡ ÀÌ ¿µ¿ª (offset, size)ÀÌ »ç¿ë°¡´ÉÇÑ ¿µ¿ªÀÎÁö üũ.
165       
166        if (offset & 0x80000000)  // device 1. Flash
167        {
168#if SUPPORT_DMW_FLASH_DB
169                // cafrii, 031201 add more check code
170                offset &= 0x7fffffff;
171
172                if (offset + size > (UINT32)NvRamGetAvailableSize(1))
173                        return FALSE;  // over the maximum.
174
175                return TRUE; // cafrii 031112
176#else
177                return FALSE;
178#endif
179        }
180        else  // device 0. EEPROM.
181        {
182#if SUPPORT_DMW_EEPROM
183                if (offset + size > (UINT32)NvRamGetAvailableSize(0))
184                        return FALSE;
185                else 
186                        return TRUE;  // safe!! this range is allowed to use.
187#else
188                return FALSE;
189#endif
190        }
191}
192
193
194// Level 1 public API.
195//   NvRam I/O.
196// 
197
198
199UINT32 DMW_CDB_GetNvRamAvailableSize(int device)
200{
201        // ÇØ´ç NvRAM deviceÀÇ »ç¿ë°¡´ÉÇÑ ¿µ¿ª Å©±â¸¦ ¸®ÅÏ.
202        //
203
204        if (device == 0)  // EEPROM
205                return NvRamGetAvailableSize(0);
206        else
207                return NvRamGetAvailableSize(1);
208}
209
210
211// cafrii 031201, add one more arguments,
212// and save directory number information in NVPARAM area.
213//
214STATUS DMW_CDB_LowLevelFormatNvRam(void)
215{
216        int err = statusOK;
217       
218        // CAUTION!
219        //  ÀÌ ÇÔ¼ö´Â ÀÏ¹Ý application ÇÁ·Î±×·¥À» À§ÇÑ °ÍÀÌ ¾Æ´Ï°í,
220        //  ¾ç»ê¿ë ÇÁ·Î±×·¥ ¶Ç´Â °Ë»ç/¼ö¸®¿ë Å×½ºÆ® ÇÁ·Î±×·¥À» À§ÇÑ °ÍÀÓ.
221        //  Á¦Ç° »ý»ê½Ã ÃÖÃÊ Blank EEPROM »óÅ¿¡¼­´Â 1ȸ ½Ç½Ã ÇÊ¿äÇÔ.
222        //
223        // cafrii 070424 add comment
224        //  ºÎÆÃ Áß¿¡ NvRam ¿µ¿ª¿¡ ¹®Á¦°¡ ÀÖ´Ù°í ÆÇ´ÜµÇ¸é
225        //  application Äڵ忡¼­ formatÀ» ÇÒ ¼ö ÀÖÀ½.
226       
227
228#if SUPPORT_DMW_FLASH_DB
229        err = NvRamFormat(); // cafrii 031112
230        if (err) return (STATUS)err;
231#endif
232       
233        return statusOK;
234}
235
236
237/*
238        DMW_CDB_CheckNvRam:
239
240        NvRamÀÌ Á¦´ë·Î formatÀÌ µÇ¾ú´ÂÁö, »ç¿ë °¡´ÉÇÑÁö üũÇÑ´Ù.
241
242*/
243STATUS DMW_CDB_CheckNvRam(void)
244{
245        return NvRamCheckValid();
246}
247
248/*
249        DMW_CDB_ReadNvRam:
250
251        NvRam ¿µ¿ªÀ» Àд´Ù.
252*/
253STATUS DMW_CDB_ReadNvRam(UINT32 address, UINT32 size, UINT8 *buf)
254{
255        if (!nvr_is_safe_area(address, size))
256                return statusNvRamBadAddress;
257               
258        return NvRamRead(address, size, buf);
259}
260
261/*
262        DMW_CDB_WriteNvRam:
263
264        NvRam ¿µ¿ª¿¡ µ¥ÀÌÅ͸¦ ±â·ÏÇÑ´Ù.
265*/
266STATUS DMW_CDB_WriteNvRam(UINT32 address, UINT32 size, UINT8 *buf)
267{
268        if (!nvr_is_safe_area(address, size))
269                return statusNvRamBadAddress;
270
271        return NvRamWrite(address, size, buf);
272}
273
274
275//----------------------------------------------------------
276// EEPROM test ÇÔ¼öµé..
277//
278
279STATUS DMW_CDB_DumpNvRam(UINT32 start, int size, char *name)
280{
281        int err;
282        UINT8 *buf;
283       
284        if (size <= 0 || size > 16384) {
285                return statusOutOfRange;
286        }
287       
288        buf = DHL_OS_Malloc(size);
289        if (buf == NULL) {
290                return statusOutOfResource;
291        }
292       
293        DHL_OS_Printf("  NvRam (%x~%x): '%s'\n", start, start+size, name ? name : "");
294       
295        err = DMW_CDB_ReadNvRam(start, size, (UINT8 *)buf);
296       
297        if (!err) {     
298                memdump2(buf, size, "NvRam", (UINT32)start-(UINT32)buf);
299        }
300       
301        DHL_OS_Free((void**)&buf);
302       
303        return statusOK;
304}
305
306
307STATUS DMW_CDB_InitNvRam(void)
308{
309        NvRamInit();
310
311        dprint(0, "Config:EEPROM size %d\n", NvRamGetAvailableSize(0));
312       
313        return statusOK;
314}
315
316
317
318//******************************************************************
319//
320//  Read/Write Channel DB
321//
322//  NVRAM access API.
323
324
325
326#if COMMENT
327_______Level_3_______(){}
328#endif
329
330STATIC UINT16 g_epgIndex;
331
332UINT16 nvr_generate_epg_index(UINT32 arg)
333{
334        return ++g_epgIndex;
335}
336
337void nvr_reset_epg_index()
338{
339        g_epgIndex = 0;
340}
341
342/*
343        Unicode (16bit) stringÀÇ ±æÀ̸¦ °è»ê.
344        StringÀº Null ¹®ÀÚ·Î Á¾·áµÇ°Å³ª ¶Ç´Â maxlen ¿¡ ÀÇÇØ¼­ Á¾·áµÊ.
345        maxlenÀÌ -1ÀÏ °æ¿ì ÃÖ´ë ±æÀÌ Á¦ÇÑ ¾øÀ½. ¿ÀÁ÷ Null Á¾·á¸¸ µÊ.
346       
347        µÞ ºÎºÐÀÇ °ø¹é¹®ÀÚ´Â ±æÀÌ¿¡ Æ÷ÇÔÇÏÁö ¾Êµµ·Ï ÇÑ´Ù. (todo)
348*/
349int nvr_uc16len(UINT16 *str, int maxlen)
350{
351        UINT16 *p = str;
352        if (!p) return 0;
353        while (*p && p<str+maxlen) p++;
354       
355        return (int)(p-str);
356}
357
358
359const UINT8 gUcmStoringVersion = 0xA8; 
360//
361// UCMÀÇ ±¸Á¶°¡ ¹Ù²î¸é ÀÌ ¹öÀüÀ» ¿Ã·Á¼­ ²À ´Ù½Ã Æ÷¸ËÀ» ÇÒ ¼ö ÀÖµµ·Ï
362// ¾Ë·ÁÁÙ ¼ö ÀÖ¾î¾ß ÇÑ´Ù.
363// ±âÁ¸¿¡ ÀúÀåµÈ °ª (NVPARAM ¿µ¿ª¿¡ ÀúÀåµÇ¾î ÀÖÀ½) °ú ´Ù¸£¸é
364// DMW_CDB_CheckNvRam ¿¡¼­ ¿¡·¯°¡ ¹ß»ýÇÒ °ÍÀÌ´Ù.
365
366/********************************************************************************
367NvRam UCM version history
368Note: this storing UCM format has its own format version.
369      the version will be incremented whenever storing UCM format is changed.
370      this version info can be found in 'ForbiddenArea' in NvRam.
371
372        A8 : cafrii 100427
373                First 32 byte structure is same as A7.
374                Next and next-next 32 byte block is as follows.
375               
376                  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F 
377                +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
378                | Ext |    Long Channel Name                    |
379                +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
380                |    Long Channel Name                          |
381                +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
382
383                Ext(16): 0xFEFE
384                Long Channel Name (16*15): extended channel name, Unicode 16, 15 characters.
385                If long channel name extension is not used, this block does not exist at all.
386
387                UCM Storing Version (USV) is stored in UCM Header area.
388                UCM Header Area structure is also changed.
389
390        A7 : cafrii 041130, scrambled flag added             
391       
392                Flag byte : Unused(1), Sc(1), Hd(1), Bk(1), Vf(1), St(2), Sk(1)
393               
394                        Sc(1) : Scrambled channel  // cafrii 041130 add
395                        Hd(1) : Hidden channel
396                        Bk(1) : Blocked channel
397                        Vf(1) : VctFlag
398                        St(2) : ServiceType
399                        Sk(1) : Skipped Channel
400             
401        A6 : cafrii 041129
402             New CSD structure is newly defined. refer 'ChannelCSD.c'
403
404        A5 : cafrii 041109 add
405                 UCM[0] is not stored at the first position of DB start address.
406             there are reserved space for management
407
408               
409        A4 : PID info will not be stored
410             source ID and frq offset will be stored
411
412        0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F 
413      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
414       Mj -- Mn -- Rf Fl N0 -- N1 -- N2 -- N3 -- N4 -- 
415      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
416       N5 -- N6 -- Freq_offset Sr -- Pn -- Si -- Ei --
417       
418        A3 : Hidden channel flag added // cafrii 040114
419                Flag byte : Unused(2), Hd(1), Bk(1), Vf(1), St(2), Sk(1)
420               
421                        Hd(1) : Hidden channel   // cafrii 040114 add
422                        Bk(1) : Blocked channel
423                        Vf(1) : VctFlag
424                        St(2) : ServiceType
425                        Sk(1) : Skipped Channel
426       
427        A2 : Blocked channel flag added
428                Flag byte : Unused(3), Bk(1), Vf(1), St(2), Sk(1)
429               
430                        Bk(1) : Blocked channel  // cafrii 031205 add
431                        Vf(1) : VctFlag
432                        St(2) : ServiceType
433                        Sk(1) : Skipped Channel
434               
435        A1 : EpgIndex added.
436              vctFlag info is overlapped on Major. vctFlag = (Major != 0)
437              Flags field inserted before ShortName. this include skip_flag, service_type info.
438              Skip_flag, Service_type is moved into Flag.
439                                                           
440        0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F 
441      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
442       Mj -- Mn -- Rf Fl N0 -- N1 -- N2 -- N3 -- N4 -- 
443      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
444       N5 -- N6 -- Pp -- Vp -- Ap -- Pn -- Si -- Ei --
445       
446        A0 : X-ray version
447        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 
448      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
449       Mj -- Mn -- Rf N0 -- N1 -- N2 -- N3 -- N4 -- N5
450      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
451       -- N6 -- Pp -- Vp -- Ap -- Pn -- St Sk Si --
452*/
453
454
455
456
457// relative offset based on start of each channel DB element.
458//
459#define OFFSET_Major         0x0
460#define OFFSET_Minor         0x2
461#define OFFSET_RF            0x4
462#define OFFSET_Flag          0x5  // newly inserted in ver A1
463#define OFFSET_ShortName     0x6
464//#define OFFSET_PcrPid        0x14
465//#define OFFSET_VideoPid      0x16
466//#define OFFSET_AudioPid      0x18
467#define OFFSET_FreqOffset    0x14
468#define OFFSET_SourceId      0x18
469#define OFFSET_ProgNumber    0x1A
470#define OFFSET_SurfIndex     0x1C
471#define OFFSET_VideoFormat   0x1D //neverdai add 101019 for saving video resolution
472#define OFFSET_EpgIndex      0x1E
473
474#define SIZEOF_UCM_DB_ITEM 0x20   // byte size of one UCM DB item in NvRAM
475
476// byte size of each channel DB element.
477//
478#define SIZE_Major         2
479#define SIZE_Minor         2
480#define SIZE_RF            1
481#define SIZE_Flag          1
482#define SIZE_ShortName     14
483#define SIZE_FreqOffset    4
484#define SIZE_SourceId      2
485//#define SIZE_PcrPid        2
486//#define SIZE_VideoPid      2
487//#define SIZE_AudioPid      2
488
489#define SIZE_ProgNumber    2
490#define SIZE_SurfIndex     1//2
491#define SIZE_VideoFormat   1
492#define SIZE_EpgIndex      2
493
494// added in ver A8
495#define OFFSET_Ext1      0x20
496#define OFFSET_LongName1 0x22
497#define OFFSET_Ext2      0x40
498#define OFFSET_LongName2 0x42
499#define SIZE_Ext       2
500#define SIZE_LongName  30
501#define UCM_EXT_MARKER 0xFEFE
502
503
504// cafrii 040114 add
505#define UCM_FLAG_SCRAMBLED  0x40
506#define UCM_FLAG_HIDDEN     0x20
507#define UCM_FLAG_BLOCKED    0x10
508#define UCM_FLAG_VCT        0x08
509#define UCM_FLAG_SKIPPED    0x01
510
511
512UINT32 DMW_CDB_GetUcmItemStoringSize()
513{
514        // sizeof(UCM_DB_T)¿Í SIZEOF_UCM_DB_ITEM´Â ´Ù¸¦ ¼ö ÀÖ´Ù.
515        // application¿¡¼­ NvRAM¿¡ µé¾î°¥ DB Å©±â °è»êÀ» ÇÒ ¶§¿¡´Â
516        // ÀÌ Á¤º¸¸¦ »ç¿ëÇÏ¿©¾ß ÇÑ´Ù.
517        //
518        // UCMÀº ¸Þ¸ð¸®¿¡ ÀÖ´Â »óÅ ±×´ë·Î writeÇÏÁö ¾Ê´Â´Ù´Â Á¡¿¡ À¯ÀÇÇÑ´Ù.
519        //
520        return SIZEOF_UCM_DB_ITEM;
521}
522
523
524//******************************************************************
525//
526//  Miscellaneous APIs which query/update individual DB element
527
528
529
530
531
532/*
533        Read one UCM DB element
534       
535        NVM¿¡¼­ ÀÐ¾î ³½ flattened UCM Á¤º¸¸¦ parsing ÇÏ¿© UCM_DB_T·Î º¯È¯.
536        NVM UCMÀÇ Å©±â´Â EXT Marker Á¤º¸¿¡ µû¶ó °¡º¯ÀÌ´Ù.
537        ½ÇÁ¦·Î parsing µÈ UCMÀÇ byte size¸¦ ¸®ÅÏÇÑ´Ù.
538        caller´Â ÀÌ Á¤º¸¸¦ ÀÌ¿ëÇÏ¿© ´ÙÀ½ NVM UCM offsetÀ» ¾Ë ¼ö ÀÖ´Ù.
539*/
540int DMW_CDB_ParseOneUcmBlockMode(UINT8 *p, UCM_DB_T *buf, UINT16 *pEpgIndex)
541{
542        UINT8 flag;
543        int this_nvm_ucm_size;
544
545        memset(buf, 0, UcmItemMemorySize()); // cafrii, 030317
546       
547        buf->Major = _m2d (p + OFFSET_Major, SIZE_Major);
548        buf->Minor = _m2d (p + OFFSET_Minor, SIZE_Minor);
549        buf->RF    = _m2d (p + OFFSET_RF, SIZE_RF);
550
551        memcpy((UINT8 *)buf->ShortName, p + OFFSET_ShortName, SIZE_ShortName);
552       
553        buf->freqOffset = _m2d (p + OFFSET_FreqOffset, SIZE_FreqOffset);
554        buf->source_id  = _m2d (p + OFFSET_SourceId, SIZE_SourceId);
555
556        buf->Prog_number  = _m2d (p + OFFSET_ProgNumber, SIZE_ProgNumber);
557       
558        // Fl: Hd(1), Bl(1), Vf(1), St(2), Sk(1)
559        flag = _m2d (p + OFFSET_Flag, SIZE_Flag);
560       
561        buf->scrambled = (flag & UCM_FLAG_SCRAMBLED) ? TRUE : FALSE; // cafrii 041130 add
562        buf->hidden = (flag & UCM_FLAG_HIDDEN) ? TRUE : FALSE; // cafrii 040114 add
563        buf->blocked = (flag >> 4) & 1;    // cafrii 031205
564        buf->VctFlag = (flag >> 3) & 1;
565        buf->Service_type = (flag >> 1) & 3;
566        buf->Skipped = (flag) & 1;
567       
568        buf->SurfIndex    = _m2d (p + OFFSET_SurfIndex, SIZE_SurfIndex);
569                //neverdai ÁÖÀÇ...surf index´Â 1byte¸¸ ±â·ÏÇÔ..
570                //video resolutionÀ» ±â·ÏÇÒ Àå¼Ò°¡ ¾øÀ½..surf¸¦ ¸¹ÀÌ »ç¿ëÇÏÁö ¾Ê°Å³ª
571                //surf index°¡ ±»ÀÌ ÇÊ¿ä ¾ø´Â °æ¿ì¸¸ °¡´É
572       
573        buf->video_format = (tDHL_DispFormat)_m2d (p + OFFSET_VideoFormat, SIZE_VideoFormat);
574                //neverdai add 101019 video format ÀúÀåÀ» À§ÇÔ.
575       
576        // cafrii, 030310
577        buf->pEpgDB = NULL;
578        if (pEpgIndex)
579                *pEpgIndex = _m2d (p + OFFSET_EpgIndex, SIZE_EpgIndex);
580               
581        buf->Uid = make_new_ucm_uid_counter(); // cafrii, 030317
582       
583        // cafrii 060630 add
584        // 1ÀÇ Àǹ̴ ¾ÆÁ÷ ÀÌ pid Á¤º¸¸¦ ȹµæÇÏÁö ¸øÇؼ­ ¾Ë ¼ö ¾ø´Â »óÅÂÀÓÀ» ÀǹÌÇÑ´Ù.
585        // 0ÀÇ ÀÇ¹Ì´Â ÇØ´ç elementary streamÀÌ Á¸ÀçÇÏÁö ¾Ê´Â´Ù´Â ÀǹÌÀÌ´Ù.
586        //   ex: audio only programÀÇ °æ¿ì Video_pid = 0..
587        //
588        buf->Pcr_pid = DMW_PID_NO_INFO;
589        buf->Video_pid = DMW_PID_NO_INFO;
590        buf->Audio_pid = DMW_PID_NO_INFO;
591        buf->pmt_pid = DMW_PID_NO_INFO;
592       
593       
594
595        if (_m2d (p + OFFSET_Ext1, SIZE_Ext) != UCM_EXT_MARKER) {
596                this_nvm_ucm_size = SIZEOF_UCM_DB_ITEM;
597        }
598        else if (_m2d (p + OFFSET_Ext2, SIZE_Ext) != UCM_EXT_MARKER) {
599                this_nvm_ucm_size = 2*SIZEOF_UCM_DB_ITEM;
600                memcpy((UINT8 *)buf->LongName, p + OFFSET_LongName1, SIZE_LongName);
601                buf->LongName[SIZE_LongName/2] = 0; // null terminate
602        }
603        else if (1) {
604                this_nvm_ucm_size = 3*SIZEOF_UCM_DB_ITEM;
605                memcpy((UINT8 *)(&buf->LongName[SIZE_LongName/2]), p + OFFSET_LongName2, SIZE_LongName);
606                //buf->LongName[SIZE_LongName] = 0; // it cannot be null terminated. no space for nullz.
607        }
608
609        return this_nvm_ucm_size;
610
611}
612
613/*
614        Write one UCM DB element
615        ¸Þ¸ð¸® »óÀÇ UCM entry Çϳª¸¦ flatten ½ÃŲ´Ù.
616       
617        UCMÀÇ LongName¿¡ µû¶ó¼­ flatten µÇ´Â ±æÀÌ´Â ´Þ¶óÁú ¼ö ÀÖ´Ù.
618*/
619int DMW_CDB_PrepareOneUcmBlockMode(UINT8 *p, UCM_DB_T *buf, UINT16 *pEpgIndex)
620{
621        UINT16 epgIndex;
622        UINT8 flag;
623        int len_ch_name = nvr_uc16len(buf->LongName, sizeof(buf->LongName)/sizeof(buf->LongName[0]));
624        int nvm_size_of_this_ucm;
625       
626        // p is memory pointer.
627        _d2m(p + OFFSET_Major, SIZE_Major, buf->Major);
628        _d2m(p + OFFSET_Minor, SIZE_Minor, buf->Minor);
629        _d2m(p + OFFSET_RF, SIZE_RF, buf->RF);
630
631        memcpy(p + OFFSET_ShortName, (UINT8 *)buf->ShortName, SIZE_ShortName);
632
633        _d2m(p + OFFSET_FreqOffset,  SIZE_FreqOffset,  buf->freqOffset);// cafrii 040812 bugfix from buf->source_id
634        _d2m(p + OFFSET_SourceId,    SIZE_SourceId,    buf->source_id);
635
636        _d2m(p + OFFSET_ProgNumber,  SIZE_ProgNumber,  buf->Prog_number);
637       
638        flag = (buf->Skipped) & 1;
639        flag |= ((buf->Service_type) & 3) << 1;
640        flag |= ((buf->VctFlag) & 1) << 3;
641        flag |= ((buf->blocked ? 1 : 0) << 4);  // cafrii 031205 add
642        flag |= (buf->hidden ? UCM_FLAG_HIDDEN : 0); // cafrii 040114 add
643        flag |= (buf->scrambled ? UCM_FLAG_SCRAMBLED : 0); // cafrii 041130 add
644       
645        _d2m(p + OFFSET_Flag,      SIZE_Flag,      flag);
646       
647        _d2m(p + OFFSET_SurfIndex, SIZE_SurfIndex, buf->SurfIndex);
648       
649        _d2m(p + OFFSET_VideoFormat, SIZE_VideoFormat, buf->video_format);
650       
651        // cafrii, 030310
652        epgIndex = nvr_generate_epg_index((UINT32)buf->pEpgDB);
653        _d2m(p + OFFSET_EpgIndex, SIZE_EpgIndex, epgIndex);
654        if (pEpgIndex)
655                *pEpgIndex = epgIndex;
656
657        // LongName ÀÇ ±æÀÌ¿¡ µû¶ó¼­ ÀúÀå UCMÀÇ Å©±â°¡ ´Þ¶óÁø´Ù.
658        // LongName ±æÀ̰¡ 0 À̸é LongName slotÀº ÇÊ¿ä ¾ø°í,
659        // LongName ±æÀ̰¡ 1~15 À̸é ÇϳªÀÇ 32-byte slotÀÌ Ãß°¡ ÇÊ¿äÇϰí,
660        // LongName ±æÀ̰¡ 16~30 À̸é, µÎ°³ÀÇ 32-byte slotÀÌ Ãß°¡ ÇÊ¿äÇÏ´Ù.
661       
662       
663        if (len_ch_name == 0) {
664                nvm_size_of_this_ucm = SIZEOF_UCM_DB_ITEM;
665                // do nothing
666        }
667        else if (len_ch_name <= 15) {
668                nvm_size_of_this_ucm = 2*SIZEOF_UCM_DB_ITEM;
669                _d2m(p + OFFSET_Ext1, SIZE_Ext, UCM_EXT_MARKER);
670                memcpy(p + OFFSET_LongName1, (UINT8 *)buf->LongName, SIZE_LongName);
671        }
672        else {
673                nvm_size_of_this_ucm = 3*SIZEOF_UCM_DB_ITEM;
674                _d2m(p + OFFSET_Ext1, SIZE_Ext, UCM_EXT_MARKER);
675                memcpy(p + OFFSET_LongName1, (UINT8 *)buf->LongName, SIZE_LongName);
676                _d2m(p + OFFSET_Ext2, SIZE_Ext, UCM_EXT_MARKER);
677                memcpy(p + OFFSET_LongName2, ((UINT8 *)buf->LongName)+SIZE_LongName, SIZE_LongName);
678        }
679        return nvm_size_of_this_ucm;
680}
681
682
683
684
685
686#if COMMENT
687_______Level_4_______(){}
688#endif
689
690/*
691
692        ucm header syntax
693
694        Ver 0x02:   defined at 100427
695
696                +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
697                |  Id |nItem| Byte Size |  UCM CRC  |HdCRC|SV|FF|
698                +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
699                |   UCM DB Description..                        |
700                +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
701
702                -------------------------------------------------------
703                Id (key + version)   : 0x47 0x02
704                Header CRC           : changed from 32 bit to 16 bit.
705                SV (Storing Version) : UCM Storing Version (== gUcmStoringVersion)
706                FF                   : not used. filled to 0xFF
707
708                Header CRC algorithm is changed also.
709               
710
711        Ver 0x01:   defined at 041110
712
713      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
714      |  Id |nItem| Byte Size |  UCM CRC  | Header CRC|
715      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
716      |   UCM DB Description..                        |
717      +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
718
719      Name                       offset   size
720      -------------------------------------------------------
721      Id (key + version)       :    0       2 bytes  0x47 0x01
722      Number of UCM item       :    2       2 bytes 
723      Byte size of this UCM DB :    4       4 bytes  (unsigned long int)
724      CRC32 of entire UCM      :    8       4 bytes  (unsigned long int)
725      CRC32 of this header     :   12       4 bytes  (unsigned long int)
726      Description of UCM       :   16      16 bytes  (ascii string, should include null-terminator)
727       
728*/
729
730
731
732#define UCM_HEADER_MAGIC_KEY  0x47
733
734UINT16 gUcmHeaderVersion = 0x02;
735        // UCM header versionÀÌ º¯°æµÇ¾îµµ
736        // UcmStoringVersion °ªÀ» upgradeÇØ¾ß ÇÑ´Ù.
737
738#define UH_OFFSET_ID          0
739#define UH_OFFSET_NITEM       2
740#define UH_OFFSET_BYTESIZE    4
741#define UH_OFFSET_UCM_CRC     8
742#define UH_OFFSET_HDR_CRC     12
743#define UH_OFFSET_USV         14
744#define UH_OFFSET_RESV        15
745#define UH_OFFSET_DESC        16
746
747#define UH_SIZE_ID            2
748#define UH_SIZE_NITEM         2
749#define UH_SIZE_BYTESIZE      4
750#define UH_SIZE_UCM_CRC       4
751#define UH_SIZE_HDR_CRC       2  /* 4->2 */
752#define UH_SIZE_USV           1
753#define UH_SIZE_RESV          1
754#define UH_SIZE_DESC          16
755
756
757#define UH_ID_VALUE ((UCM_HEADER_MAGIC_KEY<<8) | gUcmHeaderVersion)
758
759
760
761
762
763STATUS nvr_ucm_init(UINT32 db_start_address)
764{
765        int err = statusOK;
766        UINT8 TempUcm[SIZEOF_UCM_DB_ITEM];
767
768        UINT32 crc;
769       
770        dprint(1, "nvr_ucm_init (0x%x)\n", db_start_address);
771       
772       
773        memset(TempUcm, 0, SIZEOF_UCM_DB_ITEM);
774       
775        _d2m(TempUcm+UH_OFFSET_ID, UH_SIZE_ID, (UCM_HEADER_MAGIC_KEY << 8) + gUcmHeaderVersion);
776        _d2m(TempUcm+UH_OFFSET_UCM_CRC, UH_SIZE_UCM_CRC, 0xFFFFFFFF);
777       
778        crc = nvr_calc_crc32(0xFFFFFFFF, TempUcm, SIZEOF_UCM_DB_ITEM);
779        crc = (crc & 0xffff); /* ÇÏÀ§ 16 bit¸¸ ÃßÃâÇÏ¿© »ç¿ëÇÑ´Ù */
780        _d2m(TempUcm+UH_OFFSET_HDR_CRC, UH_SIZE_HDR_CRC, crc);
781       
782        dprint(2, "\t ucm header crc 0x%04x\n", crc);
783       
784        _d2m(TempUcm+UH_OFFSET_USV, UH_SIZE_USV, gUcmStoringVersion);
785        _d2m(TempUcm+UH_OFFSET_USV+1, 1, 0xFF);
786
787        err = NvRamWrite(db_start_address, SIZEOF_UCM_DB_ITEM, TempUcm);
788        if (err != statusOK) {
789                dprint(0, "!! Err nvr_ucm_init: ucm hdr, NvRamWrite err %d\n", err);
790                return (STATUS)err;
791        }
792
793        return (STATUS)err;
794}
795
796
797
798#if COMMENT
799        ____UCM____(){}
800#endif
801
802
803//---------------------
804//  DMW_CDB_InitUCM2
805//
806
807//  »õ UCM DB ±¸Á¶¿¡´Â UCM DB Header ¿µ¿ªÀ̶ó´Â°Ô »ý°å±â ¶§¹®¿¡ FormatÀ» ÇÑ ´ÙÀ½¿¡ ÀÌ ¿µ¿ªÀ»
808//  ÃʱâÈ­ ÇØ ÁÙ Çʿ䰡 ÀÖ´Ù.
809//
810//  ¸ÕÀú LowLevelFormatÀ» ¼öÇàÇϰí UCM DBÀÎ °æ¿ì¿¡´Â ÀÌ API¸¦ ºÒ·¯¼­ Header ¿µ¿ªÀ» ÃʱâÈ­ ÇØÁØ´Ù.
811//
812
813STATUS DMW_CDB_InitUCM2(UINT32 *pAddrs, int nDB, BOOL bSyncNow)
814{
815        int i, err = statusOK;
816        UINT32 address;
817        BOOL bSyncRequired = FALSE;
818               
819        dprint(1, "DMW_CDB_InitUCM2(%d DB, sync %d)\n", nDB, bSyncNow);
820
821        for (i=0; i<nDB; i++)
822        {
823                address = pAddrs[i];
824                err = nvr_ucm_init(address);
825               
826                if (address >= 0x80000000 && bSyncNow)
827                        bSyncRequired = TRUE;
828        }
829       
830        if (bSyncRequired)
831                err = NvRamSync(0x80000000, NULL);
832       
833        return (STATUS)err;
834}
835       
836       
837
838//---------------------
839//  DMW_CDB_WriteUCM2
840//
841//  g_UCM ÀÇ ³»¿ëÀ» ÇØ´ç À§Ä¡ÀÇ NvRam ¿¡ ÀúÀåÇÑ´Ù.
842//
843//  start address´Â API ÀÎÀÚ·Î Á÷Á¢ ÁöÁ¤ÇÑ´Ù.
844//
845//  WriteUCM °ú ´Ù¸¥Á¡:
846//    ÀÏ´Ü WriteUCM Àº Level 2 API (Section Directory) ¸¦ ÀÌ¿ëÇÑ´Ù.
847//
848//    WriteUCM API´Â caller°¡ directory ¼³Á¤À» ¸ðµÎ Ã¥ÀÓÁö°í °ü¸®ÇÏ´Â °æ¿ì¿¡ »ç¿ëÇÏ´Â API.
849//    DBÀÇ ÃÖ´ë Å©±â, overflow üũ (ÇÊ¿äÇÑ °æ¿ì UCM µÚÂÊ ÀϺθ¦ ¹ö¸®±âµµ ÇÔ) µîÀÇ ÀÏÀ» caller°¡ ´ã´ç.
850//    caller°¡ UCM °¹¼ö¿¡ ¸ÂÃç¼­ DB size¸¦ ¹Ì¸® Á¶Á¤ÇØ ³õÀ¸¸é WriteUCMÀº ±× Å©±â ³»¿¡¼­¸¸ ÀúÀåÇÑ´Ù.
851//
852//    WriteUCM2 API´Â Low level driver ÇÔ¼ö¸¸ »ç¿ëÇÏ¿© µ¿ÀÛÇÏ°Ô µÈ´Ù.
853//    µû¶ó¼­ UCMÀÇ ÃÖ´ë °¹¼ö°¡ ³ÑÄ¡´ÂÁöÀÇ ¿©ºÎ´Â üũÇÏÁö ¾ÊÀ¸¸ç, ÁÖÀÇÇØ¼­ »ç¿ëÇØ¾ß ÇÑ´Ù.
854//    ¿¹: ´Ù¸¥ DB¿Í °ãħ µîÀº ÀÌ API¿¡¼­ üũÇÒ ¼ö ¾øÀ½.
855//
856//    Updated by Chjeon 2007.9.13
857//    ½ÇÁ¦ data°¡ Flash¿¡ ÀúÀåµÇ·Á¸é Caller¿¡¼­ NvRamSyncÀ» È£ÃâÇØ ÁÖ¾î¾ß ÇÔ
858STATUS DMW_CDB_WriteUCM2(UINT32 db_start_address, int max_db_size, const char *description)
859{
860        STATUS returnStatus = statusOK;
861        int i, k, err;
862       
863        UCM_DB_T *pUcmToWrite;   // temporary ucm pointer
864        int nUcmToWrite;         // number of ucm entry to write
865
866        UINT8 TempUcm[SIZEOF_UCM_DB_ITEM*3];
867
868        char org_desc[UH_SIZE_DESC];
869        UINT32 offset; // db_start_address¸¦ ±âÁØÀ¸·Î ÇÏ´Â offset.
870
871        UINT32 crc, ucm_crc;
872
873        int nvm_size_of_this_ucm; // Çѹø¿¡ ±â·ÏÇÒ ucmÀÇ nvm Á¡À¯ Å©±â.
874        int len_ch_name;
875       
876        int num_ucm_writed=0; //½ÇÁ¦ ÀúÀåµÈ »çÀÌÁî Å©±â, disabled´Â counting¿¡¼­ Á¦¿ÜµÊ
877       
878        dprint(1, "%s (addr 0x%x, '%s')\n", __func__, db_start_address, description ? description : "NoInfo");
879       
880        // cafrii 070424 add, UCM ¾ø´Â »óÅ¿¡¼­ ±â·ÏÇÏ¸é ¸ðµÎ Áö¿ì´Â °ÍÀ¸·Î ÇÔ.
881#if 0
882        if (g_UCM == NULL) {
883                dprint(0, "!! UCM DB NULL\n");
884                return statusError;  // cafrii 030712, no ucm err.
885        }
886#endif
887
888        DMW_MSC_LockUcm();  // ----------------------
889        nvr_reset_epg_index();
890
891        if (1) {
892                pUcmToWrite = g_UCM ? &g_UCM[0] : NULL;
893                nUcmToWrite = g_UCM_number;
894        }
895
896        if (! nvr_is_safe_area(db_start_address, SIZEOF_UCM_DB_ITEM)) {
897                returnStatus = statusOutOfRange;
898                goto end_write_ucm;
899        }
900
901        // ¸ÕÀú header Á¤º¸¸¦ ÀоîµéÀδÙ.
902        //
903        err = NvRamRead(db_start_address, SIZEOF_UCM_DB_ITEM, TempUcm);
904        if (err) {
905                dprint(0, "!! %s: read ucm header err %d\n", __func__, err);
906                //return err;   // cafrii 041209, bugfix!!
907                returnStatus = (STATUS)err;
908                goto end_write_ucm;
909        }
910
911        memset(org_desc, 0, sizeof(org_desc));
912       
913        if (_m2d(TempUcm+UH_OFFSET_ID, UH_SIZE_ID) == UH_ID_VALUE) {
914                memcpy(org_desc, TempUcm+UH_OFFSET_DESC, UH_SIZE_DESC);
915                org_desc[UH_SIZE_DESC-1] = 0;
916                dprint(2, "\t prev DB desc: '%s'\n", org_desc);
917        }
918
919        offset = SIZEOF_UCM_DB_ITEM; // UCM header Å©±â´Â skip.
920        crc = 0xFFFFFFFF;
921        //
922        // Çѹø¿¡ ÇϳªÀÇ UCMÀ» ÀúÀåÇÏ´Â ¹æ½Ä.
923        //
924        dprint(1, "\t UCM writing, %d entries being written..\n", nUcmToWrite);
925
926        for (i=0; i<nUcmToWrite; i++) 
927        {
928                // ÇöÀç UCM entryÀÇ NVM size¿Í »ó°ü ¾øÀÌ Ç×»ó ÃÖ´ë Å©±âÀÇ nvm size °ø°£ÀÌ ÀÖ´Â °æ¿ì¿¡¸¸
929                // write¸¦ ÁøÇàÇϵµ·Ï ÇÑ´Ù.
930                if (! nvr_is_safe_area(db_start_address+offset, 3*SIZEOF_UCM_DB_ITEM)) {
931                        dprint(0, "!! ucm[%d] cannot be stored. unsafe area! (offset 0x%x, total ucm %d)\n", 
932                                i, offset, nUcmToWrite);
933                        break;
934                }
935                if (db_start_address + 3*SIZEOF_UCM_DB_ITEM > db_start_address + max_db_size) {
936                        dprint(0, "!! ucm[%d] cannot be stored. exceed max sz 0x%x! (offset 0x%x, total ucm %d)\n", 
937                                i, max_db_size, offset, nUcmToWrite);
938                        break;
939                }
940               
941                if(pUcmToWrite[i].disabled) continue; //disabled´Â ±â·ÏÇÏÁö ¾Ê´Â´Ù.
942
943                // prepare memory UCM copy.     
944                // LongName ¿¡ µû¶ó¼­ flatten µÇ´Â TempUcmÀÇ Å©±â´Â ´Þ¶óÁø´Ù.
945                nvm_size_of_this_ucm = DMW_CDB_PrepareOneUcmBlockMode(TempUcm, &pUcmToWrite[i], NULL);
946                               
947                err = NvRamWrite(db_start_address+offset, nvm_size_of_this_ucm, TempUcm);
948               
949                if (err != statusOK) {
950                        dprint(0, "!! %s: ucm[%d], NvRamWrite err %d\n", __func__, i, err);
951                        returnStatus = (STATUS)err;
952                        goto end_write_ucm;
953                }
954                crc = nvr_calc_crc32(crc, TempUcm, nvm_size_of_this_ucm);
955
956                dprint(3, "  (%d) write offset %x, size %d, crc 0x%08x\n", i, offset, nvm_size_of_this_ucm, crc);
957
958                offset += nvm_size_of_this_ucm;
959               
960                num_ucm_writed++;
961        }
962
963        if (i < nUcmToWrite) {
964                dprint(0, "!! only %d ucms saved among %d, total %d bytes\n", i, nUcmToWrite, offset);
965                        // UCM[i] °¡ ÀúÀåµÇÁö ¸øÇÏ´Ù°í ÆÇÁ¤ÀÌ ³­ »óÅÂÀ̹ǷÎ
966                        // UCM[0] ºÎÅÍ UCM[i-1] ±îÁö ÀúÀå °¡´ÉÇϸç, ÀÌ´Â ÃÑ 'i' °³ÀÇ UCMÀÌ ÀúÀå µÇ¾ú´Ù.
967                        //
968                nUcmToWrite = i;
969        }
970        else
971                dprint(2, "\t total %d ucms entries, %d bytes saved..\n", nUcmToWrite, offset);
972       
973        nUcmToWrite=num_ucm_writed;
974       
975        // DB Á¦ÀÏ ¾Õ ºÎºÐ¿¡ Ưº°ÇÑ Á¤º¸ ±â·Ï..
976        //
977        ucm_crc = crc;
978        memset(TempUcm, 0, SIZEOF_UCM_DB_ITEM);
979       
980        _d2m(TempUcm+UH_OFFSET_ID,       UH_SIZE_ID,       UH_ID_VALUE);
981        _d2m(TempUcm+UH_OFFSET_NITEM,    UH_SIZE_NITEM,    nUcmToWrite);
982        _d2m(TempUcm+UH_OFFSET_BYTESIZE, UH_SIZE_BYTESIZE, offset);
983        _d2m(TempUcm+UH_OFFSET_UCM_CRC,  UH_SIZE_UCM_CRC,  ucm_crc);
984        _d2m(TempUcm+UH_OFFSET_HDR_CRC,  UH_SIZE_HDR_CRC,  0); // ¸ÕÀú 0À» ±â·ÏÇϰí crc °è»ê ºÎÅÍ ÇÑ´Ù.
985        _d2m(TempUcm+UH_OFFSET_USV,      UH_SIZE_USV,      gUcmStoringVersion);
986        _d2m(TempUcm+UH_OFFSET_RESV,     UH_SIZE_RESV,     0xFF);
987       
988        if (description) {
989                strncpy((char *)TempUcm+UH_OFFSET_DESC, description, UH_SIZE_DESC-1);
990                TempUcm[UH_OFFSET_DESC+UH_SIZE_DESC-1] = 0;
991        }
992        else {
993                memcpy(TempUcm+UH_OFFSET_DESC, org_desc, UH_SIZE_DESC);  // ±âÁ¸ DB desc Á¤º¸¸¦ À¯Áö..
994        }
995        // UCM header ºÎºÐÀÇ CRC¸¦ °è»ê.
996        crc = nvr_calc_crc32(0xFFFFFFFF, TempUcm, SIZEOF_UCM_DB_ITEM);
997        crc = crc & 0xffff;  // ÇÏÀ§ 16 bit ¸¸..
998        _d2m(TempUcm+UH_OFFSET_HDR_CRC,  UH_SIZE_HDR_CRC, crc);
999       
1000        dprint(2, "\t nUcm %d, byte size %d, ucm crc 0x%08x, header crc 0x%04x\n", 
1001                        nUcmToWrite, offset, ucm_crc, crc);
1002
1003        err = NvRamWrite(db_start_address, SIZEOF_UCM_DB_ITEM, TempUcm);
1004        if (err != statusOK) {
1005                dprint(0, "!! %s: ucm hdr, NvRamWrite err %d\n", __func__, err);
1006                returnStatus = (STATUS)err;
1007                goto end_write_ucm;
1008        }
1009
1010end_write_ucm:
1011
1012        DMW_MSC_UnlockUcm(); // ----------------------
1013
1014        /*
1015        Caller ÂÊÀ¸·Î À̵¿
1016        err = NvRamSync(db_start_address, NULL);
1017        if (err)
1018                return err;
1019        */
1020       
1021        return returnStatus; 
1022}
1023
1024
1025
1026
1027
1028//---------------------
1029//  DMW_CDB_ReadUCM2
1030//
1031//
1032STATUS DMW_CDB_ReadUCM2(UINT32 db_start_address)
1033{
1034        STATUS returnStatus = statusOK;
1035        unsigned int i;
1036        int err;
1037
1038        UCM_DB_T *pUcm;   // temporary ucm pointer
1039
1040        UINT8 TempUcm[SIZEOF_UCM_DB_ITEM*3];
1041
1042        UINT32 offset; // db_start_address¸¦ ±âÁØÀ¸·Î ÇÏ´Â offset.
1043        UINT32 nUcmToRead, nDbByteSize;
1044       
1045        UINT32 crc, ucm_crc, hdr_crc;
1046        UINT16 idHeader;
1047        UINT8  usv;
1048        int    nvm_size_of_this_ucm; // Çѹø¿¡ ±â·ÏÇÒ ucmÀÇ nvm Á¡À¯ Å©±â.
1049
1050
1051        dprint(1, "%s (addr 0x%x)\n", __func__, db_start_address);
1052
1053
1054        // ucm header ÀÇ Á¤º¸¸¦ Àоî¿Â´Ù. ù¹øÂ° entry°¡ ¹Ù·Î ±× ¿µ¿ªÀÌ´Ù.
1055        //
1056        // ucm db header ¿µ¿ªÀ» ÀÐÀ» ¼ö ÀÖ´ÂÁö °Ë»ç..
1057        if (! nvr_is_safe_area(db_start_address, SIZEOF_UCM_DB_ITEM))
1058                return statusOutOfRange;
1059               
1060        //DHL_OS_Printf("before nvramread address(0x%x), size(%d), buf(0x%x)\n",
1061        //      db_start_address, SIZEOF_UCM_DB_ITEM, TempUcm);
1062
1063        err = NvRamRead(db_start_address, SIZEOF_UCM_DB_ITEM, TempUcm);
1064        if (err) {
1065                dprint(0, "!! %s: Read ucm header err %d\n", __func__, err);
1066                return (STATUS)err;
1067        }
1068       
1069        idHeader    = _m2d (TempUcm+UH_OFFSET_ID,       UH_SIZE_ID);
1070        nUcmToRead  = _m2d (TempUcm+UH_OFFSET_NITEM,    UH_SIZE_NITEM);
1071        nDbByteSize = _m2d (TempUcm+UH_OFFSET_BYTESIZE, UH_SIZE_BYTESIZE);
1072        ucm_crc     = _m2d (TempUcm+UH_OFFSET_UCM_CRC,  UH_SIZE_UCM_CRC);
1073        hdr_crc     = _m2d (TempUcm+UH_OFFSET_HDR_CRC,  UH_SIZE_HDR_CRC);
1074        usv         = _m2d (TempUcm+UH_OFFSET_USV,      UH_SIZE_USV);
1075       
1076        //dprint(0, "\n");
1077        //memdump(TempUcm, SIZEOF_UCM_DB_ITEM, 0);
1078        //dprint(0, "\n");
1079       
1080        _d2m(&TempUcm[UH_OFFSET_HDR_CRC], 2, 0);
1081        crc = nvr_calc_crc32(0xFFFFFFFF, TempUcm, SIZEOF_UCM_DB_ITEM);
1082        crc = crc & 0xffff;
1083       
1084        // Header ¿µ¿ªÀÌ À¯È¿ÇÑÁö validity check..
1085        //
1086        if (idHeader != UH_ID_VALUE) {
1087                dprint(0, "!! %s: ucm header id 0x%x invalid\n", __func__, idHeader);
1088                //return statusNvRamNotFormatted;
1089                nUcmToRead = 0;
1090        }
1091        else if (usv != gUcmStoringVersion) {
1092                dprint(0, "!! %s: usv mismatch. nvm %02x != sw %02x\n", usv, gUcmStoringVersion);
1093                nUcmToRead = 0;
1094        }
1095        else if (crc == hdr_crc) {
1096                dprint(2, "\t nUcm %d, Bytesize %d, ucm crc 0x%08x, hdr crc 0x%04x\n", 
1097                                        nUcmToRead, nDbByteSize, ucm_crc, hdr_crc);
1098                // NVM ucmÀÇ Å©±â°¡ ´õ ÀÌ»ó Æ¯Á¤ Å©±âÀÇ multipleÀÌ ¾Æ´Ï¹Ç·Î ¾Æ·¡ üũ´Â ºÒ°¡´É.
1099        #if 0
1100                if (nDbByteSize != nUcmToRead * SIZEOF_UCM_DB_ITEM) {
1101                        nUcmToRead = nDbByteSize / SIZEOF_UCM_DB_ITEM;
1102                        dprint(0, "!! db size is not multiple of nUcm. adjust to %d\n", nUcmToRead);
1103                }
1104        #endif
1105               
1106                if (TempUcm[UH_OFFSET_DESC]) 
1107                        dprint(2, "\t ucm description: '%s'\n", &TempUcm[UH_OFFSET_DESC]);
1108        }
1109        else {
1110                dprint(0, "!! header crc mismatch: calc 0x%08x != saved 0x%08x\n", crc, hdr_crc);
1111                nUcmToRead = 0;
1112        }
1113
1114        // ¸î °³ÀÇ ucmÀ» ÀÐ¾î µéÀÏ ¼ö ÀÖ´ÂÁö ¹Ì¸® ¾Ë ¼ö ¾ø´Ù.
1115        // Àдٰ¡ overflow µÇ¸é ¸ØÃß´Â ¹æ½ÄÀ¸·Î ÁøÇàÇÑ´Ù.
1116        dprint(2, "\t total %d ucms entries can be read..\n", nUcmToRead);
1117       
1118        DMW_MSC_LockUcm();  // ----------------------
1119
1120        DMW_CDB_ClearAll();
1121       
1122        // À§¿¡¼­ DB¸¦ ¸ðµÎ Clear¸¦ ÇØµµ È¿À²À» À§ÇØ ¸Þ¸ð¸® ¿µ¿ªÀº ³²°ÜµÎµµ·Ï µÇ¾î ÀÖ´Ù.
1123        // ±×·¯³ª »õ·Î DB¸¦ ÀоîµéÀ϶§¿¡´Â ÀûÀýÇÑ Å©±â °è»êÀ» ÇØ¼­ ÀçÇÒ´çÀ» Çϱ⠶§¹®¿¡
1124        // ¸Þ¸ð¸®¸¦ ¸ðµÎ ÇØÁ¦½ÃÄѹö¸®´Â °ÍÀÌ ³´´Ù.
1125        //
1126        if (g_UCM) {
1127                DHL_OS_Free((void**)&g_UCM);
1128                g_UCM_max = 0;
1129        }
1130       
1131        g_UCM_max = nUcmToRead + 8;
1132                // ½ÇÁ¦ ¸Þ¸ð¸®»ó¿¡ ÀÖÀ» UCM Å©±âÀÌ´Ù.
1133                //
1134                // '8' is additional space for manual channel add.
1135                // if this space is run out, we will re-alloc memory later.
1136
1137        g_UCM = DHL_OS_Malloc(g_UCM_max * UcmItemMemorySize());
1138        if (g_UCM == NULL) 
1139        {
1140                g_UCM_number = g_UCM_max = 0;
1141                returnStatus = statusOutOfMemory;
1142                goto end_read_ucm;
1143        }
1144
1145        reset_ucm_uid_counter();
1146        pUcm = &g_UCM[0];
1147        g_UCM_number = 0;
1148       
1149        crc = 0xFFFFFFFF;
1150        offset = SIZEOF_UCM_DB_ITEM; // UCM header ¿µ¿ª skip.
1151       
1152        for (i=0; i<nUcmToRead; i++)
1153        {
1154                // Á¦´ë·Î ÀúÀåÀÌ µÈ °Å¶ó¸é ÀÌ·± °æ¿ì´Â ¹ß»ýÇÒ ¼ö ¾øÀ½.
1155                // ´Ü ¸Ç ¸¶Áö¸· UCM Çϳª´Â ¹®Á¦°¡ µÉ ¼ö ÀÖÀ½. ÀÌ·¯ÇÑ °æ¿ì °í·Á ÇÊ¿äÇÔ.
1156                if (! nvr_is_safe_area(db_start_address+offset, 3*SIZEOF_UCM_DB_ITEM))
1157                        break;
1158       
1159                err = NvRamRead(db_start_address + offset, 3*SIZEOF_UCM_DB_ITEM, TempUcm);
1160                if (err) {
1161                        dprint(0, "!! %s: Read UCM #%d from NvRam err!\n", __func__, i);
1162                        returnStatus = (STATUS)err;
1163                        goto end_read_ucm;
1164                }
1165               
1166                // Á¤È®ÇÑ NVM UCM Å©±â´Â parsingÀ» ÇØ ºÁ¾ß ¾Ë ¼ö ÀÖ´Ù.
1167                nvm_size_of_this_ucm = DMW_CDB_ParseOneUcmBlockMode(TempUcm, &pUcm[i], NULL);
1168               
1169                // CRC ¿ª½Ã Á¤È®ÇÑ NVM UCM ºÎºÐ¿¡ ´ëÇØ¼­¸¸ °è»êÇØ¾ß ÇÑ´Ù.
1170                crc = nvr_calc_crc32(crc, TempUcm, nvm_size_of_this_ucm);
1171                dprint(3, "  (%d) read offset %x, size %d, crc 0x%08x\n", i, offset, nvm_size_of_this_ucm, crc);
1172               
1173                offset += nvm_size_of_this_ucm;
1174                g_UCM_number++;
1175        }
1176
1177        if (i < nUcmToRead) {
1178                dprint(0, "!! only %d ucms read among %d\n", i, nUcmToRead);
1179                // ¾Æ¸¶µµ ÀÌ·± »óȲÀÌ µÇ¸é crcµµ mismatch°¡ ³ª¼­ fail µÉ °ÍÀÓ. º°µµ ¿¡·¯ ó¸® ¾ÈÇÔ.
1180        }
1181        if (crc != ucm_crc) {
1182                dprint(0, "!! calculated crc 0x%08x != nvram crc 0x%08x\n", crc, ucm_crc);
1183                g_UCM_number = 0;
1184                returnStatus = statusError;
1185        }
1186
1187end_read_ucm:
1188
1189        DMW_MSC_UnlockUcm(); // ----------------------
1190       
1191        return returnStatus;
1192}
1193
1194
1195
1196//---------------------
1197//  DMW_CDB_WriteRawDB2
1198//
1199//  Raw DB Access API ÀÇ »õ ¹öÀü
1200// 
1201//  Directory index¸¦ »ç¿ëÇÏÁö ¾Ê°í Á÷Á¢ caller°¡ DB NvRam address¸¦ ÁöÁ¤ÇÑ´Ù
1202//  DBÀÇ Å©±âµµ Á÷Á¢ ÁöÁ¤ÇϹǷÎ, DB ÀÇ ÃÖ´ë Å©±â¸¦ ³ÑÁö ¾Êµµ·Ï caller°¡ ÁÖÀÇÇÏ¿©¾ß ÇÑ´Ù.
1203//
1204//  Updated by chjeon 2007.09.12
1205//  ±âÁ¸ÀÇ ÀÌ ÇÔ¼ö´Â Sync ÀÛ¾÷µµ Æ÷ÇÔÀÌ µÇ¾î ÀÖ¾úÁö¸¸ ÇöÀç´Â ºÐ¸® »óÅÂÀÓ
1206//  ½ÇÁ¦ Flash¿¡ ÀúÀåÇÏ·Á¸é Caller¿¡¼­ NvRamSync¸¦ È£ÃâÇØÁÖ¾î¾ß ÇÔ 
1207STATUS DMW_CDB_WriteRawDB2(UINT32 address, UINT8 *buf, int newsize)
1208{
1209        int err;
1210
1211        dprint(1, "DMW_CDB_WriteRawDB2 (0x%x, size %d)\n", address, newsize);
1212       
1213        if (! nvr_is_safe_area(address, newsize))
1214                return statusOutOfRange;
1215
1216        err = NvRamWrite(address, newsize, buf);
1217               
1218        if (err != statusOK) {
1219                dprint(0, "!! Err DMW_CDB_WriteRawDB2: NvRam Write err %d\n", err);
1220                return (STATUS)err;
1221        }
1222
1223        // Updated by Chjeon 2007.09.11
1224        // - µ¥ÀÌÅͰ¡ ÀúÀåµÇ±æ ¿øÇϸé Caller¿¡¼­ NvRamSync ÇÔ¼ö¸¦ È£ÃâÇØ ÁÖ¾î¾ß ÇÑ´Ù.
1225        /*
1226        err = NvRamSync(address, NULL);
1227        if (err)
1228                return err;
1229        */
1230
1231        return statusOK;       
1232}
1233
1234
1235//---------------------
1236//  DMW_CDB_ReadRawDB2
1237//
1238//  Raw DB Access API ÀÇ »õ ¹öÀü
1239// 
1240//
1241//
1242STATUS DMW_CDB_ReadRawDB2(UINT32 address, UINT8 *buf, int newsize)
1243{
1244        int err;
1245       
1246        dprint(1, "DMW_CDB_ReadRawDB2 (0x%x, size %d)\n", address, newsize);
1247       
1248        if (! nvr_is_safe_area(address, newsize))
1249                return statusOutOfRange;
1250
1251        err = NvRamRead(address, newsize, buf);
1252        if (err) {
1253                dprint(0, "!! DMW_CDB_ReadRawDB2: NvRam Read err %d\n", err);
1254                return (STATUS)err;
1255        }
1256       
1257        return statusOK;
1258}
1259
1260
1261
1262#if COMMENT
1263_______Util_______(){}
1264#endif
1265
1266
1267STATUS DMW_CDB_SyncNvRam(UINT32 address)
1268{
1269        STATUS err;
1270        err = NvRamSync(address, NULL);
1271        return err;
1272}
1273
1274UINT32 DMW_CDB_CalcCRC32(UINT32 crc_start, const UINT8 *data, UINT32 len)
1275{
1276        return nvr_calc_crc32(crc_start, data, len);
1277}
1278
1279// cafrii 060802 add
1280BOOL DMW_CDB_IsNvRamSyncWorking(void)
1281{
1282        BOOL bNvRamFree = NvRamIsSyncEnd();
1283
1284        return bNvRamFree ? FALSE : TRUE;
1285}
1286
1287void DMW_CDB_WaitForNvRamSyncDone()
1288{
1289        NvRamWaitForSyncEnd();
1290        dprint(2, "NvRam Sync Completed..\n");
1291}
1292
1293
1294void DMW_CDB_InvalidateNvRamCache()
1295{
1296        NvRamInvalidateCache();
1297}
1298
1299
1300
1301
1302#if COMMENT
1303_______Debug_______(){}
1304#endif
1305
1306
1307
1308void DMW_CDB_MakeTestUcm(int nItem)
1309{
1310        int i, k, r, idx;
1311       
1312        if (nItem == 0)
1313                nItem = 100;
1314               
1315        dprint(1, "DMW_CDB_MakeTestUcm: make temp %d UCM items..\n", nItem);
1316
1317        DMW_CDB_ClearAll();  // ¸ÕÀú ¸ðµç UcmÀ» »èÁ¦ÇÑ´Ù.
1318               
1319        DMW_MSC_LockUcm();
1320       
1321        r = prepare_ucm_space(32);
1322        if (r) {
1323                dprint(0, "!! out of memory for ucm\n");
1324                return;
1325        }
1326
1327        srand(DHL_OS_GetMsCount());
1328       
1329        for (i=0; i<nItem; i++) {
1330               
1331        #if 0
1332               
1333                // Á÷Á¢ UCM ¹è¿­¿¡ Á¢±ÙÇØ¼­ Ãß°¡Çϱâ.. ±ÇÀåµÇÁö ¾ÊÀ½!!
1334                memset(&g_UCM[i], 0, UcmItemMemorySize());
1335               
1336                g_UCM[i].Major = i+5;
1337                g_UCM[i].Minor = 1;
1338                g_UCM[i].RF = i+9;
1339                g_UCM[i].VctFlag = i%2;
1340                g_UCM[i].Skipped = 0;
1341                g_UCM[i].Service_type = i % 5 == 0 ? 0 : 1;
1342                g_UCM[i].Uid = make_new_ucm_uid_counter();
1343               
1344        #else
1345       
1346                int major, minor, rf, vf, st;
1347               
1348                rf = i+6;
1349                vf = rand()%10 > 2 ? 1 : 0;  // 70% possibility
1350                major = vf ? rand() % 128 + 2 : rf;
1351                minor = rand() % 8 + 1;
1352                st = 1;  // VSB only
1353               
1354                idx = DMW_CDB_MakeNewUcm(major, minor, rf, vf, st);
1355               
1356                g_UCM[idx].Skipped = rand() % 10 > 2 ? 0 : 1;
1357                g_UCM[idx].Prog_number = rand()%5 + 1;
1358                g_UCM[idx].Pcr_pid = rand()%10 + 100;
1359                g_UCM[idx].Video_pid = g_UCM[idx].Pcr_pid;
1360                g_UCM[idx].Audio_pid = g_UCM[idx].Pcr_pid + rand()%5 + 3;
1361                g_UCM[idx].source_id = rand()%5 + 1;
1362               
1363                for (k=0; k<rand()%9+4; k++) {
1364                        g_UCM[idx].ShortName[k] = rand()%27 + '@';
1365                }
1366               
1367                if (idx < 0) {
1368                        dprint(0, "!! out of memory for new ucm.. only %d items are added..\n", i);
1369                        break;
1370                }
1371                #if 0
1372                        for (k=0; g_UCM && k<g_UCM_number; k++) {
1373                                dprint(2, " %c(%02d) %2d,%d %2d %c[%03d]  %s\n",
1374                                        g_UCM[k].Skipped ? ' ' : '+',         // enabled channel.
1375                                        k, g_UCM[k].Major, g_UCM[k].Minor, g_UCM[k].RF,
1376                                        g_UCM[k].VctFlag ? 'v' : ' ',
1377                                        g_UCM[k].Uid, ServiceTypeString(g_UCM[i].Service_type));
1378                        }
1379                #endif
1380               
1381                if (i%100 == 0)
1382                        DHL_OS_Printf(".");
1383               
1384                //OS_Delay(1);
1385       
1386        #endif
1387       
1388        }
1389       
1390        DMW_MSC_UnlockUcm();
1391       
1392        dprint(2, "Test UCM is made..\n");
1393}
1394
1395
1396
1397
1398
1399#if COMMENT
1400______DebugSymbol____(){}
1401#endif
1402
1403
1404
1405
1406#if DMW_REGISTER_DEBUG_SYMBOL
1407
1408static DHL_SymbolTable ChannelNvRamSymbols[] =
1409{
1410        //---- functions
1411        DHL_FNC_SYM_ENTRY(DMW_CDB_GetNvRamAvailableSize),
1412        DHL_FNC_SYM_ENTRY(DMW_CDB_CheckNvRam),
1413        DHL_FNC_SYM_ENTRY(DMW_CDB_MakeTestUcm),
1414
1415        DHL_FNC_SYM_ENTRY(DMW_CDB_IsNvRamSyncWorking),
1416       
1417        //---- variables
1418        //DHL_VAR_SYM_ENTRY(g_Trace_ChannelDB),
1419       
1420};
1421
1422#endif // DMW_REGISTER_DEBUG_SYMBOL
1423
1424
1425void DMW_CDB_RegisterChannelNvRamSymbols()
1426{
1427#if DMW_REGISTER_DEBUG_SYMBOL
1428        DHL_DBG_RegisterSymbols(ChannelNvRamSymbols, DHL_NUMSYMBOLS(ChannelNvRamSymbols));
1429       
1430        NvRamRegisterDebugSymbol();
1431#endif
1432}
1433
1434
1435
1436/********************************************************************
1437 *
1438 * $Log: DMW_ChannelDB.c,v $
1439
1440        1.40 2004/12/17 DMW_CDB_WriteUCM2: nUcmToWrite°¡ 0À϶§µµ ±â·Ï
1441        1.39 2004/12/09 DMW_CDB_WriteUCM2: ¿¡·¯¹ß»ý½Ã UCM unlock ¾ÈÇÏ´Â ¹ö±×¼öÁ¤
1442
1443        1.38 2004/11/30 persistent scrambled flag, ucm ver->A7
1444                       
1445        1.37 2004/11/29 UcmStrongVersion -> A6
1446                        DMW_CDB_WriteUCM2 ¿¡ max_db_size ÀÎÀÚ Ãß°¡
1447                        DMW_CDB_CalcCRC32 Ãß°¡
1448
1449        1.36 2004/11/10 Level 4 API Ãß°¡
1450        1.35 2004/11/03 DMW_CDB_ReadUCM ¿¡¼­ db size°¡ 0À϶§ garbage ¸®ÅϵǴ ¹ö±× ¼öÁ¤
1451       
1452        1.34 2004/9/20 DMW_Config µµÀÔ, config »çÇ× À̵¿
1453        1.33 2004/8/12 UCM writeÇÒ¶§ freqOffset ÀúÀå¾ÈµÇ´ø ¹ö±× ¼öÁ¤ (from miyu)
1454        1.32 2004/7/26 add debug print level
1455        1.31 2004/6/7  DMW_EEPROM.h include (platform dependent flag Æ÷ÇÔ)
1456
1457        1.3 2004/05/25 new eeprom¿¡ ¸ÂÃç¼­ SetDirItemÀ» Çѹø¿¡ 8¹ÙÀÌÆ® ±â·ÏÇϵµ·Ï ¼öÁ¤
1458                      lowlevel format½Ã eeprom ¿¡·¯°¡ ³ª¸é flash´Â skip
1459       
1460        1.2 2004/04/07 Add error check code in Level 2 directory API
1461       
1462        1.12 2004/01/14 add persistant hidden flag, UCM version up
1463        1.11 2004/01/02 minor bug fix in FlashSync in WriteUCM
1464        1.10 2003/12/31
1465        ND field added in SYS_PARAM
1466       
1467        Flash DB support, GenerateTestUcm, 2003/11/13 cafrii
1468       
1469        Read/WritEncryptedDtcpCertAndKey() change, 2003/8/3 cafrii
1470        NvRam Sema4 add, 2003/7/11 cafrii
1471
1472 * Revision 1.01  2003/02/17  cafrii
1473 * NVRAM strategy is changed.
1474 * AirUCM/CableUCM code-share...
1475 *
1476 * Revision 1.0  2003/01/13  cafrii
1477 * Initial coding from ground, based on M/W API document
1478 *
1479 ********************************************************************/
Note: See TracBrowser for help on using the repository browser.