source: svn/newcon3bcm2_21bu/dst/dmw/src/EPG/DMW_EpgInterface.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: 68.4 KB
Line 
1/********************************************************************
2
3        DMW_EpgInterface.c
4       
5        EPG Middleware baseline implementation
6
7        Copyright 2004 Digital STREAM Technology, Inc.
8        All Rights Reserved
9
10        $Id: DMW_EpgInterface.c  v1.00 2004/04 cafrii Exp $
11       
12********************************************************************/
13
14/*_____ I N C L U D E __________________________________________*/
15
16#include "DMW_Platform.h"
17
18#include "DLIB_BitOp.h"
19#include "DLIB_PSI_Utils.h"
20
21#include "DMW_CodeConv.h"
22#include "DMW_ChannelAPI.h"
23#include "DMW_EpgInterface.h"
24
25//#include <string.h>
26//#include <string.h>
27
28
29DHL_MODULE("$epi", 0);
30
31
32/*-------------------------------------------------------
33         Configurations..
34-------------------------------------------------------*/
35
36#define DMW_EPG_TESTCODE 1
37        /* 1À̸é TestXX ÇÔ¼öµéÀ» ºôµå¿¡ Æ÷ÇÔ.. */
38
39/* #define USE_OLD_2_PASS_METHOD 0 */
40
41
42#define USE_EIT_FIRST_MODE_DEFAULT 0
43        /* 1À̸é Epg Update¸¦ ½ÃÀÛÇÒ ¶§
44                 ±âº»ÀûÀ¸·Î Eit first ¸ðµå·Î ½ÃÀÛÇÑ´Ù. Eit¸¦ »¡¸® ¹ÞÀ» ¼ö ÀÖ´Â ÀåÁ¡ÀÌ ÀÖ´Â ¹Ý¸é
45                 PSIP ÀÌ ¿ÏÀüÇÏÁö ¸øÇÏ´Â °æ¿ì Ett¸¦ ¾Æ¿¹ ¸ø¹ÞÀ» ¼öµµ ÀÖ´Ù..
46        */
47
48int g_PrintEventInfo = 1;
49        /* GetEvent·Î event Á¤º¸¸¦ °¡Á®¿Â ´ÙÀ½¿¡ Äֿܼ¡ ¸ðµÎ Ãâ·ÂÇØÁØ´Ù. */
50
51#define IGNORE_RRT_REGION 1
52        //±âÁ¸ rrt regionÀ¸·Î 5¸¸ ó¸®ÇßÀ¸³ª, ¾Ë·ÁÁø region 1,2¸¦ Á¦¿ÜÇÑ ³ª¸ÓÁö¸¦
53        //´Ù ó¸®Çϵµ·Ï º¯°æÇÔ.
54
55/*-------------------------------------------------------*/
56
57
58
59#define max(a,b) (((a) > (b)) ? (a) : (b))
60#define min(a,b) (((a) < (b)) ? (a) : (b))
61
62
63
64/*--------------------------------------------------------------------*/
65
66
67#if COMMENT
68____desc_parsing____(){}
69#endif
70
71
72STATUS DMW_GetPsipDescriptor(UINT8 *descriptors, UINT16 len, UINT8 tag, 
73                                                                UINT16 instance, UINT8 **descriptor)
74{
75        UINT8   *p;
76        UINT16  count;
77        UINT8   descriptor_length;
78        STATUS  status;
79
80        /* search for descriptor of type 'tag' */
81        count = 0;
82        status = statusNotFound;
83        p = descriptors;
84        while (p < descriptors + len) {
85                if (*p == tag) {
86                        if (count == instance) {
87                                /* check for length error */
88                                descriptor_length = p[1];
89                                if ((p + descriptor_length + 2) <= (descriptors + len)) {
90                                        if (descriptor)
91                                                *descriptor = p;
92                                        status = statusOK;
93                                }
94                                else
95                                        status = statusPSIPError;
96                                break;  /* break 'while' */
97                        }
98                        else {
99                                count++;
100                        }
101                }
102                descriptor_length = p[1];                       /* p[0] is tag, p[1] is length of this tag desc.. */
103                p += (descriptor_length + 2);   /* desc length + (2 bytes: tag, length itself) */
104        }
105
106        return status;
107}
108
109
110
111/* Content Advisory descriptor¸¦ »õ·Î¿î format¿¡ ¸Â°Ô parse..
112       
113         ±âÁ¸¿¡´Â ContentAdvisoryDescriptor¸¦ parsingÇÑ ´ÙÀ½¿¡
114         À̸¦ ´Ù½Ã DMW_RatingÀ¸·Î º¯È¯ÇÏ¿´À¸³ª,
115         ÀÌÁ¦´Â Á÷Á¢ descriptorÁ¤º¸¿¡¼­ DMW_RatingÀ¸·Î º¯È¯ ÃßÃâÇÑ´Ù.
116       
117         Áߺ¹µÈ regionÀÌ ¿©·¯°³ Á¸ÀçÇÒ °æ¿ì¶óµµ ¿¡·¯·Î ó¸®ÇÏÁö ¾Ê´Â´Ù.
118         caller´Â ÀÌ·± °æ¿ì¿¡ ´ëÇØ¼­ ³ª¸§´ë·ÎÀÇ policy¸¦ °¡Áö°í ÀÖ¾î¾ß ÇÑ´Ù.
119*/
120STATUS DMW_ParseRatingDescriptor(UINT8 *descriptors, int descriptor_length, 
121                                                                        DMW_Rating5 *ri)
122{
123        UINT8 *p;
124        bitBuffer_t      tBits, *bits = &tBits;
125        INT32 count, i,k;
126        STATUS status;
127
128        if (descriptors == NULL || descriptor_length <= 0) 
129                return statusInvalidArgument;
130       
131        /* search ca descriptor */
132        status = DMW_GetPsipDescriptor(descriptors, descriptor_length, 
133                                                                content_advisory_tag, 0, &p);
134        if (status) return status;      /* not found error */
135
136        if (p == NULL || p[0] != content_advisory_tag)
137                return statusInvalidArgument;
138       
139        if (ri == NULL)
140                return statusInvalidArgument;
141               
142        bitBufferInitialize(bits,p+2,p[1]);
143
144        bitBufferSkipBits(bits,2);
145        ri->region_count = bitBufferGetBits(bits,6);
146       
147        if (ri->region_count > MAX_RATING_RGNS_NUM) {
148                dprint(0, "!! region count overflow %d (max %d)\n", 
149                                ri->region_count, MAX_RATING_RGNS_NUM);
150                ri->region_count = MAX_RATING_RGNS_NUM;
151        }
152        /* °­Á¦·Î Å©±â¸¦ ÁÙ¿´À¸´Ï, raw descriptor ³¡ºÎºÐ¿¡ parsingÀÌ ¾ÈµÈ
153                 µ¥ÀÌÅͰ¡ ³²¾ÆÀÖ°Ô µÉ ¼öµµ ÀÖÀ½. */
154       
155        for (i=0; i<ri->region_count; i++) 
156        {
157                DMW_RatingRegion *rr = &ri->region[i];
158               
159                rr->region_id      = bitBufferGetBits(bits,8);
160                rr->num_dimensions = bitBufferGetBits(bits,8);
161
162                count = rr->num_dimensions;
163                if (rr->num_dimensions > MAX_RATING_DIMS_NUM) {
164                        dprint(0, "!! dims count overflow %d (max %d)\n", 
165                                        rr->num_dimensions, MAX_RATING_DIMS_NUM);
166                        rr->num_dimensions = MAX_RATING_DIMS_NUM;
167                }
168               
169                for (k=0; k<rr->num_dimensions; k++) {
170                        rr->dimension[k].index = bitBufferGetBits(bits,8);
171                        bitBufferSkipBits(bits,4);
172                        rr->dimension[k].value = bitBufferGetBits(bits,4);
173                }
174                /* truncate µÈ ¿µ¿ªÀº skipÀ» ÇØÁà¾ß ÇÔ. */
175                for ( ; k<count; k++)
176                        bitBufferSkipBits(bits, 16);    /* index 8bit, res+value 8bits */
177
178                /* ignore descriptions.. */
179                count = bitBufferGetBits(bits,8);
180                for (k=0; k<count; k++)
181                        bitBufferSkipBits(bits,8);
182        }
183       
184        return statusOK;
185}
186
187
188
189/* todo.. ÀÛ¼ºÀÚ°¡ ´©±¸Àΰ¡?
190          Á¤¸® ¿ä¸Á..
191       
192         descriptor list ¿¡¼­ Closed_Caption descriptor¸¦ ã´Â´Ù. 
193         Must : ¹Ýµå½Ã Caller¿¡¼­ cc_descPtr »ç¿ëÈÄ Memory_Free½ÃÄÑ¾ß ÇÑ´Ù.
194         Free()°¡ ¾Æ´Ñ, FreeMpegDescriptor()À» »ç¿ëÇØ¾ß ÇÑ´Ù.
195*/
196STATUS DMW_ParseCaptionDescriptor(UINT8 *descriptors, int descriptor_length, 
197                                                captionServiceDescriptorPtr_t *pccdes)
198{
199        UINT8 *desc_raw;
200        captionServiceDescriptorPtr_t cc_descPtr;
201        DHL_RESULT err = DHL_OK;
202        STATUS status;
203
204        if (descriptors == NULL || descriptor_length <= 0) 
205                return statusInvalidArgument;
206       
207        /* comment:
208                  ¿©·¯°³ÀÇ instance°¡ Á¸ÀçÇÏ´Â °æ¿ì ù¹øÂ°¸¸ »ç¿ëÇÑ´Ù. */
209        status = DMW_GetPsipDescriptor(descriptors, descriptor_length, 
210                                                        caption_service_tag, 0, &desc_raw);
211        if (status) return status; 
212       
213        err = ParseCaptionServiceDescriptor(desc_raw, &cc_descPtr);
214        if (err) return statusOutOfMemory; 
215
216        if (pccdes)
217                *pccdes = cc_descPtr;
218        else
219                FreeMpegDescriptor(cc_descPtr);
220
221        return status;
222}
223
224
225#if COMMENT
226____Util____(){}
227#endif
228
229#define NUM_ELEMENT(array) (sizeof(array)/sizeof(array[0]))
230
231DmcChannelInfo *SRCH_ChInfo(int rf)
232{
233        /* use 'rf' as id of epg database entry. */
234        return Dmc_GetChannelInfo(g_EpgDB, rf);
235}
236
237DmcSubChannelInfo *SRCH_SubchInfo(DmcChannelInfo *chInfo, UINT16 source_id)
238{
239        int i;
240        if (!chInfo) return NULL;
241        for (i=0; i<chInfo->n_subchannel; i++) {
242                if (chInfo->subchannel[i].source_id == source_id) {
243                        return &chInfo->subchannel[i];
244                }
245        }
246        return NULL;
247}
248
249
250
251#if COMMENT
252____Test____(){}
253#endif
254
255
256typedef struct
257{
258        int rf;
259        int region;
260        int n_dim;
261        int dim[5], val[5];
262
263} EpgFakeRatingInfo;
264
265/* Å×½ºÆ®¸¦ À§ÇÑ ¸ñÀûÀ¸·Î..
266         cafrii 060616
267          µ¿ÀÏ À̸§ÀÇ Äڵ尡 App¿¡ º¹»çµÇ¾î »ç¿ëÁßÀ̾
268          À̸§ º¯°æ..
269*/
270
271EpgFakeRatingInfo g_EpgFakeRatingInfo;
272
273void DMW_EPG_SetFakeRatingData(int rf, int region, int d1, int d2, int d3, int d4, int d5)
274{
275        int n_dim;
276       
277        if (rf <= 0) {  /* disable fake rating feature */
278                g_EpgFakeRatingInfo.rf = 0;
279                return;
280        }
281        g_EpgFakeRatingInfo.rf = rf;
282        g_EpgFakeRatingInfo.region = region;
283       
284        /* dn °ª¿¡ -1À» ÁöÁ¤ÇÏ¸é ±× ÀÌÈÄÀÇ argument´Â ¸ðµÎ ¹«½ÃÇÑ´Ù. */
285       
286        n_dim = 0;
287       
288        if (d1 < 0) goto label_exit;
289        g_EpgFakeRatingInfo.dim[n_dim] = (d1>>8)&0xff;
290        g_EpgFakeRatingInfo.val[n_dim] = (d1&0xff);
291        n_dim++;
292
293        if (d2 < 0) goto label_exit;
294        g_EpgFakeRatingInfo.dim[n_dim] = (d2>>8)&0xff;
295        g_EpgFakeRatingInfo.val[n_dim] = (d2&0xff);
296        n_dim++;
297
298        if (d3 < 0) goto label_exit;
299        g_EpgFakeRatingInfo.dim[n_dim] = (d3>>8)&0xff;
300        g_EpgFakeRatingInfo.val[n_dim] = (d3&0xff);
301        n_dim++;
302
303        if (d4 < 0) goto label_exit;
304        g_EpgFakeRatingInfo.dim[n_dim] = (d4>>8)&0xff;
305        g_EpgFakeRatingInfo.val[n_dim] = (d4&0xff);
306        n_dim++;
307
308        if (d5 < 0) goto label_exit;
309        g_EpgFakeRatingInfo.dim[n_dim] = (d5>>8)&0xff;
310        g_EpgFakeRatingInfo.val[n_dim] = (d5&0xff);
311        n_dim++;
312
313label_exit:
314        g_EpgFakeRatingInfo.n_dim = n_dim;
315}
316
317
318/* return TRUE if faking is success. */
319BOOL DoFakeRatingData(int rf, DMW_Rating5 *pRating)
320{
321        /* fake rating ±â´É */
322        int k;
323       
324        if (g_EpgFakeRatingInfo.rf && g_EpgFakeRatingInfo.rf == rf &&
325                g_EpgFakeRatingInfo.n_dim > 0) 
326        {
327                dprint(0, "!! %s: simulate Fake Rating information\n", __FUNCTION__);
328               
329                pRating->region_count = 1;
330                pRating->region[0].region_id = g_EpgFakeRatingInfo.region;
331                pRating->region[0].num_dimensions = g_EpgFakeRatingInfo.n_dim;
332               
333                dprint(0, "fake: region %d, %d dims\n", 
334                                        g_EpgFakeRatingInfo.region, g_EpgFakeRatingInfo.n_dim);
335               
336                for (k=0; k<g_EpgFakeRatingInfo.n_dim; k++) {
337                        pRating->region[0].dimension[k].index = g_EpgFakeRatingInfo.dim[k];
338                        pRating->region[0].dimension[k].value = g_EpgFakeRatingInfo.val[k];
339                        dprint(0, "fake:  [%d] dim idx %d, val %d\n", k, 
340                                                g_EpgFakeRatingInfo.dim[k], g_EpgFakeRatingInfo.val[k]);
341                }
342                return TRUE;
343        }
344       
345        return FALSE;
346}
347
348
349
350
351#if COMMENT
352____API____(){}
353#endif
354
355
356
357STATUS DMW_EPG_Init()
358{
359        dprint(1, "DMW_EPG_Init()\n");
360
361        /* g_fnPrevHook = DMW_CDB_RegisterUcmDeleteHook(DMW_EPG_UcmDeleteHook); */
362        /*
363                 UCM DB¿ÍÀÇ ¸µÅ©°¡ ¾ø±â ¶§¹®¿¡ UCM delete¿¡ ´ëÇØ¼­ hookingÀ» ÇÒ Çʿ䰡 ¾ø´Ù.
364                 °ü·ÃµÈ UCM DB°¡ Áö¿öÁö´õ¶óµµ EPG DB´Â °è¼Ó Á¸ÀçÇÒ ¼ö ÀÖ°í,
365                 (³ªÁß¿¡ DRF Æ©´×À» ÇÏ°Ô µÇ¸é Àç »ç¿ëµÉ ¼ö ÀÖÀ½)
366                 ÇÊ¿äÇÏ´Ù¸é DeleteAll À» ÀÌ¿ëÇØ¼­ EPG¸¦ Áö¿ï ¼ö ÀÖ´Ù.
367        */
368        return Dmc_EpgInit();
369}
370
371
372/*--------------------------------------------------------------------
373           Control API
374*/
375
376/* cafrii 060320 change prototype (add source_id) */
377STATUS DMW_EPG_UpdateCurrentRf(int rf, int source_id, EpgUpdateCallbackFn func)
378{
379        /* source_id°¡ non-zeroÀ̸é ÇØ´ç source_id¸¦ ¿ì¼±Çؼ­ ¹ÞÀ½.
380                 source_id°¡ 0À̸é preferred source_id °¡ ¾øÀ½. ¸ðµç subchannelÀ» °ñ°í·ç ¼ö½Å
381        */
382        tDHL_TSD tsd;
383        UINT32 flag;
384       
385        /* ÁöÁ¤ÇÑ rf Àüü¸¦ update ½ÃÀÛÇÑ´Ù. */
386        dprint(1, "DMW_EPG_UpdateCurrentRf(rf %d, callback 0x%x)\n", rf, func);
387       
388        /* ¾î´À TSD unitÀ» »ç¿ëÇÒ °ÍÀÎÁö ÁöÁ¤ÇÑ´Ù. */
389        tsd = DHL_DMX_GetTsd();
390        /* cafrii 041019 change, allow all possible tsd's input */
391       
392#if USE_EIT_FIRST_MODE_DEFAULT
393        flag = epgScanFlag_EitFirst;
394#else
395        flag = 0;
396#endif
397       
398        return Dmc_EpgUpdateStart(rf, tsd, (DmcEpgEventProc) func, source_id, flag);
399}
400
401STATUS DMW_EPG_UpdateCurrentChannel(int iUCMId, EpgUpdateCallbackFn func)
402{
403        /* ƯÁ¤ source_id ¸¦ prefer ÇØ¼­ udpate¸¦ ½ÃÀÛÇÑ´Ù. */
404        tDHL_TSD tsd;
405        int idx;
406        int rf, source_id = 0;
407        UINT32 flag;
408       
409        dprint(1, "DMW_EPG_UpdateCurrentChannel(uid %d)\n", iUCMId);
410
411        tsd = DHL_DMX_GetTsd();
412        /* cafrii 041019 change, allow all possible tsd's input */
413       
414        /* Uid·Î ºÎÅÍ RF °ªÀ» ¾Ë¾Æ³½´Ù.. */
415        DMW_MSC_LockUcm();
416                idx = DMW_MSC_Uid2Index(iUCMId);
417                if (idx >= 0) {
418                        rf = g_UCM[idx].RF;
419                        source_id = g_UCM[idx].source_id;
420                }
421                else {
422                        rf = -1;
423                }
424        DMW_MSC_UnlockUcm();
425       
426        if (rf < 0) return statusNotFound;
427
428#if USE_EIT_FIRST_MODE_DEFAULT
429        flag = epgScanFlag_EitFirst;
430#else
431        flag = 0;
432#endif
433
434        return Dmc_EpgUpdateStart(rf, tsd, (DmcEpgEventProc) func, source_id, flag);
435}
436
437STATUS DMW_EPG_CancelUpdate()
438{
439        dprint(1, "DMW_EPG_CancelUpdate()\n");
440       
441        return Dmc_EpgUpdateCancel();
442}
443
444STATUS DMW_EPG_DeleteAll()
445{
446        dprint(1, "DMW_EPG_DeleteAll()\n");
447       
448        return Dmc_EpgDeleteAll();
449}
450
451
452
453#if COMMENT
454____API____(){}
455#endif
456
457/*--------------------------------------------------------------------
458          Query API
459*/
460
461static void FreeEpgEventItem(DMW_EpgEvent *pEvent)
462{
463        if ((pEvent->titleTextLength) > 0 && (pEvent->titleText))
464        {
465                DHL_OS_Free((void**)&pEvent->titleText);
466                pEvent->titleTextLength = 0;
467        }
468
469        if ((pEvent->eventETMLength > 0) && (pEvent->eventETM))
470        {
471                DHL_OS_Free((void**)&pEvent->eventETM);
472                pEvent->eventETMLength = 0;
473        }
474
475        if (pEvent->caption)
476        {
477                FreeMpegDescriptor(pEvent->caption);
478                pEvent->caption = NULL;
479        }
480       
481}
482
483void DMW_EPG_FreeEpgEvent(DMW_EpgEvent *pEvent)
484{
485        if (pEvent == NULL) return;
486
487        dprint(1, "DMW_EPG_FreeEpgEvent\n");
488        FreeEpgEventItem(pEvent);
489        DHL_OS_Free((void**)&pEvent);
490}
491
492void DMW_EPG_FreeEpgEvents(DMW_EpgEvent *pEvents, int iCount)
493{
494        int i;
495
496        if (pEvents == NULL) return;
497       
498        dprint(1, "DMW_EPG_FreeEpgEvents(%d)\n", iCount);
499        for (i=0; i<iCount; i++)
500        {
501                dprint(3, "   [%d] delete EpgEvent 0x%x\n", i, &pEvents[i]);
502                FreeEpgEventItem(&pEvents[i]);
503        }
504       
505        DHL_OS_Free((void**)&pEvents);
506}
507
508
509/* MakeEpgEvent: internal function
510       
511        @event ¿¡¼­ ÇÊ¿äÇÑ Á¤º¸¸¦ ÃßÃâÇÏ¿© @pReturnEpgEvent ¸¦ ±¸¼ºÇÑ´Ù.
512        ¾î¶² Á¤º¸¸¦ ÃßÃâÇÒ °ÍÀÎÁö´Â @flag¸¦ ÅëÇØ¼­ ÁöÁ¤ÇÑ´Ù.
513        @pReturnEpgEvent ³»¿ëÀÌ ÀúÀåµÉ °ø°£Àº caller°¡ Á¦°øÇÑ´Ù.
514
515        flag´Â GET_EVENT_BASIC °ú °°Àº °ªµéÀÇ OR À̰í, ÃÖ´ë event °¹¼ö´Â Àǹ̰¡ ¾ø´Ù.
516        ¿À·ÎÁö ÇϳªÀÇ DMW_EpgEvent ¸¸ ¸¸µé¾îÁø´Ù.
517
518        @chInfo, @subchInfo µîÀº @event°¡ À§Ä¡ÇÏ´Â contextÀÌ´Ù.
519       
520        @iEit´Â ¿¬°áµÈ ett¸¦ ã±â À§Çؼ­ ÇÊ¿äÇÏ´Ù. (GET_EVENT_TEXT ÁöÁ¤½Ã¿¡¸¸ ÇÊ¿ä)
521        event ÀÚü Á¤º¸¸¸À¸·Î´Â ¾îµð¿¡ ¿¬°áµÈ ett°¡ À§Ä¡ÇÒÁö ¾Ë±â°¡ ¾î·Æ±â ¶§¹®ÀÌ´Ù.
522        @iEit °ªÀÌ À½ÀÇ °ªÀ̸é (not available) ÇØ´ç subchÀÇ ¸ðµç ett¿¡¼­ ´Ù °Ë»öÇÑ´Ù.
523*/
524static void MakeEpgEvent(DmcChannelInfo *chInfo, DmcSubChannelInfo *subchInfo, 
525                                int iEit, eitEventPtr_t event, UINT32 flag, DMW_EpgEvent *pReturnEpgEvent)
526{
527        STATUS status;
528        int i, k;
529
530        DMW_EpgEvent *p = pReturnEpgEvent;
531        int rf = chInfo->id;
532        UINT16 source_id = subchInfo->source_id;
533        ettSectionPtr_t ett;
534
535        /* ½ÃÀÛÇϱâ Àü¿¡ ¸ÕÀú resetÇÑ´Ù.
536           flag¸¦ ÀÌ¿ëÇÏ¿© incrementalÇÏ°Ô Á¤º¸¸¦ ä¿ö°¡´Â ¹æ½ÄÀº »ç¿ëÇÒ ¼ö ¾øÀ½. */
537        memset(p, 0, sizeof(DMW_EpgEvent));
538
539        /*---------- General Info --------------*/
540        p->programId = event->event_id;
541        p->programLength = event->length_in_seconds;
542        p->startTime = event->start_time;
543
544        /*---------- Rating Info --------------*/
545        if (flag & GET_EVENT_RATING) 
546        {
547                if (DoFakeRatingData(rf, &p->rating)) {
548                        /* fake rrt data loading success. */
549                }
550                else {
551                        status = DMW_ParseRatingDescriptor(event->descriptors, event->descriptor_length, 
552                                                                        &p->rating);
553                        if (status) {
554                                p->rating.region_count = 0;
555                                /* dprint(0, "[RRT] no rating info from eit\n"); */
556                        }
557                }
558        }
559
560        /*---------- Caption Info --------------*/
561        if (flag & GET_EVENT_CAPTION)
562        {
563                status = DMW_ParseCaptionDescriptor(event->descriptors, event->descriptor_length, 
564                                                                        &p->caption);
565               
566                if (status) {
567                        if (status != statusNotFound)
568                                dprint(0, "!! err in GetCaptionDesc:ParsingCaDesc.. %d\n", status);
569                        p->caption = NULL; 
570                }
571        }
572
573        /*---------- Title Info --------------*/
574        if (flag & GET_EVENT_TITLE)
575        {
576                if (event->title_length > 0) {
577                        p->titleText = DHL_OS_Malloc(event->title_length+1);
578                        if (p->titleText) {
579                                p->titleTextLength = event->title_length;
580                                memcpy(p->titleText, event->title, event->title_length);
581                        }
582                        else {
583                                dprint(0, "!! out of memory for titletext len %d of event[%d], evid 0x%x\n",
584                                                        event->title_length, iEit, event->event_id);
585                                p->titleTextLength = 0;
586                        }
587                }
588                else {
589                        dprint(0, "!! event title length %d\n", event->title_length); /* cafrii 060321 bugfix %n->%d */
590                        p->titleText = NULL;
591                        p->titleTextLength = 0;
592                }
593        }
594       
595        /*---------- Text Info --------------
596                 etmÀ» ãÀ¸·Á¸é ett list¸¦ µÚÁ®¾ß ÇÑ´Ù..
597        */
598        /* cafrii 070730 bugfix, GET_EVENT_TITLE->GET_EVENT_TEXT */
599        if (flag & GET_EVENT_TEXT)
600        {
601                UINT32 etm_id;
602                etm_id = MakeEventETMID(source_id, event->event_id);
603                        /* cafrii 041028, MakeETMID -> MakeEventETMID */
604               
605                /* ¸ðµç ett array¸¦ ´Ù µÚÁ®°¡¸ç,
606                         etm_id ¿¡ ÇØ´çµÇ´Â ett·ÎºÎÅÍ etmÀ» °¡Á®¿Í¼­ º¹»çÇÑ´Ù..
607                       
608                         --> iEit-1, iEit, iEit+1 ÀÌ·¸°Ô ¼¼°³¸¸ ºñ±³ÇÏ¸é µÉ °Í °°´Ù.
609                         EitÀÇ À§Ä¡¿Í ±×¸® ¸Ö¸® ¶³¾îÁ® ÀÖÁö ¾ÊÀ» °ÍÀ̹ǷÎ.
610                */
611                /* for (i=0; i<128; i++) // <-- inefficient!! */
612                for (i= max(0, iEit-1); i<= min(127, iEit+1); i++)      /* cafrii 041223 change */
613                {
614                        if (subchInfo->n_ett[i] == 0 || subchInfo->etts[i] == NULL) continue;
615                        for (k=0; k<subchInfo->n_ett[i]; k++) 
616                        {
617                                if (subchInfo->etts[i][k] == NULL) continue;
618                                if (subchInfo->etts[i][k]->ETM_id == etm_id) {
619                                        ett = subchInfo->etts[i][k];
620                                       
621                                        if (ett->extended_text_message_length > 0) {
622                                                p->eventETM = DHL_OS_Malloc(ett->extended_text_message_length+1);
623                                                if (p->eventETM == NULL) {
624                                                        dprint(0, "!! out of memory for etm len %d of ett[%d][%d]\n",
625                                                                        ett->extended_text_message_length, i, k);
626                                                        p->eventETMLength = 0;
627                                                }
628                                                else {
629                                                        p->eventETMLength = ett->extended_text_message_length;
630                                                        memcpy(p->eventETM, ett->extended_text_message, p->eventETMLength);
631                                                }
632                                        }
633                                        else {  /* etm length °¡ À߸øµÇ¾ú´Ù.. ¹«½Ã.. */
634                                                dprint(0, "!! ett[%d][%d] etm len %d\n", i, k, ett->extended_text_message_length);
635                                                p->eventETM = NULL;
636                                                p->eventETMLength = 0;
637                                        }
638                                        goto label_end_etm;     /* go out of this loop!! */
639                                }
640                        }
641                }
642label_end_etm:
643                ;       /* cafrii 070327 add to remove compiler warning */
644        }
645}
646
647
648/*
649         DMW_EPG_GetEventsByRF
650       
651         ÁöÁ¤ÇÑ uid ä³Î¿¡ µî·ÏµÈ EPG evnet Á¤º¸µé Áß¿¡¼­ ½ÃÀ۽ð£, duration ¿¡ ÇØ´çµÇ´Â
652           event µéÀÇ list (array) ¸¦ µ¹·ÁÁØ´Ù..
653       
654         ÇÊ¿äÇÑ ¸Þ¸ð¸®´Â ³»ºÎÀûÀ¸·Î ÇÒ´çÀ» ÇÑ´Ù. (DHL_OS_Malloc)
655         ÀúÀåµÈ °¹¼ö´Â iEventCounts ·Î ¸®ÅÏ..
656       
657         ½Ã°£ ´ÜÀ§´Â ¸ðµÎ GPS ÀÌ´Ù..
658         »ç¿ë ÈÄ¿¡ caller´Â ¸Þ¸ð¸®¸¦ ÇØÁ¦ ÇØ¾ß ÇÑ´Ù.
659*/
660STATUS DMW_EPG_GetEventsByRF(int rf, int source_id, UINT32 nStartTime, UINT32 nDuration,
661                                        DMW_EpgEventPtr *aFoundEvents, int *piEventCounts, 
662                                        UINT32 flag)
663{
664        /* todo
665                 ÀÏ´Ü ¸î°³ÀÇ Eit event °¡ ÇØ´çµÇ´ÂÁö °è»êÀ» ÇÑ ´ÙÀ½¿¡ ¸Þ¸ð¸®¸¦ ÇÒ´çÇϰí,
666                 ´Ù½Ã Eit/Ett Çϳª¾¿ Parsing ÇØ¼­ DMW_EpgEvent¸¦ ¸¸µé¾î¾ß ÇÑ´Ù.
667                 ÀÌ·¸°Ô Çϸé memory fragmentation °¡´É¼ºÀ» ´õ ÁÙÀÏ ¼ö ÀÖ´Ù.. ½Ã°£Àº ´õ°É¸².
668        */
669        #define SAFE_EXIT(val) returnStatus=(val); goto label_exit;
670                /* cafrii 060616 bugfix, status -> returnStatus */
671
672        int i, k;
673        int iEit, iEvent;
674        STATUS status;          /* temporary. */
675        STATUS returnStatus = statusOK;
676       
677        DmcChannelInfo    *chInfo = NULL;
678        DmcSubChannelInfo *subchInfo = NULL;
679       
680        DMW_EpgEvent *EventList;
681        DMW_EpgEvent *p;        /* temporary.. */
682        int iEventCount;
683        int sz_event_list;
684
685        int maxEvent;
686       
687        if (flag == 0) flag = GET_EVENT_ALL;
688        maxEvent = (flag & 0xffff);     /* ÃÖ´ë 65535°³ ±îÁö¸¸ °¡´É. */
689
690        /* cafrii 060620 add */
691        /* »ç¿ëÀÚ°¡ ½Ç¼ö·Î max °ªÀ» ÁöÁ¤ÇÏÁö ¾ÊÀº °æ¿ì µðÆúÆ® °ª ÁöÁ¤. */
692        if (maxEvent == 0) 
693                maxEvent = DEFAULT_MAX_EVENT_NUMBER; 
694       
695        dprint(1, "DMW_EPG_GetEventsByRF: rf %d, source_id %d, max %d, flag 0x%x\n", 
696                                                rf, source_id, maxEvent, flag);
697       
698        if (rf < 0) return statusNotFound;
699        if (maxEvent <= 0) return statusInvalidArgument;
700       
701        /* rf, source_id ¸¦ »ç¿ëÇÏ¿© event list¸¦ ¾ò¾î³½´Ù.
702                 rf >= 0 À̾î¾ß ÇÑ´Ù. */
703       
704        Dmc_EpgLockCoreDB(TRUE);
705       
706        chInfo = Dmc_GetChannelInfo(g_EpgDB, rf);
707        if (chInfo == NULL) {
708                dprint(2, "!! rf %d chInfo not found.. maybe epg is not ready..\n", rf);
709                        /* cafrii 041208, change debug level */
710                SAFE_EXIT(statusNotFound);
711        }
712
713        for (i=0; i<chInfo->n_subchannel; i++) {
714                if (chInfo->subchannel[i].source_id == source_id) {
715                        subchInfo = &chInfo->subchannel[i];
716                        break;
717                }
718        }
719        if (!subchInfo) {
720                dprint(1, "!! subchInfo source_id %d not found..\n", source_id);
721                SAFE_EXIT(statusNotFound);
722        }
723       
724        /* test.. */
725        dprint(3, "  sizeof DMW_EpgEvent: %d\n", sizeof(DMW_EpgEvent));
726       
727        if(flag&GET_EVENT_STATIC_MEM) { //aFoundEvents´Â À¯È¿ÇÑ static memoryÀÇ ÁÖ¼ÒÀÓ
728                sz_event_list=maxEvent;
729                EventList=*aFoundEvents;
730        }
731        else {
732                sz_event_list = 8;
733               
734                dprint(3, "   pre-alloc %d event list space..\n", sz_event_list);
735                EventList = DHL_OS_Malloc(sz_event_list * sizeof(DMW_EpgEvent));
736                if (EventList == NULL) {
737                        dprint(0, "!! out of memory for Eventlist\n");
738                        SAFE_EXIT(statusOutOfMemory);
739                }
740        }
741       
742        if((flag&GET_EVENT_STATIC_MEM)==0)
743                memset(EventList, 0, sz_event_list * sizeof(DMW_EpgEvent));
744               
745        iEventCount = 0;
746        for (iEit=0; iEit<128; iEit++) 
747        {
748                eitPtr_t eit;
749                ettSectionPtr_t ett;
750                eitEventPtr_t event;
751       
752                /* eitPtr_t */
753                UINT32 max_start_time, min_end_time;
754                UINT32 min_start_time;
755                int num_event;
756
757                if (iEventCount >= maxEvent)    /* ÀÌ¹Ì full ÀÌ¸é ±×³É ÁßÁö.. */
758                        break;
759
760                eit = subchInfo->eits[iEit];
761                if (eit == NULL) continue;
762
763                if (eit->source_id != source_id) {
764                        dprint(0, "!! eit[%d] source id %d mismatch to subch source id %d\n", iEit, eit->source_id, source_id);
765                        continue;
766                }
767               
768                num_event = eit->numEvents;
769                if (eit->event == NULL || num_event <= 0) {
770                        /* dprint(3, "   eit[%d] event %x, n_event %d\n", iEit, eit->event, num_event); */
771                        continue;
772                }
773
774                if (num_event <= 0)
775                        continue;
776
777                /* cafrii 041223, add efficient search/stop code
778                         ÀÌ eit³»¿¡ °¡Àå ºü¸¥ event°¡ ¿øÇÏ´Â time range¿¡¼­ ÇÑÂü ¹þ¾î³ª ÀÖ´Ù¸é
779                         search¸¦ Áß´ÜÇÑ´Ù.
780                */
781                min_start_time = 0xFFFFFFFF;
782               
783                for (k=0; k<num_event; k++)
784                {
785                        if (eit->event[k].start_time < min_start_time)
786                                min_start_time = eit->event[k].start_time;
787                }
788               
789                if (nStartTime + nDuration-1 + 3*3600 < min_start_time)
790                {
791                        /* ÀÌ EIT ¿¡ ÀÖ´Â ¸ðµç À̺¥Æ®µéÀÌ ¿øÇÏ´Â ½Ã°£ ±¸°£ º¸´Ù 3½Ã°£ ÀÌÈÄ¿¡ À§Ä¡ÇÑ´Ù..
792                                 ÀÌ ¸»Àº ÀÌ EIT ÀÌÈķδ ´õÀÌ»ó EIT °Ë»öÀ» ÇÒ Çʿ䰡 ¾ø´Ù´Â ÀǹÌ.. */
793                       
794                        dprint(2, "   search stop at eit[%d]..\n", iEit);
795                        continue;
796                }
797               
798               
799                for (iEvent=0; iEvent<num_event; iEvent++) 
800                {
801                        /* eitEvent_t */
802                        event = &eit->event[iEvent];
803                       
804                        /* check overlap: (nStartTime, nDuration) and
805                                                (event->start_time, event->length_in_seconds) */
806
807                        max_start_time = max(nStartTime, event->start_time);
808                        min_end_time = min(nStartTime+nDuration-1, event->start_time+event->length_in_seconds-1);
809                       
810                        if (max_start_time > min_end_time)      /* ¿µ¿ª¿¡ ¼ÓÇÏÁö ¾ÊÀ½.. */
811                                continue;
812                       
813                        /* ÇϳªÀÇ event°¡ ¿©·¯ Eit °æ°è¿¡ °ÉÃÄ ÀÖ´Â °æ¿ì¿¡ µÎ¹ø Áߺ¹ ¼öÁýµÇÁö ¾Êµµ·Ï °Ë»ç°¡ ÇÊ¿äÇÏ´Ù.. */
814                        for (i=0; i<iEventCount; i++) { /* Áö±Ý±îÁö µî·ÏÇØ ³õÀº event_id µé°ú ºñ±³.. */
815                                if (EventList[i].programId == event->event_id)  /* this is already registerred.. */
816                                        break;
817                        }
818                        if (i < iEventCount) {
819                                dprint(2, "       event id %d (%x) is already searched\n", event->event_id, event->event_id);
820                                continue;       /* ´ÙÀ½ event ÁøÇà.. */
821                        }
822                        else if (iEventCount >= maxEvent) {
823                                dprint(0, "!! num event is beyond limit %d\n", maxEvent);
824                                /* continue; */         /* Áö¿ø °¡´ÉÇÑ °¹¼ö¸¦ ³Ñ¾î¼¹À½.. */
825                                goto label_end_loop;
826                        }
827                       
828                        /*------------------*/
829                        if (iEventCount >= sz_event_list) {     /* reallocation.. */
830                                dprint(3, "    ++ realloc %d event list space..\n", sz_event_list*2);
831                                p = DHL_OS_Malloc(sz_event_list * 2 * sizeof(DMW_EpgEvent));
832                                if (p == NULL) {
833                                        dprint(0, "!! out of memory for Eventlist\n");
834                                        /* Áö±Ý±îÁö ¸¸µé¾î³õÀº ¸®¼Ò½º°¡ ¸¹À¸¹Ç·Î ÀÌ »óÅ¿¡¼­ ´ë·« ¸¶¹«¸®Çؼ­ ¸®ÅÏÇÑ´Ù.. */
835                                        for (i=0; i<iEventCount; i++)
836                                                FreeEpgEventItem(&EventList[i]);
837                                        DHL_OS_Free((void**)&EventList);
838                                        SAFE_EXIT(statusOutOfMemory);
839                                }
840                                memcpy(p, EventList, sizeof(DMW_EpgEvent)*sz_event_list);
841                                DHL_OS_Free((void**)&EventList);
842                                EventList = p;
843                                sz_event_list *= 2;
844                        }
845                        /*----------------
846                                 Parsing!!!
847                                   DMW_EpgEvent pEventList[iEventCounts] <--- event
848                        */
849                        p = &EventList[iEventCount];
850                        dprint(3, "   eit[%d] %dth event id (0x%x) parsed to 0x%x\n", 
851                                                        iEit, iEventCount, event->event_id, p);
852                       
853                        /*---------- General Info --------------*/
854                       
855                        p->programId = event->event_id;
856                        p->programLength = event->length_in_seconds;
857                        p->startTime = event->start_time;
858       
859                        /*---------- Rating Info --------------*/
860
861                        if (flag & GET_EVENT_RATING) 
862                        {
863                                if (DoFakeRatingData(rf, &p->rating)) {
864                                        /* fake rrt data loading success. */
865                                }
866                                else {
867                                        status = DMW_ParseRatingDescriptor(event->descriptors, event->descriptor_length, 
868                                                                                        &p->rating);
869                                        if (status) {
870                                                p->rating.region_count = 0;
871                                                /* dprint(0, "[RRT] no rating info from eit\n"); */
872                                        }
873                                }
874                        }
875       
876                        /*---------- Caption Info --------------*/
877                       
878                        if (flag & GET_EVENT_CAPTION)
879                        {
880                                status = DMW_ParseCaptionDescriptor(event->descriptors, event->descriptor_length, 
881                                                                                        &p->caption);
882                               
883                                if (status) {
884                                        if (status != statusNotFound)
885                                                dprint(0, "!! err in GetCaptionDesc:ParsingCaDesc.. %d\n", status);
886                                        p->caption = NULL; 
887                                }
888                        }
889
890                        /*---------- Title Info --------------*/
891                       
892                        if (flag & GET_EVENT_TITLE)
893                        {
894                                if (event->title_length > 0) {
895                                        if((flag&GET_EVENT_STATIC_MEM)==0)
896                                                p->titleText = DHL_OS_Malloc(event->title_length+1);
897                                        if (p->titleText) {
898                                                p->titleTextLength = event->title_length;
899                                                memcpy(p->titleText, event->title, event->title_length);
900                                        }
901                                        else {
902                                                dprint(0, "!! out of memory for titletext len %d of event[%d][%d]\n",
903                                                                        event->title_length, iEit, iEvent);
904                                                p->titleTextLength = 0;
905                                        }
906                                }
907                                else {
908                                        dprint(0, "!! event title length %d\n", event->title_length); /* cafrii 060321 bugfix %n->%d */
909                                        p->titleText = NULL;
910                                        p->titleTextLength = 0;
911                                }
912                        }
913                       
914                        /*---------- Text Info --------------
915                                 etmÀ» ãÀ¸·Á¸é ett list¸¦ µÚÁ®¾ß ÇÑ´Ù..
916                        */
917                        /* cafrii 070730 bugfix, GET_EVENT_TITLE->GET_EVENT_TEXT */
918                        if (flag & GET_EVENT_TEXT)
919                        {
920                                UINT32 etm_id;
921                                etm_id = MakeEventETMID(source_id, event->event_id);
922                                        /* cafrii 041028, MakeETMID -> MakeEventETMID */
923                               
924                                /* ¸ðµç ett array¸¦ ´Ù µÚÁ®°¡¸ç,
925                                         etm_id ¿¡ ÇØ´çµÇ´Â ett·ÎºÎÅÍ etmÀ» °¡Á®¿Í¼­ º¹»çÇÑ´Ù..
926                                       
927                                         --> iEit-1, iEit, iEit+1 ÀÌ·¸°Ô ¼¼°³¸¸ ºñ±³ÇÏ¸é µÉ °Í °°´Ù.
928                                         EitÀÇ À§Ä¡¿Í ±×¸® ¸Ö¸® ¶³¾îÁ® ÀÖÁö ¾ÊÀ» °ÍÀ̹ǷÎ.
929                                */
930                                /* for (i=0; i<128; i++) // <-- inefficient!! */
931                                for (i= max(0, iEit-1); i<= min(127, iEit+1); i++)      /* cafrii 041223 change */
932                                {
933                                        if (subchInfo->n_ett[i] == 0 || subchInfo->etts[i] == NULL) continue;
934                                        for (k=0; k<subchInfo->n_ett[i]; k++) 
935                                        {
936                                                if (subchInfo->etts[i][k] == NULL) continue;
937                                                if (subchInfo->etts[i][k]->ETM_id == etm_id) {
938                                                        ett = subchInfo->etts[i][k];
939                                                       
940                                                        if (ett->extended_text_message_length > 0) {
941                                                                if((flag&GET_EVENT_STATIC_MEM)==0)
942                                                                        p->eventETM = DHL_OS_Malloc(ett->extended_text_message_length+1);
943                                                                if (p->eventETM == NULL) {
944                                                                        dprint(0, "!! out of memory for etm len %d of ett[%d][%d]\n",
945                                                                                        ett->extended_text_message_length, i, k);
946                                                                        p->eventETMLength = 0;
947                                                                }
948                                                                else {
949                                                                        p->eventETMLength = ett->extended_text_message_length;
950                                                                        memcpy(p->eventETM, ett->extended_text_message, p->eventETMLength);
951                                                                }
952                                                        }
953                                                        else {  /* etm length °¡ À߸øµÇ¾ú´Ù.. ¹«½Ã.. */
954                                                                dprint(0, "!! ett[%d][%d] etm len %d\n", i, k, ett->extended_text_message_length);
955                                                                p->eventETM = NULL;
956                                                                p->eventETMLength = 0;
957                                                        }
958                                                        goto label_end_etm;     /* go out of this loop!! */
959                                                }
960                                        }
961                                }
962label_end_etm:
963                                ;       /* cafrii 070327 add to remove compiler warning */
964                        }
965                       
966                        iEventCount++;
967                       
968                        if (iEventCount >= maxEvent) {
969                                dprint(3, "  max event limit %d reached\n", maxEvent);
970                                goto label_end_loop;
971                        }
972                       
973                }       /* for iEvent */
974               
975        }       /* for iEit */
976       
977
978label_end_loop:
979
980        dprint(1, "Total %d events copied.. 0x%x\n", iEventCount, EventList);
981
982        if (1)  /* cafrii 061106 add sorting... */
983        {
984                int n_change = 0;
985                DMW_EpgEvent tmpEvent;
986               
987                for (i=0; i<iEventCount-1; i++)
988                {
989                        for (k=i+1; k<iEventCount; k++)
990                        {
991                                /* compare i and k, and swap if required */
992                                if (EventList[i].startTime > EventList[k].startTime) {
993                                        tmpEvent = EventList[i];
994                                        EventList[i] = EventList[k];
995                                        EventList[k] = tmpEvent;
996                                        n_change++;
997                                }
998                        }
999                }
1000                if (n_change > 0)
1001                        dprint(2, " sorting.. %d changes\n", n_change);
1002        }
1003               
1004        if (g_PrintEventInfo) {
1005                for (i=0; i<iEventCount; i++) {
1006                        p = &EventList[i];
1007                        if (dprintable(3))
1008                                DHL_OS_Printf("  Event[%d] id %x, start 0x%x, %d:%02d, title %d, etm %d\n", i, 
1009                                        p->programId, p->startTime, p->programLength/60, p->programLength%60, 
1010                                        p->titleTextLength, p->eventETMLength);
1011                        if (p->titleTextLength && dprintable(3))
1012                                Dmc_PrintMultipleString(p->titleText, p->titleTextLength, 10, 0);       /* indent 10 */
1013                        if (p->eventETMLength && dprintable(3))
1014                                Dmc_PrintMultipleString(p->eventETM, p->eventETMLength, 10, 0);         /* indent 10 */
1015                }
1016        }
1017
1018        if (aFoundEvents && piEventCounts) {
1019                /* BK modified (05.08.02), memory leakage */
1020                if(iEventCount>0){
1021                        if((flag&GET_EVENT_STATIC_MEM)==0)
1022                                *aFoundEvents = EventList;
1023                        *piEventCounts = iEventCount;
1024                }
1025                else{
1026                        /*iEventCount==0À¸·Î ³»·Á ¿À´Â °æ¿ì°¡ ¹ß»ýÇÔ, ÀÌ °æ¿ì caller¿¡¼­´Â ÇØÁ¦ÇÏÁö ¾Ê´Â´Ù.
1027                                 EventList freeÇϰí caller¿¡°Ô ³Ñ±âÁö ¾Ê´Â´Ù. */
1028                        if((flag&GET_EVENT_STATIC_MEM)==0) {
1029                                DHL_OS_Printf("BKDBG] iEventCount=%d, free event list\n",iEventCount);
1030                                DHL_OS_Free((void**)&EventList);
1031                                *aFoundEvents = NULL;
1032                                *piEventCounts = 0;
1033                        }
1034                        returnStatus = statusNotFound;  /* cafrii 050808 add */
1035                }
1036        }
1037        else {
1038                dprint(0, "!! null argument! free 0x%x\n", EventList);
1039                DMW_EPG_FreeEpgEvents(EventList, iEventCount);
1040                EventList = NULL;
1041                iEventCount = 0;
1042        }
1043       
1044       
1045label_exit:
1046        Dmc_EpgLockCoreDB(FALSE);
1047       
1048        return returnStatus;
1049}
1050
1051STATUS DMW_EPG_GetEventsInRange(int iUCMId, UINT32 nStartTime, UINT32 nDuration, 
1052                                        DMW_EpgEventPtr *aFoundEvents, int *piEventCounts, UINT32 flag)
1053{
1054        int idx;
1055        int rf, source_id = 0;
1056       
1057        dprint(1, "DMW_EPG_GetEventsInRange uid %d\n", iUCMId);
1058       
1059        /* Uid·Î ºÎÅÍ RF °ªÀ» ¾Ë¾Æ³½´Ù.. */
1060        DMW_MSC_LockUcm();
1061                idx = DMW_MSC_Uid2Index(iUCMId);
1062                if (idx >= 0) {
1063                        rf = g_UCM[idx].RF;
1064                        source_id = g_UCM[idx].source_id;
1065                }
1066                else {
1067                        rf = -1;
1068                }
1069        DMW_MSC_UnlockUcm();
1070       
1071        if (rf < 0) return statusNotFound;
1072
1073        return DMW_EPG_GetEventsByRF(rf, source_id, nStartTime, nDuration,
1074                                        aFoundEvents, piEventCounts, flag);
1075}
1076
1077
1078STATUS DMW_EPG_GetEventInTime(int iUCMId, UINT32 nTime, 
1079                                                        DMW_EpgEventPtr *pFoundEvent, UINT32 flag)
1080{
1081        int idx;
1082        int rf, source_id = 0;
1083       
1084        dprint(1, "DMW_EPG_GetEventsInTime uid %d\n", iUCMId);
1085       
1086        /* Uid·Î ºÎÅÍ RF °ªÀ» ¾Ë¾Æ³½´Ù.. */
1087        DMW_MSC_LockUcm();
1088                idx = DMW_MSC_Uid2Index(iUCMId);
1089                if (idx >= 0) {
1090                        rf = g_UCM[idx].RF;
1091                        source_id = g_UCM[idx].source_id;
1092                }
1093                else {
1094                        rf = -1;
1095                }
1096        DMW_MSC_UnlockUcm();
1097       
1098        if (rf < 0) return statusNotFound;
1099
1100        return DMW_EPG_GetEventInTimeByRf(rf, source_id, nTime, pFoundEvent, flag);
1101       
1102}
1103
1104
1105STATUS DMW_EPG_GetEventInTimeByRf(int rf, int source_id, UINT32 nTime, 
1106                                                        DMW_EpgEventPtr *pFoundEvent, UINT32 flag)
1107
1108{
1109        int i, nEventCount;
1110        STATUS status;
1111       
1112        dprint(1, "DMW_EPG_GetEventsInTimeByRf (rf %d, sid %d)\n", rf, source_id);
1113
1114        flag = (flag & ~0xffff) | 1;
1115        /* max event °¹¼ö¸¦ 1·Î ÇÑ´Ù. ÇѰ³¸¸ ÇÊ¿äÇϱ⠶§¹®. */
1116       
1117        status = DMW_EPG_GetEventsByRF(rf, source_id, nTime, 1, pFoundEvent, &nEventCount, flag);
1118                /* nDuration : 1 seconds
1119                         nEventToFetch : 1
1120                         ¿©·¯°³ÀÇ event°¡ ½Ã°£»óÀ¸·Î °ãÃÆÀ» ¶§¿¡µµ ´Ü 1°³¸¸ °¡Á®¿Â´Ù.. */
1121       
1122        if (status) return status;
1123       
1124        if (nEventCount > 1) {
1125                /* ÇѰ³¸¸ °¡Á®¿À±æ ¹Ù·¨´Âµ¥, 2°³ ÀÌ»ó Get µÇ¾ú´Ù¸é Çϳª¸¸ ³öµÎ°í ´Ù Áö¿î´Ù.. */
1126                dprint(0, "!!!! too many events %d.. delete all without 1\n", nEventCount);
1127                for(i=1; i<nEventCount; i++) {
1128                        dprint(2, "     delete [%d] event\n", i);
1129                        FreeEpgEventItem(&(*pFoundEvent)[i]);
1130                }
1131                /* ¸Þ¸ð¸®¸¦ shrink ÇÒ ÇÊ¿ä´Â ¾ø´Ù.. ³ªÁß¿¡ Àüü freeÇÒ¶§ ¾ø¾îÁú °ÍÀÓ.. */
1132        }
1133        return statusOK;        /* cafrii 040728 add */
1134}
1135
1136/*  DMW_EPG_GetEventByEvid: API
1137
1138        Epg DB¿¡¼­ ƯÁ¤ event Á¤º¸¸¦ ã´Â´Ù.
1139       
1140        rf, source_id ´ë½Å ucm_id (uid)¸¦ »ç¿ëÇÏ¿© ä³Î ÁöÁ¤ÇÏ´Â °ÍÀ» Á¦¿ÜÇϸé
1141        DMW_EPG_GetEventByEvidAndRf ¿Í µ¿ÀÏÇÏ´Ù.
1142*/
1143STATUS DMW_EPG_GetEventByEvid(int iUCMId, UINT16 evid, 
1144                                                        DMW_EpgEventPtr *pFoundEvent, UINT32 flag)
1145{
1146        int idx;
1147        int rf, source_id = 0;
1148       
1149        dprint(1, "%s: uid %d\n", __FUNCTION__, iUCMId);
1150       
1151        /* Uid·Î ºÎÅÍ RF °ªÀ» ¾Ë¾Æ³½´Ù.. */
1152        DMW_MSC_LockUcm();
1153                idx = DMW_MSC_Uid2Index(iUCMId);
1154                if (idx >= 0) {
1155                        rf = g_UCM[idx].RF;
1156                        source_id = g_UCM[idx].source_id;
1157                }
1158                else {
1159                        rf = -1;
1160                }
1161        DMW_MSC_UnlockUcm();
1162       
1163        if (rf < 0) return statusNotFound;
1164
1165        return DMW_EPG_GetEventInTimeByRf(rf, source_id, evid, pFoundEvent, flag);
1166
1167}
1168
1169/*  DMW_EPG_GetEventByEvidAndRf: API
1170       
1171        Epg DB¿¡¼­ ƯÁ¤ ÇÁ·Î±×·¥ Á¤º¸¸¦ ã´Â´Ù.
1172
1173        @rf, @source_id´Â Á¤º¸¸¦ ãÀ¸·Á°í Çϴ ä³Î(¼­ºêä³Î) id ÀÌ´Ù.
1174        @evid´Â ã°íÀÚ ÇÏ´Â ÇÁ·Î±×·¥ÀÇ event_id ÀÌ´Ù.
1175
1176        ÇÁ·Î±×·¥À» ã¾Æ¼­ ³»ºÎ¿¡¼­ DMW_EpgEvent* ¹öÆÛ¸¦ µ¿Àû ÇÒ´çÇϰí,
1177        @ppReturnEvent¸¦ ÅëÇØ¼­ ¸®ÅÏÇÑ´Ù.
1178        »ç¿ë ÈÄ DMW_EPG_FreeEpgEvent()¸¦ ÀÌ¿ëÇÏ¿© free ÇØ¾ß ÇÑ´Ù.
1179
1180        @flag¸¦ »ç¿ëÇÏ¿© ¾î¶°ÇÑ À̺¥Æ® Á¤º¸¸¦ ãÀ» °ÍÀÎÁö ÁöÁ¤ÇÑ´Ù.
1181        flag Çü½ÄÀº DMW_EPG_GetEventsByRF()ÀÇ °æ¿ì¿Í ºñ½ÁÇÏÁö¸¸
1182        maxEvent Á¤º¸´Â »ç¿ëµÇÁö ¾Ê´Â´Ù. ÀÌ ÇÔ¼ö´Â Ç×»ó ÇϳªÀÇ event¸¸ ã´Â´Ù.
1183       
1184        @flag·Î ¾Æ¹«°Íµµ ÁöÁ¤ÇÏÁö ¾ÊÀ¸¸é (0À» ÁöÁ¤Çϸé) ¾ÆÁÖ ±âº»ÀûÀÎ Á¤º¸¸¸À» ¸®ÅÏÇϹǷÎ
1185        ´ëºÎºÐ GET_EVENT_TITLE¿Í °°Àº Ç÷¡±×¸¦ ÁöÁ¤ÇØ¾ß ÇÑ´Ù.
1186
1187        ¸®Åϰª: ãÀ¸¸é statusOK, ¸øÃ£À¸¸é statusNotFound.
1188       
1189*/
1190STATUS DMW_EPG_GetEventByEvidAndRf(int rf, int source_id, UINT16 evid, 
1191                                                        DMW_EpgEventPtr *ppReturnEvent, UINT32 flag)
1192{
1193        #define SAFE_EXIT(val) returnStatus=(val); goto label_exit;
1194
1195        int iEit, iEvent;
1196        STATUS returnStatus = statusNotFound;
1197       
1198        DmcChannelInfo    *chInfo = NULL;
1199        DmcSubChannelInfo *subchInfo = NULL;
1200        DMW_EpgEvent      *pEvent = NULL;
1201
1202        dprint(1, "%s: rf %d, source_id %d, flag 0x%x\n", 
1203                                        __FUNCTION__, rf, source_id, flag);
1204       
1205        if (rf < 0) return statusNotFound;
1206       
1207        Dmc_EpgLockCoreDB(TRUE);
1208       
1209        if (!(chInfo = SRCH_ChInfo(rf))) {
1210                dprint(2, "!! rf %d chInfo not found.. maybe epg is not ready..\n", rf);
1211                SAFE_EXIT(statusNotFound);
1212        }
1213        if (!(subchInfo = SRCH_SubchInfo(chInfo, source_id))) {
1214                dprint(1, "!! subchInfo source_id %d not found..\n", source_id);
1215                SAFE_EXIT(statusNotFound);
1216        }
1217
1218        pEvent = DHL_OS_Malloc(sizeof(DMW_EpgEvent));
1219        if (pEvent == NULL) {
1220                dprint(0, "!! out of memory for Event\n");
1221                SAFE_EXIT(statusOutOfMemory);
1222        }
1223        memset(pEvent, 0, sizeof(DMW_EpgEvent));
1224
1225        /* ¸ðµç eit, ¸ðµç event ¿¡¼­ evid¸¦ °¡Áø event Á¤º¸¸¦ ã´Â´Ù. */
1226        for (iEit=0; iEit<128; iEit++) 
1227        {
1228                eitPtr_t eit = subchInfo->eits[iEit];
1229               
1230                if (eit == NULL) continue; /* it is not error. not received yet. */
1231                if (eit->source_id != source_id) continue; /* something wrong. */
1232               
1233                for (iEvent=0; eit->event && iEvent<eit->numEvents; iEvent++) 
1234                {
1235                        if (eit->event[iEvent].event_id != evid) 
1236                                continue; /* this is not what we want to find. */
1237
1238                        /* now, we found the event! */
1239                        MakeEpgEvent(chInfo, subchInfo, iEit, &eit->event[iEvent], flag, pEvent);
1240                       
1241                        returnStatus = statusOK;
1242                        goto label_exit;
1243                }
1244        }
1245       
1246label_exit:
1247        Dmc_EpgLockCoreDB(FALSE);
1248
1249        if (returnStatus != statusOK) {
1250                /* event not found. don't return event pointer. */
1251                DHL_OS_Free((void**)&pEvent);
1252        }
1253        else {
1254                *ppReturnEvent = pEvent;
1255        }
1256        return returnStatus;
1257}
1258
1259/* cafrii 060814 add */
1260void DMW_EPG_GetScanStatus(int uid, DmcEpgStatus *pStat)
1261{
1262        /* ÇØ´ç subchannelÀÌ complete »óÅÂÀÎÁö ¾Æ´ÑÁö..
1263                 ÇØ´ç subchannelÀÇ ÃÑ °Ë»ö ´©Àû ½Ã°£ÀÌ ¸îÃÊÀÎÁö.. */
1264
1265        int rf, source_id = 0;
1266        int idx;
1267        DmcEpgStatus stat;
1268
1269        memset(&stat, 0, sizeof(stat));
1270       
1271        /* Uid·Î ºÎÅÍ RF °ªÀ» ¾Ë¾Æ³½´Ù.. */
1272        DMW_MSC_LockUcm();
1273                idx = DMW_MSC_Uid2Index(uid);
1274                if (idx >= 0) {
1275                        rf = g_UCM[idx].RF;
1276                        source_id = g_UCM[idx].source_id;
1277                }
1278                else {
1279                        rf = -1;
1280                }
1281        DMW_MSC_UnlockUcm();
1282       
1283        if (rf < 0) 
1284                stat.cStatus = EPG_STATUS_NOT_FOUND;
1285        else
1286        {
1287                dprint(2, "DMW_EPG_GetEventsInTimeByRf (uid %d, rf %d, sid %d)\n", uid, rf, source_id);
1288               
1289                Dmc_EpgCheckScanStatus(rf, source_id, &stat);
1290        }
1291       
1292        if (pStat)
1293                *pStat = stat;
1294}
1295
1296
1297
1298#if COMMENT
1299____API2____(){}
1300#endif
1301
1302/*
1303         ÇØ´ç ½Ã°£ÀÇ À̺¥Æ®¿¡¼­ Caption descrioptor Á¤º¸¸¦ ÃßÃâÇÑ´Ù.
1304         ÇöÀç CC screen ratio¸¦ ¾Ë¾Æ³»±â À§Çؼ­ »ç¿ëÇÑ´Ù.
1305         Banner OSD¿¡¼­ CC icon Ç¥½Ã¿ëÀ¸·Î´Â CC MWÀÇ query¸¦ ÀÌ¿ëÇÏ´Â°Ô ³´´Ù.
1306*/ 
1307STATUS DMW_EPG_GetCaptionDescriptor(int iUCMId, UINT32 nTime, 
1308                                        captionServiceDescriptorPtr_t *pccdesc)
1309{
1310        STATUS status = statusOK;
1311        int i;
1312        int rf, source_id = 0;
1313        int iEit, iEvent;
1314
1315        captionServiceDescriptor_t *cc_descriptor = NULL;
1316
1317        DmcChannelInfo *chInfo = NULL;
1318        DmcSubChannelInfo *subchInfo = NULL;
1319       
1320        if (pccdesc == NULL)
1321                return statusInvalidArgument;
1322       
1323        /* Uid·Î ºÎÅÍ RF °ªÀ» ¾Ë¾Æ³½´Ù.. */
1324        if (1) {
1325                int idx;
1326
1327                DMW_MSC_LockUcm();
1328                idx = DMW_MSC_Uid2Index(iUCMId);
1329                if (idx >= 0) {
1330                        rf = g_UCM[idx].RF;
1331                        source_id = g_UCM[idx].source_id;
1332                }
1333                else {
1334                        rf = -1;
1335                }
1336                DMW_MSC_UnlockUcm();
1337        }
1338
1339        /* Core DB¸¦ °Ë»öÇÑ´Ù. */
1340        *pccdesc = NULL;
1341        Dmc_EpgLockCoreDB(TRUE);
1342       
1343        chInfo = Dmc_GetChannelInfo(g_EpgDB, rf);
1344        if (chInfo == NULL) {
1345                dprint(2, "!! rf %d chInfo not found.. maybe epg is not ready..\n", rf);
1346                Dmc_EpgLockCoreDB(FALSE);
1347                return statusNotFound;
1348        }
1349
1350        for (i=0; i<chInfo->n_subchannel; i++) {
1351                if (chInfo->subchannel[i].source_id == source_id) {
1352                        subchInfo = &chInfo->subchannel[i];
1353                        break;
1354                }
1355        }
1356        if (!subchInfo) {
1357                dprint(1, "!! subchInfo source_id %d not found..\n", source_id);
1358                Dmc_EpgLockCoreDB(FALSE);
1359                return statusNotFound;
1360        }
1361
1362        for (iEit=0; iEit<=1; iEit++)   /* Eit-0, Eit-1 ¸¸ °Ë»ç.. */
1363        {
1364                eitPtr_t eit;                                                           /* temporary shortcut value */
1365                eitEventPtr_t event;
1366
1367                eit = subchInfo->eits[iEit];
1368                if (eit == NULL) continue;
1369
1370                if (eit->source_id != source_id) {
1371                        dprint(0, "!! eit[%d] source id %d mismatch to subch source id %d\n", iEit, eit->source_id, source_id);
1372                        continue;
1373                }
1374               
1375                if (eit->event == NULL || eit->numEvents <= 0) {
1376                        continue;
1377                }
1378
1379                for (iEvent=0; iEvent<eit->numEvents; iEvent++) {
1380                        event = &eit->event[iEvent];
1381                       
1382                        if (nTime < event->start_time || 
1383                                event->start_time + event->length_in_seconds-1 < nTime)
1384                                continue;
1385                               
1386                        status = DMW_ParseCaptionDescriptor(event->descriptors, event->descriptor_length, 
1387                                                                                &cc_descriptor);
1388                       
1389                        if (status) {
1390                                if (status != statusNotFound)
1391                                        dprint(0, "!! err in GetCaptionDesc:ParsingCaDesc.. %d\n", status);
1392                                cc_descriptor = NULL; 
1393                        }
1394
1395                        *pccdesc = cc_descriptor;
1396                       
1397                        /* if (cc_descriptor) break; */
1398                        break;
1399                        /* cafrii 060308 fix
1400                                 °á°ú¿¡ »ó°ü¾øÀÌ ¹Ù·Î ºüÁ® ³ª°£´Ù.
1401                                 µÑ ÀÌ»óÀÇ event°¡ ÁßøµÇ´Â °æ¿ì´Â °í·Á ¾ÈÇÑ´Ù. */
1402                }
1403               
1404                if (cc_descriptor) break;
1405        }
1406
1407        Dmc_EpgLockCoreDB(FALSE);
1408
1409        if (cc_descriptor == NULL) {    /* Event°¡ ¾ø°Å³ª, Rating Info°¡ event³»¿¡ ¾ø´Â °æ¿ì.. */
1410                dprint(3, "  no event or no rating info..\n");
1411                return statusNotFound;
1412        }
1413
1414        return status;
1415}
1416
1417
1418
1419STATUS DMW_EPG_GetCaptionDescriptorInPMT(captionServiceDescriptorPtr_t *pCC_Service)
1420{
1421        DHL_RESULT err;
1422        STATUS status = statusNotFound;
1423        UINT8 *pDescriptor = 0;
1424
1425        ProgramAVInfo *av = Dmc_LockAVMutex();
1426
1427        *pCC_Service = NULL;
1428
1429        if (av->pmt)
1430        {
1431                /* PMT¿¡¼­ descriptorsÁ¤º¸°¡ ÀÖÀ» °æ¿ì¸¸... */
1432                if (av->pmt->descriptors != NULL && av->pmt->descriptor_length > 0) {
1433                        status = DMW_GetPsipDescriptor(av->pmt->descriptors, 
1434                                                                        av->pmt->descriptor_length, 
1435                                                                        caption_service_tag, 
1436                                                                        0,             /* ù¹øÂ° instance¸¸ ã´Â´Ù. */
1437                                                                        &pDescriptor);
1438                }
1439                                                               
1440                if (!status) {
1441                        err = ParseCaptionServiceDescriptor(pDescriptor, pCC_Service);
1442                        if (!err)
1443                                status = statusOK;             
1444                        else
1445                                status = statusOutOfMemory;
1446                }
1447               
1448        }
1449
1450        Dmc_UnlockAVMutex();
1451
1452        return status;
1453}
1454
1455
1456
1457/*
1458         ÇöÀçÀÇ Rating Á¤º¸¸¦ queryÇÑ´Ù.
1459         rating block üũ¸¦ À§Çؼ­ »ç¿ëµÈ´Ù.
1460*/ 
1461STATUS DMW_EPG_GetRatingInfo(int iUCMId, UINT32 nTime, DMW_Rating5 *pRating)
1462{
1463        int idx;
1464        int rf, source_id = 0;
1465       
1466        DMW_MSC_LockUcm();
1467        idx = DMW_MSC_Uid2Index(iUCMId);
1468        if (idx >= 0) {
1469                rf = g_UCM[idx].RF;
1470                source_id = g_UCM[idx].source_id;
1471        }
1472        else {
1473                rf = -1;
1474        }
1475        DMW_MSC_UnlockUcm();
1476
1477        return DMW_EPG_GetRatingInfoByRF(rf, source_id, nTime, pRating);
1478}
1479
1480
1481/* cafrii 060605 add */
1482STATUS DMW_EPG_GetRatingInfoByRF(int rf, UINT16 source_id, UINT32 nTime, DMW_Rating5 *pRating)
1483{
1484        int i, j;
1485        STATUS status = statusOK;
1486               
1487        DmcChannelInfo *chInfo = NULL;
1488        DmcSubChannelInfo *subchInfo = NULL;
1489
1490        dprint(1, "%s: rf %d, sid %d, time %x\n", __FUNCTION__, rf, source_id, nTime);
1491
1492        if (pRating == NULL)
1493                return statusInvalidArgument;
1494
1495        pRating->region_count = 0;      /* cafrii 060609 add */
1496       
1497        /* fake rating ±â´É */
1498        if (DoFakeRatingData(rf, pRating))
1499                return statusOK;
1500       
1501        Dmc_EpgLockCoreDB(TRUE);
1502       
1503        chInfo = Dmc_GetChannelInfo(g_EpgDB, rf);
1504        if (chInfo == NULL) {
1505                dprint(0, "!! rf %d chInfo not found.. maybe epg is not ready..\n", rf);
1506                status = statusNotFound;
1507                goto label_exit;
1508        }
1509
1510        for (i=0; i<chInfo->n_subchannel; i++) {
1511                if (chInfo->subchannel[i].source_id == source_id) {
1512                        subchInfo = &chInfo->subchannel[i];
1513                        break;
1514                }
1515        }
1516        if (!subchInfo) {
1517                dprint(0, "!! subchInfo source_id %d not found..\n", source_id);
1518        }
1519       
1520        for(i=0; i<=1 && subchInfo; i++)        /* eit 0, 1 °Ë»ç */
1521        {
1522                eitPtr_t eit;                                                                           /* temporary shortcut value */
1523                eitEventPtr_t event;
1524               
1525                eit = subchInfo->eits[i];
1526                if (eit == NULL) continue;
1527
1528                if (eit->source_id != source_id) {
1529                        dprint(0, "!! eit[%d] source id %d mismatch to subch source id %d\n", 
1530                                                                        i, (int)eit->source_id, source_id);
1531                        continue;
1532                }
1533               
1534                if (eit->event == NULL || eit->numEvents <= 0)
1535                        continue;
1536               
1537                for (j=0; j<eit->numEvents; j++) 
1538                {
1539                        event = &eit->event[j];
1540                       
1541                        if (nTime < event->start_time || 
1542                                event->start_time + event->length_in_seconds-1 < nTime)
1543                                continue;
1544
1545                        /* cafrii 060609 add more check */
1546                        if (event->descriptor_length > 0) {
1547                                status = DMW_ParseRatingDescriptor(event->descriptors, event->descriptor_length, 
1548                                                        pRating);
1549                                if (status) {
1550                                        pRating->region_count = 0;
1551                                        /* dprint(0, "[RRT] no rating info from eit\n"); */
1552                                }
1553                                else
1554                                        status = statusOK;
1555                        }
1556                        /* event¸¦ Çϳª¶óµµ ó¸®ÇßÀ¸¸é ±× ´ÙÀ½ event¸¦ º¸Áö ¾Êµµ·Ï ÇÑ´Ù.
1557                                 event°¡ °ãÄ¡´Â °ÍÀ» Çã¿ëÇÏÁö ¾Ê´Â´Ù. */
1558                       
1559                        goto label_exit;
1560                }
1561        }
1562
1563        status = statusNotFound;        /* cafrii 060609 bugfix? */
1564       
1565label_exit:
1566        Dmc_EpgLockCoreDB(FALSE);
1567
1568        return status;
1569}
1570
1571
1572
1573STATUS DMW_EPG_GetRatingInfoInPMT(DMW_Rating5 *pRating)
1574{
1575        STATUS status = statusNotFound;
1576        ProgramAVInfo *av;
1577       
1578        av = Dmc_LockAVMutex();
1579        if (av->pmt) {
1580                status = DMW_ParseRatingDescriptor(av->pmt->descriptors, 
1581                                                        av->pmt->descriptor_length, 
1582                                                        pRating);
1583                if (status)
1584                        pRating->region_count = 0;
1585        }
1586        Dmc_UnlockAVMutex();
1587
1588        return status;
1589}
1590
1591
1592BOOL DMW_EPG_IsValidRating766Info(DMW_Rating766 *pr766)
1593{
1594        DMW_Rating766 r766 = *pr766;
1595       
1596        if (r766.type == RATING766_US_Entire_Audience ||
1597                r766.type == RATING766_US_Children ||
1598                r766.type == RATING766_US_MPAA ||
1599                r766.type == RATING766_CANADA_English ||
1600                r766.type == RATING766_CANADA_French)
1601        {       
1602                return TRUE;
1603        }
1604       
1605        return FALSE;
1606}
1607
1608/*
1609         General rating informationÀ»
1610         EIA 766 typeÀÇ rating informationÀ¸·Î º¯È¯ÇÑ´Ù.
1611         rating regionÀº 1, 2 ±×¸®°í Ưº°ÇÑ °æ¿ì 4 ±îÁö Æ÷ÇÔÇÑ´Ù.
1612*/
1613void DMW_EPG_ConvertToRating766Info(DMW_RatingRegion *pRegion, DMW_Rating766 *pR766)
1614{
1615        int nRatingTV = 0, nRatingTVY = 0, nRatingMPAA = 0; 
1616        int D=0, L=0, S=0, V=0, FV=0;
1617        int nRatingCaEng = -1, nRatingCaFre = -1;       /* Canadian RatingÀº 0°ªÀÌ valid ÇϹǷΠÁÖÀÇ.. */
1618        int i, region, count=0;
1619       
1620        DMW_Rating766 r766[RRT1_MAX_DIM];                                       /* = (DMW_Rating766 *)OS_Malloc(sizeof(DMW_Rating766)*5); */
1621       
1622        if (pR766 == NULL)
1623                return;
1624               
1625        if (pRegion == NULL) {  /* Missing rating üũ */
1626                /* memset(pR766, 0, sizeof(DMW_Rating766)); */
1627                for(i=0;i<RRT1_MAX_DIM;i++)
1628                        pR766[i].type = RATING766_NONE;
1629                return;
1630        }
1631
1632        /* cafrii 081217 ¸ÕÀú ÃʱâÈ­. */
1633        memset(r766, 0, sizeof(r766));
1634        for (i=0; i<RRT1_MAX_DIM; i++)
1635                r766[i].type = RATING766_NONE;
1636
1637        /* test¸¦ À§Çؼ­ region 4 ratingÀ» region 1À¸·Î °£ÁÖÇÏ´Â ¿É¼ÇÀ» µÐ´Ù. */
1638        region = pRegion->region_id;
1639        if (0 && region==0x04)  /* region 4 test -> Ȥ½Ã region 4µµ ¾²ÀÏ ¼ö ÀÖÀ¸¹Ç·Î ¸·À½*/
1640                region = 0x01;
1641
1642        if (region == 0x01)
1643                goto label_region_1;
1644
1645        if (region == 0x02)
1646                goto label_region_2;
1647       
1648        /* region1,2ÀÌ ¾Æ´Ï¸é.. */
1649        goto label_end;
1650        /*
1651        for(i=0;i<RRT1_MAX_DIM;i++)
1652                pR766[i].type = RATING766_NONE;
1653        return;
1654        */
1655
1656        #define ADJRANGE(val, mn, mx) ((val)>=(mn)&&(val)<=(mx) ? (val) : 0)
1657        #define ADJMAX(val, mx) ((val)<=(mx) ? (val) : 0)
1658       
1659
1660label_region_1:
1661        /*
1662                 1. µ¿ÀÏÇÑ dimensionÀÌ ¿©·¯°³ µé¾îÀÖ´Â °æ¿ì
1663                    -> dim 0, 5, 7 Àº óÀ½¿¡ ³ª¿Â °ÍÀ» ¿ì¼±. ³ª¸ÓÁö DLS..µîÀº ³ªÁß°É·Î overwrite
1664                 2. dim 0, 5, 7ÀÌ ¿©·¯°³ Æ÷ÇԵǾî ÀÖ´Â °æ¿ì
1665                    -> ³»ºÎ¿¡¼­ Á¤ÇÑ ¿ì¼± ¼øÀ§´ë·Î..
1666        */
1667        for (i=0; i<pRegion->num_dimensions; i++) {
1668                if (pRegion->dimension[i].index == 0 && nRatingTV == 0) {
1669                        nRatingTV = ADJRANGE(pRegion->dimension[i].value, 1, 5);
1670                }
1671                else if (pRegion->dimension[i].index == 5 && nRatingTVY == 0) {
1672                        nRatingTVY = ADJRANGE(pRegion->dimension[i].value, 1, 2);
1673                }
1674                else if (pRegion->dimension[i].index == 7 && nRatingMPAA == 0) {
1675                        nRatingMPAA = ADJRANGE(pRegion->dimension[i].value, 1, 8);
1676                }
1677                /* DLSV µîÀº º¹¼ö°³ Á¸ÀçÇÒ °æ¿ì ÃÖÈÄÀÇ °ªÀÌ Ã¤ÅõÊ.     */
1678                else if (pRegion->dimension[i].index == 1)
1679                        D = pRegion->dimension[i].value ? 1 : 0;
1680                else if (pRegion->dimension[i].index == 2)
1681                        L = pRegion->dimension[i].value ? 1 : 0;
1682                else if (pRegion->dimension[i].index == 3)
1683                        S = pRegion->dimension[i].value ? 1 : 0;
1684                else if (pRegion->dimension[i].index == 4)
1685                        V = pRegion->dimension[i].value ? 1 : 0;
1686                else if (pRegion->dimension[i].index == 6)
1687                        FV = pRegion->dimension[i].value ? 1 : 0;
1688        }
1689
1690        /* À§¿¡¼­ ¹Ì¸® ÃʱâÈ­.. */
1691        /* memset(r766,0,sizeof(DMW_Rating766)*RRT1_MAX_DIM); */
1692
1693        /* validity check.. some combination is not allowed */
1694       
1695        if (nRatingTV) {
1696                r766[count].type = RATING766_US_Entire_Audience;
1697                r766[count].value = nRatingTV;
1698                if (nRatingTV != 1) {   /* TV-NoneÀº ¾î¶°ÇÑ DLSVµµ Çã¿ëÇÏÁö ¾ÊÀ½ */
1699                        r766[count].D = nRatingTV != 5 ? D : 0; /* TV-MA´Â D¸¦ Çã¿ëÇÏÁö ¾ÊÀ½ */
1700                        r766[count].L = L;
1701                        r766[count].S = S;
1702                        r766[count].V = V;
1703                }
1704                count++;
1705        }
1706        if (nRatingTVY) {
1707                r766[count].type = RATING766_US_Children;
1708                r766[count].value = nRatingTVY;
1709                r766[count].FV = nRatingTVY == 2 ? FV : 0;      /* FV´Â TV-Y7¿¡¼­¸¸ Çã¿ë */
1710                count++;
1711        }
1712        if (nRatingMPAA) {
1713                r766[count].type = RATING766_US_MPAA;
1714                r766[count].value = nRatingMPAA;
1715                count++;
1716        }
1717        goto label_end;
1718
1719label_region_2:
1720       
1721        /* iskang 080623. 1°³¸¸ °Ë»çÇÏ´ø °ÍÀº dim¼ö¸¸Å­ ÇÑ´Ù. */
1722               
1723        /* cafrii 081217 bugfix!!
1724                 dimensionÀÌ 3°³ ÀÌ»óÀÎ °æ¿ì r766 buf overflow ¹ß»ý!!
1725                 loop ¸ÕÀú µ¹¸é¼­ üũ ÇÑ ÈÄ r766 write ÇÔ.
1726               
1727                 ¸Ç óÀ½ ¹ß°ßµÇ´Â °ªµé·Î nRatingCaEng, nRatingCaFre ÀúÀå.
1728        */
1729        for (i=0; i<pRegion->num_dimensions; i++) {
1730                if (pRegion->dimension[i].index == 0 && nRatingCaEng == -1) {
1731                        nRatingCaEng = ADJMAX(pRegion->dimension[i].value, 6);
1732                }
1733                else if (pRegion->dimension[i].index == 1 && nRatingCaFre == -1) {
1734                        nRatingCaFre = ADJMAX(pRegion->dimension[i].value, 5);
1735                }
1736        }
1737       
1738        if (nRatingCaEng >= 0) {
1739                r766[count].type = RATING766_CANADA_English;
1740                r766[count].value = nRatingCaEng;
1741                count++;
1742        }
1743        if (nRatingCaFre >= 0) {
1744                r766[count].type = RATING766_CANADA_French;
1745                r766[count].value = nRatingCaFre;
1746                count++;
1747        }
1748
1749        goto label_end;
1750       
1751        #undef ADJRANGE
1752        #undef ADJMAX
1753
1754label_end:
1755
1756         memcpy(pR766, r766, sizeof(DMW_Rating766)*RRT1_MAX_DIM);       
1757
1758}
1759
1760
1761
1762char *DMW_EPG_Rating766String(DMW_Rating766 *pInfo, char *buf)
1763{
1764        /* argument 'buf'´Â ÃæºÐÇÑ °ø°£À» °¡Áö°í ÀÖ¾î¾ß ÇÑ´Ù°í °¡Á¤ÇÏÀÚ.
1765                 ÃÖ´ë ±æÀÌ´Â
1766                 "TV-PG (DLSV)"
1767                 "TV-PG-D-L-S-V"
1768                 "TV-PG (D,L,S,V)"
1769        */
1770        static char _buf[30];   /* internal static buffer */
1771       
1772        if (buf == NULL) buf = _buf;
1773               
1774        if (pInfo->type == RATING766_US_Children) {
1775                strcpy(buf,
1776                                (pInfo->value == 1) ? "TV-Y" :
1777                                (pInfo->value == 2) ? "TV-Y7" : "TV-Y?");
1778                strcat(buf, pInfo->value==2 && pInfo->FV ? "-FV" : "");
1779        }
1780        else if (pInfo->type == RATING766_US_Entire_Audience) {
1781                strcpy(buf,
1782                                (pInfo->value == 1) ? "TV-None" :
1783                                (pInfo->value == 2) ? "TV-G" :
1784                                (pInfo->value == 3) ? "TV-PG" :
1785                                (pInfo->value == 4) ? "TV-14" :
1786                                (pInfo->value == 5) ? "TV-MA" : "TV-?");
1787       
1788        #if 0
1789                /* °ýÈ£¸¦ »ç¿ëÇϴ ǥ±â¹ý, "TV-PG (DLSV)" */
1790                if (pInfo->D||pInfo->L||pInfo->S||pInfo->V) {
1791                        strcat(buf, " (");
1792                        if (pInfo->D) strcat(buf, "D");
1793                        if (pInfo->L) strcat(buf, "L");
1794                        if (pInfo->S) strcat(buf, "S");
1795                        if (pInfo->V) strcat(buf, "V");
1796                        strcat(buf, ")");
1797                }
1798        #elif 0
1799                /* °ýÈ£¿Í coma »ç¿ëÇϴ ǥ±â¹ý, "TV-PG (D,L,S,V)"
1800                       
1801                         cafrii 060801, remove parenthasis to shrink string length
1802                          --> "TV-PG D,L,S,V"
1803                */
1804                if (pInfo->D||pInfo->L||pInfo->S||pInfo->V) {
1805                        BOOL comma = 0;
1806                        strcat(buf, " ");       /* strcat(buf, " ("); */
1807                        if (pInfo->D) strcat(buf, comma ? ",D" : "D"), comma=1;
1808                        if (pInfo->L) strcat(buf, comma ? ",L" : "L"), comma=1;
1809                        if (pInfo->S) strcat(buf, comma ? ",S" : "S"), comma=1;
1810                        if (pInfo->V) strcat(buf, comma ? ",V" : "V"), comma=1;
1811                        /* strcat(buf, ")"); */
1812                }
1813        #elif 1
1814                /* dash¸¦ »ç¿ëÇϴ ǥ±â¹ý. "TV-PG-D-L-S-V" */
1815                if (pInfo->D||pInfo->L||pInfo->S||pInfo->V) {
1816                        strcat(buf, pInfo->D ? "-D" : "");
1817                        strcat(buf, pInfo->L ? "-L" : "");
1818                        strcat(buf, pInfo->S ? "-S" : "");
1819                        strcat(buf, pInfo->V ? "-V" : "");
1820                }
1821        #else
1822                /* any other format? */
1823        #endif
1824        }
1825        else if (pInfo->type == RATING766_US_MPAA) {
1826                strcpy(buf,
1827                                (pInfo->value == 1) ? "MPAA-N/A" :
1828                                (pInfo->value == 2) ? "MPAA-G" :
1829                                (pInfo->value == 3) ? "MPAA-PG" :
1830                                (pInfo->value == 4) ? "MPAA-PG-13" :
1831                                (pInfo->value == 5) ? "MPAA-R" :
1832                                (pInfo->value == 6) ? "MPAA-NC-17" :
1833                                (pInfo->value == 7) ? "MPAA-X" :
1834                                (pInfo->value == 8) ? "MPAA-NR" : "MPAA ?");
1835        }
1836        else if (pInfo->type == RATING766_CANADA_English) {
1837                strcpy(buf, 
1838                                (pInfo->value == 0) ? "E" :
1839                                (pInfo->value == 1) ? "C" :
1840                                (pInfo->value == 2) ? "C8+" :
1841                                (pInfo->value == 3) ? "G" :
1842                                (pInfo->value == 4) ? "PG" :
1843                                (pInfo->value == 5) ? "14+" :
1844                                (pInfo->value == 6) ? "18+" : "CA Eng ?");
1845        }
1846        else if (pInfo->type == RATING766_CANADA_French) {
1847                strcpy(buf, 
1848                                (pInfo->value == 0) ? "E" :
1849                                (pInfo->value == 1) ? "G" :
1850                                (pInfo->value == 2) ? "8 ans+" :
1851                                (pInfo->value == 3) ? "13 ans+" :
1852                                (pInfo->value == 4) ? "16 ans+" :
1853                                (pInfo->value == 5) ? "18 ans+" : "CA Fre ?");
1854        }
1855        else {  /* RATING766_NONE */
1856                strcpy(buf, "None");    /* ÀÌ·±°Ô ³ª¿À¸é ¾ÈµÈ´Ù. */
1857        }
1858        return buf;
1859}
1860
1861
1862
1863/*----------------------------------
1864          DMW_EPG_CheckRatingBlockByRRT
1865       
1866          RRT ±âÁØÀ¸·Î pRating Á¤º¸ÀÇ block ¿©ºÎ¸¦ üũÇÑ´Ù.
1867          param:
1868            IN: pRating
1869            OUT: pbNoRating,
1870       
1871          return value
1872            TRUE : blocked
1873*/
1874BOOL DMW_EPG_CheckRatingBlockByRRT(DMW_Rating5 *pRating, BOOL *pbNoRating)
1875{
1876        /* ÁÖÀÇ:
1877                  RRT°¡ º¯°æµÇ´Â ¼ø°£ µîÀÇ Æ¯¼öÇÑ °æ¿ì¿¡´Â
1878                  Rating°ú RRT°¡ ¼­·Î ÀÏÄ¡ÇÏÁö ¾ÊÀ» °æ¿ì°¡ ÀÖ´Ù. index Á¶°Ç üũ¸¦ È®½ÇÈ÷ ÇØ¾ß ÇÑ´Ù.
1879                  ¿¹:
1880                   °¢ ä³Îº°·Î ´Ù¸¥ RRT versionÀÌ Àü¼ÛµÇ°í ÀÖ´Â °æ¿ì, ä³ÎÀ» º¯°æÇÒ ¶§..
1881        */   
1882       
1883        int iRegion, iDim;
1884        BOOL bNoRating = TRUE;
1885                /* RatingÀÇ °¢ °ªµéÀÌ RRTÀÇ ¾î¶°ÇÑ Á¶°Ç¿¡µµ °É¸®Áö ¾ÊÀ¸¸é No RatingÀÌ µÈ´Ù.
1886                         Çϳª¶óµµ Á¶°Ç¿¡ ¸Â´Â°Ô ÀÖÀ¸¸é (block ¿©ºÎ¿¡ °ü°è¾øÀÌ) No RatingÀÌ ¾Æ´Ï´Ù. */
1887               
1888        BOOL bBlock = FALSE;
1889
1890        int index, value, k;
1891        rrtSectionPtr_t pRrt;
1892       
1893        Dmc_EpgLockRrtDB(TRUE, TRUE);   /* cafrii 060719 CoreDB->RrtDB */
1894       
1895        pRrt = Dmc_EpgGetCurrentRrt();
1896        if (pRrt == NULL) {
1897                /* RRT°¡ ¾ÆÁ÷ ¾ø´Â °æ¿ì¸¦ No RatingÀ¸·Î º¼ °ÍÀÎÁö¿¡ ´ëÇØ¼­´Â À̰ßÀÌ ÀÖÀ» ¼ö ÀÖÀ½.
1898                         ±×·¯³ª Region 5ÀÇ ratingÀº RRT ¾øÀÌ´Â ¾Æ¹«·± Àǹ̰¡ ¾ø´Â °ÍÀ̹ǷÎ
1899                         RatingÀÌ ¾ø´Â °Å³ª ´Ù¸¦ ¹Ù ¾ø´Ù. */
1900                goto label_exit;
1901        }
1902       
1903        /* region 5¸¸ °Ë»ç.
1904                 Â÷ ÈÄ¿¡´Â regionÀÌ ´õ Ãß°¡µÉ Áö´Â ¸ð¸£°ÚÀ¸³ª.. ÇöÀç´Â 5.
1905               
1906                 region 5°¡ ¿©·¯°³ ÀÖ´Â °æ¿ì óÀ½ À§Ä¡ÇÏ´Â region 5¸¸ ó¸®ÇÔ.
1907                 ±× ÀÌÈÄÀÇ region 5´Â ¹«½Ã.
1908        */
1909
1910        /* cafrii 060719 change
1911                  region 5°¡ ¿©·¯°³·Î ³ª´©¾îÁ® Á¸ÀçÇÒ ¼ö ÀÖÀ¸¹Ç·Î
1912                  ¸ðµç region 5¸¦ ´Ù °Ë»çÇØ¾ß ÇÑ´Ù.
1913        */
1914#if 0
1915        /* search region 5 */
1916        for (iRegion=0; iRegion<pRating->region_count; iRegion++) {
1917                if (pRating->region[iRegion].region_id == 5)
1918                        break;
1919        }
1920
1921        if (iRegion >= pRating->region_count) {
1922                dprint(3, "check rating: region 5 not found in rating info\n");
1923                goto label_exit;
1924        }
1925#endif
1926
1927        for (iRegion=0; iRegion<pRating->region_count; iRegion++) 
1928        {
1929#if IGNORE_RRT_REGION==0
1930                if (pRating->region[iRegion].region_id != 5)
1931                        continue;
1932#else
1933                if (pRating->region[iRegion].region_id == 1 || 
1934                                pRating->region[iRegion].region_id == 2)
1935                        continue;
1936#endif
1937       
1938                for (iDim=0; iDim<pRating->region[iRegion].num_dimensions; iDim++) 
1939                {
1940                        /* Rating Á¤º¸·ÎºÎÅÍ rating dimension°ú value¸¦ °¡Á®¿Â´Ù. */
1941                        index = pRating->region[iRegion].dimension[iDim].index;
1942                        value = pRating->region[iRegion].dimension[iDim].value;
1943
1944                        /* RRTÀÇ dimension & value¸¦ Âü°íÇÏ¿© block ¿©ºÎ¸¦ ¾Ë¾Æ³½´Ù. */
1945
1946                        if (pRrt->dimensions_defined <= index) {
1947                                dprint(0, "[RRT] !! Warning : Invalid Dimension idx %d (should be 0 ~ %d)\n", 
1948                                                index, 0, pRrt->dimensions_defined-1);
1949                                continue;
1950                        }
1951               
1952                        if (pRrt->dimension[index].first_value_empty)
1953                                value--;
1954
1955                        if (value < 0) {
1956                                dprint(0, "[RRT] !! value 0 used in empty first dimension\n");
1957                                continue;
1958                        }
1959                       
1960                        /* ¾Æ·¡ °æ¿ì´Â value°¡ ÃÖ´ë°ªÀ» ¹þ¾î³­ À߸øµÈ °æ¿ìÀÌÁö¸¸, grad schedule¿¡ µû¶ó ÃÖ¼Ò ´ëÀÀÀº ÇÑ´Ù. */
1961                        if (pRrt->dimension[index].values_defined <= value) 
1962                        {
1963                                /* graduate schedule°ú ÇÏÀ§ value °ª¿¡ µû¶ó block ÇØ¾ß ÇÒ ¼öµµ ÀÖÀ½. */
1964                                for (k=0; k<pRrt->dimension[index].values_defined; k++) {
1965                                        if (pRrt->dimension[index].value[k].block_on) {
1966                                                bBlock = TRUE;
1967                                                break;
1968                                        }
1969                                }
1970                                if (bBlock) {
1971                                        dprint(0, "[RRT] Notice: undefined value %d, but blocked\n", value);
1972                                        break;
1973                                }
1974                                else {
1975                                        dprint(0, "[RRT] !! Warning : Invalid value %d\n", value);
1976                                        continue;
1977                                }
1978                        }
1979                       
1980                        bNoRating = FALSE; 
1981                                /* Á¦´ë·Î µÈ rrt entry¸¦ ¹ß°ßÇßÀ¸¹Ç·Î Àû¾îµµ missing ratingÀº ¾Æ´Ï´Ù.
1982                                         block ¿©ºÎ¿Í´Â »ó°ü ¾øÀ½. */
1983                       
1984                        if (pRrt->dimension[index].value[value].block_on) {
1985                                bBlock = TRUE;
1986                                break;
1987                        }
1988                }
1989        }
1990
1991label_exit:
1992        Dmc_EpgLockRrtDB(FALSE, TRUE);  /* cafrii 060719 CoreDB->RrtDB */
1993
1994        if (bBlock)     /* in case for undefined value block */
1995                bNoRating = FALSE;
1996
1997        if (pbNoRating)
1998                *pbNoRating = bNoRating;
1999
2000        return bBlock;
2001       
2002}
2003
2004
2005#if 0
2006
2007/* sorting library
2008         todo..
2009         string compositionÀ» ÇÒ ¶§ sortingÀ» ÇØ¾ß ÇÏ´ÂÁö´Â
2010         °­Á¦ »çÇ×Àº ¾øÀ¸³ª
2011         ±âÁ¸ Äڵ忡¼­ Çß´ø ÀûÀÌ ÀÖÀ¸¹Ç·Î ½Ã°£ µÉ¶§ Á¤¸®ÇÏÀÚ.
2012*/
2013static int QMakeNum(UINT32 numStr)
2014{
2015        UINT16 *temp=(UINT16 *)&numStr;
2016        return *temp *100000 + *(temp+1);
2017}
2018
2019
2020static void QSwap(UINT32 *a, UINT32 *b)
2021{
2022        UINT32 temp;
2023       
2024        if(a==b)
2025                return;
2026       
2027        temp=*a;
2028        *a=*b;
2029        *b=temp;
2030}
2031
2032static void BSort(UINT32 *str, UINT16 numItem)
2033{
2034        int i, j;
2035       
2036        if(numItem <= 1)
2037                return;
2038       
2039        for(i=0; i<numItem-1; i++) {
2040                for(j=0; j<numItem-i-1; j++) {
2041                        if(QMakeNum(str[j]) > QMakeNum(str[j+1]))
2042                                QSwap(&str[j], &str[j+1]);
2043                }
2044        }
2045}
2046
2047#endif
2048
2049
2050/* #define RATING_MSG_SEPARATOR '-' */
2051UINT16 RATING_MSG_SEPARATOR = '-';
2052UINT16 RATING_MSG_SEPARATOR_COMMA = ',';
2053
2054/*
2055         Dynamic RRT »óÈ£ ÂüÁ¶¿¡ ÀÇÇÑ ÇöÀç ÇÁ·Î±×·¥ÀÇ Rating stringÀ» °¡Á®¿Â´Ù.
2056       
2057         ¸¸¾à ÇØ´ç regionÀÇ Á¤º¸·ÎºÎÅÍ ÀûÀýÇÑ stringÀ» ¾òÁö ¸øÇϸé FALSE¸¦ ¸®ÅÏÇÑ´Ù.
2058*/
2059STATUS DMW_EPG_GetRatingStringByRRT(DMW_Rating5 *pRating, UINT16 *str, int nBufSize)
2060{
2061        int iRegion, len;
2062        int index, value;
2063        int iDim;
2064        STATUS status = statusOK;
2065
2066        #define MAX_TEXT 32     /* °¢ dimensionº° ±ÛÀÚ´Â ÃÖ´ë 32 */
2067
2068        UINT16 cTemp[MAX_TEXT+1];
2069       
2070        rrtSectionPtr_t rrt;
2071
2072        if (pRating == NULL || str == NULL)
2073                return statusInvalidArgument;
2074
2075        str[0] = 0;
2076
2077        Dmc_EpgLockRrtDB(TRUE, TRUE);   /* cafrii 060719 CoreDB->RrtDB */
2078
2079        rrt = Dmc_EpgGetCurrentRrt();
2080       
2081        if (rrt == NULL) {
2082                dprint(1, "!! %s: no rrt yet\n", __FUNCTION__);
2083                status = statusError;
2084                goto label_exit;
2085        }
2086
2087
2088#if 0   /* ¿¹Àü ¹æ½Ä.. »ç¿ë ±ÝÁö.. */
2089        /* search region 5 */
2090        iRegion = -1;
2091        for (i=0; i<pRating->region_count; i++) {
2092                if (pRating->region[i].region_id == 5) {
2093                        iRegion = i;
2094                        break;
2095                }
2096        }
2097
2098        if (iRegion < 0) {
2099                dprint(2, "  region 5 not found\n");
2100                status = statusNotFound;
2101                goto label_exit;
2102        }
2103#endif
2104
2105        status = statusNotFound;
2106
2107        /* cafrii 060719 change
2108                  region 5°¡ ¿©·¯°³·Î ³ª´©¾îÁ® Á¸ÀçÇÒ ¼ö ÀÖÀ¸¹Ç·Î
2109                  ¸ðµç region 5¸¦ ´Ù °Ë»çÇØ¾ß ÇÑ´Ù.
2110        */
2111
2112        for (iRegion=0; iRegion<pRating->region_count; iRegion++) 
2113        {
2114#if IGNORE_RRT_REGION==0
2115                if (pRating->region[iRegion].region_id != 5)
2116                        continue;
2117#else
2118                if (pRating->region[iRegion].region_id == 1 || 
2119                                pRating->region[iRegion].region_id == 2)
2120                        continue;
2121#endif 
2122                /* BSort((UINT32 *)pRating->region[region].dims, pRating->region[region].dimsNum); */
2123
2124                /* ¸ðµç dimensionÀÇ À̸§À» decodingÇÏ¿© ¿¬°á½ÃŲ´Ù. */
2125                for (iDim=0; iDim<pRating->region[iRegion].num_dimensions; iDim++) 
2126                {
2127                        index = pRating->region[iRegion].dimension[iDim].index;
2128                        value = pRating->region[iRegion].dimension[iDim].value;
2129
2130                        if (rrt->dimensions_defined <= index) {
2131                                dprint(3, "[RRT] !! Warning : Invalid Dimension idx %d (should be 0 ~ %d)\n", 
2132                                                index, 0, rrt->dimensions_defined-1);
2133                                continue;
2134                        }
2135                       
2136                        if (rrt->dimension[index].first_value_empty)
2137                                value--;
2138                       
2139                        if (value < 0) {
2140                                /* dprint(3, "[RRT] !! value 0 used in empty first dimension\n"); */
2141                                continue;
2142                        }
2143                       
2144                        if (rrt->dimension[index].values_defined <= value) {
2145                                /* dprint(3, "[RRT] !! invalid value \n"); */
2146                                continue;
2147                        }
2148
2149                        len = DLIB_PSI_DecodeMultipleStringStructure(
2150                                rrt->dimension[index].value[value].abbrev_rating_value_length,
2151                                rrt->dimension[index].value[value].abbrev_rating_value,
2152                                "eng", MAX_TEXT, cTemp);
2153
2154                        if (len <= 0)
2155                                len = DLIB_PSI_DecodeMultipleStringStructure(
2156                                        rrt->dimension[index].value[value].abbrev_rating_value_length,
2157                                        rrt->dimension[index].value[value].abbrev_rating_value,
2158                                        "kor", MAX_TEXT, cTemp);
2159
2160                        if (len <= 0) {
2161                                /* dprint(0, "!! decode MSS return null\n"); */
2162                        }
2163                        else if (len + UniStrLen(str) >= nBufSize)  {
2164                                dprint(0, "!! warning: rating string buf overflow.\n");
2165                        }
2166                        else
2167                        {
2168                                status = statusOK;
2169
2170                                if (len >= MAX_TEXT)
2171                                        cTemp[MAX_TEXT-1] = 0;
2172                                else
2173                                        cTemp[len] = 0;
2174
2175                                if (str[0] == 0)
2176                                        UniStrCopy(str, cTemp);
2177                                else {
2178                                        len = UniStrLen(str);
2179                                        str[len] = (UINT16) RATING_MSG_SEPARATOR_COMMA;
2180                                        UniStrCopy(str+len+1, cTemp);
2181                                }
2182                        }
2183               
2184                }
2185        }
2186       
2187label_exit:
2188        Dmc_EpgLockRrtDB(FALSE, TRUE);  /* cafrii 060719 CoreDB->RrtDB */
2189       
2190        return status;
2191       
2192}
2193
2194
2195
2196#if COMMENT
2197____API3____(){}
2198#endif
2199
2200/*
2201        ÀÌ API3 ±×·ìÀÇ ÇÔ¼öµéÀº DMW_EpgUtils.c ¿¡¼­ °¡Á®¿Â °ÍµéÀÓ.
2202        EpgUtils ÀϺΠÇÔ¼öµéÀº DLIB_PSI_Utils.c ·Î À̵¿µÇ¾úÀ½
2203*/
2204
2205void DMW_EPG_FreeMLInfo(DMW_AudioElementPtr aLingualInfos)
2206{
2207        if (aLingualInfos)
2208                DHL_OS_Free((void**)&aLingualInfos);
2209}
2210
2211/*
2212         PMT·ÎºÎÅÍ DMW_AudioElement Á¤º¸¸¦ ¾ò´Â´Ù.
2213         language Á¤º¸°¡ ¾ø´Â °æ¿ì¿¡µµ AudioElement¸¦ ÀúÀåÇÑ´Ù. Áï Àüü audio °¹¼ö¸¦ ¾Ë¼ö ÀÖ´Ù.
2214*/ 
2215STATUS DMW_EPG_GetMLInfoInPMT(MPEG_PMT *pmt, DMW_AudioElementPtr *aLingualInfos, int *iLingualCount)
2216{
2217        int i, j;
2218        STATUS status = statusOK;
2219        DHL_RESULT dhr;
2220        DMW_AudioElementPtr pAudioElements = NULL;
2221       
2222        int nAudioStreamPMT;            /* PMT¿¡ µî·ÏµÈ Àüü audio stream °¹¼ö */
2223        int iAudioCount = 0;            /* Áߺ¹µÇÁö ¾ÊÀº PID¸¦ °¡Áø audio stream °¹¼ö */
2224       
2225        UINT32 languageCode;
2226        int serviceType;
2227        BOOLEAN bSameAudioExist = FALSE;
2228       
2229        if (pmt == NULL) {
2230                status = statusNotFound;
2231                goto label_end;
2232        }
2233       
2234        /* PMT¿¡¼­ audio stream ÀÇ °¹¼ö¸¦ count. */
2235        nAudioStreamPMT = 0;
2236        for (i=0; i<pmt->numStreams; i++) {
2237                switch (pmt->streams[i].stream_type)
2238                {
2239                        case StreamType_AC3Audio:
2240                        case StreamType_MPEG1Audio:
2241                        case StreamType_MPEG2Audio:
2242                        case StreamType_AACAudioADTS:
2243                        case StreamType_AACAudioLATM:
2244                                nAudioStreamPMT++;
2245                                break;
2246                        default:
2247                                break;
2248                }
2249        }
2250       
2251        if (nAudioStreamPMT == 0) {
2252                status = statusNotFound;
2253                goto label_end;
2254        }
2255       
2256        /* ¸Þ¸ð¸®¸¦ ÇÒ´çÇÑ´Ù. */
2257        pAudioElements = DHL_OS_Malloc(sizeof(DMW_AudioElement) * nAudioStreamPMT);
2258        if (pAudioElements == NULL) {
2259                dprint(0, "!! %s: Out of memory for AudioElement\n", __FUNCTION__);
2260                status = statusOutOfMemory;
2261                goto label_end;
2262        }
2263        memset(pAudioElements, 0, sizeof(DMW_AudioElement) * nAudioStreamPMT);
2264       
2265        for (i=0; i<pmt->numStreams; i++)
2266        {
2267                switch (pmt->streams[i].stream_type)
2268                {
2269                        case StreamType_AC3Audio:
2270                        case StreamType_MPEG1Audio:
2271                        case StreamType_MPEG2Audio:
2272                        case StreamType_AACAudioADTS:
2273                        case StreamType_AACAudioLATM:
2274                                break;
2275                        default:
2276                                continue;
2277                                break;
2278                }
2279                       
2280                /* ÀÌ¹Ì °°Àº PIDÀÇ Audio°¡ gatherµÈ °æ¿ì´Â ¹«½Ã. */
2281                bSameAudioExist = FALSE;
2282               
2283                for (j=0; j<iAudioCount; j++) {
2284                        if (pAudioElements[j].elementaryPid == pmt->streams[i].elementary_PID)  {
2285                                bSameAudioExist = TRUE;
2286                                break;
2287                        }
2288                }
2289                if (bSameAudioExist)
2290                        continue;
2291               
2292                dhr = DLIB_PSI_GetLanguageCodeFromDescriptors(
2293                                                        pmt->streams[i].descriptors,
2294                                                        pmt->streams[i].descriptor_length,
2295                                                        0, &languageCode, &serviceType);
2296
2297                /* cafrii 060220 fix
2298                         audio °¹¼ö Á¤º¸¸¦ ¾ò´Â ¸ñÀûµµ ÀÖÀ¸¹Ç·Î
2299                          ML Á¤º¸°¡ ¾ø´õ¶óµµ audio count´Â Ãß°¡ÇØÁØ´Ù. */
2300                if (dhr != DHL_OK) {
2301                        languageCode = 0;
2302                        serviceType = 0;
2303                }
2304
2305                pAudioElements[iAudioCount].elementaryPid = pmt->streams[i].elementary_PID;
2306                pAudioElements[iAudioCount].ISO639_LanguageCode = languageCode;
2307                pAudioElements[iAudioCount].serviceType = serviceType;
2308                pAudioElements[iAudioCount].audioType = eDHL_AUDIO_TYPE_AC3;
2309
2310                switch (pmt->streams[i].stream_type)
2311                {
2312                        case StreamType_AC3Audio:
2313                                break;
2314                        case StreamType_MPEG1Audio:
2315                                pAudioElements[iAudioCount].audioType = eDHL_AUDIO_TYPE_MPEG_1;
2316                                break;
2317                        case StreamType_MPEG2Audio:
2318                                pAudioElements[iAudioCount].audioType = eDHL_AUDIO_TYPE_MPEG_2;
2319                                break;
2320                        case StreamType_AACAudioADTS:
2321                                pAudioElements[iAudioCount].audioType = eDHL_AUDIO_TYPE_AAC_ADTS;
2322                                break;
2323                        case StreamType_AACAudioLATM:
2324                                pAudioElements[iAudioCount].audioType = eDHL_AUDIO_TYPE_AAC_LATM;
2325                                break;
2326                        default:
2327                                continue;
2328                                break;
2329                }
2330
2331                iAudioCount++;
2332        }
2333       
2334        /* iAudioCount¿Í nAudioStreamPMTÀº ´Ù¸¦ ¼ö ÀÖÀ½.
2335                 audio pid°¡ Áߺ¹µÈ °æ¿ì iAudioCount´Â ´õ ÀûÀº °ªÀ» °¡Áø´Ù. */
2336       
2337        if (iAudioCount <= 0) {
2338                dprint(0, "!! audio count cannot be 0!\n");
2339                *iLingualCount = 0;
2340                *aLingualInfos = NULL;
2341                DHL_OS_Free((void**)&pAudioElements);   /* cafrii 060607 add for bugfix.. memory leak */
2342                status = statusNotFound;
2343        }
2344        else {
2345                *iLingualCount = iAudioCount;
2346                *aLingualInfos = pAudioElements;
2347                status = statusOK;
2348        }
2349       
2350label_end:
2351
2352        return status;
2353}
2354
2355
2356
2357/* cafrii 061114 add */
2358#if SUPPORT_MPEG_AUDIO
2359        #define StreamTypeToAudioType(t) ( \
2360                (t) == StreamType_AC3Audio ? eDHL_AUDIO_TYPE_AC3: \
2361                (t) == StreamType_MPEG2Audio ? eDHL_AUDIO_TYPE_MPEG_2 : eDHL_AUDIO_TYPE_UNKNOWN )
2362#else
2363        #define StreamTypeToAudioType(t) ( \
2364                (t) == StreamType_AC3Audio ? eDHL_AUDIO_TYPE_AC3 : eDHL_AUDIO_TYPE_UNKNOWN )
2365#endif
2366
2367
2368/*
2369         VCTÀÇ Service Location Descriptor Á¤º¸¸¦ ÀÌ¿ëÇÏ¿©
2370           audio language Á¤º¸¸¦ ¾ò¾î¿Â´Ù.
2371         ³»ºÎ¿¡¼­ ¸Þ¸ð¸® ÇÒ´çÀ» Çϱ⠶§¹®¿¡ »ç¿ë ÈÄ¿¡ FreeMLInfo ÇØ¾ß ÇÔ.
2372*/
2373STATUS DMW_EPG_GetMLInfoInVctDescriptors(UINT8 *descriptors, int descriptor_length,
2374                                                                                 DMW_AudioElementPtr *aMLInfo, int *piCount)
2375{
2376        int i, k, err;
2377        int count;              /* Áߺ¹µÇÁö ¾Ê´Â ¼ø¼öÇÑ audio °¹¼ö */
2378        DMW_AudioElementPtr mlInfo;
2379        int mlCount;
2380        tDHL_AudioCodingType audioType;
2381       
2382        UINT8 *desc;
2383        serviceLocationDescriptorPtr_t sld = NULL;
2384       
2385        /* service_location_tag : 0xA1 */
2386        err = GetMpegDescriptor(descriptors, descriptor_length, 0xA1, 0, &desc);
2387
2388        if (err) {
2389                return statusNotFound;
2390        }
2391       
2392        err = ParseServiceLocationDescriptor(desc, &sld);
2393
2394        if (err) {
2395                sld = NULL;
2396                return (STATUS)err;     /* ÁÖ·Î ¸Þ¸ð¸® °ü·Ã ¿¡·¯.. */
2397        }
2398       
2399        /* count audio stream number */
2400        mlCount = 0;
2401        for (i=0; i<sld->number_elements; i++)
2402        {
2403                /* cafrii 061114 add support multiple audio format */
2404                if (StreamTypeToAudioType(sld->element[i].stream_type) != eDHL_AUDIO_TYPE_UNKNOWN)
2405                        mlCount++;
2406        }
2407       
2408        if (mlCount == 0) {
2409                FreeMpegDescriptor(sld);
2410                return statusNotFound;
2411        }
2412               
2413        mlInfo = (DMW_AudioElement *) DHL_OS_Malloc(mlCount * sizeof(DMW_AudioElement));
2414       
2415        if (mlInfo == NULL)
2416        {
2417                FreeMpegDescriptor(sld);
2418                return statusOutOfMemory;
2419        }
2420        memset(mlInfo, 0, mlCount * sizeof(DMW_AudioElement));
2421               
2422        for (i=0, count=0; i<sld->number_elements; i++)
2423        {
2424#if DEVELOPMENT_BUILD           /* cafrii 080303 avoid using assert */
2425                DHL_ASSERT(count < mlCount, "error");
2426#else
2427                /* cafrii 080305 fix again
2428                         ¿¹Àü¿¡´Â ÀÌ À§Ä¡°¡ count++ ±¸¹® ¾Æ·¡¿¡ ÀÖ¾ú´Ù°¡
2429                         Äڵ带 À§·Î ¿Å±ä °ÍÀ̹ǷΠ>= °¡ ¸ÂÀ½. */
2430                if (count >= mlCount) {
2431                        dprint(0, "%s: ml count %d exceed to expected %d\n", __FUNCTION__, count, mlCount);
2432                        break;
2433                }
2434#endif
2435               
2436                /* cafrii 061114 add support multiple audio format */
2437                audioType = StreamTypeToAudioType(sld->element[i].stream_type);
2438
2439                if (audioType == eDHL_AUDIO_TYPE_UNKNOWN)
2440                        continue;       /* Áö¿øÇÏÁö ¾Ê´Â streamÀº °Ç³Ê¶Ü. */
2441                       
2442                /* ±âÁ¸¿¡ Áߺ¹µÇ´Â pid ÀÖ´ÂÁö È®ÀÎ.. */
2443                for (k=0; k<count; k++) {
2444                        if (mlInfo[k].elementaryPid == sld->element[i].elementary_PID)
2445                                break;
2446                }
2447                if (k < count)  /* Áߺ¹ ¹ß°ß. skip.. */
2448                        continue;
2449               
2450                mlInfo[count].elementaryPid = sld->element[i].elementary_PID;
2451                mlInfo[count].ISO639_LanguageCode = sld->element[i].ISO639_language_code;
2452                mlInfo[count].serviceType = 0;
2453                mlInfo[count].audioType = audioType;    /* AudioType_AC3; */
2454                count++;
2455        }
2456       
2457        FreeMpegDescriptor(sld);
2458
2459        if (aMLInfo)
2460                *aMLInfo = mlInfo;
2461               
2462        if (piCount)
2463                *piCount = count;       /* mlCount¿Í ´Ù¸¦ ¼ö ÀÖÀ½. pid Áߺ¹ÀÇ °æ¿ì.. */
2464               
2465        return statusOK;
2466}
2467
2468
2469STATUS DMW_EPG_GetMLInfoInVct(xvctChannelPtr_t vctch, DMW_AudioElementPtr *aMLInfo, 
2470                                                        int *piCount)
2471{
2472        if (vctch == NULL)
2473                return statusInvalidArgument;
2474
2475        return DMW_EPG_GetMLInfoInVctDescriptors(vctch->descriptors, vctch->descriptor_length,
2476                                                                                 aMLInfo, piCount);
2477
2478}
2479
2480
2481
2482
2483#if COMMENT
2484_____DebugSymbol____(){}
2485#endif
2486
2487
2488#if DMW_REGISTER_DEBUG_SYMBOL
2489
2490static DHL_SymbolTable _EpgIntfSymbolLink[] =
2491{
2492        DHL_FNC_SYM_ENTRY(DMW_EPG_DeleteAll),
2493        DHL_FNC_SYM_ENTRY(DMW_EPG_SetFakeRatingData),
2494
2495        DHL_VAR_SYM_ENTRY(g_PrintEventInfo),
2496        //DHL_VAR_SYM_ENTRY(g_Trace_EpgIntf),
2497
2498        DHL_VAR_SYM_ENTRY(RATING_MSG_SEPARATOR),
2499
2500};
2501
2502#endif
2503
2504void DMW_EPG_RegisterEpgIntfSymbols()
2505{
2506#if DMW_REGISTER_DEBUG_SYMBOL
2507        DHL_DBG_RegisterSymbols(_EpgIntfSymbolLink, DHL_NUMSYMBOLS(_EpgIntfSymbolLink));
2508#endif
2509}
2510
2511
2512
2513
2514
2515#if COMMENT
2516_____Test_____(){}
2517#endif
2518
2519#if DMW_EPG_TESTCODE
2520
2521
2522#include "DMW_SysTime.h"
2523
2524
2525void TestEpgGetEvents(int rf, int source_id)
2526{
2527        int err, st;
2528        UINT32 utc, gps;
2529       
2530        DMW_GetUTCTime(NULL, &utc);
2531        gps = DMW_ConvertUTC2GPS(NULL, utc);
2532
2533        err = DMW_EPG_GetEventsByRF(rf, source_id, gps, 72000, NULL, NULL, 1000);
2534        DHL_OS_Printf("************* GetEvents err %d ***************\n", err);
2535        st = Dmc_EpgCheckScanStatus(rf, source_id, NULL);
2536        DHL_OS_Printf("************ EpgStatus : %s *************\n", EpgStatusString(st));
2537}
2538
2539
2540int g_StopTestEpgIntfOverload = 0;
2541
2542void TestEpgIntfOverload(int rf, int source_id)
2543{
2544        int err;
2545
2546        while (g_StopTestEpgIntfOverload == 0)
2547        {
2548                DHL_OS_Printf("************* start epg update ***************\n");
2549                err = Dmc_EpgUpdateStart(rf, Dmc_GetCurrentTsd(), NULL, 0, 0);
2550                DHL_OS_Printf("************* err in update start %d ***************\n", err);
2551               
2552                DHL_OS_Delay(rand()%10 * 1000);
2553
2554                TestEpgGetEvents(rf, source_id);
2555
2556                DHL_OS_Delay(rand()%10 * 1000);
2557        }
2558}
2559
2560/*
2561        Å×½ºÆ® ¹æ¹ý:
2562        epg_list¸¦ ¼öÇàÇÏ¿© ÇØ´ç ä³Î epg Àüü ¸®½ºÆ®¸¦ º¸°í,
2563        ett°¡ Æ÷ÇÔµÈ Æ¯Á¤ event¸¦ ¼±Åà ÈÄ ±× event id¸¦ ÁöÁ¤ÇÑ´Ù.
2564
2565        title, text°¡ Á¦´ë·Î Ãâ·ÂµÇ´ÂÁö È®ÀÎÇÑ´Ù.
2566*/
2567void TestEpgFindEventByEvid(int rf, int source_id, UINT16 evid)
2568{
2569        STATUS status;
2570        UINT32 tick1, tick2; /* for performance checking */
2571       
2572        UINT32 flag = GET_EVENT_TITLE | GET_EVENT_TEXT;
2573        DMW_EpgEvent *pEvent = NULL;
2574        char buf1[64];
2575
2576        DHL_OS_Printf("== searching evid %x event in rf %d/$%d channel..\n", evid, rf, source_id);
2577
2578        tick1 = DHL_OS_GetMsCount();
2579        status = DMW_EPG_GetEventByEvidAndRf(rf, source_id, evid, &pEvent, flag);
2580        tick2 = DHL_OS_GetMsCount();
2581       
2582        if (status) {
2583                DHL_OS_Printf("!! event not found.\n");
2584                return;
2585        }
2586
2587        DHL_OS_Printf("== event found in %d ms\n", (tick2-tick1)*1000/1000);
2588        DHL_OS_Printf("   start time: gps %x, %s\n", 
2589                pEvent->startTime, GpsTimeString2(pEvent->startTime, buf1, 2));
2590        DHL_OS_Printf("   duration: %d sec\n", pEvent->programLength);
2591        DHL_OS_Printf("   title:\n");
2592        Dmc_PrintMultipleString(pEvent->titleText, pEvent->titleTextLength, 6, 0);
2593        DHL_OS_Printf("   text:\n");
2594        Dmc_PrintMultipleString(pEvent->eventETM, pEvent->eventETMLength, 6, 0);
2595
2596        DMW_EPG_FreeEpgEvent(pEvent);
2597}
2598
2599
2600#endif  /* DMW_EPG_TESTCODE */
2601
2602/********************************************************************
2603   $Log: DMW_EpgInterface.c,v $
2604
2605        1.29 2005/2/3   remove unused header include
2606                        change some debug level
2607        1.28 2005/1/6   DMW_EPG_TESTCODE ¸¦ 0À¸·Î..
2608                        TestEpgGetEvents ¿¡¼­ Standard API »ç¿ë ¾ÈÇÔ
2609        1.27 2004/12/23 EventÀÇ È¿À²ÀûÀÎ °Ë»öÀ» À§ÇÑ Á¶°Ç½Ä Ãß°¡..
2610                        descriptor parser ¸î°³ public API ·Î º¯°æ
2611       
2612        1.26 2004/12/22 DMW_EpgEvent ±¸Á¶Ã¼¿¡¼­ ¾È¾²´Â ÇÊµå »èÁ¦
2613        1.25 2004/12/09 DMW_EPG2_GetRating ÃÖÀûÈ­
2614        1.24 2004/12/08 DMW_EPG2_GetEvents ¿¡¼­ debug level ¼öÁ¤ 1°÷
2615        1.23 2004/11/30 DMW_EPG2_GetRating prototype changed
2616        1.22 2004/11/01 eit first mode¸¦ µðÆúÆ®·Î ÇÏÁö ¾ÊÀ½.
2617        1.21 2004/10/28 MakeETMID¸¦ event/channel ¿ë ±¸ºÐ
2618        1.2  2004/10/19 tsd argument is added in CoreAPI
2619        1.1  2004/7/28  add statusOK in GetEventsInTime
2620        1.0  2004/07/15 first design
2621
2622*********************************************************************/
2623
Note: See TracBrowser for help on using the repository browser.