source: svn/newcon3bcm2_21bu/dst/dmw/src/Channel/DMW_ChannelCSD.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: 37.6 KB
Line 
1/*******************************************************************
2 * DMW_ChannelCSD.c
3 *
4 * Channel Specific Data implementation
5 *
6 * Copyright 2003 Digital STREAM Technology, Inc.
7 * All Rights Reserved
8 *
9 * $Id: DMW_ChannelCSD.c, v 1.0 2004/11  cafrii Exp $
10 *
11 ********************************************************************/
12
13
14#include "DMW_Platform.h"
15
16#include "DMW_Config.h"
17#include "DMW_Status.h"
18
19#include "DMW_DebugUtil.h"
20#include "DMW_CodeConv.h"
21#include "dmw_nvram_priv.h"
22#include "DMW_ChannelAPI.h"
23
24//#include <string.h>
25
26
27
28DHL_MODULE("$csd", 0);
29
30
31//===========================================================================
32//
33//       Design Notes
34//
35//
36
37/*
38        CSD¶õ Channel Specific DataÀÇ ¾àÀÚÀÌ´Ù.
39        CSD´Â channelÀÇ extended name °ú °°ÀÌ °¢ ä³Î °íÀ¯ÀÇ Á¤º¸¸¦ ÀúÀÇ?¼ö ÀÖ´Ù.
40
41        UCMÀÇ field Áß¿¡ csd ¶ó´Â Æ÷ÀÎÅͰ¡ °¢ ä³Î º° CSD Á¤º¸¸¦ °¡¸®Å°´Â ¸µÅ© Æ÷ÀÎÅÍÀÌ´Ù.
42
43        CSD ÀÚü´Â tag length data ¿Í °°Àº ±¸Á¶ÀÇ µ¥ÀÌÅͰ¡ Â÷·Ê·Î ºÙ¿©Á® ¸¸µé¾îÁ® ÀÖ´Ù.
44                tag´Â ¾î¶² CSD ŸÀÔ Á¤º¸ÀÎÁö¸¦ ÀǹÌÇÑ´Ù. ÀÌ tagµéÀº ¹Ì¸® Á¤ÇØÁ® ÀÖ´Ù.
45                length´Â ±× µÚ dataÀÇ byte-lengthÀÌ´Ù.
46                data´Â tag¿¡ ÇØ´çµÇ´Â raw µ¥ÀÌÅÍÀÌ´Ù. extended channel nameÀÇ °æ¿ì MSS Çü½ÄÀÌ´Ù.
47
48        CSD µ¥ÀÌÅͰ¡ NVM¿¡ ÀúÀå µÉ ¶§¿¡´Â
49        DMW_CDB_FlattenCsd() API¸¦ ÀÌ¿ëÇÏ¿© flatten µÈ ÈÄ¿¡ º°µµÀÇ DB¿¡ ÀúÀåµÈ´Ù.
50
51
52
53
54
55//===========================================================================
56
57        CSDÀÇ NvRam ÀúÀå ±¸Á¶..
58       
59       
60        CSD format: 
61       
62                ver 1.0 : 2004/11/26,  first design
63
64
65    +=================================+
66    | Header (16 bytes)               |
67    |    magic key :  2 bytes         |  offset 0
68    |    n_record  :  2 bytes         |  offset 2
69    |    byte size :  4 bytes         |  offset 4
70    |    crc       :  4 bytes         |  offset 8
71    |    dummy     :  4 bytes         |  offset 12
72    +=================================+---------------
73    | Identifier (4 bytes)            |
74    |    start     :  1 bytes         | (0x5m, m is continuity counter from 0x0 ~ 0xF)
75    |    RF        :  1 bytes         |
76    |    source_id :  2 bytes         |
77    +---------------------------------+ <--- Flat CSD Start
78    | num_csd      :  1 bytes         |   ÇϳªÀÇ UCM µ¥ÀÌÅÍ¿¡ º¹¼ö°³ÀÇ csd record entry °¡ Á¸Àç
79    +----+----------------------------+
80    |    |(0) tag       :  1 bytes    |   (if unrecognized tag found, just skip the tag)
81    |    |    size      :  1 bytes    |   (not including tag, size itself.  only data size)
82    |    |    data      :  n bytes    |   (no limit. typically ~40 bytes..)
83    |    +----------------------------+
84    |    |(1) tag       :  1 bytes    |
85    |    |    size      :  1 bytes    |
86    |    |    data      :  n bytes    |
87    |    +----------------------------+
88    |    |(2)                         |
89    |    +----------------------------+
90    |    |    ...                     |
91    |    +----------------------------+
92    |    |(num_csd - 1)               |
93    +====+============================+---------------
94    | Identifier (4 bytes)            |
95    |    start     :  1 bytes         | (0x5m+1)
96    |    RF        :  1 bytes         |
97    |    source_id :  2 bytes         |
98    +---------------------------------+
99    |    ...                          |
100    |                                 |
101    +---------------------------------+
102
103
104        ÀÌ CSD ±¸Á¶ÀÇ ¹öÀüÀ» ³ªÅ¸³»´Â Á¤º¸´Â µû·Î ÀúÀå °ü¸®ÇÏÁö ¾Ê´Â´Ù.
105        ¾îÂ¥ÇÇ CSD °¡ UCM¿¡ Á¾¼ÓµÈ ±¸Á¶À̱⠶§¹®¿¡ UCM ÀÇ ¹öÀü¿¡ Æ÷ÇÔ½ÃÄѼ­ °ü¸®ÇÑ´Ù.
106       
107        ÀÌ ±¸Á¶°¡ Á¶±ÝÀÌ¶óµµ º¯°æµÉ °æ¿ì¿¡´Â ChannelDB ÀÇ ¾Æ·¡ ¹öÀüÀ» º¯°æ½ÃÄÑ¾ß ÇÑ´Ù.
108       
109                gUcmStoringVersion
110               
111 
112
113*/
114
115
116
117//===========================================================================
118//
119//      Configuration parameters
120//
121//   °¢Á¾ ¿É¼Ç ±â´ÉÀÇ On/Off ¼³Á¤, ÄÄÆÄÀÏ·¯ ¿É¼Ç ¼³Á¤,
122//   µå¶óÀ̹ö °ü·Ã ȯ°æ ¼³Á¤ µî..
123//
124
125
126#define  USE_DMW_EPGX_LIB  0
127        //
128        // Dmc_ConvertMss2Ks, Dmc_ConvertKs2Mss, Dmc_PrintMultipleString
129        //
130        // À§ SymbolÀº EPGX ¿¡¼­ Á¦°øµÇ´Â °ÍµéÀ̱⠶§¹®¿¡
131        // EPGX ¸¦ »ç¿ëÇÏÁö ¾Ê°í ÀÖ´Ù¸é ¸·¾Æ¾ß ÇÑ´Ù.
132       
133
134#define  USE_DMW_SCTESI_LIB  0
135        //
136        // Dmc_ConvertMts2Ks, Dmc_ConvertMts2Uc
137        //
138        // À§ SymbolÀº SCTESI ¿¡¼­ Á¦°øµÇ´Â °ÍµéÀ̱⠶§¹®¿¡
139        // SCTESI ¸¦ »ç¿ëÇϰí ÀÖÁö ¾Ê´Ù¸é ¸·¾Æ¾ß ÇÑ´Ù.
140       
141
142#if USE_DMW_EPGX_LIB
143        #include "DMW_EpgBase.h"
144#endif
145
146#if USE_DMW_SCTESI_LIB
147        #include "DMW_SiParser.h"
148        #include "DMW_ScteSiScan.h"
149#endif
150
151
152
153
154
155
156#define CSD_INCREASE_STEP 4
157        //
158        // CSD record ¿¡´Â º¹¼ö°³ÀÇ tag Á¤º¸¸¦ µî·ÏÇÒ ¼ö ÀÖÀ¸¸ç, »õ·Î¿î tag¸¦ µî·ÏÇÒ ¶§
159        // csd record ¸Þ¸ð¸®°¡ ºÎÁ·ÇÒ °æ¿ì È®ÀåÀ» ÇÑ´Ù. À̶§ Áõ°¡µÇ´Â ´ÜÀ§ÀÓ.
160        // Åë»óÀûÀ¸·Î ÇÑ UCM entry ¿¡ ´ë·« 4°³ ¹Ì¸¸ÀÇ tag°¡ »ç¿ëµÇ°í ÀÖ´Ù.
161       
162
163BOOL g_TestCsdMultipleTagAllowed = 0;
164        //
165        // test flag
166        // TRUE À̸é ÇÑ csd record¿¡ ¿©·¯°³ÀÇ µ¿ÀÏÇÑ tag°¡ µî·ÏµÉ ¼ö ÀÖµµ·Ï Çã¿ëÇÑ´Ù.
167        // ÀÌ´Â Á¤»óÀûÀÎ »ç¿ëÀº ¾Æ´ÏÁö¸¸, tagÀÇ °¹¼ö°¡ ¸¹¾ÆÁú °æ¿ì¿¡ ´ëÇÑ Å×½ºÆ® ¿ëµµ·Î »ç¿ëµÈ´Ù.
168        //
169        // cafrii 041201, change name to remove ambiguity
170        // g_bMultipleTagAllowed --> g_TestCsdMultipleTagAllowed
171
172
173
174
175//===========================================================================
176//
177//       Constants, Variables, Function declarations
178//
179
180
181
182#if COMMENT
183       
184        //---------------------
185        //   CSS DB pointer
186        //
187       
188        CSS_DB_T *g_CSS;         // CSS (Channel Specific Storage) DB pointer
189        INT32     g_CSS_number;  // number of DB element stored in RAM, not NvRam!!!
190        INT32     g_CSS_max;     // max number of DB (unit: element)
191       
192       
193        // CSS DB ´Â CSS_DB_T elementÀÇ 1Â÷¿ø array ±¸Á¶·Î µÇ¾î ÀÖ´Ù.
194        //
195        // CSS DB ´Â rf, source_id ¼ø¼­·Î ¿À¸§Â÷¼ø Á¤·ÄµÇ¾î ÀÖ´Ù.
196        //
197        // CSS element ³»ÀÇ csd µéÀº tag ÀÇ °ª°ú »ó°üÀÌ À§Ä¡ÇØ ÀÖÀ½. Áï Á¤·ÄÀÌ µÇ¾î ÀÖÁö ¾ÊÀ½.
198       
199
200#endif // 0
201
202
203
204//===========================================================================
205//
206//       Implementations
207//
208
209
210
211
212//----------------------------------------------------------------------------
213
214
215
216
217const char *CsdTagString(int tag)
218{
219        return 
220                tag == CSD_TAG_SHORT_NAME ? "ShortName" :
221                tag == CSD_TAG_EXTENDED_NAME ? "ExtendedName" :
222                tag == CSD_TAG_EXTENDED_TEXT ? "ExtendedText" :
223                tag == CSD_TAG_SI_SOURCE_NAME ? "SiSourceName" :
224                       
225                // cafrii 041221 add
226                tag == CSD_TAG_XDS_CALL_LETTER ? "XdsCallLetter" :
227                tag == CSD_TAG_XDS_NETWORK_NAME ? "XdsNetworkName" :
228                       
229                tag == CSD_TAG_USER_CHANNEL_NAME ? "UserChannelName" : "??";
230}
231
232
233
234
235#if COMMENT
236____API______(){}
237#endif
238
239
240//------------------------------------------------------------------------------
241
242
243
244
245/*--------------------------------------
246        DMW_CDB_PrintCsd
247
248        ÁÖ¾îÁø CSDÀÇ ³»¿ëÀ» È­¸é¿¡ Ãâ·ÂÇÑ´Ù.
249        num_csd °¹¼ö ¸¸Å­À» Ãâ·ÂÇÑ´Ù. num_csd Á¤º¸ ¿ª½Ã UCM ¾È¿¡ ÀÖ´Ù.
250
251        DMW_CDB_PrintOneUcm ¿¡¼­ ³»ºÎÀûÀ¸·Î »ç¿ëµÈ´Ù.
252*/
253void DMW_CDB_PrintCsd(ChannelSpecificData *csd, int num_csd, int indent, int detailLevel)
254{
255        int i;
256        char indent_buf[33];
257        char buf[80];
258        UINT8 *ks;
259       
260        if (indent > 32) indent = 32;
261       
262        for (i=0; i<indent; i++)
263                indent_buf[i] = ' ';
264        indent_buf[i] = 0;
265
266        if (detailLevel == 1)  // simplest..  one line per csd entry, multiple tags..
267        {
268                DHL_OS_Printf("%s",
269                        indent_buf, i, csd[i].tag, CsdTagString(csd[i].tag), csd[i].byte_len);
270
271                for (i=0; csd && i<num_csd; i++) {
272                       
273                        if (csd[i].tag == 0) continue;
274                       
275                        if (csd[i].tag == CSD_TAG_SHORT_NAME) {
276                                // csd data is 16-bit unicode format
277                                ks = DMW_ConvUc2Ks((UINT16 *)csd[i].ptr, -1);
278                                strncpy(buf, ks ? (char*)ks : "!! Error in convertion to KS", 80);
279                                buf[79] = 0;
280                                DMW_FreeKsString(ks);
281
282                                DHL_OS_Printf("H:'%s' ", buf);  // Short Name
283                        }
284                        else if (csd[i].tag == CSD_TAG_EXTENDED_NAME_UC) {
285                                // csd data is 16-bit unicode format
286                                ks = DMW_ConvUc2Ks((UINT16 *)csd[i].ptr, -1);
287                                strncpy(buf, ks ? (char*)ks : "!! Error in convertion to KS", 80);
288                                buf[79] = 0;
289                                DMW_FreeKsString(ks);
290
291                                DHL_OS_Printf("U:'%s' ", buf);  // Long Name Unicode
292                        }
293#if USE_DMW_EPGX_LIB                   
294                        else if (csd[i].tag == CSD_TAG_EXTENDED_NAME) {
295                                // MSS ±¸Á¶
296                                Dmc_ConvertMss2Ks(csd[i].ptr, csd[i].byte_len, buf, 80, NULL, 0); // ù¹øÂ° instance..
297
298                                DHL_OS_Printf("L:'%s' ", buf);  // Long Name
299                        }
300                        else if (csd[i].tag == CSD_TAG_EXTENDED_TEXT) {
301                                // MSS ±¸Á¶
302                                Dmc_ConvertMss2Ks(csd[i].ptr, csd[i].byte_len, buf, 80, 0); // ù¹øÂ° instance..
303
304                                DHL_OS_Printf("X:'%s' ", buf);  // Extended Text
305                        }
306#endif
307
308#if USE_DMW_SCTESI_LIB
309                        else if (csd[i].tag == CSD_TAG_SI_SOURCE_NAME) {
310                                // MTS ±¸Á¶
311                                Dmc_ConvertMts2Ks(csd[i].ptr, csd[i].byte_len, buf, 80, NULL);
312
313                                DHL_OS_Printf("S:'%s' ", buf);  // Source Name
314                        }
315#endif
316
317                        else if (csd[i].tag == CSD_TAG_XDS_CALL_LETTER) {
318                                // ASCIIZ ±¸Á¶
319                                DHL_OS_Printf("C:'%s' ", csd[i].ptr);
320                        }
321                        else if (csd[i].tag == CSD_TAG_XDS_NETWORK_NAME) {
322                                // ASCIIZ ±¸Á¶
323                                DHL_OS_Printf("N:'%s' ", csd[i].ptr);
324                        }
325                        else if (csd[i].tag == CSD_TAG_USER_CHANNEL_NAME) {
326                                strncpy(buf, (char *)csd[i].ptr, 80);
327                                buf[79] = 0;
328                               
329                                DHL_OS_Printf("U:'%s' ", buf);  // User Name
330                        }
331                }
332                DHL_OS_Printf("\n");
333                return;
334        }
335       
336        for (i=0; csd && i<num_csd; i++) 
337        {
338                if (csd[i].tag == 0) {
339                        DHL_OS_Printf("     !!!! csd[%d]: zero tag\n", i, csd[i].tag);
340                        continue;
341                }
342               
343                if (detailLevel == 2)  // one line per csd entry
344                {
345                        //OS_DbgPrintf("      ---- csd[%d]: tag 0x%x, ptr 0x%x, sz %d..\n",
346                        //                      i, csd[i].tag, csd[i].ptr, csd[i].byte_len);
347                       
348                        // ÇöÀç Àß ¾Ë·ÁÁ® ÀÖ´Â ¸î°¡Áö TAG ¿¡ ´ëÇØ¼­´Â Äֿܼ¡ Ãâ·ÂÀ» ÇØÁØ´Ù.
349                        //
350                        if (csd[i].tag == CSD_TAG_SHORT_NAME) {
351                                // csd data is 16-bit unicode format
352                                UINT8 *ks;
353                                ks = DMW_ConvUc2Ks((UINT16 *)csd[i].ptr, -1);
354                                strncpy(buf, ks ? (char*)ks : "!! Error in convertion to KS", 80);
355                                buf[79] = 0;
356                                DMW_FreeKsString(ks);
357                        }
358#if USE_DMW_EPGX_LIB
359                        else if (csd[i].tag == CSD_TAG_EXTENDED_NAME || csd[i].tag == CSD_TAG_EXTENDED_TEXT) {
360                                // MSS ±¸Á¶
361                                Dmc_ConvertMss2Ks(csd[i].ptr, csd[i].byte_len, buf, 80, 0); // ù¹øÂ° instance..
362                        }
363#endif
364
365#if USE_DMW_SCTESI_LIB
366                        else if (csd[i].tag == CSD_TAG_SI_SOURCE_NAME) {
367                                // MTS ±¸Á¶
368                                Dmc_ConvertMts2Ks(csd[i].ptr, csd[i].byte_len, buf, 80, NULL);
369                        }
370#endif
371
372                        else if (csd[i].tag == CSD_TAG_USER_CHANNEL_NAME) {
373                                strncpy(buf, (char *)csd[i].ptr, 80);
374                                buf[79] = 0;
375                        }
376                        else if (csd[i].tag == CSD_TAG_XDS_CALL_LETTER || csd[i].tag == CSD_TAG_XDS_NETWORK_NAME) {
377                                strncpy(buf, (char *)csd[i].ptr, 32);
378                                buf[32] = 0;
379                        }
380                        buf[79] = 0;
381                       
382                        DHL_OS_Printf("%s(%d) tag 0x%x (%s) sz %d, '%s'\n",
383                                indent_buf, i, csd[i].tag, CsdTagString(csd[i].tag), csd[i].byte_len, buf);
384                        continue;
385                }
386               
387                DHL_OS_Printf("%s(%d) tag 0x%x (%s), sz %d, ptr 0x%x\n",
388                                indent_buf, i, csd[i].tag, CsdTagString(csd[i].tag), csd[i].byte_len, csd[i].ptr);
389               
390                if (csd[i].tag == CSD_TAG_SHORT_NAME) {
391                        // csd data is 16-bit unicode format
392                       
393                        UINT8 *ks = DMW_ConvUc2Ks((UINT16 *)csd[i].ptr, -1);
394                        DHL_OS_Printf("%s  '%s'\n", indent_buf, 
395                                                        ks ? (char*)ks : "!! Error in convertion to KS");
396                        DMW_FreeKsString(ks);
397
398                }
399       
400#if USE_DMW_EPGX_LIB
401                else if (csd[i].tag == CSD_TAG_EXTENDED_NAME || csd[i].tag == CSD_TAG_EXTENDED_TEXT) {
402                        // MSS ±¸Á¶
403                        Dmc_PrintMultipleString(csd[i].ptr, csd[i].byte_len, indent+2, 0);
404                }
405#endif
406               
407#if USE_DMW_SCTESI_LIB
408                else if (csd[i].tag == CSD_TAG_SI_SOURCE_NAME) {
409                        // MTS ±¸Á¶
410                        Dmc_ConvertMts2Ks(csd[i].ptr, csd[i].byte_len, buf, 80, NULL);
411                        DHL_OS_Printf("%s  '%s'\n", indent_buf, buf);
412                }
413#endif
414                else if (csd[i].tag == CSD_TAG_USER_CHANNEL_NAME) {
415                        DHL_OS_Printf("%s  '%s'\n", indent_buf, csd[i].ptr);
416                }
417        }
418}
419
420
421/*--------------------------------------
422        DMW_CDB_DeleteCsd
423
424        ÁöÁ¤ÇÑ csd ¸¦ »èÁ¦ÇÑ´Ù. ¿¬°áµÇ¾î ÀÖ´Â ¸ðµç tagÀÇ csdµéÀ» ´Ù »èÁ¦.
425*/
426STATUS DMW_CDB_DeleteCsd(ChannelSpecificData *csd, int num_csd)
427{
428        int i;
429       
430        if (csd == NULL) {
431                return statusOK;
432        }
433       
434        for (i=0; i<num_csd; i++) {
435                DHL_OS_Free((void**)&csd[i].ptr);
436        }
437        DHL_OS_Free((void**)&csd);
438       
439        return statusOK;
440}
441
442
443/*-------------------------------------
444        DMW_CDB_DeleteUcmCsd
445
446        ÇØ´ç indexÀÇ ucm entry¿¡ ¿¬°áµÈ csd¸¦ Á¦°ÅÇÑ´Ù.
447*/
448void DMW_CDB_DeleteUcmCsd(int idx)
449{
450        int i;
451
452        if (idx < 0 || idx >= g_UCM_number)
453                return;
454       
455        //if (g_UCM[idx].max_csd == 0)
456       
457        if (g_UCM[idx].csd == NULL) {
458                g_UCM[idx].num_csd = g_UCM[idx].max_csd = 0;
459                return;
460        }
461       
462        dprint(2, "delete CSD of UCM[%d], 0x%x, %d csds\n", idx, g_UCM[idx].csd, g_UCM[idx].num_csd);
463       
464        for (i=0; i<g_UCM[idx].num_csd; i++) {
465                DHL_OS_Free((void**)&g_UCM[idx].csd[i].ptr);
466        }
467        DHL_OS_Free((void**)&g_UCM[idx].csd);
468       
469        g_UCM[idx].num_csd = g_UCM[idx].max_csd = 0;
470       
471}
472
473
474/*--------------------------------------
475        DMW_CDB_DeleteAllUcmCsd
476
477        ¸ðµç CSD¸¦ Á¦°ÅÇÑ´Ù.
478*/
479void DMW_CDB_DeleteAllUcmCsd(void)
480{
481        int i, n_deleted = 0;
482       
483        DMW_MSC_LockUcm();
484       
485        for (i=0; i<g_UCM_number; i++) {
486       
487                if (g_UCM[i].csd) {
488                       
489                        if (g_UCM[i].num_csd > g_UCM[i].max_csd)
490                                dprint(0, "!! ucm[%d] num csd %d > max csd %d\n", g_UCM[i].num_csd, g_UCM[i].max_csd);
491                       
492                        DMW_CDB_DeleteCsd(g_UCM[i].csd, g_UCM[i].num_csd);
493                        g_UCM[i].csd = NULL;
494                        g_UCM[i].num_csd = g_UCM[i].max_csd = 0;
495                       
496                        n_deleted++;
497                }
498                else if (g_UCM[i].num_csd || g_UCM[i].max_csd) {
499                        dprint(0, "!! ucm[%d] num/max csd wrong\n", i);
500                        g_UCM[i].num_csd = g_UCM[i].max_csd = 0;
501                }
502        }
503
504        dprint(2, "  total %d csd / %d ucm deleted\n", n_deleted, g_UCM_number);
505       
506        DMW_MSC_UnlockUcm();
507       
508}
509
510
511/*--------------------------------------
512        DMW_CDB_DeleteCsdEntry
513
514        csd list¿¡¼­ ÁöÁ¤ÇÑ tagÀÇ csd entry ¸¸À» »èÁ¦ÇÑ´Ù. ¿©·¯°³°¡ ¹ß°ßµÇ¸é ¸ðµÎ »èÁ¦ÇÑ´Ù.
515        »èÁ¦ ÈÄ¿¡ csd ÃÖÁ¾ °¹¼ö¸¦ ¸®ÅÏÇÑ´Ù.
516*/
517int DMW_CDB_DeleteCsdEntry(ChannelSpecificData *csd, int num_csd, int tag)
518{
519        int i, k;
520       
521        for (i=num_csd-1; i>=0; i--) {
522               
523                if (csd[i].tag == tag) {
524                       
525                        DHL_OS_Free((void**)&csd[i].ptr);
526                       
527                        for (k=i+1; k<num_csd; k++) {
528                                csd[k-1] = csd[k];    // Áö¿öÁø µÚÀÇ ºó °ø°£À» ¸Þ²Û´Ù. µÚ¿¡¼­ Çϳª¾¿ ¾ÕÀ¸·Î..
529                        }
530                        num_csd--;
531                }
532        }
533       
534        return num_csd;
535}
536
537
538
539
540
541/*--------------------------------------
542        DMW_CDB_GetCsdPtr
543*/
544STATUS DMW_CDB_GetCsdPtr(ChannelSpecificData *csd, int num_csd, int tag, int *pLen, UINT8 **pPtr)
545{
546        // ƯÁ¤ tag¸¦ °¡Áø CSD Á¤º¸¸¦ ÃßÃâÇÑ´Ù.
547        // ¿øº» pointer¸¦ ±×´ë·Î ¸®ÅÏÇϱ⠶§¹®¿¡
548        // ¹Ýµå½Ã lock ÀÌ °É¸° »óÅ¿¡¼­ È£ÃâÇÏ°í »ç¿ëÈÄ¿¡ release ¸¦ ÇØ¾ß ÇÑ´Ù.
549
550        int i;
551       
552        if (csd == NULL || pLen == NULL || pPtr == NULL) 
553                return statusInvalidArgument;
554       
555        for (i=0; i<num_csd; i++) {
556               
557                if (csd[i].tag == tag) {
558                       
559                        *pLen = csd[i].byte_len;
560                        *pPtr = csd[i].ptr;
561                       
562                        return statusOK;
563                }
564        }
565       
566        *pLen = 0;
567        *pPtr = NULL;
568       
569        return statusNotFound;
570}
571
572
573
574//--------------------------------------
575//   DMW_CDB_GetCsdCopy
576//
577//
578//
579STATUS DMW_CDB_GetCsdCopy(ChannelSpecificData *csd, int num_csd, int tag, int *pLen, UINT8 **pPtr)
580{
581        // ÇØ´ç tag ÀÇ csd ¸¦ ã¾Æ¼­ ±× »çº»À» ¸®ÅÏÇÑ´Ù.
582        // ¿øº»°ú´Â ´Ù¸£±â ¶§¹®¿¡ caller´Â º°µµÀÇ lock ÀýÂ÷°¡ ÇÊ¿ä ¾øÀ¸¸ç,
583        // ´ë½Å »ç¿ë ÈÄ¿¡ pPtrÀ» free ½ÃÄѾ߸¸ ÇÑ´Ù.
584        //
585
586        int i;
587       
588        if (csd == NULL || pLen == NULL || pPtr == NULL) 
589                return statusInvalidArgument;
590       
591        for (i=0; i<num_csd; i++) {
592               
593                if (csd[i].tag == tag) {
594                       
595                        *pLen = csd[i].byte_len;
596                        *pPtr = DHL_OS_Malloc(*pLen);
597                       
598                        if (*pPtr == NULL) {
599                                *pLen = 0;
600                                return statusOutOfMemory;
601                        }
602                               
603                        memcpy(*pPtr, csd[i].ptr, *pLen);
604                       
605                        return statusOK;
606                }
607        }
608       
609        if (pLen) *pLen = 0;
610        if (pPtr) *pPtr = NULL;
611       
612        return statusNotFound;
613}
614
615
616
617
618/*--------------------------------------
619        DMW_CDB_DuplicateCsd
620
621        ÁÖ¾îÁø csd ¿Í ¿ÏÀüÈ÷ µ¿ÀÏÇÑ csd ·Î º¹»ç¸¦ ÇÑ´Ù.
622        csd °¹¼ö, csd array Å©±â µîÀº µ¿ÀÏÇÑ °ªÀÌ µÉ °ÍÀ̹ǷΠ»õ csd pointer¸¸ ¸®ÅÏÇÑ´Ù.
623        ¿¡·¯°¡ ¹ß»ýÇϸé NULLÀ» ¸®ÅÏÇÑ´Ù.
624*/
625ChannelSpecificData *DMW_CDB_DuplicateCsd(ChannelSpecificData *csd, int num_csd, int max_csd)
626{
627        int i;
628        ChannelSpecificData *csd2;
629
630        dprint(2, "DuplicateCsd: %d/%d\n", num_csd, max_csd);
631       
632        if (num_csd > max_csd) {
633                dprint(0, "!! DuplicateCsd: num csd %d > max csd %d\n", num_csd, max_csd);
634                num_csd = max_csd;
635        }
636       
637        csd2 = DHL_OS_Malloc(max_csd * sizeof(ChannelSpecificData));
638       
639        if (csd2 == NULL) {
640                dprint(0, "!! DuplicateCsd: out of memory for new csd array\n");
641                return NULL;
642        }
643       
644        for (i=0; i<num_csd; i++)
645        {
646                dprint(3, "    dup csd[%d] tag 0x%x, len %d\n", i, csd[i].tag, csd[i].byte_len);
647                csd2[i].tag = csd[i].tag;
648                csd2[i].byte_len = csd[i].byte_len;
649               
650                csd2[i].ptr = DHL_OS_Malloc(csd[i].byte_len);
651               
652                if (csd2[i].ptr == NULL) {
653                        dprint(0, "!! DuplicateCsd: out of memory for csd[%d] tag 0x%x..\n", i, csd[i].tag);
654                        goto label_err_exit;
655                }
656               
657                memcpy(csd2[i].ptr, csd[i].ptr, csd[i].byte_len);
658        }
659       
660        return csd2;
661
662label_err_exit:
663
664        for (i=0; i<num_csd; i++) {
665                if (csd2[i].ptr)
666                        DHL_OS_Free((void**)&csd2[i].ptr);
667        }
668        DHL_OS_Free((void**)&csd2);
669       
670        return NULL;   
671}
672
673
674
675/*--------------------------------------
676        DMW_CDB_UpdateCsd
677
678        src csd ¸¦ dst csd ·Î update ÇÑ´Ù.
679        dst csd ´Â Çʿ信 µû¶ó È®Àå, replace°¡ µÉ ¼ö ÀÖ´Ù.
680
681        ÀÌ ÇÔ¼ö´Â autoscanÀÇ ¸Ç ¸¶Áö¸· ´Ü°è¿¡¼­
682        ÇØ´ç ä³ÎÀÇ Àüü csd list¸¦ ¸ðµÎ ÇѲ¨¹ø¿¡ updateÇÏ´Â ¿ëµµ·Î »ç¿ëµÈ´Ù.
683*/
684STATUS DMW_CDB_UpdateCsd(ChannelSpecificData **pdst, int *pdst_num, int *pdst_max,
685                                                ChannelSpecificData *src, int src_num)
686{
687       
688        // cafrii 041201 change method..
689        //
690        // Update µµÁß¿¡ ¿¡·¯°¡ ¹ß»ýÇÒ °æ¿ì ÀÌ¹Ì Update µÈ tag´Â ±×´ë·Î µÎ°í ¸®ÅÏÇÏ´Â ÄÚµå.
691        // ¸Þ¸ð¸® º¹»ç °úÁ¤ÀÌ ´õ °£´ÜÇϹǷΠÁ» ´õ È¿À²ÀûÀ¸·Î µ¿ÀÛÇÑ´Ù.
692
693        int i, err;
694        BOOL bChanged = FALSE;
695       
696        for (i=0; i<src_num; i++) {
697               
698                err = DMW_CDB_UpdateCsdEntry(pdst, pdst_num, pdst_max, 
699                                        src[i].tag, src[i].byte_len, src[i].ptr);
700               
701                if (err == statusOK) {
702                        bChanged = TRUE;
703                }
704                else if (err == statusNotChanged) {
705                        // ÀúÀåµÈ ³»¿ëÀÌ µ¿ÀÏÇÏ¿© º¯°æ»çÇ×ÀÌ ¾ø´Â °æ¿ì..
706                }
707                else {
708                        return (STATUS)err;
709                }
710        }
711
712        // Çϳª¶óµµ º¯°æµÈ °ÍÀÌ ÀÖÀ¸¸é OK¸¦ ¸®ÅÏÇÑ´Ù.
713        //
714        return  bChanged ? statusOK : statusNotChanged;
715
716}
717
718
719
720/*--------------------------------------
721        DMW_CDB_UpdateCsdEntry
722
723        ÁÖÀÇ:  º¯°æ »çÇ×ÀÌ ¾øÀ» °æ¿ì 'statusNotChanged' °ªÀÌ ¸®ÅϵȴÙ.
724               ÀϹÝÀûÀÎ »ó½ÄÀ¸·Î´Â ÀÌ °æ¿ì´Â ¿¡·¯¶ó°í º¼¼ö´Â ¾ø´Ù.
725               ´ÜÁö Á¤º¸¸¦ ¸®ÅÏÇϱâ À§ÇØ »ç¿ëÇÏ´Â °ªÀÌ´Ù.
726*/
727STATUS DMW_CDB_UpdateCsdEntry(ChannelSpecificData **pdst, int *pdst_num, int *pdst_max,
728                                                int tag, int len, UINT8 *ptr)
729{
730        int k, idx;
731        int err = DHL_OK;
732        UINT8 *new_ptr;
733       
734        ChannelSpecificData *dst;
735        int dst_num, dst_max;
736       
737        if (pdst == NULL || pdst_num == NULL || pdst_max == NULL) {
738                return statusInvalidArgument;
739        }
740
741        dprint(1, "UpdateCsd: dst (%d/%d csd) <-- src tag 0x%x, len %d, ptr 0x%x\n", 
742                                                *pdst_num, *pdst_max, tag, len, ptr);
743       
744        if (len == 0 || ptr == NULL) {
745                dprint(0, "!! UpdateCsd: invalid src.. len %d, ptr %x\n", len, ptr);
746                return statusInvalidArgument;
747        }
748       
749        if (*pdst == NULL) {  // ¾ÆÁ÷ ÀüÇô csd°¡ ¾ø´Â °æ¿ì.. ¼Ò½º¸¦ º¹»çÇÏ¸é µÈ´Ù.
750               
751                ChannelSpecificData csd;
752               
753                csd.tag = tag;
754                csd.ptr = ptr;
755                csd.byte_len = len;
756               
757                dprint(2, "  new dst csd creating.. num/max: %d/%d\n", 1, CSD_INCREASE_STEP);
758               
759                *pdst = DMW_CDB_DuplicateCsd(&csd, 1, CSD_INCREASE_STEP);
760               
761                if (*pdst == NULL) {
762                        *pdst_max = *pdst_num = 0;
763                       
764                        err = statusOutOfMemory;
765                }
766                else {
767                        *pdst_num = 1;
768                        *pdst_max = CSD_INCREASE_STEP;
769                       
770                        err = statusOK;
771                }
772               
773                return (STATUS)err;
774        }
775
776        dst     = *pdst;
777        dst_num = *pdst_num;
778        dst_max = *pdst_max;
779
780        for (k=0; k<dst_num; k++) {
781                if (tag == dst[k].tag)
782                        break;
783        }
784       
785        if (g_TestCsdMultipleTagAllowed)  // Å×½ºÆ® ¸ðµå.. tag°¡ °°´õ¶óµµ Ç×»ó Ãß°¡¸¸ ÇÑ´Ù. ¸Þ¸ð¸® Å×½ºÆ®..
786                k = dst_num;
787       
788        if (k >= dst_num)  // ÀÏÄ¡ÇÏ´Â tag °¡ ¹ß°ßÀÌ µÇÁö ¾Ê´Â °æ¿ì.. »õ·Ó°Ô Ãß°¡ÇؾßÇÑ´Ù. ¸ÕÀú °ø°£È®º¸.
789        {
790                // check if space available
791                //
792                if (dst_max <= dst_num) // ³²¾Æ ÀÖ´Â ºó °ø°£ÀÌ ¾ø´Â °æ¿ì..
793                {
794                        ChannelSpecificData *tmp;
795
796                        dprint(2, "  no match, increasing dst_csd: num %d, max %d->%d\n", 
797                                                        dst_num, dst_max, dst_max + CSD_INCREASE_STEP);
798                        // Á¦´ë·Î µÇ¾ú´Ù¸é ¹Ýµå½Ã num == max ÀÏ °ÍÀÌ´Ù. ¾ÈÀüÀ» À§ÇØ ´Ù½Ã Çѹø È®ÀÎ.
799                        //
800                        dst_num = dst_max;
801                        tmp = DHL_OS_Malloc(sizeof(ChannelSpecificData) * dst_max + CSD_INCREASE_STEP);
802                       
803                        if (tmp == NULL) {
804                                dprint(0, "!! UpdateCsd: out of memory for dst extending\n");
805                               
806                                err = statusOutOfMemory;
807                                goto label_exit;
808                        }
809                        memcpy(tmp, dst, sizeof(ChannelSpecificData) * dst_max);
810                       
811                        DHL_OS_Free((void**)&dst);
812                        dst = tmp;
813                        dst_max += CSD_INCREASE_STEP;
814                }
815                else 
816                        dprint(2, "  no match, empty space found.. csd[%d]\n", dst_num);
817               
818                idx = dst_num;   // idx ÀÚ¸®¿¡ Ãß°¡ÇÏ¸é µÈ´Ù.
819        }
820        else { // ÀÏÄ¡ÇÏ´Â tag °¡ ¹ß°ßµÈ °æ¿ì.. ÀÌ °æ¿ì´Â overwrite update ÇÏ¸é µÈ´Ù.
821                   // ¸ÕÀú ±âÁ¸ µ¥ÀÌÅ͸¦ »èÁ¦ÇÑ´Ù.
822               
823                dprint(2, "  existing tag found.. csd[%d]\n", k);
824               
825                // cafrii 041127 add, compare if identical.. skip if same..
826                if (dst[k].byte_len == len &&
827                        memcmp(dst[k].ptr, ptr, len) == 0) {
828                               
829                        dprint(2, "  exactly same csd entry.. skip update..\n");
830                       
831                        //err = statusOK;
832                        err = statusNotChanged;  // cafrii 041201 add
833                        // À̰ÍÀ» ¿¡·¯¶ó°í ÇÒ¼ö´Â ¾øÁö¸¸ caller¿¡°Ô ÀÌ »ç½ÇÀ» ¾Ë·ÁÁÖ¸é ¿©·¯¸ð·Î ÁÁ´Ù.
834                        goto label_exit;
835                }
836                idx = k;
837        }
838       
839        // ÀÌÁ¦ idx ¹øÂ° csd ¿¡ source csd ¸¦ º¹»çÇÑ´Ù. dst.csd[idx]¿¡ ±âÁ¸ csd°¡ ÀÖÀ» ¼öµµ ÀÖ´Ù.
840        //
841        dprint(2, "  dst_csd[%d] <-- csd tag %d, len %d, update..\n", idx, tag, len);
842       
843       
844        new_ptr = DHL_OS_Malloc(len);
845       
846        if (new_ptr == NULL) {
847                dprint(0, "!! UpdateCsd: out of memory for dup src csd\n");
848
849                err = statusOutOfMemory;
850                goto label_exit;
851        }
852        // csd º¹»ç..
853        memcpy(new_ptr, ptr, len);
854       
855        if (dst[idx].ptr) {               // overwrite..
856
857                dprint(2, "  delete previous csd ptr.. 0x%x\n", dst[idx].ptr);
858                DHL_OS_Free((void**)&dst[idx].ptr);
859
860                dst[idx].ptr = new_ptr;
861                dst[idx].byte_len = len;
862                dst[idx].tag = tag;
863        }
864        else {                          // newly insert..
865                dst[idx].ptr = new_ptr;
866                dst[idx].byte_len = len;
867                dst[idx].tag = tag;
868
869                dst_num++;
870        }
871       
872        err = statusOK;
873       
874label_exit:
875
876        // ¸®Åϰª ±â·Ï..
877       
878        *pdst = dst;
879        *pdst_num = dst_num;
880        *pdst_max = dst_max;
881       
882        return (STATUS)err;
883
884}
885
886
887/*--------------------------------------
888        DMW_CDB_UpdateCsdExtendedText
889
890        ƯÁ¤ UCM¿¡ csd Á¤º¸¸¦ update ÇÑ´Ù.
891
892        useful for Epg-X module
893*/
894STATUS DMW_CDB_UpdateUcmCsdEntry(int rf, int source_id, int tag, int length, UINT8 *ptr)
895{
896        int idx;
897        int err = statusOK;
898       
899        if (length == 0 || ptr == NULL) 
900                return statusInvalidArgument;
901       
902        DMW_MSC_LockUcm();
903       
904        // rf / source_id ÀÇ UCM À» ¸ÕÀú ã´Â´Ù.
905        //
906        for (idx=0; idx<g_UCM_number; idx++) {
907       
908                if (g_UCM[idx].RF == rf && g_UCM[idx].source_id == source_id)
909                        break;
910        }
911
912        if (idx >= g_UCM_number) {
913                err = statusNotFound;   // ±×·± UCM ÀÌ ¾øÀ½.
914                goto label_end;
915        }
916       
917        err = DMW_CDB_UpdateCsdEntry(&g_UCM[idx].csd, &g_UCM[idx].num_csd, &g_UCM[idx].max_csd,
918                                                tag, length, ptr);
919
920        if (err) {  // out of memory... no change..
921               
922                // nothing to do.. just ignore new etm..
923        }       
924
925label_end:
926
927        DMW_MSC_UnlockUcm();
928       
929        return (STATUS)err;
930}
931
932
933/*
934        SCTE SIÀÇ Source NameÀ¸·ÎºÎÅÍ Short NameÀ» ¸¸µé¾î UCM¿¡ ÀúÀåÇÑ´Ù.
935
936        cafrii 041202 add
937*/
938void DMW_CDB_MakeUpShortNameFromSourceName(void)
939{
940       
941#if USE_DMW_SCTESI_LIB
942
943        // UcmÀÇ Source NameÀ» ShortNameÀ¸·Î º¯È¯ º¹»ç..ÇØÁØ´Ù..
944        //
945        //
946        int i, err;
947        int mts_len;
948        UINT8 *mts_ptr;
949       
950        UINT16 *p, short_name_buf[8];  // including NULL, 8 Unicode character required.
951
952        DMW_MSC_LockUcm();
953       
954        for (i=0; i<g_UCM_number; i++) 
955        {
956                if (g_UCM[i].csd == NULL || g_UCM[i].num_csd < 0) continue;
957                        // SNS Á¤º¸°¡ ¾ø´Â °æ¿ì..
958               
959                if (g_UCM[i].ShortName[0] != 0x0000) continue;
960                        // ÀÌ¹Ì ShortName¿¡ ¾î¶² Á¤º¸°¡ Á¸ÀçÇÏ´Â °æ¿ì..
961               
962                err = DMW_CDB_GetCsdPtr(g_UCM[i].csd, g_UCM[i].num_csd, 
963                                CSD_TAG_SI_SOURCE_NAME, &mts_len, &mts_ptr);
964                               
965                if (err) {   // SNS À̸§ÀÌ ¾øÀ½.
966                        continue;
967                }
968               
969                p = Dmc_ConvertMts2Uc(mts_ptr, mts_len, short_name_buf, 16, NULL);
970               
971                if (p == NULL) {  // º¯È¯¿¡ ½ÇÆÐ..
972                        continue;
973                }
974               
975                memcpy(g_UCM[i].ShortName, short_name_buf, 14);
976        }
977       
978        DMW_MSC_UnlockUcm();
979
980#endif // USE_DMW_SCTESI_LIB
981
982}
983
984
985
986
987#if COMMENT
988____NvRam_IO_API______(){}
989#endif
990
991
992// utility function
993
994/*
995
996STATIC UINT32 _m2d(UINT8 *p, int bytesize)  // memory to digit
997{
998        UINT32 result = 0;
999        int i;
1000
1001        if (bytesize > 4) bytesize = 4;
1002
1003        for (i=0; i<bytesize; i++)
1004                result = (result<<8) | p[i];
1005       
1006        return result;
1007}
1008
1009STATIC STATUS _d2m(UINT8 *p, int bytesize, UINT32 data)  // digit to memory
1010{
1011        int i;
1012
1013        if (bytesize > 4) bytesize = 4; // 'data' is only 4 byte-sized variable at maximum.
1014
1015        for (i=0; i<bytesize; i++) {
1016               
1017                p[bytesize-1-i] = (data & 0xff);  // fill BYTE from rear to front..
1018                data >>= 8;
1019        }
1020        return statusOK;       
1021}
1022
1023*/
1024
1025// Á¤¼ö¸¦ byte array·Î º¯È¯
1026//
1027#define UINT8_TO_PTR(num, ptr) ( \
1028                ((ptr)[0] = (((UINT8)(num)) & 0xff)) )
1029
1030#define UINT16_TO_PTR(num, ptr) ( \
1031                ((ptr)[0] = (((UINT16)(num)>>8) & 0xff)),  \
1032                ((ptr)[1] = (((UINT16)(num)   ) & 0xff)) )
1033
1034#define UINT32_TO_PTR(num, ptr) ( \
1035                ((ptr)[0] = (((UINT32)(num)>>24) & 0xff)),  \
1036                ((ptr)[1] = (((UINT32)(num)>>16) & 0xff)),  \
1037                ((ptr)[2] = (((UINT32)(num)>> 8) & 0xff)),  \
1038                ((ptr)[3] = (((UINT32)(num)    ) & 0xff)) )
1039
1040
1041
1042#define PTR_TO_UINT8(ptr) \
1043                ( ((ptr)[0]) )
1044
1045#define PTR_TO_UINT16(ptr) \
1046                ( ((ptr)[0] << 8U) | ((ptr)[1]) )
1047
1048#define PTR_TO_UINT32(ptr) \
1049                ( ((ptr)[0] << 24UL) | ((ptr)[1] << 16UL) | ((ptr)[2] << 8UL) | ((ptr)[3]) )
1050
1051
1052
1053/*
1054        CSD ÀúÀå ±¸Á¶¿¡ ´ëÇÑ ³»¿ëÀº ÀÌ ÆÄÀÏ ¸Ç ¾ÕºÎºÐÀ¸·Î À̵¿.
1055*/
1056
1057
1058
1059#define MAX_CSD_SIZE_PER_CHANNEL  100  // Bytes..
1060
1061// magic key.. values from "ZaPpa"
1062//
1063#define CSD_DB_MAGIC_KEY0  0x5A   // 'Z'
1064#define CSD_DB_MAGIC_KEY1  0x50   // 'P'
1065
1066#define CSD_HEADER_SIZE   16
1067
1068
1069int DMW_CDB_GetCsdFlatSize(ChannelSpecificData *csd, int num_csd)
1070{
1071        // °¢ csd ÀÇ header ¿µ¿ªÀº Á¦¿Ü..
1072        //
1073        int i, total_size = 0;
1074       
1075        if (csd == NULL) 
1076                return 0;
1077       
1078        total_size = 1;
1079        for (i=0; i<num_csd; i++) {
1080
1081                if (csd[i].ptr == NULL || csd[i].byte_len == 0)
1082                        continue;
1083               
1084                total_size += 2;  // tag, byte_len
1085                total_size += csd[i].byte_len;
1086        }
1087       
1088        return total_size;
1089}
1090
1091
1092//--------------------------------
1093//  DMW_CDB_FlattenCsd
1094//
1095//  ÁÖ¾îÁø csd µ¥ÀÌÅ͸¦ flatten ½ÃÄѼ­ ÁöÁ¤ ¹öÆÛ¿¡ ÀúÀåÇÑ´Ù.
1096// 
1097//  csd record entry´Â º¹¼ö°³ À̹ǷΠflatten º¯È¯ ÈÄÀÇ Å©±â¸¦ ¹Ì¸® ¾Ë ¼ö ¾øÀ¸¹Ç·Î
1098//  caller´Â ¹öÆÛ Å©±â¸¦ ÁöÁ¤ÇØ¾ß Çϴµ¥,
1099//  º¯È¯ Áß¿¡ ¹öÆÛ Å©±â¸¦ ³Ñ¾î¼­°Ô µÇ¸é  record ´ÜÀ§·Î truncate µÈ´Ù.
1100// 
1101//  ½ÇÁ¦·Î º¯È¯µÈ csd record ÀÇ °¹¼ö´Â ¹öÆÛÀÇ ¸Ç óÀ½ (flat csd ÀÇ offset 0) ¿¡ ÀúÀåµÈ´Ù.
1102//  ÃÖ´ë°ªÀº 255 (UINT8 type À̹ǷÎ)
1103//
1104//
1105int DMW_CDB_FlattenCsd(ChannelSpecificData *csd, int num_csd, UINT8 *buf, int buf_limit)
1106{
1107        int i;
1108        int total_size = 0;
1109        int num_real_csd = 0;  // ½ÇÁ¦ ÀúÀåµÈ csd entry °¹¼ö
1110       
1111        if (csd == NULL || buf == NULL) 
1112                return 0;
1113       
1114        if (buf_limit < 1) {
1115                dprint(0, "!! FlattenCsd: buf limit %d too small\n", buf_limit);
1116                return 0;
1117        }
1118       
1119        buf[total_size++] = 0;  // ÀÌ °ªÀº ³ªÁß¿¡ º¯°æµÈ´Ù.
1120       
1121        for (i=0; i<num_csd; i++) {
1122               
1123                if (csd[i].ptr == NULL || csd[i].byte_len == 0)
1124                        continue;
1125               
1126                if (total_size + 2 + csd[i].byte_len > buf_limit) {
1127                        dprint(0, "!! FlattenCsd: exceed buf limit %d\n", buf_limit);
1128                        break;
1129                }
1130               
1131                buf[total_size++] = csd[i].tag;
1132                buf[total_size++] = csd[i].byte_len;
1133               
1134                memcpy(&buf[total_size], csd[i].ptr, csd[i].byte_len);
1135                total_size += csd[i].byte_len;
1136               
1137                num_real_csd++;
1138        }
1139       
1140        buf[0] = (UINT8) num_real_csd;
1141       
1142        dprint(2, "    %d/%d csd flattened, record size %d\n", num_real_csd, num_csd, total_size);
1143       
1144        return total_size;
1145}
1146
1147//--------------------------------
1148//   DMW_CDB_InitCSD
1149//
1150//   NvRam CSD DB¸¦ ÃʱâÈ­ ÇÑ´Ù.
1151// 
1152//   DB address¸¦ array¿Í °¹¼ö·Î ¹Þ¾ÆµéÀ̹ǷΠ¿©·¯°³ÀÇ DB¸¦ ÃʱâÈ­ ÇÒ ¼ö ÀÖ´Ù.
1153//   ÁÖ·Î NvRam Format ½Ã¿¡ »ç¿ëµÈ´Ù.
1154//
1155//
1156STATUS DMW_CDB_InitCSD(UINT32 *pAddrList, int n_csd_db)
1157{
1158        int i, err;
1159        int n_record = 0, total_size = 0;
1160
1161        UINT32 address, crc = 0xFFFFFFFF;
1162       
1163        UINT8 tmp_buf[MAX_CSD_SIZE_PER_CHANNEL];
1164       
1165        if (pAddrList == NULL) return statusInvalidArgument;
1166       
1167        for (i=0; i<n_csd_db; i++)
1168        {
1169                address = pAddrList[i];
1170               
1171                memset(tmp_buf, 0, sizeof(tmp_buf));
1172       
1173                UINT8_TO_PTR  (CSD_DB_MAGIC_KEY0, tmp_buf+0);  // (0)
1174                UINT8_TO_PTR  (CSD_DB_MAGIC_KEY1, tmp_buf+1);  // (1)
1175                UINT16_TO_PTR (n_record,          tmp_buf+2);  // (2..3)
1176                UINT32_TO_PTR (total_size,        tmp_buf+4);  // (4..7)
1177                UINT32_TO_PTR (crc,               tmp_buf+8);  // (8..11)
1178               
1179                err = NvRamWrite(address, CSD_HEADER_SIZE, tmp_buf);
1180       
1181                if (err) {
1182                        dprint(0, "!! InitCsd: write header err %d\n", err);   
1183                        // ÀÏ´Ü ¿¡·¯°¡ ³ªµµ °è¼Ó ÁøÇàÇÏÀÚ..
1184                }
1185        }
1186
1187#if SUPPORT_DMW_FLASH_DB
1188
1189        // ´õÀÌ»ó Level2 API¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù.. DB ¿ëÀ¸·Î ÇÒ´çµÈ flash Àü ¿µ¿ªÀ» Àç±â·ÏÇÑ´Ù.
1190        // address 0x80000000 Àº ´ëÇ¥ Flash address ÀÌ´Ù. ÀÌ ÁÖ¼Ò°ªÀº device ¼±ÅÃÀ¸·Î¹Û¿¡ »ç¿ëµÇÁö ¾Ê´Â´Ù.
1191        err = NvRamSync(0x80000000, NULL);
1192       
1193        if (err) {
1194                dprint(0, "!! WriteCsd: err in NvRamSync()\n");
1195        }
1196
1197#endif // SUPPORT_DMW_FLASH_DB
1198       
1199        return (STATUS)err;
1200       
1201}
1202
1203
1204
1205//--------------------------------
1206//   DMW_CDB_WriteCSD
1207//
1208//   CSD ¸¦ NvRam CSD DB ¿¡ ±â·ÏÇÑ´Ù.
1209// 
1210//   CSD DBÀÇ ÃÑ ´©Àû ±â·Ï Å©±â°¡ max_size¸¦ ÃʰúÇÏÁö ¾Êµµ·Ï ÇÑ´Ù.
1211//   DBÀÇ Çì´õ ¿µ¿ªÀÇ Å©±â, Identifier ¿µ¿ªÀÇ Å©±â, °¢ CSD record entryÀÇ ¸ðµç Å©±âÀÇ ÇÕÀÌ
1212//   max_size¸¦ ³ÑÁö ¾Ê´Â´Ù.
1213//
1214//   ±â·Ï µµÁß DBÀÇ Å©±â°¡ max_size¸¦ ÃʰúÇÒ °æ¿ì UCM entry ´ÜÀ§·Î truncate µÈ´Ù.
1215//   
1216//   
1217//
1218STATUS DMW_CDB_WriteCSD(UINT32 db_start_address, int max_size)
1219{
1220        int idx, err = statusOK;
1221        int total_size;        // total byte size of csd data area (except header)
1222        int record_byte_size;  // byte size of csd record (csd entries belong to same channel)
1223        int n_record;          // number of csd records actually written to NvRam..
1224       
1225        UINT8 tmp_buf[MAX_CSD_SIZE_PER_CHANNEL];
1226        int continuity_counter = 0xF;
1227       
1228        UINT32 address;
1229        UINT32 crc;
1230       
1231        if (max_size < 16)
1232                return statusInvalidArgument;
1233       
1234       
1235        total_size = n_record = 0;
1236        crc = 0xFFFFFFFF;
1237       
1238        address = db_start_address + CSD_HEADER_SIZE;  // skip header part..
1239
1240
1241        // g_UCM ¿¡ Á÷Á¢ Á¢±ÙÀ» ÇØ¾ß ÇϹǷΠlockÀ» Çϰí ÁøÇàÇÑ´Ù.
1242        DMW_MSC_LockUcm(); //----------------------------
1243       
1244       
1245        for (idx=0; idx<g_UCM_number; idx++) 
1246        {
1247                if (g_UCM[idx].csd == NULL || g_UCM[idx].num_csd == 0) {
1248                        continue;
1249                }
1250
1251                //tmp_buf[0] = continuity_counter
1252                //tmp_buf[1] = g_UCM[idx].RF;
1253                //tmp_buf[2] = ((UINT16)g_UCM[idx].source_id >> 8) & 0xff;
1254                //tmp_buf[3] = ((UINT16)g_UCM[idx].source_id) & 0xff;
1255               
1256                // tmp_buf [0] Àº continuity counter..
1257               
1258                UINT8_TO_PTR (g_UCM[idx].RF,        tmp_buf+1);
1259                UINT16_TO_PTR(g_UCM[idx].source_id, tmp_buf+2);
1260               
1261               
1262                // 4 byte °¡ identifier ¿µ¿ªÀÇ Å©±â..
1263               
1264                record_byte_size = DMW_CDB_FlattenCsd(g_UCM[idx].csd, g_UCM[idx].num_csd, 
1265                                                tmp_buf + 4, MAX_CSD_SIZE_PER_CHANNEL - 4);
1266
1267                if (record_byte_size == 0) {
1268                        dprint(0, "!! flatten ucm[%d] csd err\n", idx);
1269                        continue;
1270                }
1271               
1272                continuity_counter = (continuity_counter + 1) % 0x10;
1273                tmp_buf[0] = 0x50 + continuity_counter;
1274               
1275                record_byte_size += 4;  // identifier part
1276               
1277                dprint(2, "  (%d) ucm[%d] cc %02x rf %d, source_id %d, %d/%d saved, %d bytes\n", 
1278                                        n_record, idx, tmp_buf[0],
1279                                        g_UCM[idx].RF, g_UCM[idx].source_id, 
1280                                        tmp_buf[4], g_UCM[idx].num_csd, record_byte_size);
1281
1282                if (address + record_byte_size  > db_start_address + max_size) {
1283                        dprint(0, "!! WriteCsd: exceed NvRam range at ucm[%d]\n", idx);
1284                        break;
1285                }
1286
1287                err = NvRamWrite(address, record_byte_size, tmp_buf);
1288                if (err) {
1289                        dprint(0, "!! WriteCsd: ucm[%d] NvRamWrite err %d\n", idx, err);
1290                        break;
1291                }
1292
1293                address += record_byte_size;
1294                crc = DMW_CDB_CalcCRC32(crc, tmp_buf, record_byte_size);
1295
1296                total_size += record_byte_size;
1297                n_record++;
1298        }
1299
1300        dprint(2, "  total %d csds / %d ucms saved, total size %d, crc 0x%08x\n", 
1301                                        n_record, g_UCM_number, total_size, crc);
1302
1303       
1304        memset(tmp_buf, 0, sizeof(tmp_buf));
1305
1306        UINT8_TO_PTR  (CSD_DB_MAGIC_KEY0, tmp_buf+0);  // (0)
1307        UINT8_TO_PTR  (CSD_DB_MAGIC_KEY1, tmp_buf+1);  // (1)
1308        UINT16_TO_PTR (n_record,          tmp_buf+2);  // (2..3)
1309        UINT32_TO_PTR (total_size,        tmp_buf+4);  // (4..7)
1310        UINT32_TO_PTR (crc,               tmp_buf+8);  // (8..11)
1311       
1312        err = NvRamWrite(db_start_address, CSD_HEADER_SIZE, tmp_buf);
1313
1314        if (err) {
1315                dprint(0, "!! WriteCsd: write header err %d\n", err);   
1316        }
1317
1318        DMW_MSC_UnlockUcm();  //------------------------------------
1319       
1320               
1321#if SUPPORT_DMW_FLASH_DB
1322
1323        // ´õÀÌ»ó Level2 API¸¦ »ç¿ëÇÏÁö ¾Ê´Â´Ù.. DB ¿ëÀ¸·Î ÇÒ´çµÈ flash Àü ¿µ¿ªÀ» Àç±â·ÏÇÑ´Ù.
1324        // address 0x80000000 Àº ´ëÇ¥ Flash address ÀÌ´Ù. ÀÌ ÁÖ¼Ò°ªÀº device ¼±ÅÃÀ¸·Î¹Û¿¡ »ç¿ëµÇÁö ¾Ê´Â´Ù.
1325        err = NvRamSync(0x80000000, NULL);
1326       
1327        if (err) {
1328                dprint(0, "!! WriteCsd: err in NvRamSync()\n");
1329        }
1330
1331#endif // SUPPORT_DMW_FLASH_DB
1332       
1333        return (STATUS)err;
1334}
1335
1336
1337
1338
1339
1340//--------------------------------
1341//   DMW_CDB_WriteCSD
1342//
1343//   CSD ¸¦ NvRam CSD DB ¿¡ ±â·ÏÇÑ´Ù.
1344// 
1345//   todo..  max_size¸¦ °í·ÁÇØ¼­ ÀÛ¼ºÇØ¾ß ÇÔ..
1346//
1347//
1348STATUS DMW_CDB_ReadCSD(UINT32 db_start_address, int max_size)
1349{
1350        int i, k, err = statusOK;
1351       
1352        unsigned int max_csd_data_size;
1353        int n_record;          // number of csd records actually written to NvRam..
1354       
1355        UINT8 tmp_buf[MAX_CSD_SIZE_PER_CHANNEL];
1356        int continuity_counter;
1357       
1358        UINT32 address;
1359        UINT32 crc, crc_org;
1360       
1361        int rf, source_id, num_csd;
1362        int csd_tag, csd_byte_size;
1363
1364        dprint(1, "ReadCsd: addr 0x%x, max_size 0x%x\n", db_start_address, max_size);
1365               
1366
1367        err = NvRamRead(db_start_address, CSD_HEADER_SIZE, tmp_buf);
1368       
1369        if (err) {
1370                dprint(0, "!! err\n");
1371                return (STATUS)err;
1372        }
1373       
1374        if (tmp_buf[0] != CSD_DB_MAGIC_KEY0 || 
1375                tmp_buf[1] != CSD_DB_MAGIC_KEY1) {
1376                dprint(0, "!! magic key corrupt\n");
1377        }
1378
1379        n_record          = PTR_TO_UINT16 (tmp_buf + 2);  // (2..3)
1380        max_csd_data_size = PTR_TO_UINT32 (tmp_buf + 4);  // (4..7)
1381        crc_org           = PTR_TO_UINT32 (tmp_buf + 8);  // (8..11)
1382       
1383        dprint(2, "ReadCsd: %d record,  %d bytes, crc 0x%08x\n", n_record, max_csd_data_size, crc_org);
1384       
1385       
1386        if (n_record == 0 || max_csd_data_size == 0) {
1387                dprint(2, "  no csd data..\n");
1388                return statusOK;
1389        }
1390       
1391        //--------------- precheck CRC --------------------
1392        // crc ºÎÅÍ ¸ÕÀú Çѹø °è»êÀ» ÇØ º»´Ù.
1393       
1394        crc= 0xFFFFFFFF;
1395        address = db_start_address + CSD_HEADER_SIZE;
1396        for (i=0; (unsigned int)i<max_csd_data_size; i++) {
1397                NvRamRead(address+i, 1, tmp_buf);
1398                crc = DMW_CDB_CalcCRC32(crc, tmp_buf, 1);
1399        }
1400       
1401        if (crc != crc_org) {
1402                dprint(0, "!!   calc crc 0x%x != org_crc 0x%x\n", crc, crc_org);
1403        }
1404        else
1405                dprint(2, "  crc 0x%x ok.. for %d bytes..\n", crc, max_csd_data_size);
1406
1407        //-------------------------
1408
1409#define CHECK_ADDR_LIMIT(size) \
1410        if (address + (size) - db_start_address - CSD_HEADER_SIZE > max_csd_data_size) { \
1411                dprint(0, "!! address offset %d exceed limit by total size org %d\n", \
1412                                        address - db_start_address - CSD_HEADER_SIZE, max_csd_data_size); \
1413        }
1414
1415       
1416        crc= 0xFFFFFFFF;
1417        address = db_start_address + CSD_HEADER_SIZE;
1418
1419        continuity_counter = 0xF;
1420        //total_size = 0;
1421       
1422        for (i=0; i<n_record; i++) 
1423        {
1424                // read identifier part
1425                //
1426                CHECK_ADDR_LIMIT(5);
1427               
1428                //dprint(2, "----- address: %x\n", address);
1429               
1430                err = NvRamRead(address, 5, tmp_buf);
1431                if (err) {
1432                        dprint(0, "!! nvr read err\n");
1433                        goto label_exit;
1434                }
1435                address += 5;
1436                //total_size += 5;
1437                crc = DMW_CDB_CalcCRC32(crc, tmp_buf, 5);
1438               
1439                //memdump(tmp_buf, 5, 0);
1440               
1441                // check counter
1442                continuity_counter = (continuity_counter + 1) % 0x10;
1443               
1444                if (tmp_buf[0] != 0x50 + continuity_counter) {
1445                        dprint(0, "!! counter 0x%x != 0x%x expected..\n", 
1446                                                tmp_buf[0], 0x50 + continuity_counter);
1447                        goto label_exit;
1448                }
1449               
1450                rf        = PTR_TO_UINT8  (tmp_buf + 1);   // 1
1451                source_id = PTR_TO_UINT16 (tmp_buf + 2);   // 2..3
1452                num_csd   = PTR_TO_UINT8  (tmp_buf + 4);   // 4
1453               
1454                if (num_csd == 0) {
1455                        dprint(0, "!! csd rec[%d]: num csd zero\n", i);
1456                        continue;
1457                }
1458
1459                dprint(2, "  (%d) rf %d, source_id %d, num csd %d\n", i, rf, source_id, num_csd);
1460               
1461                for (k=0; k<num_csd; k++) 
1462                {
1463                        CHECK_ADDR_LIMIT(2);
1464                        err = NvRamRead(address, 2, tmp_buf);
1465                        if (err) {
1466                                dprint(0, "!! nvr read err\n");
1467                                goto label_exit;
1468                        }
1469                       
1470                        csd_tag       = tmp_buf[0];
1471                        csd_byte_size = tmp_buf[1];
1472                       
1473                        address += 2;
1474                        crc = DMW_CDB_CalcCRC32(crc, tmp_buf, 2);
1475
1476                        dprint(2, "      [%d] tag 0x%x, byte_len %d\n", k, csd_tag, csd_byte_size);
1477                       
1478                        CHECK_ADDR_LIMIT(csd_byte_size);
1479                        err = NvRamRead(address, csd_byte_size, tmp_buf);
1480                        if (err) {
1481                                dprint(0, "!! nvr read err\n");
1482                                goto label_exit;
1483                        }
1484                        address += csd_byte_size;
1485                        crc = DMW_CDB_CalcCRC32(crc, tmp_buf, csd_byte_size);
1486                       
1487                        err = DMW_CDB_UpdateUcmCsdEntry(rf, source_id, csd_tag, csd_byte_size, tmp_buf);
1488                        if (err) {
1489                                dprint(0, "!! update csd entry err\n");
1490                        }
1491                }
1492        }
1493       
1494        if (address - db_start_address - CSD_HEADER_SIZE != max_csd_data_size) {
1495                dprint(0, "!! total size mismatch.. %d !=  total size org %d\n",
1496                                address - db_start_address - CSD_HEADER_SIZE, max_csd_data_size);
1497        }
1498        else {
1499                dprint(2, "total size ok.. %d\n", max_csd_data_size);
1500        }
1501       
1502        if (crc != crc_org) {
1503                dprint(0, "!!   calc crc 0x%x != org_crc 0x%x\n", crc, crc_org);
1504        }
1505       
1506
1507label_exit:
1508
1509       
1510        return (STATUS)err;
1511}
1512
1513
1514
1515#if COMMENT
1516____TEST____(){}
1517#endif
1518
1519
1520
1521
1522/*******************************************************************
1523  Update:
1524
1525        1.05  2005/3/22   EPGX, SCTESI dependency¸¦ ÇÇÇϱâ À§ÇØ flag Ãß°¡
1526                          USE_DMW_EPGX_LIB, USE_DMW_SCTESI_LIB
1527       
1528        1.04  2004/12/21  XDS °ü·Ã ³»¿ëÀÌ tag·Î Ãß°¡µÊ
1529       
1530        1.03  2004/12/02  DMW_CDB_MakeUpShortNameFromSourceName Ãß°¡
1531       
1532        1.02  2004/12/01  UpdateCsdEntry: º¯°æ³»¿ëÀÌ ¾øÀ¸¸é statusNotChanged ¸®ÅÏ
1533                          UpdateCsd: Á»´õ È¿À²ÀûÀÎ ÄÚµå·Î º¯°æ..
1534                          g_TestCsdMultipleTagAllowed À̸§ º¯°æ
1535       
1536        1.01  2004/11/29  CSD re-desinged based on UCM link
1537                          NvRam I/O API added
1538        1.00  2004/11/25  CSD first design
1539
1540*******************************************************************/
Note: See TracBrowser for help on using the repository browser.