source: svn/trunk/zas_dstar/hal/common/dsthalPsiDvbSi.c @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
File size: 207.8 KB
Line 
1/****************************************************************************
2 *_Copyright (c) 2009 DST Technologies Inc.  All Rights Reserved.
3 *
4 * Filename: dsthalPsiDvbSi.c
5 * Author:       Junku Park (hwatk@dstreamtech.com)
6 * Description: Monitor and parse DVB-SI tables.
7 *             
8 ***************************************************************************/
9
10#include "dsthalcommon.h"
11#include "dstoslayer.h"
12#include "dsthalerror.h"
13
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17
18#include "dsthalPsiMemChain.h"
19#include "dsthalPsiBitBuffer.h"
20#include "dsthalPsiMpegSi.h"
21#include "dsthalPsiDvbSi.h"
22
23#ifdef DMALLOC
24#include <dmalloc.h>
25#endif
26
27/******************************************************************************
28 * Global variable declaration
29 ******************************************************************************/
30
31/******************************************************************************
32 * Imported variable declaration
33 ******************************************************************************/
34extern DHL_PSI_HANDLE gPsiHandle;
35extern DHL_RESULT GetMpegDescriptor (DS_U8 *descriptors, DS_U16 len, DS_U8 tag, DS_U16 instance, DS_U8 **descriptor);
36
37/******************************************************************************
38 * Imported function declaration
39 ******************************************************************************/
40extern void hal_cbPSISyncEventProc ( PSIEvent event , DHL_TBL_HANDLE hTblHandle , DS_U32 userParam );
41
42/******************************************************************************
43 * Local definitions
44 ******************************************************************************/
45#define checkMemoryError(p)                     if (p == NULL) {err = DHL_FAIL_OUT_OF_RESOURCE ; goto ParseExit;}
46
47#define MEM_LIMIT                       0x00004000      /* 16k */
48//#define MEM_EIT_LIMIT       0x00010000  /* 64k */
49
50#define SEGMENT_TABLE_MODE   0xFF
51#define SEGMENT_EAGER_MODE  0x80
52
53/******************************************************************************
54 * Local typedefs
55 ******************************************************************************/
56
57
58/******************************************************************************
59 * Local variables declaration
60 ******************************************************************************/
61
62/******************************************************************************
63 * Local function prototypes
64 ******************************************************************************/
65static void DHL_PSI_ParseEventGroupDescriptor(DS_U8 *p_desc, memId_t memId, arib_event_group_descriptor_t **pp_event_grp);
66void DHL_PSI_ParseNetworkNameDescriptor(DS_U8 *p_desc, memId_t memId, DS_U8 **pp_network_name, DS_U8 *p_length);
67void DHL_PSI_ParseServiceListDescriptor(DS_U8 *p_desc, memId_t memId, dvb_service_list_descriptor_t **pp_service_list);
68void DHL_PSI_ParseServiceDescriptor(DS_U8 *p_desc, memId_t memId, dvb_service_descriptor_t **pp_service_desc);
69void DHL_PSI_ParseShortEventDescriptor(DS_U8 *p_desc, memId_t memId, DS_U32 prefLangCode, dvb_short_event_descriptor_t **pp_short_event);
70void DHL_PSI_ParseExtendedEventDescriptor(DS_U8 *p_desc, memId_t memId, DS_U32 prefLangCode, dvb_extended_event_descriptor_t **pp_extended_event);
71void DHL_PSI_DecodeDate(DS_U16 date_in_mjd, DS_U16 *p_year, DS_U8 *p_month, DS_U8 *p_day);
72static void DHL_PSI_ParseParentalRatingDescriptorEx (DS_U8* p, memId_t memId, dvb_parental_rating_descriptor_t **pp_desc);
73void DHL_PSI_ParseLocalTimeOffsetDescriptor( DS_U8 *p, int numItems, dvb_local_time_t *p_desc );
74static int DHL_PSI_ParseTSInformationDescriptor(DS_U8* p, memId_t memId, arib_ts_information_descriptor_t **pp_ts_info);
75static int DHL_PSI_ParseSystemManagementDescriptor(DS_U8* p, DS_U16* p_system_management_id);
76void DHL_PSI_ParseBouquetNameDescriptor(DS_U8 *p_desc, memId_t memId, DS_U8 **pp_bouquet_name, DS_U8 *p_length);
77void DHL_PSI_ParseHierarchicalTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_hierarchical_transmission_descriptor_t **pp_hierarchical_transmission );
78void DHL_PSI_ParseDigitalCopyControlDescriptor(DS_U8* p, memId_t memId, arib_digital_copy_control_descriptor_t **pp_digital_copy_control);
79void DHL_PSI_ParseNetworkIdentificationDescriptor( DS_U8 *p, memId_t memId, arib_network_identification_descriptor_t **pp_network_identification );
80void DHL_PSI_ParsePartialTSTimeDescriptor( DS_U8 *p, memId_t memId, arib_partialTS_time_descriptor_t **pp_partialTS_time );
81void DHL_PSI_ParseAudioComponentDescriptor( DS_U8 *p, memId_t memId, arib_audio_component_descriptor_t **pp_audio_component );
82void DHL_PSI_ParseHyperlinkDescriptor( DS_U8 *p, memId_t memId, arib_hyperlink_descriptor_t **pp_hyperlink );
83void DHL_PSI_ParseTargetRegionDescriptor( DS_U8 *p, memId_t memId, arib_target_region_descriptor_t **pp_target_region );
84void DHL_PSI_ParseDataContentDescriptor( DS_U8 *p, memId_t memId, arib_data_content_descriptor_t **pp_data_content );
85void DHL_PSI_ParseVideoDecodeControlDescriptor( DS_U8 *p, memId_t memId, arib_video_decode_control_descriptor_t **pp_video_decode_control );
86void DHL_PSI_ParseLogoTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_logo_transmission_descriptor_t **pp_logo_transmission );
87void DHL_PSI_ParseBasicLocalEventDescriptor( DS_U8 *p, memId_t memId, arib_basic_local_event_descriptor_t **pp_basic_local_event );
88void DHL_PSI_ParseReferenceDescriptor( DS_U8 *p, memId_t memId, arib_reference_descriptor_t **pp_reference );
89void DHL_PSI_ParseNodeRelationDescriptor( DS_U8 *p, memId_t memId, arib_node_relation_descriptor_t **pp_node_relation );
90void DHL_PSI_ParseShortNodeInformationDescriptor( DS_U8 *p, memId_t memId, arib_short_node_information_descriptor_t **pp_short_node_information );
91void DHL_PSI_ParseSTCReferenceDescriptor( DS_U8 *p, memId_t memId, arib_stc_reference_descriptor_t **pp_stc_reference );
92void DHL_PSI_ParseSeriesDescriptor( DS_U8 *p, memId_t memId, arib_series_descriptor_t **pp_series );
93void DHL_PSI_ParseSIParameterDescriptor( DS_U8 *p, memId_t memId, arib_si_parameter_descriptor_t **pp_si_parameter );
94void DHL_PSI_ParseBroadcasterNameDescriptor(DS_U8 *p, memId_t memId, DS_U8 **pp_broadcaster_name, DS_U8 *p_length);
95void DHL_PSI_ParseComponentGroupDescriptor( DS_U8 *p, memId_t memId, arib_component_group_descriptor_t **pp_component_group );
96void DHL_PSI_ParseSIPrimeTSDescriptor( DS_U8 *p, memId_t memId, arib_si_prime_ts_descriptor_t **pp_si_prime_ts );
97void DHL_PSI_ParseBoardInformationDescriptor( DS_U8 *p, memId_t memId, arib_board_information_descriptor_t **pp_board_information );
98void DHL_PSI_ParseLDTLinkageDescriptor( DS_U8 *p, memId_t memId, arib_ldt_linkage_descriptor_t **pp_ldt_linkage );
99void DHL_PSI_ParseConnectedTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_connected_transmission_descriptor_t **pp_connected_tx );
100void DHL_PSI_ParseContentAvailabilityDescriptor( DS_U8 *p, memId_t memId, arib_content_availability_descriptor_t **pp_content_availability );
101void DHL_PSI_ParseConditionalPlaybackDescriptor( DS_U8 *p, memId_t memId, arib_conditional_playback_descriptor_t **pp_conditional_playback );
102void DHL_PSI_ParseTerrestrialDeliverySystemDescriptor( DS_U8 *p, memId_t memId, arib_terrestrial_delivery_system_descriptor_t **pp_terrestrial_delivery_system );
103void DHL_PSI_ParsePartialReceptionDescriptor(DS_U8 *p, memId_t memId, DS_U16 **pp_partial_reception, DS_U8 *p_length);
104void DHL_PSI_ParseEmergencyInformationDescriptor(DS_U8 *p_desc, memId_t memId, arib_emergency_information_descriptor_t **pp_emergency_info);
105void DHL_PSI_ParseDataComponentDescriptor(DS_U8 *p_desc, memId_t memId, arib_data_component_descriptor_t **pp_data_component);
106void DHL_PSI_ParseExtendedBroadcasterDescriptor(DS_U8 *p_desc, memId_t memId, arib_extended_broadcaster_descriptor_t **pp_ex_broad);
107void DHL_PSI_ParseServiceGroupDescriptor(DS_U8 *p_desc, memId_t memId, arib_service_group_descriptor_t **pp_service_grp);
108void DHL_PSI_ParseDownloadContentDescriptor(DS_U8 *p, memId_t memId, arib_download_content_descriptor_t **pp_download);
109static DS_U32 _ConvertMJD2UTC(DS_U16 Mjd, DS_U32 TimeInBCD);
110
111
112
113void DHL_PSI_Dump(DS_U8 *p_desc, int length)
114{
115    int i;
116   
117    for(i=0; i<length; i++)
118    {
119        printf("0x%02X ", p_desc[i]);
120        if ( i && (i%40)==0 )
121            printf("\n");
122    }
123    printf("\n");
124}
125
126#if 0
127___Network_Information_Table___()
128#endif
129DHL_RESULT DHL_PSI_MonitorDvbNit(               DHL_PSI_HANDLE sysInfo,
130                                                                        DS_BOOL current_next_indicator,
131                                                                        DS_BOOL eager,
132                                                                        DS_BOOL b_actual,
133                                                                        PSIUpdateMode updateMode,
134                                                                        PSIEventProc_f eventProc,
135                                                                        DS_U32 userParam, 
136                                                                        DHL_TBL_HANDLE *returnPSICtl)
137{
138        PSIMask_t               *pref;
139        DHL_RESULT              err;
140
141        if ((err = DD_PSI_GetTIDPSIMask (&pref,
142                                                                        b_actual ? 
143                                                                            DVB_TID_network_information_section_actual : 
144                                                                            DVB_TID_network_information_section_other,
145                                                                        current_next_indicator))) {
146                printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err);
147                return(err);
148        }
149
150        if ((err = DD_PSI_MonitorPSIPid(sysInfo,
151                                                         DVB_PID_NIT, 
152                                                         eager ? eagerTableMode : tableMode, 
153                                                         updateMode,
154                                                         pref,
155                                                         /*MAX_PSI_MPEG_DATA*/1024,
156                                                         MAX_PSI_SECTIONS,
157                                                         eventProc,
158                                                         userParam,
159                                                         returnPSICtl))) 
160    {
161                printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err);                                         
162                PSI_Free(pref);
163        }
164       
165        return(err);
166}
167
168DHL_RESULT DHL_PSI_ParseDvbNit(DS_U8 **sectionArr, DS_BOOL b_actual, dvb_nit_t **pp_nit)
169{
170        DHL_RESULT err = DHL_OK;
171        int i, k;
172        int numStreams;
173        int numSections;
174        int index;
175        const DS_U8 *p;
176        int len;
177        dvb_nit_t *p_nit = NULL;
178        int version_number;
179        int network_descriptor_length;
180        int transport_loop_length;
181        DS_BOOL current_next_indicator;
182        memId_t                 memId = NULL;
183        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
184    transport_stream_t *p_ts;
185
186        if (sectionArr == NULL || (pp_nit == NULL)) 
187        {
188                return (DHL_FAIL_NULL_POINTER);
189        }
190
191        if (sectionArr[0] == NULL) 
192        {
193                return (DHL_FAIL_NULL_POINTER);
194        }
195        else 
196        {
197                numSections = get_last_section_number(sectionArr[0]) + 1;
198        }
199
200        /* now verify all other sections are present */
201        for (i=1; i<numSections; i++) 
202    {
203                if (sectionArr[i] == NULL) {
204                        return (DHL_FAIL_NULL_POINTER);
205                }
206        }
207       
208        /*
209         * First pass, we verify section syntax and count the number of programs
210         */
211        numStreams = 0;
212        for (i = 0; i < numSections; ++i) {
213                p = sectionArr[i];
214               
215                if( p == NULL )
216                {       
217                    printf( "%s: NULL section", __func__);
218                        return DHL_FAIL_NULL_POINTER;
219                }
220                       
221                if ( (b_actual && p[SECTION_TID] != DVB_TID_network_information_section_actual) ||
222                     (!b_actual && p[SECTION_TID] != DVB_TID_network_information_section_other) ) {
223                        /*
224                         * This thing isn't a PAT. Stop right here.
225                         */
226                        printf("NIT: Bad table ID. (0x%02X)", p[SECTION_TID]);
227                        err = DHL_FAIL_INVALID_TABLEID;
228                        goto ParseExit;
229                }
230               
231                if ((p[SECTION_LEN_HI] & 0x80) != 0x80) {
232                        printf("NIT: section_syntax_indicator not set");
233                }
234               
235        /*
236         * Counts number of transport_stream.
237         */
238        network_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF;
239        transport_loop_length = ((p[10+network_descriptor_length]<<8) + p[11+network_descriptor_length]) & 0xFFF;
240        p = &sectionArr[i][12+network_descriptor_length];
241        for(k=0; k<transport_loop_length; )
242        {
243            int original_network_id;
244            int transport_descriptor_length;
245           
246            original_network_id = ((p[k+2]<<8)+p[k+3]);
247            transport_descriptor_length = ((p[k+4]<<8)+p[k+5]) & 0xFFF;
248            if ( original_network_id != 0 )
249                numStreams++;
250           
251            k += 6+transport_descriptor_length;
252        }
253        }
254       
255        /* create the memChain */
256        err = memChainCreate(&memId,&memSetup);
257        if (err) {
258                goto ParseExit;
259        }
260   
261        p_nit = (dvb_nit_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_nit_t)+sizeof(memId_t))) + 1);
262        checkMemoryError(p_nit);
263   
264    p_nit->num_transport_stream = numStreams;
265    if ( numStreams )
266    {
267        p_nit->transport_streams = (transport_stream_t *)memChainAlloc(memId,sizeof(transport_stream_t)*numStreams);
268        checkMemoryError(p_nit->transport_streams);
269    }
270    else
271    {
272        p_nit->transport_streams = (transport_stream_t *)NULL;
273    }
274   
275    /*
276     * Now fill-out all the remaining fields over the all sections.
277     */
278        index = 0;
279        p_nit->network_descriptors = (DS_U8 *)NULL;
280        p_ts = p_nit->transport_streams;
281        for (i = 0; i < numSections; ++i) 
282        {
283            DS_U8 last_section_number;
284            int network_id;
285           
286                p = &sectionArr[i][0];
287                len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
288
289                network_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]);
290                version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> 
291                                                        SECTION_VERSION_SHIFT;
292                current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0;
293        network_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF;
294        last_section_number = p[SECTION_NUM_LAST];
295        p_nit->b_system_management_id = DS_FALSE;
296       
297                if (i == 0) 
298                {
299                    /* First section */
300                        p_nit->network_id = network_id;
301                        p_nit->version_number = version_number;
302                        //p_nit->current_next_indicator = current_next_indicator;
303           
304                        p_nit->section_number = p[SECTION_NUM];
305                        p_nit->last_section_number = last_section_number;
306                       
307            /*
308             * CONFIRM ME: Is network_descriptor is same on each sections?
309             */
310                        if ( p_nit->network_descriptors == (DS_U8 *)NULL && network_descriptor_length )
311                    {
312                        DS_U8 *p_desc = (DS_U8 *)NULL;
313                       
314                        p_nit->network_descriptor_length = network_descriptor_length;
315                        p_nit->network_descriptors = (DS_U8 *)memChainAlloc(memId, network_descriptor_length);
316                        memcpy( p_nit->network_descriptors, &p[10], network_descriptor_length);
317
318                        err=GetMpegDescriptor( p_nit->network_descriptors, 
319                                               network_descriptor_length, 
320                                               DVB_TAG_network_name_descriptor,
321                                               0, /* only find first one. */
322                                               &p_desc );
323                if ( p_desc && !err )
324                {
325                    DHL_PSI_ParseNetworkNameDescriptor( p_desc, memId, &(p_nit->p_network_name), &(p_nit->network_name_length) );
326                }
327                else
328                {
329                    p_nit->p_network_name = (DS_U8 *)NULL;
330                    p_nit->network_name_length = 0;
331                }
332               
333                p_desc = (DS_U8 *)NULL;
334                err=GetMpegDescriptor( p_nit->network_descriptors, 
335                                               network_descriptor_length, 
336                                       ARIB_TAG_system_management_descriptor,
337                                       0,
338                                       &p_desc );
339                if ( p_desc && !err )
340                {
341                    if ( DHL_PSI_ParseSystemManagementDescriptor( p_desc, &p_nit->system_management_id ) == 0 )
342                        p_nit->b_system_management_id = DS_TRUE;
343                }
344                    }
345                }
346                else 
347                {
348                        if (p_nit->network_id != network_id)
349                                printf("NIT: Inconsistent network_id (0x%x, 0x%x)\n", p_nit->network_id, network_id);
350                        if (p_nit->version_number != version_number)
351                                printf("NIT: inconsistent version_number (0x%x, 0x%x)\n", p_nit->version_number, version_number);
352            if (p_nit->network_descriptor_length != network_descriptor_length)
353                printf("NIT: Inconsistent network_descriptor_length (0x%x, 0x%x)\n", p_nit->network_descriptor_length, network_descriptor_length );
354            if (p_nit->last_section_number != last_section_number )
355                printf("NIT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_nit->last_section_number, last_section_number);
356                }
357               
358            transport_loop_length = ((p[10+network_descriptor_length]<<8) + p[11+network_descriptor_length]) & 0xFFF;
359            if (!p_ts && transport_loop_length)
360            {
361                printf("NIT: transport_loop_length is not NULL, but transport_streams is NULL.\n");
362                err = DHL_FAIL_INVALID_TABLEID;
363                goto ParseExit;
364            }
365           
366        p = &sectionArr[i][12+network_descriptor_length];
367        for(k=0; k<transport_loop_length; )
368        {
369            int transport_stream_id;
370            int original_network_id;
371            int transport_descriptor_length;
372           
373            transport_stream_id = ((p[k+0]<<8)+p[k+1]);
374            original_network_id = ((p[k+2]<<8)+p[k+3]);
375            transport_descriptor_length = ((p[k+4]<<8)+p[k+5]) & 0xFFF;
376           
377            p_ts->transport_stream_id = transport_stream_id;
378            p_ts->original_network_id = original_network_id;
379            p_ts->transport_descriptor_length = transport_descriptor_length;
380            if ( transport_descriptor_length )
381            {
382                DS_U8 *p_desc = (DS_U8 *)NULL;
383               
384                p_ts->transport_descriptors = (DS_U8 *)memChainAlloc( memId, transport_descriptor_length );
385                if ( !(p_ts->transport_descriptors) )
386                {
387                    err = DHL_FAIL_OUT_OF_RESOURCE;
388                    goto ParseExit;
389                }
390                memcpy( p_ts->transport_descriptors, &p[k+6], transport_descriptor_length );
391               
392                /*
393                 * Parse Service List descriptor
394                 */
395                        err=GetMpegDescriptor( p_ts->transport_descriptors, 
396                                               transport_descriptor_length, 
397                                               DVB_TAG_service_list_descriptor,
398                                               0, /* only find first one. */
399                                               &p_desc );
400                if ( p_desc )
401                {
402                    DHL_PSI_ParseServiceListDescriptor( p_desc, memId, &(p_ts->p_service_list) );
403                }
404                else
405                {
406                    p_ts->p_service_list = (dvb_service_list_descriptor_t *)NULL;
407                }
408               
409                /*
410                 * Parse TS information descriptor.
411                 */
412                p_desc = (DS_U8 *)NULL;
413                        err=GetMpegDescriptor( p_ts->transport_descriptors, 
414                                               transport_descriptor_length, 
415                                               ARIB_TAG_ts_information_descriptor,
416                                               0, /* only find first one. */
417                                               &p_desc );
418                if ( p_desc )
419                {
420                    DHL_PSI_ParseTSInformationDescriptor( p_desc, memId, &(p_ts->p_ts_info) );
421                }
422                else
423                {
424                    p_ts->p_ts_info = (arib_ts_information_descriptor_t *)NULL;
425                }
426               
427            }
428            else
429            {
430                p_ts->transport_descriptors = (DS_U8 *)NULL;
431                p_ts->p_service_list = (dvb_service_list_descriptor_t *)NULL;
432                p_ts->p_ts_info = (arib_ts_information_descriptor_t *)NULL;
433            }
434           
435            k += 6+transport_descriptor_length;
436            p_ts++;
437        }
438        }
439   
440    err = DHL_OK;
441        *(((memId_t *)p_nit)-1) = memId;
442        *pp_nit = p_nit;
443        memId = 0;      /* Don't delete below */
444
445ParseExit:
446        if (memId) 
447        {
448                /* delete the patSection memory */
449                memChainDestroy(memId);
450        }
451
452        return(err);
453}
454
455DHL_RESULT DHL_PSI_GetDvbNit( DHL_PSI_HANDLE sysInfo, DS_BOOL b_actual, DVB_NIT **pp_nit, int timeOut )
456{
457    DHL_RESULT err = DHL_OK;
458        void *returnPSICtl = NULL;
459        PSIEventProcData_t      procData;
460        int res = 0;
461
462        procData.desc = NULL;
463        procData.err = (DS_U32)DHL_OK;
464        /*creae a no-name , non-signaled event.*/
465        //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ ));
466        procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 );
467       
468    if (procData.hEvent == (OS_SEMAPHORE_ID)0)
469    {
470        printf ("DHL_PSI_GetPAT : OS_CreateBinarySemaphore() fails.\n");
471        return DHL_FAIL_OUT_OF_RESOURCE;
472    }   
473
474        if ((err = DHL_PSI_MonitorDvbNit(sysInfo,
475                                                  _TRUE_ /* current */,
476                                                  _FALSE_ /* not eager */,
477                                                  b_actual,
478                                                  psiOneShot, 
479                                                  hal_cbPSISyncEventProc,
480                                                  (DS_U32)&procData,
481                                                  &returnPSICtl))) 
482    {
483                goto done;
484        }
485       
486        //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut );
487        res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut );
488    if (res != 0)
489    {
490        #ifdef PSI_DGB
491        printf("DHL_PSI_GetPAT : OS_TakeSemaphore TIMEOUT %d \n", timeOut);
492        #endif
493       
494        #ifdef PSI_DBG
495                printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n");
496                #endif
497                               
498        err = DHL_FAIL_TIMEOUT;
499        goto done2;
500    }
501
502        if ((err = (DHL_RESULT)(procData.err))) {
503                printf("DHL_PSI_GetPAT : procData.err = %d \n",  err );
504                goto done2;
505        }
506
507        err = DHL_PSI_ParseDvbNit(procData.desc->sectPtr, b_actual, pp_nit);
508
509done2:
510        DHL_PSI_CancelMonitor(returnPSICtl);
511        if( procData.desc )
512            DD_PSI_FreePSIData(procData.desc);
513   
514done:
515        if(procData.hEvent)
516        {
517                OS_DeleteSemaphore(procData.hEvent);
518        }
519       
520        return(err);
521}
522
523DHL_RESULT DHL_PSI_PrintDvbNit( DVB_NIT *p_nit )
524{
525    DHL_RESULT err = DHL_OK;
526    transport_stream_t *p_ts;
527    int i;
528   
529    if (!p_nit)
530        return (err);
531       
532    printf("NIT (Network Information Table)\n");
533    printf("    network_id: 0x%04X\n", p_nit->network_id);
534    printf("    version_number: %d\n", p_nit->version_number);
535    printf("    section_number: %d\n", p_nit->section_number);
536    printf("    last_section_number: %d\n", p_nit->last_section_number);
537   
538    if ( p_nit->p_network_name )
539        printf("    network_name: %s\n", p_nit->p_network_name);
540    else
541        printf("    network_name: (not found)\n");
542       
543    printf("    network_descriptor_length: %d\n", p_nit->network_descriptor_length );
544    printf("    network_descriptors\n");
545    DHL_PSI_Dump(p_nit->network_descriptors, p_nit->network_descriptor_length);
546   
547    if ( p_nit->b_system_management_id )
548        printf("    system_management_id: 0x%04X\n", p_nit->system_management_id );
549    else
550        printf("    NO system_management_id!\n");
551   
552    printf("    num_transport_stream: %d\n", p_nit->num_transport_stream);
553    p_ts = p_nit->transport_streams;
554    for (i=0; i<p_nit->num_transport_stream; i++)
555    {
556        printf("    transport_stream %d\n", i);
557        printf("        transport_stream_id: 0x%04X\n", p_ts->transport_stream_id);
558        printf("        original_network_id: 0x%04X\n", p_ts->original_network_id);
559        if ( p_ts->p_service_list )
560        {
561            int n;
562            dvb_service_t *p_service = p_ts->p_service_list->p_service;
563           
564            printf("        service_list (%d)\n", p_ts->p_service_list->numServices);
565            for(n=0; n<p_ts->p_service_list->numServices; n++)
566            {
567                printf("        service #%d: service_id 0x%04X, service_type 0x%02X\n", n, 
568                        p_service->service_id, p_service->service_type);
569                p_service++;
570            }
571        }
572       
573        if ( p_ts->p_ts_info )
574        {
575            arib_ts_information_descriptor_t *p_ts_info = p_ts->p_ts_info;
576           
577            printf("        TS_info.remote_control_key_id = %d\n", p_ts_info->remote_control_key_id);
578            if ( p_ts_info->ts_name_length && p_ts_info->ts_name )
579            {
580                int n;
581
582#ifndef CONV_TO_ASCII
583#define CONV_TO_ASCII(x)    ( ((x) >= ' ' && (x) <= '~') ? (x) : '.' )
584#endif
585               
586                printf("        TS_info.ts_name = ");
587                for (n=0; n<p_ts_info->ts_name_length; n++)
588                    printf("%c", CONV_TO_ASCII(p_ts_info->ts_name[n]));
589                printf("\n");
590
591                printf("        TS_info.ts_name = ");
592                for (n=0; n<p_ts_info->ts_name_length; n++)
593                    printf("%02X ", p_ts_info->ts_name[n]);
594                printf("\n");
595            }
596           
597            if ( p_ts_info->transmission_type_count )
598            {
599                int n;
600                arib_transmission_type_t *p_tx_type = p_ts_info->transmission_type;
601               
602                for (n=0; n<p_ts_info->transmission_type_count; n++)
603                {
604                    printf("        TS_info.tx_type[%d].type: 0x%02X (%s-%s) See ARIB TR-B14 Table 3\n", n, 
605                                    p_tx_type->transmission_type_info,
606                                    ((p_tx_type->transmission_type_info>>6)&3) == 0 ? "Type A" :
607                                    ((p_tx_type->transmission_type_info>>6)&3) == 1 ? "Type B" :
608                                    ((p_tx_type->transmission_type_info>>6)&3) == 2 ? "Type C" :"Reserved",
609                                    ((p_tx_type->transmission_type_info>>4)&3) == 0 ? "64QAM" :
610                                    ((p_tx_type->transmission_type_info>>4)&3) == 1 ? "16QAM" :
611                                    ((p_tx_type->transmission_type_info>>4)&3) == 2 ? "QPSK" : "Reserved");
612                   
613                    if ( p_tx_type->number_of_service && p_tx_type->service_id )
614                    {
615                        int k;
616                       
617                        printf("        TS_info.tx_type[%d].service_id list\n", n);
618                        for (k=0; k<p_tx_type->number_of_service; k++)
619                        {
620                            printf("            0x%04X\n", p_tx_type->service_id[k]);
621                        }
622                    }
623                   
624                    p_tx_type++;
625                }
626            }
627        }
628
629        printf("        transport_descriptor_length: 0x%04X\n", p_ts->transport_descriptor_length);
630        DHL_PSI_Dump(p_ts->transport_descriptors, p_ts->transport_descriptor_length);
631       
632        p_ts++;
633    }
634   
635    return (err);
636}
637
638#if 0
639___Service_Description_Table___()
640#endif
641DHL_RESULT DHL_PSI_MonitorDvbSdt(               DHL_PSI_HANDLE sysInfo,
642                                                                        DS_BOOL current_next_indicator,
643                                                                        DS_BOOL eager,
644                                                                        DS_BOOL b_actual,
645                                                                        PSIUpdateMode updateMode,
646                                                                        PSIEventProc_f eventProc,
647                                                                        DS_U32 userParam, 
648                                                                        DHL_TBL_HANDLE *returnPSICtl)
649{
650        PSIMask_t               *pref;
651        DHL_RESULT              err=DHL_OK;
652
653        if ((err = DD_PSI_GetTIDPSIMask (&pref,
654                                                                        b_actual ? 
655                                                                            DVB_TID_service_description_section_actual : 
656                                                                            DVB_TID_service_description_section_other,
657                                                                        current_next_indicator))) {
658                printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err);
659                return(err);
660        }
661
662        if ((err = DD_PSI_MonitorPSIPid(sysInfo,
663                                                         DVB_PID_SDT, 
664                                                         eager ? eagerTableMode : tableMode, 
665                                                         updateMode,
666                                                         pref,
667                                                         /*MAX_PSI_MPEG_DATA*/1024,
668                                                         MAX_PSI_SECTIONS,
669                                                         eventProc,
670                                                         userParam,
671                                                         returnPSICtl))) 
672    {
673                printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err);                                         
674                PSI_Free(pref);
675        }
676       
677        return(err);
678}
679
680DHL_RESULT DHL_PSI_ParseDvbSdt(DS_U8 **sectionArr, DS_BOOL b_actual, dvb_sdt_t **pp_sdt)
681{
682        DHL_RESULT err = DHL_OK;
683        int i, k;
684        int numChannels;
685        int numSections;
686        int index;
687        const DS_U8 *p;
688        int len;
689        dvb_sdt_t *p_sdt = NULL;
690        int version_number;
691        DS_BOOL current_next_indicator;
692        memId_t                 memId = NULL;
693        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
694    dvb_sdt_service_t *p_service;
695       
696        if (sectionArr == NULL || (pp_sdt == NULL)) 
697        {
698                return (DHL_FAIL_NULL_POINTER);
699        }
700
701        if (sectionArr[0] == NULL) 
702        {
703                return (DHL_FAIL_NULL_POINTER);
704        }
705        else 
706        {
707                numSections = get_last_section_number(sectionArr[0]) + 1;
708        }
709
710        /* now verify all other sections are present */
711        for (i=1; i<numSections; i++) 
712    {
713                if (sectionArr[i] == NULL) {
714                        return (DHL_FAIL_NULL_POINTER);
715                }
716        }
717       
718        /*
719         * First pass, we verify section syntax and count the number of programs
720         */
721        numChannels = 0;
722        for (i = 0; i < numSections; ++i) 
723        {
724            int service_length;
725           
726                p = sectionArr[i];
727               
728                if( p == NULL )
729                {       
730                    printf( "%s: NULL section", __func__);
731                        return DHL_FAIL_NULL_POINTER;
732                }
733                       
734                if ( (b_actual && p[SECTION_TID] != DVB_TID_service_description_section_actual) ||
735                     (!b_actual && p[SECTION_TID] != DVB_TID_service_description_section_other) ) {
736                        /*
737                         * This thing isn't a PAT. Stop right here.
738                         */
739                        printf("SDT: Bad table ID. (0x%02X)\n", p[SECTION_TID]);
740                        err = DHL_FAIL_INVALID_TABLEID;
741                        goto ParseExit;
742                }
743               
744                if ((p[SECTION_LEN_HI] & 0x80) != 0x80) {
745                        printf("SDT: section_syntax_indicator not set\n");
746                }
747               
748                len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
749       
750        /*
751         * Counts number of services.
752         */
753        service_length = len - 8;
754        if ( service_length < 5 )
755        {
756            /* No service available for this section. */
757            continue;
758        }
759       
760        p = &sectionArr[i][11];
761        for(k=0; (k+5+4)<service_length; )
762        {
763            int descriptor_loop_length;
764           
765            descriptor_loop_length = ((p[k+3]<<8)+p[k+4]) & 0xFFF;
766            numChannels++;
767           
768            k += 5+descriptor_loop_length;
769        }
770        }
771       
772        /* create the memChain */
773        err = memChainCreate(&memId,&memSetup);
774        if (err) {
775                goto ParseExit;
776        }
777   
778        p_sdt = (dvb_sdt_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_sdt_t)+sizeof(memId_t))) + 1);
779        checkMemoryError(p_sdt);
780   
781    p_sdt->numServices = numChannels;
782    if ( numChannels )
783    {
784        p_sdt->services = (dvb_sdt_service_t *)memChainAlloc(memId,sizeof(dvb_sdt_service_t)*numChannels);
785        checkMemoryError(p_sdt->services);
786    }
787    else
788    {
789        p_sdt->services = (dvb_sdt_service_t *)NULL;
790    }
791   
792    /*
793     * Now fill-out all the remaining fields over the all sections.
794     */
795        index = 0;
796        p_service = p_sdt->services;
797        for (i = 0; i < numSections; ++i) 
798        {
799            DS_U16 original_network_id;
800            DS_U16 transport_stream_id;
801            DS_U8 last_section_number;
802            int service_length;
803           
804                p = &sectionArr[i][0];
805                len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
806
807                transport_stream_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]);
808                version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> 
809                                                        SECTION_VERSION_SHIFT;
810                current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0;
811        original_network_id = ((p[8]<<8) + p[9]);
812        last_section_number = p[SECTION_NUM_LAST];
813       
814                if (i == 0) 
815                {
816                    /* First section */
817                        p_sdt->transport_stream_id = transport_stream_id;
818                        p_sdt->version_number = version_number;
819                    p_sdt->original_network_id = original_network_id;
820                       
821                        p_sdt->section_number = p[SECTION_NUM];
822                        p_sdt->last_section_number = last_section_number;
823                       
824            /*
825             * CONFIRM ME: Is network_descriptor is same on each sections?
826             */
827                }
828                else 
829                {
830                        if (p_sdt->transport_stream_id != transport_stream_id)
831                                printf("SDT: Inconsistent transport_stream_id (0x%x, 0x%x)\n", p_sdt->transport_stream_id, transport_stream_id);
832                        if (p_sdt->version_number != version_number)
833                                printf("SDT: Inconsistent version_number (0x%x, 0x%x)\n", p_sdt->version_number, version_number);
834            if (p_sdt->original_network_id != original_network_id )
835                printf("SDT: Inconsistent original_network_id (0x%x, 0x%x)\n", p_sdt->original_network_id, original_network_id );
836            if (p_sdt->last_section_number != last_section_number )
837                printf("SDT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_sdt->last_section_number, last_section_number);
838                }
839               
840        service_length = len - 8;
841        if ( service_length < 5 )
842        {
843            /* No service available for this section. */
844            continue;
845        }
846       
847        p = &sectionArr[i][11];
848        for(k=0; (k+5+4)<service_length; )
849        {
850            p_service->service_id           = ((p[k+0]<<8)+p[k+1]);
851            p_service->EIT_user_defined_flags = (p[k+2]>>2) & 0x07;
852            p_service->EIT_schedule_flag    = (p[k+2] & 0x02) ? DS_TRUE : DS_FALSE;
853            p_service->EIT_present_following_flag = (p[k+2] & 0x01) ? DS_TRUE : DS_FALSE;
854            p_service->running_status       = (p[k+3]>>5) & 0x07;
855            p_service->free_CA_mode         = ((p[k+3]>>4) & 0x01) ? DS_TRUE : DS_FALSE;
856            p_service->descriptor_length = ((p[k+3]<<8)+p[k+4]) & 0xFFF;
857           
858            p_service->descriptors = (DS_U8 *)NULL;
859            p_service->p_service_desc = (dvb_service_descriptor_t *)NULL;
860            p_service->logo_tx_desc = (arib_logo_transmission_descriptor_t *)NULL;
861            if ( p_service->descriptor_length )
862            {
863                DS_U8 *p_desc = (DS_U8 *)NULL;
864               
865                p_service->descriptors = (DS_U8 *)memChainAlloc( memId, p_service->descriptor_length );
866                if ( !(p_service->descriptors) )
867                {
868                    err = DHL_FAIL_OUT_OF_RESOURCE;
869                    goto ParseExit;
870                }
871                memcpy( p_service->descriptors, &p[k+5], p_service->descriptor_length );
872               
873                //
874                // Parse service_descriptor if available.
875                //
876                        err=GetMpegDescriptor( p_service->descriptors, 
877                                               p_service->descriptor_length, 
878                                               DVB_TAG_service_descriptor,
879                                               0, /* only find first one. */
880                                               &p_desc );
881                if ( p_desc && err == DHL_OK )
882                {
883                    p_service->p_service_desc = (dvb_service_descriptor_t *)NULL;
884                    DHL_PSI_ParseServiceDescriptor( p_desc, memId, &(p_service->p_service_desc) );
885                }
886
887                //
888                // Parse service_descriptor if available.
889                //
890                        err=GetMpegDescriptor( p_service->descriptors, 
891                                               p_service->descriptor_length, 
892                                               ARIB_TAG_logo_transmission_descriptor,
893                                               0, /* only find first one. */
894                                               &p_desc );
895                if ( p_desc && err == DHL_OK )
896                {
897                    p_service->logo_tx_desc = (arib_logo_transmission_descriptor_t *)NULL;
898                    DHL_PSI_ParseLogoTransmissionDescriptor( p_desc, memId, &(p_service->logo_tx_desc) );
899                }
900            }
901           
902            k += 5+p_service->descriptor_length;
903            p_service++;
904            if ( index++ > numChannels )
905            {
906                printf("SDT: Inconsistent number of services.\n");
907                        err = DHL_FAIL_INVALID_TABLEID;
908                        goto ParseExit;
909                }
910        }
911        }
912   
913    err = DHL_OK;
914        *(((memId_t *)p_sdt)-1) = memId;
915        *pp_sdt = p_sdt;
916        memId = 0;      /* Don't delete below */
917
918ParseExit:
919   
920        if (memId) 
921        {
922                /* delete the patSection memory */
923                memChainDestroy(memId);
924        }
925
926        return(err);
927}
928
929DHL_RESULT DHL_PSI_GetDvbSdt( DHL_PSI_HANDLE sysInfo, DS_BOOL b_actual, DVB_SDT **pp_sdt, int timeOut )
930{
931    DHL_RESULT err = DHL_OK;
932        void *returnPSICtl = NULL;
933        PSIEventProcData_t      procData;
934        int res = 0;
935
936        procData.desc = NULL;
937        procData.err = (DS_U32)DHL_OK;
938        /*creae a no-name , non-signaled event.*/
939        //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ ));
940        procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 );
941       
942    if (procData.hEvent == (OS_SEMAPHORE_ID)0)
943    {
944        printf ("%s: OS_CreateBinarySemaphore() fails.\n", __func__);
945        return DHL_FAIL_OUT_OF_RESOURCE;
946    }   
947
948        if ((err = DHL_PSI_MonitorDvbSdt(sysInfo,
949                                                  _TRUE_ /* current */,
950                                                  _FALSE_ /* not eager */,
951                                                  b_actual,
952                                                  psiOneShot, 
953                                                  hal_cbPSISyncEventProc,
954                                                  (DS_U32)&procData,
955                                                  &returnPSICtl))) 
956    {
957        printf("%s: DHL_PSI_MonitorDvbSdt()=0x%02X\n", __func__, err);
958                goto done;
959        }
960       
961        //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut );
962        res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut );
963    if (res != 0)
964    {
965        //#ifdef PSI_DGB
966        printf("%s: OS_TakeSemaphore TIMEOUT %d \n", __func__, timeOut);
967        //#endif
968       
969        #ifdef PSI_DBG
970                printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n");
971                #endif
972                               
973        err = DHL_FAIL_TIMEOUT;
974        goto done2;
975    }
976
977        if ((err = (DHL_RESULT)(procData.err))) {
978                printf("%s: procData.err = %d\n", __func__, err );
979                goto done2;
980        }
981
982        err = DHL_PSI_ParseDvbSdt(procData.desc->sectPtr, b_actual, pp_sdt);
983
984done2:
985        DHL_PSI_CancelMonitor(returnPSICtl);
986        if( procData.desc )
987            DD_PSI_FreePSIData(procData.desc);
988   
989done:
990        if(procData.hEvent)
991        {
992                OS_DeleteSemaphore(procData.hEvent);
993        }
994       
995        return(err);
996}
997
998DHL_RESULT DHL_PSI_PrintDvbSdt( DVB_SDT *p_sdt )
999{
1000    DHL_RESULT err=DHL_OK;
1001    dvb_sdt_service_t *p_service;
1002    int i;
1003   
1004    if (!p_sdt)
1005        return err;
1006   
1007    p_service = p_sdt->services;
1008   
1009    printf("SDT (Service Description Table)\n");
1010    printf("    transport_stream_id: 0x%04X\n", p_sdt->transport_stream_id);
1011    printf("    version_number: %d\n", p_sdt->version_number);
1012    printf("    section_number: %d\n", p_sdt->section_number);
1013    printf("    last_section_number: %d\n", p_sdt->last_section_number);
1014    printf("    original_network_id: 0x%04X\n\n", p_sdt->original_network_id);
1015   
1016    if ( !p_service )
1017        return (err);
1018   
1019    for (i=0; i<p_sdt->numServices; i++)
1020    {
1021        printf("Service #%d\n", i );
1022        printf("    service_id: 0x%04X\n", p_service->service_id);
1023        printf("    EIT_user_defined_flags: %d\n", p_service->EIT_user_defined_flags);
1024        printf("    EIT_schedule_flag: %s (%d)\n", p_service->EIT_schedule_flag ? "TRUE" : "FALSE", p_service->EIT_schedule_flag);
1025        printf("    EIT_present_following_flag: %s (%d)\n", p_service->EIT_present_following_flag ? "TRUE" : "FALSE", p_service->EIT_present_following_flag);
1026        printf("    running_status: %d\n", p_service->running_status);
1027        printf("    free_CA_mode: %d\n", p_service->free_CA_mode);
1028
1029        DHL_PSI_Dump(p_service->descriptors, p_service->descriptor_length);
1030
1031        if ( p_service->logo_tx_desc )
1032        {
1033                        arib_logo_transmission_descriptor_t *p_logo;
1034                        p_logo = p_service->logo_tx_desc;
1035                       
1036                        printf("    logo_transmission_descriptor\n");
1037
1038                        if ( p_logo->logo_transmission_type == 0x1 )
1039                        {
1040                                printf("    logo_id: 0x%04X\n", p_logo->logo_id);
1041                                printf("    logo_version: 0x%04X\n", p_logo->logo_version);
1042                                printf("    download_data_id: 0x%04X\n", p_logo->download_data_id);
1043                        }
1044                        else if ( p_logo->logo_transmission_type == 0x2 )
1045                        {
1046                                printf("    logo_id: 0x%04X\n", p_logo->logo_id);
1047                        }
1048                        else if ( p_logo->logo_transmission_type == 0x3 )
1049                        {
1050                                printf("    logo_char: %s\n", p_logo->logo_char);
1051                        }
1052                }
1053       
1054        if ( p_service->p_service_desc )
1055        {
1056            printf("    service_type: 0x%02X\n", p_service->p_service_desc->service_type);
1057            printf("    provider_name: %s\n", p_service->p_service_desc->p_provider_name);
1058            printf("    service_name : %s\n", p_service->p_service_desc->p_service_name);
1059        }
1060       
1061        p_service++;
1062    }
1063   
1064    return (err);
1065}
1066
1067
1068#if 0
1069___Event_Information_Table___()
1070#endif
1071DHL_RESULT DHL_PSI_MonitorDvbEitEx(     DHL_PSI_HANDLE sysInfo,
1072                                                                        DS_BOOL b_actual,
1073                                    DS_U16  eit_pid,
1074                                                                        DS_U8   scheduleTableId,
1075                                                                        DS_U16  service_id,
1076                                                                        DS_U8   segment_number,
1077                                                                        PSIUpdateMode updateMode,
1078                                                                        PSIEventProc_f eventProc,
1079                                                                        DS_U32 userParam, 
1080                                                                        DHL_TBL_HANDLE *returnPSICtl)
1081{
1082        PSIMask_t               *pref;
1083        DHL_RESULT              err=DHL_OK;
1084        DS_U8           tableId = DVB_TID_event_information_section_actual_present;
1085   
1086    /*
1087     * If b_schedule is TRUE, then schedule_table_id shall be valid one.
1088     */
1089    if ( scheduleTableId )
1090    {
1091        tableId = scheduleTableId;
1092    }
1093    else
1094    {
1095        if ( b_actual )
1096            tableId = DVB_TID_event_information_section_actual_present;
1097        else
1098            tableId = DVB_TID_event_information_section_other_present;
1099    }
1100   
1101    if ( segment_number == SEGMENT_TABLE_MODE || segment_number == SEGMENT_EAGER_MODE )
1102    {
1103        if ((err = DD_PSI_GetExTIDPSIMask(&pref, tableId, service_id, 1)))
1104        {
1105                printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err);
1106                return(err);
1107        }
1108    }
1109    else
1110    {
1111        if ((err = DD_PSI_GetDvbEitMask(&pref, tableId, service_id, segment_number, 1)))
1112        {
1113                printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err);
1114                return(err);
1115        }
1116    }
1117
1118        if ((err = DD_PSI_MonitorPSIPid(sysInfo,
1119                                                         eit_pid ? eit_pid : DVB_PID_EIT, 
1120                                                         SEGMENT_TABLE_MODE == segment_number ? segmentTableMode : 
1121                                                         SEGMENT_EAGER_MODE == segment_number ? segmentEagerMode : segmentOnlyMode, 
1122                                                         updateMode,
1123                                                         pref,
1124                                                         /*MAX_PSI_MPEG_DATA*/4096,
1125                                                         MAX_PSI_SECTIONS,
1126                                                         eventProc,
1127                                                         userParam,
1128                                                         returnPSICtl))) 
1129    {
1130                printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err);                                         
1131                PSI_Free(pref);
1132        }
1133       
1134        if ( segment_number != SEGMENT_TABLE_MODE && segment_number != SEGMENT_EAGER_MODE && *returnPSICtl )
1135        {
1136            DD_PSI_SetSegmentNumber(*returnPSICtl, segment_number);
1137    }
1138   
1139        return(err);
1140}
1141
1142
1143DHL_RESULT DHL_PSI_MonitorDvbEit(       DHL_PSI_HANDLE sysInfo,
1144                                                                        DS_BOOL b_actual,
1145                                                                        DS_U16  eit_pid,
1146                                                                        DS_U8   scheduleTableId,
1147                                                                        DS_U16  service_id,
1148                                                                        PSIUpdateMode updateMode,
1149                                                                        PSIMode psiMode,
1150                                                                        PSIEventProc_f eventProc,
1151                                                                        DS_U32 userParam, 
1152                                                                        DHL_TBL_HANDLE *returnPSICtl)
1153{
1154    int mode=0;
1155   
1156    switch(psiMode)
1157    {
1158        case segmentTableMode:
1159            mode = SEGMENT_TABLE_MODE;
1160            break;
1161       
1162        case segmentEagerMode:
1163            mode = SEGMENT_EAGER_MODE;
1164            break;
1165       
1166        default:
1167            printf("|%s| ERROR!! Invalid mode (%d)\n", __func__, psiMode);
1168            return DHL_FAIL;
1169    }
1170   
1171    return DHL_PSI_MonitorDvbEitEx( sysInfo, b_actual, eit_pid, scheduleTableId, service_id, mode, updateMode, eventProc, userParam, returnPSICtl );
1172}
1173
1174DHL_RESULT DHL_PSI_ParseDvbEitEx(DS_U8 **sectionArr, DS_BOOL b_actual, int i_section_mode, DS_U8 scheduleTableId, DS_U32 prefLangCode, DVB_EIT **pp_eit)
1175{
1176        DHL_RESULT err = DHL_OK;
1177        int i, k;
1178        int numEvents;
1179        int numSections;
1180        int index;
1181        const DS_U8 *p;
1182        int len;
1183        dvb_eit_t *p_eit = NULL;
1184        DS_BOOL current_next_indicator;
1185        memId_t                 memId = NULL;
1186        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
1187        DS_U8 expectedTableId;
1188    dvb_eit_event_t *p_event;
1189    DS_BOOL b_first = DS_TRUE;
1190    DS_BOOL b_exist = DS_FALSE;
1191    int instance;
1192   
1193        if (sectionArr == NULL || (pp_eit == NULL)) 
1194        {
1195                return (DHL_FAIL_NULL_POINTER);
1196        }
1197
1198    if ( i_section_mode )
1199    {
1200        numSections = i_section_mode;
1201    }
1202    else
1203    {   
1204        if (sectionArr[0] == NULL) 
1205        {
1206                //return (DHL_FAIL_NULL_POINTER);
1207                numSections = 256;
1208        }
1209        else 
1210        {
1211                numSections = get_last_section_number(sectionArr[0]) + 1;
1212        }
1213    }
1214
1215        /* now verify all other sections are present */
1216        for (b_exist=DS_FALSE, i=0; i<numSections; i++) 
1217    {
1218                if (sectionArr[i]) 
1219        {
1220                        b_exist = DS_TRUE;
1221                }
1222        }
1223       
1224    if ( b_exist == DS_FALSE )
1225    {
1226        printf("!! None of section pointer is valid.\n");
1227        return (DHL_FAIL_NULL_POINTER);
1228    }
1229   
1230        if ( scheduleTableId )
1231        {
1232            expectedTableId = scheduleTableId;
1233        }
1234        else
1235        {
1236            if ( b_actual )
1237                expectedTableId = DVB_TID_event_information_section_actual_present;
1238            else
1239                expectedTableId = DVB_TID_event_information_section_other_present;
1240        }
1241       
1242        /*
1243         * First pass, we verify section syntax and count the number of events.
1244         */
1245        numEvents = 0;
1246        for (i = 0; i < numSections; ++i) 
1247        {
1248        int descriptor_loop_length;
1249            int event_length;
1250            DS_U16 service_id;
1251           
1252                p = sectionArr[i];
1253
1254                if( p == NULL )
1255                {       
1256#if 0
1257                    printf( "%s: NULL section", __func__);
1258                        return DHL_FAIL_NULL_POINTER;
1259#else
1260            /* Skip null pointer section. */
1261            continue;
1262#endif
1263                }
1264           
1265//              if ( p[SECTION_TID] != expectedTableId ) {
1266//                      /*
1267//                       * This thing isn't a PAT. Stop right here.
1268//                       */
1269//                      printf("EIT: Bad table ID. i=%d, (0x%02X)\n", i, p[SECTION_TID]);
1270//                      err = DHL_FAIL_INVALID_TABLEID;
1271//                      goto ParseExit;
1272//              }
1273               
1274                if ((p[SECTION_LEN_HI] & 0x80) != 0x80) {
1275                        printf("EIT: section_syntax_indicator not set\n");
1276                }
1277               
1278                len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
1279        service_id = (p[SECTION_TID_EXT_HI] << 8) + p[SECTION_TID_EXT_LO];
1280        if ( service_id == 0 )
1281        {
1282            printf("EIT: Bad service ID. (0x%04X)\n", service_id);
1283            err = DHL_FAIL_INVALID_TABLEID;
1284            goto ParseExit;
1285        }
1286       
1287        /*
1288         * Counts number of services.
1289         */
1290        event_length = len - 14/*table_id to last_table_id*/ - 4/*crc_32*/;
1291        if ( event_length < 12 )
1292        {
1293            /* No events are available for this section. */
1294            continue;
1295        }
1296       
1297        //printf("event_length: %d\n", event_length);
1298       
1299        p = &sectionArr[i][14];
1300        for(k=0; (k+12+4)<event_length; )
1301        {
1302            descriptor_loop_length = ((p[k+10]<<8)+p[k+11]) & 0xFFF;
1303            //printf("k: %d, descriptor_loop_length: %d\n", k, descriptor_loop_length);
1304           
1305            /* If start_time is not NULL, then take it as valid one. */
1306            //if ( p[k+2] || p[k+3] )
1307                numEvents++;
1308           
1309            k += 12+descriptor_loop_length;
1310        }
1311        }
1312       
1313//      printf("EIT: numEvents: %d\n", numEvents);
1314       
1315        /* create the memChain */
1316        err = memChainCreate(&memId,&memSetup);
1317        if (err) {
1318                goto ParseExit;
1319        }
1320   
1321        p_eit = (dvb_eit_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_eit_t)+sizeof(memId_t))) + 1);
1322        checkMemoryError(p_eit);
1323   
1324    p_eit->numEvents = numEvents;
1325    if ( numEvents )
1326    {
1327        p_eit->eit_events = (dvb_eit_event_t *)memChainAlloc(memId,sizeof(dvb_eit_event_t)*numEvents);
1328        checkMemoryError(p_eit->eit_events);
1329    }
1330    else
1331    {
1332        p_eit->eit_events = (dvb_eit_event_t *)NULL;
1333    }
1334   
1335    /*
1336     * Now fill-out all the remaining fields over the all sections.
1337     */
1338        index = 0;
1339        p_event = p_eit->eit_events;
1340        b_first = 0;
1341        for (i = 0; i < numSections; ++i) 
1342        {
1343        DS_U16  service_id;
1344        DS_U8   version_number;
1345        DS_U8   last_section_number;
1346        DS_U8   segment_last_section_number;
1347        DS_U8   table_id;
1348        DS_U16  transport_stream_id;
1349        DS_U16  original_network_id;
1350        DS_U8   last_table_id;
1351
1352        int     event_length;
1353       
1354       
1355                if( sectionArr[i] == NULL )
1356                {       
1357            /* Skip null pointer section. */
1358            //printf("skip %d section due to NULL.\n", i);
1359            continue;
1360                }
1361               
1362                p = &sectionArr[i][0];
1363                len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
1364
1365                service_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]);
1366                version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> 
1367                                                        SECTION_VERSION_SHIFT;
1368                current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0;
1369        last_section_number = p[SECTION_NUM_LAST];
1370        table_id = p[SECTION_TID];
1371       
1372        transport_stream_id = ((p[8]<<8) + p[9]);
1373        original_network_id = ((p[10]<<8) + p[11]);
1374        segment_last_section_number = p[12];
1375        last_table_id = p[13];
1376       
1377                if (b_first == 0) 
1378                {
1379                    //DHL_PSI_Dump( (DS_U8 *)p, 32 );
1380                   
1381                    /* First section */
1382                    p_eit->table_id                    = table_id;
1383            p_eit->service_id                  = service_id;                   
1384            p_eit->version_number              = version_number;             
1385            p_eit->section_number              = p[6];
1386            p_eit->last_section_number         = last_section_number;
1387            p_eit->segment_last_section_number = segment_last_section_number;
1388            p_eit->transport_stream_id         = transport_stream_id;
1389            p_eit->original_network_id         = original_network_id;
1390            p_eit->last_table_id               = last_table_id;
1391            b_first = 1;
1392                }
1393                else 
1394                {
1395                    if (p_eit->table_id != table_id)
1396                        printf("EIT: Inconsistent table_id (0x%x, 0x%x)\n", p_eit->table_id, table_id);
1397                    if (p_eit->service_id != service_id)
1398                        printf("EIT: Inconsistent service_id (0x%x, 0x%x)\n", p_eit->service_id, service_id);
1399                        if (p_eit->version_number != version_number)
1400                                printf("EIT: Inconsistent version_number (0x%x, 0x%x)\n", p_eit->version_number, version_number);
1401            if (p_eit->last_section_number != last_section_number )
1402                printf("EIT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_eit->last_section_number, last_section_number);
1403#if 0
1404            /* Don't need to check this. */
1405            if (p_eit->segment_last_section_number != segment_last_section_number )
1406                printf("EIT: Inconsistent segment_last_section_number (0x%x, 0x%x)\n", p_eit->segment_last_section_number, segment_last_section_number);
1407#endif
1408                        if (p_eit->transport_stream_id != transport_stream_id)
1409                                printf("EIT: Inconsistent transport_stream_id (0x%x, 0x%x)\n", p_eit->transport_stream_id, transport_stream_id);
1410            if (p_eit->original_network_id != original_network_id )
1411                printf("EIT: Inconsistent original_network_id (0x%x, 0x%x)\n", p_eit->original_network_id, original_network_id );
1412            if (p_eit->last_table_id != last_table_id )
1413                printf("EIT: Inconsistent last_table_id (0x%x, 0x%x)\n", p_eit->last_table_id, last_table_id );
1414                }
1415               
1416        event_length = len - 14 - 4;
1417        if ( event_length < 12 )
1418        {
1419            /* No service available for this section. */
1420            continue;
1421        }
1422       
1423        p = &sectionArr[i][14];
1424        for(k=0; (k+12+4)<event_length; )
1425        {
1426            int descriptor_length;
1427
1428            p_event->event_id = (p[k+0]<<8)+p[k+1];
1429            p_event->start_date = (p[k+2]<<8)+p[k+3];
1430            p_event->start_time = (p[k+4]<<16)+(p[k+5]<<8)+p[k+6];
1431            p_event->duration = (p[k+7]<<16)+(p[k+8]<<8)+p[k+9];
1432
1433            p_event->start_time_utc = _ConvertMJD2UTC(p_event->start_date, p_event->start_time);
1434            p_event->duration_in_sec = _ConvertMJD2UTC(0, p_event->duration);
1435
1436            p_event->running_status = (p[k+10]>>5) & 0x07;
1437            p_event->free_CA_mode = (p[k+10]>>4) & 0x01;
1438            descriptor_length = p_event->descriptor_length = ((p[k+10]<<8)+p[k+11]) & 0xFFF;
1439
1440            p_event->descriptor_length = 0;
1441            p_event->descriptors = (DS_U8 *)NULL;
1442           
1443            if ( descriptor_length )
1444            {
1445                DS_U8 *p_desc_sect = (DS_U8 *)&p[k+12];
1446                DS_U8 *p_desc = (DS_U8 *)NULL;
1447                DS_U8 langCode[3];
1448#if 0               
1449                p_event->descriptors = (UINT8 *)memChainAlloc( memId, descriptor_length );
1450                if ( !(p_event->descriptors) )
1451                {
1452                    err = outOfCPUMemoryError;
1453                    goto ParseExit;
1454                }
1455                memcpy( p_event->descriptors, &p[k+12], descriptor_length );
1456#endif
1457                {
1458                    /*
1459                     * ShortEventDescriptor°¡ 2°³ ÀÌ»óÀÎ °æ¿ì¸¦ À§ÇÏ¿© ¾øÀ» ¶§ ±îÁö ã¾Æ¼­ Parse.
1460                     */
1461                     
1462                    dvb_short_event_descriptor_t *pp_short_event[MAX_SHORT_EVENTS];
1463
1464                    p_event->pp_short_event = (dvb_short_event_descriptor_t **)NULL;
1465                    memset( pp_short_event, 0, sizeof(dvb_short_event_descriptor_t *)*MAX_SHORT_EVENTS );
1466                    instance = 0;
1467                    do {
1468                        p_desc = (DS_U8 *)NULL;
1469                        if ( prefLangCode )
1470                        {
1471                            langCode[0] = (prefLangCode>>16) & 0xFF;
1472                            langCode[1] = (prefLangCode>>8) & 0xFF;
1473                            langCode[2] = (prefLangCode>>0) & 0xFF;
1474                           
1475                            err=GetMpegDescriptorEx( p_desc_sect, descriptor_length, DVB_TAG_short_event_descriptor,
1476                                                     2/*Offset to ISO_639_language_code*/, langCode, 3/*Langcode=3byte*/, 
1477                                                     instance,
1478                                                     &p_desc );
1479                        }
1480                        else 
1481                        {
1482                                err=GetMpegDescriptor( p_desc_sect, 
1483                                                       descriptor_length, 
1484                                                       DVB_TAG_short_event_descriptor,
1485                                                       instance,
1486                                                       &p_desc );
1487                        }
1488                       
1489                        if (p_desc && err == DHL_OK)
1490                        {
1491                            DHL_PSI_ParseShortEventDescriptor( p_desc, memId, prefLangCode, &pp_short_event[instance] );
1492                            instance++;
1493                        }
1494                    } while (p_desc && err == DHL_OK && instance < MAX_SHORT_EVENTS);
1495                   
1496                    if (instance)
1497                    {
1498                        /*
1499                         * ãÀº ¼ö ¸¸Å­ pointer¸¦ º¹»çÇϰí, count¸¦ ¼³Á¤.
1500                         */
1501                        p_event->pp_short_event = (dvb_short_event_descriptor_t **)memChainAlloc(memId, sizeof(dvb_short_event_descriptor_t *) * instance);
1502                        checkMemoryError(p_event->pp_short_event);
1503                        memcpy( p_event->pp_short_event, pp_short_event, sizeof(dvb_short_event_descriptor_t *) * instance );
1504                    }
1505                    p_event->numShortEvents = instance;
1506                }
1507               
1508                {
1509                    /*
1510                     * extended_event_descriptor°¡ 2°³ ÀÌ»óÀÎ °æ¿ì¸¦ À§ÇÏ¿© ¾øÀ» ¶§ ±îÁö ã¾Æ¼­ Parse.
1511                     */
1512                    dvb_extended_event_descriptor_t *pp_extended_event[MAX_EXTENDED_EVENTS];
1513
1514                    p_event->pp_extended_event = (dvb_extended_event_descriptor_t **)NULL;
1515                    memset( pp_extended_event, 0, sizeof(dvb_extended_event_descriptor_t *) * MAX_EXTENDED_EVENTS );
1516                    instance = 0;
1517                    do {
1518                        p_desc = (DS_U8 *)NULL;
1519                        if ( prefLangCode )
1520                        {
1521                            err=GetMpegDescriptorEx( p_desc_sect, descriptor_length, DVB_TAG_extended_event_descriptor,
1522                                                     3/*Offset to ISO_639_language_code*/, langCode, 3/*Langcode=3byte*/, instance, &p_desc );
1523                        }
1524                        else
1525                        {
1526                                err=GetMpegDescriptor( p_desc_sect, 
1527                                                       descriptor_length, 
1528                                                       DVB_TAG_extended_event_descriptor,
1529                                                       instance,
1530                                                       &p_desc );
1531                        }
1532                       
1533                        if (p_desc && err == DHL_OK)
1534                        {
1535                            DHL_PSI_ParseExtendedEventDescriptor( p_desc, memId, prefLangCode, &pp_extended_event[instance] );
1536                            instance++;
1537                        }
1538                    } while (p_desc && err == DHL_OK && instance < MAX_EXTENDED_EVENTS);
1539                   
1540                    /*
1541                     * ãÀº ¼ö ¸¸Å­ pointer¸¦ º¹»çÇϰí, count¸¦ ¼³Á¤.
1542                     */
1543                    if (instance)
1544                    {
1545                        p_event->pp_extended_event = (dvb_extended_event_descriptor_t **)memChainAlloc(memId, sizeof(dvb_extended_event_descriptor_t *) * instance);
1546                        checkMemoryError(p_event->pp_extended_event);
1547                        memcpy( p_event->pp_extended_event, pp_extended_event, instance * sizeof(dvb_extended_event_descriptor_t *) );
1548                    }
1549                    p_event->numExtendedEvents = instance;
1550                }
1551               
1552                {
1553                    /*
1554                     * Find Parental_Rating descriptor.
1555                     */
1556                    dvb_parental_rating_descriptor_t *pp_pr_desc[MAX_RATINGS];
1557
1558                    p_event->pp_pr_desc = (dvb_parental_rating_descriptor_t **)NULL;
1559                    memset( pp_pr_desc, 0, sizeof(dvb_parental_rating_descriptor_t *) * MAX_RATINGS );
1560                    instance = 0;
1561                    do {
1562                        p_desc = (DS_U8 *)NULL;
1563                        err=GetMpegDescriptor( p_desc_sect, 
1564                                                       descriptor_length, 
1565                                                       DVB_TAG_parental_rating_descriptor,
1566                                                       instance, 
1567                                                       &p_desc );
1568                       
1569                        if (p_desc && err == DHL_OK)
1570                        {
1571                            DHL_PSI_ParseParentalRatingDescriptorEx( p_desc, memId, &pp_pr_desc[instance] );
1572                            instance++;
1573                        }
1574                    } while (p_desc && err == DHL_OK && instance < MAX_RATINGS);
1575                   
1576                    if (instance)
1577                    {
1578                        p_event->pp_pr_desc = (dvb_parental_rating_descriptor_t **)memChainAlloc(memId, sizeof(dvb_parental_rating_descriptor_t *) * instance);
1579                        checkMemoryError(p_event->pp_pr_desc);
1580                        memcpy( p_event->pp_pr_desc, pp_pr_desc, sizeof(dvb_parental_rating_descriptor_t *) * instance );
1581                    }
1582                    p_event->numParentalRating = instance;
1583                }
1584               
1585                /*
1586                 * Find Event Group descriptor.
1587                 */
1588                p_desc = (DS_U8 *)NULL;
1589                err=GetMpegDescriptor( p_desc_sect, 
1590                                               descriptor_length, 
1591                                               ARIB_TAG_event_group_descriptor,
1592                                               0, /* only find first one. */
1593                                               &p_desc );
1594                if (p_desc && err == DHL_OK)
1595                    DHL_PSI_ParseEventGroupDescriptor( p_desc, memId, &p_event->p_event_group );
1596               
1597                {
1598                    /*
1599                     * Find Audio component descriptor.
1600                     */
1601                    arib_audio_component_descriptor_t *pp_audio_component[MAX_AUDIO_COMPONENT];
1602   
1603                    p_event->pp_audio_component = (arib_audio_component_descriptor_t **)NULL;
1604                    memset( pp_audio_component, 0, sizeof(arib_audio_component_descriptor_t *) * MAX_AUDIO_COMPONENT );
1605                    instance = 0;
1606                    do {
1607                        p_desc = (DS_U8 *)NULL;
1608                        err=GetMpegDescriptor( p_desc_sect, 
1609                                                descriptor_length, 
1610                                                ARIB_TAG_audio_component_descriptor,
1611                                                instance,
1612                                                &p_desc );
1613                        if (p_desc && err == DHL_OK)
1614                        {
1615                            DHL_PSI_ParseAudioComponentDescriptor( p_desc, memId, &pp_audio_component[instance] );
1616                            instance++;
1617                        }
1618                    } while (p_desc && err == DHL_OK && instance < MAX_AUDIO_COMPONENT);
1619                   
1620                    if (instance)
1621                    {
1622                        p_event->pp_audio_component = (arib_audio_component_descriptor_t **)memChainAlloc(memId, sizeof(arib_audio_component_descriptor_t *) * instance);
1623                        checkMemoryError(p_event->pp_audio_component);
1624                        memcpy( p_event->pp_audio_component, pp_audio_component, sizeof(arib_audio_component_descriptor_t *) * instance );
1625                    }
1626                    p_event->numAudioComponent = instance;
1627                }
1628               
1629                {
1630                    //
1631                    // Data component descriptor
1632                    //
1633                    arib_data_content_descriptor_t *pp_data_content[MAX_CAPTION_ES];
1634                   
1635                    p_event->pp_data_content = (arib_data_content_descriptor_t **)NULL;
1636                    memset( pp_data_content, 0, sizeof(arib_data_content_descriptor_t *) * MAX_CAPTION_ES );
1637                    instance = 0;
1638                   
1639                    langCode[0] = 0x00;
1640                    langCode[1] = 0x08;
1641                    do {
1642                        p_desc = (DS_U8 *)NULL;
1643                        err=GetMpegDescriptorEx( p_desc_sect, descriptor_length, ARIB_TAG_data_content_descriptor,
1644                                                 2/*Offset to data_component_id*/, langCode/*=0x0008*/, 2/*Langcode=3byte*/, 
1645                                                 instance,
1646                                                 &p_desc );
1647                        if (p_desc && err == DHL_OK)
1648                        {
1649                            DHL_PSI_ParseDataContentDescriptor( p_desc, memId, &pp_data_content[instance] );
1650                            instance++;
1651                        }
1652                    } while (p_desc && err == DHL_OK && instance < MAX_CAPTION_ES);
1653                   
1654                    if (instance)
1655                    {
1656                        p_event->pp_data_content = (arib_data_content_descriptor_t **)memChainAlloc( memId, sizeof(arib_data_content_descriptor_t *) * instance );
1657                        checkMemoryError(p_event->pp_data_content);
1658                        memcpy( p_event->pp_data_content, pp_data_content, sizeof(arib_data_content_descriptor_t *) * instance );
1659                    }
1660                    p_event->numDataContent = instance;
1661                }
1662            }
1663            else
1664            {
1665                p_event->descriptors = (DS_U8 *)NULL;
1666                p_event->numShortEvents = 0;
1667                p_event->numExtendedEvents = 0;
1668                p_event->numParentalRating = 0;
1669                p_event->numAudioComponent = 0;
1670                p_event->numDataContent = 0;
1671                p_event->p_event_group = (arib_event_group_descriptor_t *)NULL;
1672                //p_event->pp_audio_component = (arib_audio_component_descriptor_t **)NULL;
1673            }
1674           
1675            k += 12+descriptor_length;
1676            p_event++;
1677            if ( index++ > numEvents )
1678            {
1679                printf("EIT: Inconsistent number of events.\n");
1680                        err = DHL_FAIL_INVALID_TABLEID;
1681                        goto ParseExit;
1682                }
1683        }
1684        }
1685   
1686    err = DHL_OK;
1687        *(((memId_t *)p_eit)-1) = memId;
1688        *pp_eit = p_eit;
1689        memId = 0;      /* Don't delete below */
1690
1691ParseExit:
1692   
1693        if (memId) 
1694        {
1695                /* delete the patSection memory */
1696                memChainDestroy(memId);
1697        }
1698
1699        return(err);
1700}
1701
1702DHL_RESULT DHL_PSI_ParseDvbEit(DS_U8 **sectionArr, DS_BOOL b_actual, DS_U8 scheduleTableId, DVB_EIT **pp_eit)
1703{
1704    return DHL_PSI_ParseDvbEitEx(sectionArr, b_actual, 0, scheduleTableId, 0, pp_eit );
1705}
1706
1707DHL_RESULT DHL_PSI_GetDvbEitEx( DHL_PSI_HANDLE sysInfo, 
1708                              DS_BOOL b_actual, 
1709                              DS_U8   scheduleTableId,
1710                                                          DS_U16  service_id,
1711                                                          DS_U8   segment_number,
1712                              DVB_EIT **pp_eit, 
1713                              int timeOut )
1714{
1715    DHL_RESULT err = DHL_OK;
1716        PSIContext_t *returnPSICtl = NULL;
1717        PSIEventProcData_t      procData;
1718        int res = 0;
1719
1720        procData.desc = NULL;
1721        procData.err = (DS_U32)DHL_OK;
1722        /*creae a no-name , non-signaled event.*/
1723        //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ ));
1724        procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 );
1725
1726    if (procData.hEvent == (OS_SEMAPHORE_ID)0)
1727    {
1728        printf ("%s: OS_CreateBinarySemaphore() fails.\n", __func__);
1729        return DHL_FAIL_OUT_OF_RESOURCE;
1730    }   
1731
1732        if ((err = DHL_PSI_MonitorDvbEitEx(sysInfo,
1733                                                  b_actual,
1734                                                  0,
1735                                                  scheduleTableId,
1736                                                  service_id,
1737                                                  segment_number,
1738                                                  psiOneShot, 
1739                                                  hal_cbPSISyncEventProc,
1740                                                  (DS_U32)&procData,
1741                                                  (DHL_PSI_HANDLE *)&returnPSICtl))) 
1742    {
1743        printf("%s: DHL_PSI_MonitorDvbEit()=0x%02X\n", __func__, err);
1744                goto done;
1745        }
1746        printf("returnPSICtl->segment_number: %d\n", returnPSICtl->segment_number);
1747       
1748        //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut );
1749        res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut );
1750    if (res != 0)
1751    {
1752        //#ifdef PSI_DGB
1753        printf("%s: OS_TakeSemaphore TIMEOUT %d \n", __func__, timeOut);
1754        //#endif
1755       
1756        #ifdef PSI_DBG
1757                printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n");
1758                #endif
1759                               
1760        err = DHL_FAIL_TIMEOUT;
1761        goto done2;
1762    }
1763
1764        if ((err = (DHL_RESULT)(procData.err))) {
1765                printf("%s: procData.err = %d\n", __func__, err );
1766                goto done2;
1767        }
1768
1769    if ( procData.desc )
1770            err = DHL_PSI_ParseDvbEit(procData.desc->sectPtr, b_actual, scheduleTableId, pp_eit);
1771    else
1772        err = DHL_FAIL;
1773       
1774done2:
1775        DHL_PSI_CancelMonitor(returnPSICtl);
1776        if( procData.desc )
1777            DD_PSI_FreePSIData(procData.desc);
1778   
1779done:
1780        if(procData.hEvent)
1781        {
1782                OS_DeleteSemaphore(procData.hEvent);
1783        }
1784       
1785        return(err);
1786}
1787
1788DHL_RESULT DHL_PSI_GetDvbEit( DHL_PSI_HANDLE sysInfo, 
1789                              DS_BOOL b_actual, 
1790                              DS_U8   scheduleTableId,
1791                                                          DS_U16  service_id,
1792                              DVB_EIT **pp_eit, 
1793                              int timeOut )
1794{
1795    return  DHL_PSI_GetDvbEitEx( sysInfo, b_actual, scheduleTableId, service_id, 0xFF, pp_eit, timeOut );
1796}
1797
1798static const char BitUnmap[256] = 
1799{
1800    -1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1801     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1802     5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1803     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1804     6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1805     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1806     5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1807     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1808     7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1809     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1810     5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1811     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1812     6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1813     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1814     5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
1815     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
1816};
1817
1818static const char BitCount[256] = {
1819     0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1820     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1821     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1822     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1823     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1824     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1825     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1826     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1827     1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1828     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1829     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1830     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1831     2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1832     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1833     3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1834     4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
1835};
1836
1837static int getFirstBit(DS_U32 bitmap)
1838{
1839    int k;
1840   
1841    union {
1842        DS_U32 ul;
1843        DS_U8  uc[4];
1844    } u;
1845   
1846    if (!bitmap)
1847        return -1;
1848   
1849    u.ul = bitmap;
1850    for (k=0; k<4; k++)
1851    {
1852        if ( BitUnmap[u.uc[k]] >= 0 )
1853            return ((k*8)+BitUnmap[u.uc[k]]);
1854    }
1855   
1856    return -1;
1857}
1858
1859int getBitCount(DS_U32 bitmap)
1860{
1861    int k, cnt;
1862   
1863    union {
1864        DS_U32 ul;
1865        DS_U8  uc[4];
1866    } u;
1867   
1868    u.ul = bitmap;
1869    for (cnt=0,k=0; k<4; k++)
1870        cnt += BitCount[u.uc[k]];
1871   
1872    return cnt;
1873}
1874
1875int getBitCountEx(DS_U32 bitmap, int n)
1876{
1877    int k, cnt;
1878   
1879    union {
1880        DS_U32 ul;
1881        DS_U8  uc[4];
1882    } u;
1883   
1884    for(k=n; k<32; k++)
1885        bitmap &= ~(1<<k);
1886   
1887    u.ul = bitmap;
1888    for (cnt=0,k=0; k<4; k++)
1889        cnt += BitCount[u.uc[k]];
1890   
1891    return cnt;
1892}
1893
1894typedef struct tag_PSIEagerEventData_t {
1895    PSIDataArray_t *desc;
1896    DS_U32 err;
1897    DS_U32 hEvent;
1898   
1899    DS_U32 exist_segment_map;
1900    DS_U32 newly_received_map;
1901    DS_U32 processed_map;
1902    DS_S32 last_segment_number;
1903    P_DS_U8 section_data[8];
1904} PSIEagerEventData_t;
1905
1906static void cbPsiEagerFunction(PSIEvent event, DHL_TBL_HANDLE hTblHandle, DS_U32 userParam)
1907{
1908        DHL_RESULT                      err;
1909        PSIEagerEventData_t     *procData = (PSIEagerEventData_t *)userParam;
1910        PSIDataArray_t          *desc = NULL;
1911
1912        if(!hTblHandle || !procData)
1913                return;
1914               
1915        switch (event) {
1916                case psiDataReceived:
1917                        err = DD_PSI_ReadPSIData( hTblHandle, &desc );
1918                        if (err) 
1919                        {
1920                                printf("  ReadPSIData returned 0x%x\n", err);
1921                                procData->desc = NULL; /*for safety.*/
1922                        }
1923                        else 
1924                        {
1925                                procData->desc = desc;
1926                        }
1927                       
1928                        procData->err = err;
1929                        if( procData->hEvent )
1930                        {
1931                                //AtiCore_EventSet((ACL_HANDLE)(procData->hEvent));
1932                                OS_GiveSemaphore(procData->hEvent);
1933                               
1934                                #ifdef PSI_DBG
1935                                printf("hal_cbPSISyncEventProc : set procData->hEvent.\r\n");
1936                                #endif
1937                        }
1938                       
1939                        break;
1940       
1941        case psiSectionReceived:
1942        {
1943            DS_S32 segment_number, segment_count;
1944            int i;
1945            P_DS_U8 p[8];
1946           
1947            segment_number = segment_count = -1;
1948            memset(p, 0, sizeof(p));
1949            err = DD_PSI_GetLastReceivedSegment( hTblHandle, DS_FALSE, &segment_number, &segment_count, p );
1950            if (err || (segment_number <0) || (segment_count < 0))
1951            {
1952                printf("ERROR!! DD_PSI_GetLastReceivedSegment() = %d, (%d/%d)\n", err, (int)segment_number, (int)segment_count);
1953                return;
1954            }
1955           
1956            if ( procData->exist_segment_map & (1<<segment_number) )
1957            {
1958                printf("We already have %ld segment. Drop it!\n", segment_number);
1959                err = DD_PSI_GetLastReceivedSegment( hTblHandle, DS_TRUE, &segment_number, &segment_count, p );
1960                for (i=0; i<8; i++)
1961                {
1962                    if (p[i] && p[i] != (DS_U8 *)-1)
1963                        PSI_Free(p[i]);
1964                }
1965                return;
1966            }
1967           
1968            printf("psiSectionReceived: %ld/%ld\n", segment_number, segment_count);
1969               
1970            procData->desc = NULL;
1971            procData->newly_received_map |= (1<<segment_number);
1972            procData->last_segment_number = segment_count;
1973            for (i=0; i<8; i++)
1974                procData->section_data[i] = p[i];
1975           
1976                        procData->err = err;
1977                        if( procData->hEvent )
1978                        {
1979                                //AtiCore_EventSet((ACL_HANDLE)(procData->hEvent));
1980                                OS_GiveSemaphore(procData->hEvent);
1981                        }               
1982            break;
1983        }
1984       
1985                default:
1986                        break;
1987        }
1988}
1989
1990
1991DHL_RESULT DHL_PSI_GetDvbEitEager( DHL_PSI_HANDLE sysInfo, 
1992                              DS_BOOL b_actual, 
1993                              DS_U8   scheduleTableId,
1994                                                          DS_U16  service_id,
1995                                                          DS_U32  exist_segment_map,
1996                              P_DVB_EIT *pp_eitPtr, 
1997                              int timeOut )
1998{
1999    DHL_RESULT err = DHL_OK;
2000        PSIContext_t *returnPSICtl = NULL;
2001        PSIEagerEventData_t     procData;
2002        DS_U32 endTime = OS_GetTickCount() + timeOut/10;
2003        DS_U32 temp_received_map;
2004        int res = 0;
2005    int current_segment=0;
2006    int received_count=0;
2007   
2008    //memset(&procData, 0, sizeof(procData));
2009        procData.desc = NULL;
2010        procData.err = (DS_U32)DHL_OK;
2011        /*creae a no-name , non-signaled event.*/
2012        //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ ));
2013        procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 );
2014    procData.newly_received_map = 0;
2015    procData.processed_map = 0;
2016    procData.last_segment_number = -1;
2017    procData.exist_segment_map = exist_segment_map;
2018   
2019    if (procData.hEvent == (OS_SEMAPHORE_ID)0)
2020    {
2021        printf ("%s: OS_CreateBinarySemaphore() fails.\n", __func__);
2022        return DHL_FAIL_OUT_OF_RESOURCE;
2023    }   
2024
2025        if ((err = DHL_PSI_MonitorDvbEitEx(sysInfo,
2026                                                  b_actual,
2027                                                  0,
2028                                                  scheduleTableId,
2029                                                  service_id,
2030                                                  SEGMENT_EAGER_MODE,
2031                                                  psiOneShot, 
2032                                                  cbPsiEagerFunction,
2033                                                  (DS_U32)&procData,
2034                                                  (DHL_PSI_HANDLE *)&returnPSICtl))) 
2035    {
2036        printf("%s: DHL_PSI_MonitorDvbEit()=0x%02X\n", __func__, err);
2037                goto done;
2038        }
2039        //printf("returnPSICtl->segment_number: %d\n", returnPSICtl->segment_number);
2040       
2041        do {
2042        //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut );
2043        res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut );
2044        if (res != 0)
2045        {
2046                //#ifdef PSI_DGB
2047            printf("%s: OS_TakeSemaphore TIMEOUT %d \n", __func__, timeOut);
2048            //#endif
2049           
2050            #ifdef PSI_DBG
2051                printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n");
2052                #endif
2053                               
2054            err = DHL_FAIL_TIMEOUT;
2055            goto done2;
2056        }
2057   
2058        if ((err = (DHL_RESULT)(procData.err))) {
2059                printf("%s: procData.err = %d\n", __func__, err );
2060                goto done2;
2061        }
2062       
2063        /*
2064         * FIX ME: ¾Æ·¡¿¡¼­ Event¸¦ ó¸®Çϱâ Àü¿¡, Çѹø ´õ Event°¡ ¿À¸é ¹®Á¦°¡ ¹ß»ýÇÔ.
2065         * => BITMAPÀ¸·Î º¯°æÇÏ¿© ¹®Á¦ ÇØ°áµÊ.
2066         */
2067        temp_received_map = procData.newly_received_map;
2068        current_segment = getFirstBit(temp_received_map & (~procData.processed_map));
2069        if (procData.desc)
2070        {
2071            err = DHL_PSI_ParseDvbEit(procData.desc->sectPtr, b_actual, scheduleTableId, &pp_eitPtr[0]);
2072            goto done2;
2073        }
2074        else if (current_segment >= 0)
2075        {
2076            //err = DHL_PSI_ParseDvbEit(procData.section_data, b_actual, scheduleTableId, &pp_eitPtr[1+procData.current_section_number]);
2077            err = DHL_PSI_ParseDvbEitEx(&procData.section_data[0], b_actual, 8, scheduleTableId, 0, &pp_eitPtr[1+current_segment]);
2078            procData.processed_map |= (1<<current_segment);
2079            received_count = getBitCountEx(procData.exist_segment_map | procData.processed_map, procData.last_segment_number);
2080//            received_count++;
2081
2082            printf("parse segment 0x%08lX-0x%08lX => %d (segment_count: %d/%ld)\n", temp_received_map, procData.processed_map, current_segment, received_count, procData.last_segment_number);
2083            printf("total count: %d\n", getBitCountEx( temp_received_map | procData.exist_segment_map, procData.last_segment_number ));
2084           
2085            if ( procData.last_segment_number <= received_count )
2086                goto done2;
2087        }
2088        else
2089        {
2090            printf("%s| ERROR!! Both desc and section_number is invalid!\n", __func__);
2091        }
2092       
2093    } while ( OS_GetTickCount() < endTime );
2094   
2095    if ( OS_GetTickCount() > endTime )
2096        err = DHL_FAIL_TIMEOUT;
2097       
2098done2:
2099        DHL_PSI_CancelMonitor(returnPSICtl);
2100        if( procData.desc )
2101            DD_PSI_FreePSIData(procData.desc);
2102   
2103done:
2104        if(procData.hEvent)
2105        {
2106                OS_DeleteSemaphore(procData.hEvent);
2107        }
2108       
2109        return(err);
2110}
2111
2112DHL_RESULT DHL_PSI_PrintDvbEit( DVB_EIT *p_eit )
2113{
2114    DHL_RESULT err=DHL_OK;
2115    int i;
2116    dvb_eit_event_t *p_event;
2117    DS_U16 y;
2118    DS_U8 m, d;
2119    dvb_short_event_descriptor_t *p_short_event;
2120    dvb_extended_event_descriptor_t *p_extended_event;
2121   
2122    printf("EIT (Event Information Table)\n");
2123    printf("    service_id: 0x%04X\n", p_eit->service_id);
2124    printf("    version_number: 0x%02X\n", p_eit->version_number);
2125    printf("    section # (%d/%d)\n", p_eit->section_number, p_eit->last_section_number);
2126    printf("    segment_last_section_number: %d\n", p_eit->segment_last_section_number);
2127    printf("    transport_stream_id: 0x%04X\n", p_eit->transport_stream_id);
2128    printf("    original_network_id: 0x%04X\n", p_eit->original_network_id);
2129    printf("    last_table_id: 0x%02X\n", p_eit->last_table_id);
2130   
2131    printf("Number of events: %d\n", p_eit->numEvents);
2132    p_event = p_eit->eit_events;
2133    for (i=0; i<p_eit->numEvents; i++)
2134    {
2135        int idx;
2136       
2137        printf("    Event #%d\n", i);
2138        printf("        event_id: 0x%04X\n", p_event->event_id);
2139        DHL_PSI_DecodeDate(p_event->start_date, &y, &m, &d);
2140        printf("        start_date: (0x%04X) %4d/%02d/%02d %02X:%02X:%02X\n", p_event->start_date, y, m, d, 
2141                                    (DS_U16)((p_event->start_time>>16)&0xFF),
2142                                    (DS_U16)((p_event->start_time>>8)&0xFF), 
2143                                    (DS_U16)((p_event->start_time)&0xFF));
2144        printf("        duration:  %02X:%02X:%02X\n", 
2145                                    (DS_U16)((p_event->duration>>16)&0xFF), 
2146                                    (DS_U16)((p_event->duration>>8)&0xFF), 
2147                                    (DS_U16)(p_event->duration)&0xFF);
2148        printf("        running_status: %d\n", p_event->running_status);
2149        printf("        free_CA_mode: %s (%d)\n", p_event->free_CA_mode ? "Free" : "Scrambled", p_event->free_CA_mode);
2150        if (p_event->p_event_group)
2151        {
2152            arib_event_t *p_grp_event;
2153            arib_other_event_t *p_other_event;
2154            int idx;
2155
2156            printf("        Event_Group> GroupType: 0x%X\n", p_event->p_event_group->group_type);
2157            p_grp_event = p_event->p_event_group->p_event;
2158            for (idx=0; idx<p_event->p_event_group->numEvents; idx++)
2159            {
2160                printf("                     EventGroup%d: Service_Id 0x%04X  Event_Id 0x%04X\n", idx, 
2161                    p_grp_event->service_id, p_grp_event->event_id);
2162                p_grp_event++;
2163            }
2164           
2165            p_other_event = p_event->p_event_group->p_other_event;
2166            for (idx=0; idx<p_event->p_event_group->numOtherNetworkEvents; idx++)
2167            {
2168                printf("                     OtherEventGroup%d: ONID 0x%04X  TSID 0x%04X  Service_Id 0x%04X  Event_Id 0x%04X\n", idx, 
2169                    p_other_event->original_network_id, p_other_event->transport_stream_id, p_other_event->service_id, p_other_event->event_id);
2170                p_other_event++;
2171            }
2172        }
2173       
2174        for (idx=0; idx<p_event->numParentalRating; idx++)
2175        {
2176            int idxRatings;
2177           
2178            dvb_parental_rating_descriptor_t *p_pr_desc=p_event->pp_pr_desc[idx];
2179            dvb_parental_rating_entry_t *p_ratings;
2180           
2181            printf("\n       Parental Rating %d...\n", idx);
2182           
2183            p_ratings = p_pr_desc->p_ratings;
2184            for (idxRatings=0; idxRatings<p_pr_desc->i_num_ratings; idxRatings++)
2185            {
2186                printf("       Country_Code: %c%c%c ", 
2187                                    (DS_U8)((p_ratings->country_code>>16)&0xFF),
2188                                    (DS_U8)((p_ratings->country_code>>8)&0xFF),
2189                                    (DS_U8)((p_ratings->country_code>>0)&0xFF));
2190                printf("       Rating_value: 0x%x\n", p_ratings->rating_value);
2191                p_ratings++;
2192            }
2193        }
2194       
2195        for (idx=0; idx<p_event->numAudioComponent; idx++)
2196        {
2197            arib_audio_component_descriptor_t *p_audio_component;
2198           
2199            p_audio_component = p_event->pp_audio_component[idx];
2200           
2201            printf("        AUDIO #%d\n", idx);
2202            printf("        stream_content: 0x%02X\n", p_audio_component->stream_content);
2203            printf("        component_type: 0x%02X\n", p_audio_component->component_type);
2204            printf("        component_tag : 0x%02X\n", p_audio_component->component_tag);
2205            printf("        stream_type   : 0x%02X\n", p_audio_component->stream_type);
2206            printf("        ES_multi_lingu: 0x%02X\n", p_audio_component->ES_multi_lingual_flag);
2207            printf("        Sampling_rate:  0x%02X\n", p_audio_component->sampling_rate);
2208            printf("        ISO_639_language_code : 0x%06lX (%c%c%c)\n", p_audio_component->ISO_639_language_code,
2209                                                    (DS_U8)((p_audio_component->ISO_639_language_code>>16)&0xFF),
2210                                                    (DS_U8)((p_audio_component->ISO_639_language_code>>8)&0xFF),
2211                                                    (DS_U8)((p_audio_component->ISO_639_language_code>>0)&0xFF));
2212            printf("        ISO_639_language_code_2 : 0x%06lX (%c%c%c)\n", 
2213                                                    p_audio_component->ISO_639_language_code_2,
2214                                                    (DS_U8)((p_audio_component->ISO_639_language_code_2>>16)&0xFF),
2215                                                    (DS_U8)((p_audio_component->ISO_639_language_code_2>>8)&0xFF),
2216                                                    (DS_U8)((p_audio_component->ISO_639_language_code_2>>0)&0xFF));
2217        }
2218       
2219        for (idx=0; idx<p_event->numDataContent; idx++)
2220        {
2221            arib_data_content_descriptor_t *p_data_content;
2222           
2223            p_data_content = p_event->pp_data_content[idx];
2224           
2225            printf("       DATA_CONTENT %d\n", idx);
2226            printf("       data_component_id: 0x%04X\n", p_data_content->data_component_id);
2227            printf("       entry_component: 0x%04X\n", p_data_content->entry_component);
2228           
2229            if ( p_data_content->selector_length && p_data_content->selector_byte )
2230            {
2231                int k;
2232               
2233                printf("       Selector_byte: ");
2234                for (k=0; k<p_data_content->selector_length; k++)
2235                    printf("%02X ", p_data_content->selector_byte[k]);
2236                printf("\n");
2237            }
2238            printf("       ISO_639_lang_code: %c%c%c\n", 
2239                                (DS_U8)((p_data_content->ISO_639_language_code>>16)&0xFF),
2240                                (DS_U8)((p_data_content->ISO_639_language_code>>8)&0xFF),
2241                                (DS_U8)((p_data_content->ISO_639_language_code>>0)&0xFF));
2242        }
2243       
2244       
2245        for (idx=0; idx<p_event->numShortEvents; idx++)
2246        {
2247            p_short_event = p_event->pp_short_event[idx];
2248           
2249            if (p_short_event)
2250            {
2251                printf("\n        Short_event%d: %c%c%c\n", idx,
2252                                (DS_U8)((p_short_event->ISO_639_language_code>>16)&0xFF),
2253                                (DS_U8)((p_short_event->ISO_639_language_code>>8)&0xFF),
2254                                (DS_U8)((p_short_event->ISO_639_language_code>>0)&0xFF));
2255               
2256                if (p_short_event->event_name_length && p_short_event->p_event_name)
2257                    printf("        Event_Name: %s\n", p_short_event->p_event_name);
2258                else
2259                    printf("        Event_Name: NULL\n");
2260   
2261                if (p_short_event->text_length && p_short_event->p_text)               
2262                    printf("        Text: %s\n", p_short_event->p_text);
2263                else
2264                    printf("        Text: NULL\n");
2265            }
2266            else
2267            {
2268                printf("        Why it's NULL????? %d\n", idx);
2269            }
2270        }
2271       
2272        for (idx=0; idx<p_event->numExtendedEvents; idx++)
2273        {
2274            p_extended_event = p_event->pp_extended_event[idx];
2275            if (p_extended_event)
2276            {
2277                dvb_ext_event_item_t *p_ext_item;
2278                int j;
2279               
2280                printf("\n        Extended_event%d: %c%c%c\n", idx,
2281                                (DS_U8)((p_extended_event->ISO_639_language_code>>16)&0xFF),
2282                                (DS_U8)((p_extended_event->ISO_639_language_code>>8)&0xFF),
2283                                (DS_U8)((p_extended_event->ISO_639_language_code>>0)&0xFF));
2284               
2285                printf("        descriptor #: (%d/%d)\n", p_extended_event->descriptor_number, p_extended_event->last_descriptor_number);
2286               
2287                p_ext_item = p_extended_event->items;
2288                for (j=0; j<p_extended_event->numItems; j++)
2289                {
2290                    if (p_ext_item->item_description_length && p_ext_item->p_item_description) 
2291                    {
2292                        printf("        item_description: %s\n", p_ext_item->p_item_description);
2293                    }
2294                   
2295                    if (p_ext_item->item_length && p_ext_item->p_item_char)
2296                    {
2297                        printf("        item: %s\n", p_ext_item->p_item_char);
2298                    }
2299                   
2300                    p_ext_item++;
2301                }
2302               
2303                if (p_extended_event->text_length && p_extended_event->p_text)
2304                    printf("        Text: %s\n", p_extended_event->p_text);
2305                else
2306                    printf("        Text: NULL\n");
2307            }
2308        }
2309       
2310        p_event++;
2311    }
2312   
2313    return (err);
2314}
2315
2316#if 0
2317___Time_Data_Table___()
2318#endif
2319DHL_RESULT DHL_PSI_MonitorDvbTdt(       DHL_PSI_HANDLE sysInfo,
2320                                                                        PSIUpdateMode updateMode,
2321                                                                        PSIEventProc_f eventProc,
2322                                                                        DS_U32 userParam, 
2323                                                                        DHL_TBL_HANDLE *returnPSICtl)
2324{
2325        PSIMask_t               *pref;
2326        DHL_RESULT              err=DHL_OK;
2327
2328        if ((err = DD_PSI_GetTIDPSISimpleMask (&pref,
2329                                                                    DVB_TID_time_date_section)))
2330    {
2331                printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err);
2332                return(err);
2333        }
2334
2335        if ((err = DD_PSI_MonitorPSIPid(sysInfo,
2336                                                         DVB_PID_TDT,
2337                                                         privateMode,
2338                                                         updateMode,
2339                                                         pref,
2340                                                         /*MAX_PSI_MPEG_DATA*/1024,
2341                                                         1,
2342                                                         eventProc,
2343                                                         userParam,
2344                                                         returnPSICtl)))
2345    {
2346                printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err);                                         
2347                PSI_Free(pref);
2348        }
2349       
2350        return(err);
2351}
2352
2353DHL_RESULT DHL_PSI_ParseDvbTdt(DS_U8 *sectionArr, dvb_tdt_t **pp_tdt)
2354{
2355        DHL_RESULT err = DHL_OK;
2356        const DS_U8 *p;
2357        int len;
2358        dvb_tdt_t *p_tdt = NULL;
2359        memId_t                 memId = NULL;
2360        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
2361       
2362        if (sectionArr == NULL || (pp_tdt == NULL)) 
2363        {
2364                return (DHL_FAIL_NULL_POINTER);
2365        }
2366   
2367    p = sectionArr;
2368        if ( p[SECTION_TID] != DVB_TID_time_date_section )
2369        {
2370                /*
2371                 * This thing isn't a PAT. Stop right here.
2372                 */
2373                printf("TDT: Bad table ID. (0x%02X)\n", p[SECTION_TID]);
2374                err = DHL_FAIL_INVALID_TABLEID;
2375                goto ParseExit;
2376        }
2377
2378        if ((p[SECTION_LEN_HI] & 0x80) != 0x00) {
2379                printf("TDT: section_syntax_indicator set\n");
2380        }
2381       
2382        len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
2383    if ( len < 8 )
2384    {
2385                err = DHL_FAIL_INVALID_TABLEID;
2386        goto ParseExit;
2387    }
2388       
2389        /* create the memChain */
2390        err = memChainCreate(&memId,&memSetup);
2391        if (err) {
2392                goto ParseExit;
2393        }
2394   
2395        p_tdt = (dvb_tdt_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_tdt_t)+sizeof(memId_t))) + 1);
2396        checkMemoryError(p_tdt);
2397   
2398    p_tdt->date = (p[3]<<8)+p[4];
2399    p_tdt->time = (p[5]<<16)+(p[6]<<8)+p[7];
2400   
2401    err = DHL_OK;
2402        *(((memId_t *)p_tdt)-1) = memId;
2403        *pp_tdt = p_tdt;
2404        memId = 0;      /* Don't delete below */
2405
2406ParseExit:
2407   
2408        if (memId) 
2409        {
2410                /* delete the patSection memory */
2411                memChainDestroy(memId);
2412        }
2413
2414        return(err);
2415}
2416
2417DHL_RESULT DHL_PSI_GetDvbTdt( DHL_PSI_HANDLE sysInfo, DVB_TDT **pp_tdt, int timeOut )
2418{
2419    DHL_RESULT err = DHL_OK;
2420        void *returnPSICtl = NULL;
2421        PSIEventProcData_t      procData;
2422        int res = 0;
2423
2424        procData.desc = NULL;
2425        procData.err = (DS_U32)DHL_OK;
2426        /*creae a no-name , non-signaled event.*/
2427        //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ ));
2428        procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 );
2429       
2430    if (procData.hEvent == (OS_SEMAPHORE_ID)0)
2431    {
2432        printf ("%s: OS_CreateBinarySemaphore() fails.\n", __func__);
2433        return DHL_FAIL_OUT_OF_RESOURCE;
2434    }   
2435
2436        if ((err = DHL_PSI_MonitorDvbTdt(sysInfo,
2437                                                  psiOneShot, 
2438                                                  hal_cbPSISyncEventProc,
2439                                                  (DS_U32)&procData,
2440                                                  &returnPSICtl))) 
2441    {
2442        printf("%s: DHL_PSI_MonitorDvbTdt()=0x%02X\n", __func__, err);
2443                goto done;
2444        }
2445       
2446        //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut );
2447        res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut );
2448    if (res != 0)
2449    {
2450        //#ifdef PSI_DGB
2451        printf("%s: OS_TakeSemaphore TIMEOUT %d \n", __func__, timeOut);
2452        //#endif
2453       
2454        #ifdef PSI_DBG
2455                printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n");
2456                #endif
2457                               
2458        err = DHL_FAIL_TIMEOUT;
2459        goto done2;
2460    }
2461
2462        if ((err = (DHL_RESULT)(procData.err))) {
2463                printf("%s: procData.err = %d\n", __func__, err );
2464                goto done2;
2465        }
2466
2467        err = DHL_PSI_ParseDvbTdt(procData.desc->sectPtr[0], pp_tdt);
2468   
2469done2:
2470        DHL_PSI_CancelMonitor(returnPSICtl);
2471        if( procData.desc )
2472            DD_PSI_FreePSIData(procData.desc);
2473   
2474done:
2475        if(procData.hEvent)
2476        {
2477                OS_DeleteSemaphore(procData.hEvent);
2478        }
2479       
2480        return(err);
2481}
2482
2483DHL_RESULT DHL_PSI_PrintDvbTdt(DVB_TDT *p_tdt)
2484{
2485    DHL_RESULT err = DHL_OK;
2486    DS_U16 y;
2487    DS_U8  m, d;
2488   
2489    if (!p_tdt)
2490        return (err);
2491   
2492    printf("TDT (Time Date Table)\n");
2493   
2494    y=m=d=0;
2495    DHL_PSI_DecodeDate(p_tdt->date, &y, &m, &d);
2496    printf("    Date: 0x%04X (%d/%d/%d)\n", p_tdt->date, y, m, d );
2497    printf("    Time: %02X:%02X:%02X\n", (DS_U16)((p_tdt->time>>16)&0xFFFF), (DS_U16)((p_tdt->time>>8)&0xFF), (DS_U16)((p_tdt->time & 0xFF)));
2498   
2499    return (err);
2500}
2501
2502
2503#if 0
2504___Time_Offset_Table___()
2505#endif
2506DHL_RESULT DHL_PSI_MonitorDvbTot(   DHL_PSI_HANDLE sysInfo,
2507                                                                        PSIUpdateMode updateMode,
2508                                                                        PSIEventProc_f eventProc,
2509                                                                        DS_U32 userParam, 
2510                                                                        DHL_TBL_HANDLE *returnPSICtl)
2511{
2512        PSIMask_t               *pref;
2513        DHL_RESULT              err=DHL_OK;
2514
2515        if ((err = DD_PSI_GetTIDPSISimpleMask (&pref,
2516                                                                    DVB_TID_time_offset_section)))
2517    {
2518                printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err);
2519                return(err);
2520        }
2521
2522        if ((err = DD_PSI_MonitorPSIPid(sysInfo,
2523                                                         DVB_PID_TOT,
2524                                                         privateMode,
2525                                                         updateMode,
2526                                                         pref,
2527                                                         /*MAX_PSI_MPEG_DATA*/1024,
2528                                                         1,
2529                                                         eventProc,
2530                                                         userParam,
2531                                                         returnPSICtl)))
2532    {
2533                printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err);                                         
2534                //PSI_Free(pref);
2535        }
2536       
2537        return(err);
2538}
2539
2540DHL_RESULT DHL_PSI_ParseDvbTot(DS_U8 *sectionArr, dvb_tot_t **pp_tot)
2541{
2542        DHL_RESULT err = DHL_OK;
2543        const DS_U8 *p;
2544        int len, descriptor_length;
2545        dvb_tot_t *p_tot = NULL;
2546        memId_t                 memId = NULL;
2547        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
2548       
2549        if (sectionArr == NULL || (pp_tot == NULL)) 
2550        {
2551                return (DHL_FAIL_NULL_POINTER);
2552        }
2553   
2554    p = sectionArr;
2555        if ( p[SECTION_TID] != DVB_TID_time_offset_section )
2556        {
2557                /*
2558                 * This thing isn't a TDT. Stop right here.
2559                 */
2560                printf("TOT: Bad table ID. (0x%02X)\n", p[SECTION_TID]);
2561                err = DHL_FAIL_INVALID_TABLEID;
2562                goto ParseExit;
2563        }
2564
2565        if ((p[SECTION_LEN_HI] & 0x80) != 0x00) {
2566                printf("TOT: section_syntax_indicator set\n");
2567        }
2568       
2569        len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
2570    if ( len < 8 )
2571    {
2572                err = DHL_FAIL_INVALID_TABLEID;
2573        goto ParseExit;
2574    }
2575       
2576        /* create the memChain */
2577        err = memChainCreate(&memId,&memSetup);
2578        if (err) {
2579                goto ParseExit;
2580        }
2581   
2582        p_tot = (dvb_tot_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_tot_t)+sizeof(memId_t))) + 1);
2583        checkMemoryError(p_tot);
2584   
2585    p_tot->date = (p[3]<<8)+p[4];
2586    p_tot->time = (p[5]<<16)+(p[6]<<8)+p[7];
2587   
2588    p_tot->p_lto = (dvb_local_time_offset_descriptor_t *)NULL;
2589    p_tot->descriptor_length = 0;
2590    p_tot->descriptors = (DS_U8 *)NULL;
2591    if ( len >= 11 )
2592    {
2593        DS_U8 *p_desc = (DS_U8 *)NULL;
2594        dvb_local_time_t *p_lt;
2595        int numLocaltime;
2596       
2597        descriptor_length = ((p[8]<<8)+p[9]) & 0xFFF;
2598        if ( descriptor_length > 1024 )
2599        {
2600            printf("TOT: too long descriptor length %d\n", descriptor_length);
2601            goto NoDescExit;
2602        }
2603
2604        /*
2605         * Counts number of local_time.
2606         */
2607        err=GetMpegDescriptor( (DS_U8 *)&p[10], 
2608                       descriptor_length, 
2609                       DVB_TAG_local_time_offset_descriptor,
2610                       0,
2611                       &p_desc );
2612        if (err==DHL_OK && p_desc)
2613        {
2614            numLocaltime = p_desc[1] / 13;
2615            if (numLocaltime <= 0)
2616                goto NoDescExit;
2617
2618            p_tot->p_lto = (dvb_local_time_offset_descriptor_t *)memChainAlloc(memId, sizeof(dvb_local_time_offset_descriptor_t));
2619            checkMemoryError(p_tot->p_lto);
2620
2621            p_lt = p_tot->p_lto->p_local_time = (dvb_local_time_t *)memChainAlloc(memId, sizeof(dvb_local_time_t)*numLocaltime);
2622            checkMemoryError(p_tot->p_lto->p_local_time);
2623
2624            p_tot->p_lto->i_num_local_time = numLocaltime;
2625            DHL_PSI_ParseLocalTimeOffsetDescriptor( p_desc, numLocaltime, p_lt );
2626        }
2627        else
2628        {
2629            printf("TOT: cannot find local_time_offset descriptor.\n");
2630        }
2631    }
2632
2633NoDescExit:
2634    err = DHL_OK;
2635        *(((memId_t *)p_tot)-1) = memId;
2636        *pp_tot = p_tot;
2637        memId = 0;      /* Don't delete below */
2638
2639ParseExit:
2640   
2641        if (memId) 
2642        {
2643                /* delete the patSection memory */
2644                memChainDestroy(memId);
2645        }
2646
2647        return(err);
2648}
2649
2650DHL_RESULT DHL_PSI_GetDvbTot( DHL_PSI_HANDLE sysInfo, DVB_TOT **pp_tot, int timeOut )
2651{
2652    DHL_RESULT err = DHL_OK;
2653        void *returnPSICtl = NULL;
2654        PSIEventProcData_t      procData;
2655        int res = 0;
2656
2657        procData.desc = NULL;
2658        procData.err = (DS_U32)DHL_OK;
2659        /*creae a no-name , non-signaled event.*/
2660        //procData.hEvent = (UINT32)(AtiCore_EventCreate( 0, _FALSE_ ));
2661        procData.hEvent = OS_CreateBinarySemaphore( "semTot0", 0, 0 );
2662       
2663    if (procData.hEvent == (OS_SEMAPHORE_ID)0)
2664    {
2665        printf ("%s: OS_CreateBinarySemaphore() fails.\n", __func__);
2666        return DHL_FAIL_OUT_OF_RESOURCE;
2667    }   
2668
2669        if ((err = DHL_PSI_MonitorDvbTot(sysInfo,
2670                                                  psiOneShot, 
2671                                                  hal_cbPSISyncEventProc,
2672                                                  (DS_U32)&procData,
2673                                                  &returnPSICtl))) 
2674    {
2675        printf("%s: DHL_PSI_MonitorDvbTot()=0x%02X\n", __func__, err);
2676                goto done;
2677        }
2678       
2679        //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut );
2680        res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut );
2681    if (res != 0)
2682    {
2683        //#ifdef PSI_DGB
2684        printf("%s: OS_TakeSemaphore TIMEOUT %d \n", __func__, timeOut);
2685        //#endif
2686       
2687        #ifdef PSI_DBG
2688                printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n");
2689                #endif
2690                               
2691        err = DHL_FAIL_TIMEOUT;
2692        goto done2;
2693    }
2694
2695        if ((err = (DHL_RESULT)(procData.err))) {
2696                printf("%s: procData.err = %d\n", __func__, err );
2697                goto done2;
2698        }
2699
2700        err = DHL_PSI_ParseDvbTot(procData.desc->sectPtr[0], pp_tot);
2701   
2702done2:
2703        DHL_PSI_CancelMonitor(returnPSICtl);
2704        if( procData.desc )
2705            DD_PSI_FreePSIData(procData.desc);
2706   
2707done:
2708        if(procData.hEvent)
2709        {
2710                OS_DeleteSemaphore(procData.hEvent);
2711        }
2712       
2713        return(err);
2714}
2715
2716DHL_RESULT DHL_PSI_PrintDvbTot(DVB_TOT *p_tot)
2717{
2718    DHL_RESULT err = DHL_OK;
2719    DS_U16 y;
2720    DS_U8  m, d;
2721    int i;
2722    dvb_local_time_t *p_lt;
2723   
2724    if (!p_tot)
2725        return (err);
2726   
2727    printf("TOT (Time Offset Table)\n");
2728   
2729    y=m=d=0;
2730    DHL_PSI_DecodeDate(p_tot->date, &y, &m, &d);
2731    printf("    Date: 0x%04X (%d/%d/%d)\n", p_tot->date, y, m, d );
2732    printf("    Time: %02X:%02X:%02X\n", (DS_U16)((p_tot->time>>16)&0xFFFF), (DS_U16)((p_tot->time>>8)&0xFF), (DS_U16)((p_tot->time & 0xFF)));
2733   
2734    if (p_tot->p_lto)
2735    {
2736        printf("    Number of local time: %d\n", p_tot->p_lto->i_num_local_time);
2737        p_lt = p_tot->p_lto->p_local_time;
2738        for (i=0; i<p_tot->p_lto->i_num_local_time; i++)
2739        {
2740            printf("\n    #%d\n", i);
2741            printf("    Country_code: 0x%06lX, Region_id: %d, Local_time_offset: %c0x%04X\n", 
2742                p_lt->country_code, p_lt->country_region_id, 
2743                p_lt->local_time_offset_polarity ? '-' : '+',
2744                p_lt->local_time_offset);
2745   
2746            y=m=d=0;
2747            DHL_PSI_DecodeDate(p_lt->time_of_change_date, &y, &m, &d);
2748   
2749            printf("    Time_of_change: 0x%04X (%d/%d/%d)\n", p_lt->time_of_change_date, y, m, d);
2750            printf("    Time_of_change: %02X:%02X:%02X\n",  (DS_U16)((p_lt->time_of_change_time>>16)&0xFFFF), (DS_U16)((p_lt->time_of_change_time>>8)&0xFF), (DS_U16)((p_lt->time_of_change_time & 0xFF)));
2751            printf("    next_time_offset: 0x%04X\n", p_lt->next_time_offset);
2752           
2753            p_lt++;
2754        }
2755    }
2756    return (err);
2757}
2758
2759#if 0
2760___Broadcaster_Information_Table___()
2761#endif
2762DHL_RESULT DHL_PSI_MonitorDvbBit(       DHL_PSI_HANDLE sysInfo,
2763                                                                        DS_BOOL current_next_indicator,
2764                                                                        DS_BOOL eager,
2765//                                                                      DS_BOOL b_actual,
2766                                                                        PSIUpdateMode updateMode,
2767                                                                        PSIEventProc_f eventProc,
2768                                                                        DS_U32 userParam, 
2769                                                                        DHL_TBL_HANDLE *returnPSICtl)
2770{
2771        PSIMask_t               *pref;
2772        DHL_RESULT              err;
2773
2774        if ((err = DD_PSI_GetTIDPSIMask (&pref, DVB_TID_broadcaster_information_section, current_next_indicator)))
2775        {
2776                printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err);
2777                return(err);
2778        }
2779
2780        if ((err = DD_PSI_MonitorPSIPid(        sysInfo,
2781                                                                                DVB_PID_BIT, 
2782                                                                                eager ? eagerTableMode : tableMode, 
2783                                                                                updateMode,
2784                                                                                pref,
2785                                                                                /*MAX_PSI_MPEG_DATA*/1024,
2786                                                                                MAX_PSI_SECTIONS,
2787                                                                                eventProc,
2788                                                                                userParam,
2789                                                                                returnPSICtl))) 
2790    {
2791                printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err);                                         
2792                PSI_Free(pref);
2793        }
2794       
2795        return(err);
2796}
2797
2798DHL_RESULT DHL_PSI_ParseDvbBit(DS_U8 **sectionArr, dvb_bit_t **pp_bit)
2799{
2800        DHL_RESULT err = DHL_OK;
2801        int i, k;
2802        int len, lenBroadcaster;
2803        int numBroadcaster;
2804        int numSections;
2805        int index;
2806        const DS_U8 *p;
2807        dvb_bit_t *p_bit = NULL;
2808        int version_number;
2809        int first_descriptor_length;
2810        DS_BOOL current_next_indicator;
2811        DS_BOOL broadcast_view_propriety;
2812        memId_t                 memId = NULL;
2813        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
2814    broadcaster_t *p_broadcaster;
2815
2816        if ((sectionArr == NULL) || (pp_bit == NULL)) 
2817        {
2818                return (DHL_FAIL_NULL_POINTER);
2819        }
2820
2821        if (sectionArr[0] == NULL) 
2822        {
2823                return (DHL_FAIL_NULL_POINTER);
2824        }
2825        else 
2826        {
2827                numSections = get_last_section_number(sectionArr[0]) + 1;
2828        }
2829
2830        /* now verify all other sections are present */
2831        for (i=1; i<numSections; i++) 
2832    {
2833                if (sectionArr[i] == NULL) {
2834                        return (DHL_FAIL_NULL_POINTER);
2835                }
2836        }
2837
2838        /*
2839         * First pass, we verify section syntax and count the number of broadcaster.
2840         */
2841        numBroadcaster = 0;
2842        for (i = 0; i < numSections; ++i) 
2843        {
2844                p = sectionArr[i];
2845               
2846                if( p == NULL )
2847                {       
2848                    printf( "%s: NULL section", __func__);
2849                        return DHL_FAIL_NULL_POINTER;
2850                }
2851                       
2852                if ( p[SECTION_TID] != DVB_TID_broadcaster_information_section )
2853                {
2854                        /*
2855                         * This thing isn't a PAT. Stop right here.
2856                         */
2857                        printf("BIT: Bad table ID. (0x%02X)", p[SECTION_TID]);
2858                        err = DHL_FAIL_INVALID_TABLEID;
2859                        goto ParseExit;
2860                }
2861               
2862                if ((p[SECTION_LEN_HI] & 0x80) != 0x80) 
2863                {
2864                        printf("BIT: section_syntax_indicator not set");
2865                }
2866               
2867                len = ((p[1]<<8) + p[2]) & 0xFFF;
2868
2869        /*
2870         * Counts number of broadcaster.
2871         */
2872                broadcast_view_propriety = ((p[8] >> 4) & 0x1);
2873                first_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF;
2874                lenBroadcaster = len - (7+first_descriptor_length+4);
2875                p = &sectionArr[i][10+first_descriptor_length];
2876
2877                for ( k=0 ; k < lenBroadcaster ; )
2878                {
2879                        int broadcaster_id;
2880                        int broadcaster_descriptor_length;
2881
2882                        broadcaster_id = p[k+0];
2883                        broadcaster_descriptor_length = ((p[k+1]<<8) + p[k+2]) & 0xFFF;
2884
2885                        if ( broadcaster_id )
2886                                numBroadcaster++;
2887
2888                        k += 3+broadcaster_descriptor_length;
2889                }
2890        }
2891
2892        /* create the memChain */
2893        err = memChainCreate(&memId,&memSetup);
2894       
2895        if (err) 
2896        {
2897                goto ParseExit;
2898        }
2899       
2900        p_bit = (dvb_bit_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_bit_t)+sizeof(memId_t))) + 1);
2901        checkMemoryError(p_bit);
2902   
2903    p_bit->num_broadcaster = numBroadcaster;
2904
2905    if ( numBroadcaster > 0 )
2906    {
2907        p_bit->broadcaster = (broadcaster_t *)memChainAlloc(memId,sizeof(broadcaster_t)*numBroadcaster);
2908        checkMemoryError(p_bit->broadcaster);
2909    }
2910    else
2911    {
2912        p_bit->broadcaster = (broadcaster_t *)NULL;
2913    }
2914   
2915    /*
2916     * Now fill-out all the remaining fields over the all sections.
2917     */
2918        index = 0;
2919        p_bit->first_descriptors = (DS_U8 *)NULL;
2920        p_broadcaster = p_bit->broadcaster;
2921
2922        for (i = 0 ; i < numSections ; ++i) 
2923        {
2924            DS_U8 last_section_number;
2925            int original_network_id;
2926           
2927                p = &sectionArr[i][0];
2928                len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3; // lenth + 3 ( p[0] (TID) + p[1] + p[2] )
2929
2930                original_network_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]);
2931                version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> 
2932                                                        SECTION_VERSION_SHIFT;
2933                current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0;
2934        first_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF;
2935        last_section_number = p[SECTION_NUM_LAST];
2936       
2937                if (i == 0) 
2938                {
2939                    /* First section */
2940                        p_bit->original_network_id = original_network_id;
2941                        p_bit->version_number = version_number;
2942                        p_bit->section_number = p[SECTION_NUM];
2943                        p_bit->last_section_number = last_section_number;
2944
2945                        if ( p_bit->first_descriptors == (DS_U8 *)NULL && first_descriptor_length )
2946                        {
2947                                DS_U8 *p_desc = (DS_U8 *)NULL;
2948
2949                                p_bit->first_descriptor_length = first_descriptor_length;
2950                                p_bit->first_descriptors = (DS_U8 *)memChainAlloc(memId, first_descriptor_length);
2951                                memcpy(p_bit->first_descriptors, &p[10], first_descriptor_length);
2952                                /*
2953                                 * Parse SI Parameter Descriptor
2954                                 */
2955                                err = GetMpegDescriptor( p_bit->first_descriptors,
2956                                                                 first_descriptor_length,
2957                                                                                 ARIB_TAG_si_parameter_descriptor,
2958                                                                                 0, /* only find first one. */
2959                                                                                 &p_desc );
2960
2961                                if ( p_desc && !err )
2962                                {
2963                                        DHL_PSI_ParseSIParameterDescriptor( p_desc, memId, &(p_bit->p_si_parameter));
2964                                }
2965                                else
2966                                {
2967//                                      printf("BIT: cannot find si_parameter descriptor.\n");
2968                                        p_bit->p_si_parameter = (arib_si_parameter_descriptor_t *)NULL;
2969                                }
2970
2971                        }
2972                }
2973                else
2974                {
2975                        if (p_bit->original_network_id != original_network_id)
2976                                printf("BIT: Inconsistent original_network_id (0x%x, 0x%x)\n", p_bit->original_network_id, original_network_id);
2977                        if (p_bit->version_number != version_number)
2978                                printf("BIT: inconsistent version_number (0x%x, 0x%x)\n", p_bit->version_number, version_number);
2979            if (p_bit->first_descriptor_length != first_descriptor_length)
2980                printf("BIT: Inconsistent first_descriptor_length (0x%x, 0x%x)\n", p_bit->first_descriptor_length, first_descriptor_length );
2981            if (p_bit->last_section_number != last_section_number )
2982                printf("BIT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_bit->last_section_number, last_section_number);
2983                }
2984
2985            lenBroadcaster = len - first_descriptor_length - 4 - 3 - 7;
2986               
2987                if ( !p_broadcaster && lenBroadcaster ) 
2988                {
2989                        printf("BIT: broadcaster length is not NULL, but broadcaster is NULL.\n");
2990                err = DHL_FAIL_INVALID_TABLEID;
2991                goto ParseExit;
2992
2993                }       
2994               
2995                p = &sectionArr[i][10+first_descriptor_length];
2996       
2997                for ( k = 0 ; k < lenBroadcaster ; )
2998                {
2999                        int broadcaster_id;
3000                        int broadcaster_descriptor_length;
3001                       
3002                        broadcaster_id = p[k+0];
3003                        broadcaster_descriptor_length = ((p[k+1]<<8) + p[k+2]) & 0xFFF;
3004                        p_broadcaster->broadcaster_id = broadcaster_id;
3005                        p_broadcaster->broadcaster_descriptor_length = broadcaster_descriptor_length;
3006
3007                        if ( broadcaster_descriptor_length )
3008                        {
3009                                DS_U8 *p_desc = (DS_U8 *)NULL;
3010
3011                                p_broadcaster->broadcaster_descriptors = (DS_U8 *)memChainAlloc(memId, broadcaster_descriptor_length);
3012
3013                                if ( !(p_broadcaster->broadcaster_descriptors) )
3014                                {
3015                                        err = DHL_FAIL_OUT_OF_RESOURCE;
3016                                        goto ParseExit;
3017                                }
3018
3019                                memcpy(p_broadcaster->broadcaster_descriptors, &p[k+3], broadcaster_descriptor_length);
3020                               
3021                                /*
3022                                 * Parse Extended Broadcaster Descriptor
3023                                 */
3024                                err = GetMpegDescriptor( p_broadcaster->broadcaster_descriptors,
3025                                                                 broadcaster_descriptor_length,
3026                                                                                 ARIB_TAG_extended_broadcaster_descriptor,
3027                                                                                 0, /* only find first one. */
3028                                                                                 &p_desc );
3029
3030                                if ( p_desc && !err )
3031                                {
3032                                        DHL_PSI_ParseExtendedBroadcasterDescriptor(p_desc, memId, &(p_broadcaster->p_ex_broad));
3033                                }
3034                                else
3035                                {
3036//                                      printf("BIT: cannot find extended_broadcaster descriptor.\n");
3037                                        p_broadcaster->p_ex_broad = (arib_extended_broadcaster_descriptor_t *)NULL; 
3038                                }
3039                               
3040                                p_desc = (DS_U8 *)NULL;
3041
3042                                /*
3043                                 * Parse SI Parameter Descriptor
3044                                 */
3045                                err = GetMpegDescriptor( p_broadcaster->broadcaster_descriptors,
3046                                                                 broadcaster_descriptor_length,
3047                                                                                 ARIB_TAG_si_parameter_descriptor,
3048                                                                                 0, /* only find first one. */
3049                                                                                 &p_desc );
3050
3051                                if ( p_desc && !err )
3052                                {
3053                                        DHL_PSI_ParseSIParameterDescriptor( p_desc, memId, &(p_broadcaster->p_si_parameter));
3054                                }
3055                                else
3056                                {
3057//                                      printf("BIT: cannot find si_parameter descriptor.\n");
3058                                        p_broadcaster->p_si_parameter = (arib_si_parameter_descriptor_t *)NULL;
3059                                }
3060                        }       
3061            else
3062            {
3063                                p_broadcaster->broadcaster_descriptors = (DS_U8 *)NULL;
3064                                p_broadcaster->p_ex_broad = (arib_extended_broadcaster_descriptor_t *)NULL;
3065                                p_broadcaster->p_si_parameter = (arib_si_parameter_descriptor_t *)NULL;
3066            }
3067           
3068            k += 3+broadcaster_descriptor_length;
3069            p_broadcaster++;
3070        }
3071        }
3072   
3073    err = DHL_OK;
3074        *(((memId_t *)p_bit)-1) = memId;
3075        printf("p_bit = 0x%x\n",(int)memId);
3076        *pp_bit = p_bit;
3077        memId = 0;      /* Don't delete below */
3078
3079ParseExit:
3080        if (memId) 
3081        {
3082                /* delete the patSection memory */
3083                memChainDestroy(memId);
3084        }
3085
3086        return(err);
3087}
3088
3089DHL_RESULT DHL_PSI_GetDvbBit( DHL_PSI_HANDLE sysInfo, DVB_BIT **pp_bit, int timeOut )
3090{
3091        DHL_RESULT err = DHL_OK;
3092        void *returnPSICtl = NULL;
3093        PSIEventProcData_t      procData;
3094        int res = 0;
3095
3096        procData.desc = NULL; procData.err = (DS_U32)DHL_OK;
3097        /*creae a no-name , non-signaled event.*/
3098        //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ ));
3099        procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 );
3100       
3101        if (procData.hEvent == (OS_SEMAPHORE_ID)0) 
3102        { 
3103                printf ("DHL_PSI_GetPAT :       OS_CreateBinarySemaphore() fails.\n");
3104                return DHL_FAIL_OUT_OF_RESOURCE; 
3105        }       
3106
3107        if ((err = DHL_PSI_MonitorDvbBit(       sysInfo,
3108                                                                                _TRUE_,
3109                                                                                _FALSE_,
3110                                                                                psiOneShot,
3111                                                                                hal_cbPSISyncEventProc,
3112                                                                                (DS_U32)&procData,
3113                                                                                &returnPSICtl)))
3114        { 
3115                goto done;
3116        }
3117
3118        //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut );
3119        res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut );
3120        if (res != 0)
3121        { 
3122                #ifdef PSI_DGB
3123                printf("DHL_PSI_GetPAT : OS_TakeSemaphore TIMEOUT %d \n", timeOut);
3124                #endif
3125       
3126                #ifdef PSI_DBG
3127                printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n");
3128                #endif
3129                               
3130                err = DHL_FAIL_TIMEOUT; goto done2; }
3131
3132        if ((err = (DHL_RESULT)(procData.err)))
3133        {
3134                printf("DHL_PSI_GetPAT : procData.err = %d \n",  err );
3135                goto done2;
3136        }
3137
3138        err = DHL_PSI_ParseDvbBit(procData.desc->sectPtr, pp_bit);
3139
3140done2:
3141        DHL_PSI_CancelMonitor(returnPSICtl);
3142        if( procData.desc )
3143            DD_PSI_FreePSIData(procData.desc);
3144   
3145done:
3146        if(procData.hEvent)
3147        {
3148                OS_DeleteSemaphore(procData.hEvent);
3149        }
3150       
3151        return(err);
3152}
3153
3154DHL_RESULT DHL_PSI_PrintDvbBit( DVB_BIT *p_bit )
3155{
3156    DHL_RESULT err = DHL_OK;
3157        broadcaster_t *p_broadcaster;
3158    int i, j, k, l, m, n, o, p;
3159   
3160    if (!p_bit)
3161        return (err);
3162       
3163    printf("BIT (Broadcaster Information Table)\n");
3164    printf("    original_network_id: 0x%04X\n", p_bit->original_network_id);
3165    printf("    version_number: %d\n", p_bit->version_number);
3166    printf("    section_number: %d\n", p_bit->section_number);
3167    printf("    last_section_number: %d\n", p_bit->last_section_number);
3168 
3169        printf("    first_descriptor_length: %d\n", p_bit->first_descriptor_length);
3170        printf("    first_descriptors\n");
3171        DHL_PSI_Dump(p_bit->first_descriptors, p_bit->first_descriptor_length);
3172
3173        if ( p_bit->p_si_parameter )
3174        {
3175                arib_si_parameter_descriptor_t *p_si_parameter;
3176                arib_table_description_t *table_description;
3177                p_si_parameter = p_bit->p_si_parameter;
3178                table_description = p_si_parameter->table_description;
3179
3180                printf("SI parameter descriptor\n");
3181                printf("    parameter_version: 0x%02X\n", p_si_parameter->parameter_version);
3182                printf("    update_time: 0x%04X\n", p_si_parameter->update_time);
3183               
3184                if ( p_si_parameter->numTable > 0 )
3185                {
3186                        for ( i=0 ; i < p_si_parameter->numTable ; i++ )
3187                        {
3188                                printf("    table_id: 0x%02X\n", table_description->table_id);
3189                                printf("    table_description_length: %d\n", table_description->table_description_length);
3190
3191                                for ( j=0 ; j < table_description->table_description_length ; j++ )
3192                                {
3193                                        printf("    table_description_byte: 0x%02X\n", table_description->table_description_byte[j]);
3194                                }
3195
3196                                table_description++;
3197                        }
3198                }
3199        }
3200
3201        p_broadcaster = p_bit->broadcaster;
3202   
3203
3204        for ( i=0 ; i < p_bit->num_broadcaster ; i++ )
3205    {
3206                printf("    broadcaster %d\n", p_bit->num_broadcaster);
3207        printf("    broadcaster_id: 0x%02X\n", p_broadcaster->broadcaster_id);
3208       
3209                if ( p_broadcaster->broadcaster_descriptor_length )
3210                {
3211                        for ( j=0 ; j < p_broadcaster->broadcaster_descriptor_length ; )
3212                        {
3213                                if ( p_broadcaster->p_ex_broad )
3214                                {
3215                                        arib_extended_broadcaster_descriptor_t *p_ex;
3216
3217                                        p_ex = p_broadcaster->p_ex_broad;
3218
3219                                        printf("Extend Broadcaster descriptor\n");
3220                                        printf("    broadcaster_type: 0x%02X\n", p_ex->broadcaster_type);
3221
3222                                        j += 3;
3223
3224                                        if ( p_ex->broadcaster_type == 0x1 )
3225                                        {
3226                                                printf("    terrestrial_broadcaster_id: 0x%04X\n", p_ex->terrestrial_broadcaster_id);
3227                                       
3228                                                if ( p_ex->num_affiliation_id > 0 )
3229                                                {
3230                                                        for ( k=0 ; k < p_ex->num_affiliation_id ; k++ )
3231                                                        {
3232                                                                printf("    affiliation_id: 0x%02X\n", p_ex->affiliation_id[k]);
3233//                                                              p_ex->affiliation_id++;
3234                                                        }
3235                                                }       
3236                                               
3237                                                if ( p_ex->num_broadcaster_id )
3238                                                {
3239                                                        for ( l=0 ; l < p_ex->num_broadcaster_id ; l++ )
3240                                                        {
3241                                                                printf("    original_network_id: 0x%04X\n", p_ex->origin_network_id[l]);
3242                                                                printf("    broadcaster_id: 0x%02X\n", p_ex->broadcaster_id[l]);
3243//                                                              p_ex->origin_network_id++;
3244//                                                              p_ex->broadcaster_id++;
3245                                                        }
3246                                                }
3247
3248                                                j += 3+(p_ex->num_affiliation_id)+(p_ex->num_broadcaster_id*3);
3249                                        }
3250                                        else if ( p_ex->broadcaster_type == 0x2 )
3251                                        {
3252                                                printf("    terrestrial_sound_broadcaster_id: 0x%04X\n", p_ex->terrestrial_broadcaster_id);
3253                                       
3254                                                if ( p_ex->num_affiliation_id )
3255                                                {
3256                                                        for ( m=0 ; m < p_ex->num_affiliation_id ; m++ )
3257                                                        {
3258                                                                printf("    sound_broadcaster_affiliation_id: 0x%02X\n", p_ex->affiliation_id[m]);
3259//                                                              p_ex->affiliation_id++;
3260                                                        }
3261                                                }       
3262                                               
3263                                                if ( p_ex->num_broadcaster_id )
3264                                                {
3265                                                        for ( n=0 ; n < p_ex->num_broadcaster_id ; n++ )
3266                                                        {
3267                                                                printf("    original_network_id: 0x%04X\n", p_ex->origin_network_id[n]);
3268                                                                printf("    broadcaster_id: 0x%02X\n", p_ex->broadcaster_id[n]);
3269//                                                              p_ex->origin_network_id++;
3270//                                                              p_ex->broadcaster_id++;
3271                                                        }
3272                                                }
3273
3274                                                j += 3+(p_ex->num_affiliation_id)+(p_ex->num_broadcaster_id*3);
3275                                        }
3276
3277                                }       
3278
3279                                if ( p_broadcaster->p_si_parameter )
3280                                {
3281                                        arib_si_parameter_descriptor_t *broad_si_parameter;
3282                                        arib_table_description_t *broad_table_description;
3283
3284                                        broad_si_parameter = p_broadcaster->p_si_parameter;
3285                                        broad_table_description = broad_si_parameter->table_description;
3286                                        printf("SI parameter descriptor\n");
3287                                        printf("    parameter_version: 0x%02X\n", broad_si_parameter->parameter_version);
3288                                        printf("    update_time: 0x%04X\n", broad_si_parameter->update_time);
3289                                        j += 5;
3290
3291                                        if ( broad_si_parameter->numTable > 0 )
3292                                        {
3293                                                for ( o=0 ; o < broad_si_parameter->numTable ; o++ )
3294                                                {
3295                                                        printf("    table_id: 0x%02X\n", broad_table_description->table_id);
3296                                                        printf("    table_description_length: %d\n", broad_table_description->table_description_length);
3297
3298                                                        for ( p=0 ; p < broad_table_description->table_description_length ; p++ )
3299                                                        {
3300                                                                printf("    table_description_byte: 0x%02X\n", broad_table_description->table_description_byte[p]);
3301                                                        }
3302
3303                                                        j += 2+(broad_table_description->table_description_length);
3304                                                        broad_table_description++;
3305                                                }
3306                                        }
3307                                }
3308                        }
3309                }
3310
3311                printf("    broadcaster_descriptor_length: %d\n", p_broadcaster->broadcaster_descriptor_length);       
3312        DHL_PSI_Dump(p_broadcaster->broadcaster_descriptors, p_broadcaster->broadcaster_descriptor_length);
3313                 
3314        p_broadcaster++;
3315    }
3316
3317    return (err);
3318}
3319
3320#if 0
3321___Bouquet_Association_Table___()
3322#endif
3323DHL_RESULT DHL_PSI_MonitorDvbBat(       DHL_PSI_HANDLE sysInfo,
3324                                                                        DS_BOOL current_next_indicator,
3325                                                                        DS_BOOL eager,
3326                                                                        DS_BOOL b_actual,
3327                                                                        PSIUpdateMode updateMode,
3328                                                                        PSIEventProc_f eventProc,
3329                                                                        DS_U32 userParam, 
3330                                                                        DHL_TBL_HANDLE *returnPSICtl)
3331{
3332        PSIMask_t               *pref;
3333        DHL_RESULT              err;
3334
3335        if ((err = DD_PSI_GetTIDPSIMask (&pref, DVB_TID_bouquet_association_section, current_next_indicator))) {
3336                printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err);
3337                return(err);
3338        }
3339
3340        if ((err = DD_PSI_MonitorPSIPid(sysInfo,
3341                                                         DVB_PID_BAT, 
3342                                                         eager ? eagerTableMode : tableMode, 
3343                                                         updateMode,
3344                                                         pref,
3345                                                         /*MAX_PSI_MPEG_DATA*/1024,
3346                                                         MAX_PSI_SECTIONS,
3347                                                         eventProc,
3348                                                         userParam,
3349                                                         returnPSICtl))) 
3350    {
3351                printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err);                                         
3352                PSI_Free(pref);
3353        }
3354       
3355        return(err);
3356}
3357
3358DHL_RESULT DHL_PSI_ParseDvbBat( DS_U8 **sectionArr, DS_BOOL b_actual, dvb_bat_t **pp_bat )
3359{
3360        DHL_RESULT err = DHL_OK;
3361        int i, k;
3362        int numStreams;
3363        int numSections;
3364        int index;
3365        const DS_U8 *p;
3366        int len;
3367        dvb_bat_t *p_bat = NULL;
3368        int version_number;
3369        int bouquet_descriptor_length;
3370        int transport_loop_length;
3371        DS_BOOL current_next_indicator;
3372        memId_t                 memId = NULL;
3373        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
3374    transport_stream_t *p_ts;
3375
3376        if (sectionArr == NULL || (pp_bat == NULL)) 
3377        {
3378                return (DHL_FAIL_NULL_POINTER);
3379        }
3380
3381        if (sectionArr[0] == NULL) 
3382        {
3383                return (DHL_FAIL_NULL_POINTER);
3384        }
3385        else 
3386        {
3387                numSections = get_last_section_number(sectionArr[0]) + 1;
3388        }
3389
3390        /* now verify all other sections are present */
3391        for (i=1; i<numSections; i++) 
3392    {
3393                if (sectionArr[i] == NULL) {
3394                        return (DHL_FAIL_NULL_POINTER);
3395                }
3396        }
3397       
3398        /*
3399         * First pass, we verify section syntax and count the number of programs
3400         */
3401        numStreams = 0;
3402        for (i = 0; i < numSections; ++i) {
3403                p = sectionArr[i];
3404               
3405                if( p == NULL )
3406                {       
3407                    printf( "%s: NULL section", __func__);
3408                        return DHL_FAIL_NULL_POINTER;
3409                }
3410                       
3411                if (( b_actual && p[SECTION_TID] != DVB_TID_bouquet_association_section ))
3412                {
3413                        /*
3414                         * This thing isn't a PAT. Stop right here.
3415                         */
3416                        printf("BAT: Bad table ID. (0x%02X)", p[SECTION_TID]);
3417                        err = DHL_FAIL_INVALID_TABLEID;
3418                        goto ParseExit;
3419                }
3420               
3421                if ((p[SECTION_LEN_HI] & 0x80) != 0x80) {
3422                        printf("BAT: section_syntax_indicator not set");
3423                }
3424               
3425        /*
3426         * Counts number of transport_stream.
3427         */
3428        bouquet_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF;
3429        transport_loop_length = ((p[10+bouquet_descriptor_length]<<8) + p[11+bouquet_descriptor_length]) & 0xFFF;
3430        p = &sectionArr[i][12+bouquet_descriptor_length];
3431        for(k=0; k<transport_loop_length; )
3432        {
3433            int original_network_id;
3434            int transport_descriptor_length;
3435           
3436            original_network_id = ((p[k+2]<<8)+p[k+3]);
3437            transport_descriptor_length = ((p[k+4]<<8)+p[k+5]) & 0xFFF;
3438            if ( original_network_id != 0 )
3439                numStreams++;
3440           
3441            k += 6+transport_descriptor_length;
3442        }
3443        }
3444       
3445        /* create the memChain */
3446        err = memChainCreate(&memId,&memSetup);
3447        if (err) {
3448                goto ParseExit;
3449        }
3450   
3451        p_bat = (dvb_bat_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_bat_t)+sizeof(memId_t))) + 1);
3452        checkMemoryError(p_bat);
3453   
3454    p_bat->num_transport_stream = numStreams;
3455    if ( numStreams )
3456    {
3457        p_bat->transport_streams = (transport_stream_t *)memChainAlloc(memId,sizeof(transport_stream_t)*numStreams);
3458        checkMemoryError(p_bat->transport_streams);
3459    }
3460    else
3461    {
3462        p_bat->transport_streams = (transport_stream_t *)NULL;
3463    }
3464   
3465    /*
3466     * Now fill-out all the remaining fields over the all sections.
3467     */
3468        index = 0;
3469        p_bat->bouquet_descriptors = (DS_U8 *)NULL;
3470        p_ts = p_bat->transport_streams;
3471        for (i = 0; i < numSections; ++i) 
3472        {
3473            DS_U8 last_section_number;
3474            int bouquet_id;
3475           
3476                p = &sectionArr[i][0];
3477                len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
3478
3479                bouquet_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]);
3480                version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> 
3481                                                        SECTION_VERSION_SHIFT;
3482                current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0;
3483        bouquet_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF;
3484        last_section_number = p[SECTION_NUM_LAST];
3485       
3486                if (i == 0) 
3487                {
3488                    /* First section */
3489                        p_bat->bouquet_id = bouquet_id;
3490                        p_bat->version_number = version_number;
3491           
3492                        p_bat->section_number = p[SECTION_NUM];
3493                        p_bat->last_section_number = last_section_number;
3494                       
3495                        if ( p_bat->bouquet_descriptors == (DS_U8 *)NULL && bouquet_descriptor_length )
3496                    {
3497                        DS_U8 *p_desc = (DS_U8 *)NULL;
3498                       
3499                        p_bat->bouquet_descriptor_length = bouquet_descriptor_length;
3500                        p_bat->bouquet_descriptors = (DS_U8 *)memChainAlloc(memId, bouquet_descriptor_length);
3501                        memcpy( p_bat->bouquet_descriptors, &p[10], bouquet_descriptor_length);
3502
3503                        err=GetMpegDescriptor( p_bat->bouquet_descriptors, 
3504                                               bouquet_descriptor_length, 
3505                                               DVB_TAG_bouquet_name_descriptor,
3506                                               0, /* only find first one. */
3507                                               &p_desc );
3508                if ( p_desc && !err )
3509                {
3510                    DHL_PSI_ParseBouquetNameDescriptor( p_desc, memId, &(p_bat->p_bouquet_name), &(p_bat->bouquet_name_length) );
3511                }
3512                else
3513                {
3514                    p_bat->p_bouquet_name = (DS_U8 *)NULL;
3515                    p_bat->bouquet_name_length = 0;
3516                }
3517                    }
3518                }
3519                else 
3520                {
3521                        if (p_bat->bouquet_id != bouquet_id)
3522                                printf("BAT: Inconsistent bouquet_id (0x%x, 0x%x)\n", p_bat->bouquet_id, bouquet_id);
3523                        if (p_bat->version_number != version_number)
3524                                printf("BAT: inconsistent version_number (0x%x, 0x%x)\n", p_bat->version_number, version_number);
3525            if (p_bat->bouquet_descriptor_length != bouquet_descriptor_length)
3526                printf("BAT: Inconsistent bouquet_descriptor_length (0x%x, 0x%x)\n", p_bat->bouquet_descriptor_length, bouquet_descriptor_length );
3527            if (p_bat->last_section_number != last_section_number )
3528                printf("BAT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_bat->last_section_number, last_section_number);
3529                }
3530               
3531            transport_loop_length = ((p[10+bouquet_descriptor_length]<<8) + p[11+bouquet_descriptor_length]) & 0xFFF;
3532            if (!p_ts && transport_loop_length)
3533            {
3534                printf("BAT: transport_loop_length is not NULL, but transport_streams is NULL.\n");
3535                err = DHL_FAIL_INVALID_TABLEID;
3536                goto ParseExit;
3537            }
3538           
3539        p = &sectionArr[i][12+bouquet_descriptor_length];
3540        for(k=0; k<transport_loop_length; )
3541        {
3542            int transport_stream_id;
3543            int original_network_id;
3544            int transport_descriptor_length;
3545           
3546            transport_stream_id = ((p[k+0]<<8)+p[k+1]);
3547            original_network_id = ((p[k+2]<<8)+p[k+3]);
3548            transport_descriptor_length = ((p[k+4]<<8)+p[k+5]) & 0xFFF;
3549           
3550            p_ts->transport_stream_id = transport_stream_id;
3551            p_ts->original_network_id = original_network_id;
3552            p_ts->transport_descriptor_length = transport_descriptor_length;
3553            if ( transport_descriptor_length )
3554            {
3555                DS_U8 *p_desc = (DS_U8 *)NULL;
3556               
3557                p_ts->transport_descriptors = (DS_U8 *)memChainAlloc( memId, transport_descriptor_length );
3558                if ( !(p_ts->transport_descriptors) )
3559                {
3560                    err = DHL_FAIL_OUT_OF_RESOURCE;
3561                    goto ParseExit;
3562                }
3563                memcpy( p_ts->transport_descriptors, &p[k+6], transport_descriptor_length );
3564               
3565                /*
3566                 * Parse Service List descriptor
3567                 */
3568                        err=GetMpegDescriptor( p_ts->transport_descriptors, 
3569                                               transport_descriptor_length, 
3570                                               DVB_TAG_service_list_descriptor,
3571                                               0, /* only find first one. */
3572                                               &p_desc );
3573                if ( p_desc )
3574                {
3575                    DHL_PSI_ParseServiceListDescriptor( p_desc, memId, &(p_ts->p_service_list) );
3576                }
3577                else
3578                {
3579                    p_ts->p_service_list = (dvb_service_list_descriptor_t *)NULL;
3580                }
3581               
3582                /*
3583                 * Parse TS information descriptor.
3584                 */
3585                p_desc = (DS_U8 *)NULL;
3586                        err=GetMpegDescriptor( p_ts->transport_descriptors, 
3587                                               transport_descriptor_length, 
3588                                               ARIB_TAG_ts_information_descriptor,
3589                                               0, /* only find first one. */
3590                                               &p_desc );
3591                if ( p_desc )
3592                {
3593                    DHL_PSI_ParseTSInformationDescriptor( p_desc, memId, &(p_ts->p_ts_info) );
3594                }
3595                else
3596                {
3597                    p_ts->p_ts_info = (arib_ts_information_descriptor_t *)NULL;
3598                }
3599               
3600            }
3601            else
3602            {
3603                p_ts->transport_descriptors = (DS_U8 *)NULL;
3604                p_ts->p_service_list = (dvb_service_list_descriptor_t *)NULL;
3605                p_ts->p_ts_info = (arib_ts_information_descriptor_t *)NULL;
3606            }
3607           
3608            k += 6+transport_descriptor_length;
3609            p_ts++;
3610        }
3611        }
3612   
3613    err = DHL_OK;
3614        *(((memId_t *)p_bat)-1) = memId;
3615        *pp_bat = p_bat;
3616        memId = 0;      /* Don't delete below */
3617
3618ParseExit:
3619        if (memId) 
3620        {
3621                /* delete the patSection memory */
3622                memChainDestroy(memId);
3623        }
3624
3625        return(err);
3626}
3627
3628DHL_RESULT DHL_PSI_GetDvbBat( DHL_PSI_HANDLE sysInfo, DS_BOOL b_actual, DVB_BAT **pp_bat, int timeOut )
3629{
3630    DHL_RESULT err = DHL_OK;
3631        void *returnPSICtl = NULL;
3632        PSIEventProcData_t      procData;
3633        int res = 0;
3634
3635        procData.desc = NULL;
3636        procData.err = (DS_U32)DHL_OK;
3637        /*creae a no-name , non-signaled event.*/
3638        //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ ));
3639        procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 );
3640       
3641    if (procData.hEvent == (OS_SEMAPHORE_ID)0)
3642    {
3643        printf ("DHL_PSI_GetPAT : OS_CreateBinarySemaphore() fails.\n");
3644        return DHL_FAIL_OUT_OF_RESOURCE;
3645    }   
3646
3647        if ((err = DHL_PSI_MonitorDvbBat(sysInfo,
3648                                                  _TRUE_ /* current */,
3649                                                  _FALSE_ /* not eager */,
3650                                                  b_actual,
3651                                                  psiOneShot, 
3652                                                  hal_cbPSISyncEventProc,
3653                                                  (DS_U32)&procData,
3654                                                  &returnPSICtl))) 
3655    {
3656                goto done;
3657        }
3658       
3659        //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut );
3660        res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut );
3661    if (res != 0)
3662    {
3663        #ifdef PSI_DGB
3664        printf("DHL_PSI_GetPAT : OS_TakeSemaphore TIMEOUT %d \n", timeOut);
3665        #endif
3666       
3667        #ifdef PSI_DBG
3668                printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n");
3669                #endif
3670                               
3671        err = DHL_FAIL_TIMEOUT;
3672        goto done2;
3673    }
3674
3675        if ((err = (DHL_RESULT)(procData.err))) {
3676                printf("DHL_PSI_GetPAT : procData.err = %d \n",  err );
3677                goto done2;
3678        }
3679
3680        err = DHL_PSI_ParseDvbBat(procData.desc->sectPtr, b_actual, pp_bat);
3681
3682done2:
3683        DHL_PSI_CancelMonitor(returnPSICtl);
3684        if( procData.desc )
3685            DD_PSI_FreePSIData(procData.desc);
3686   
3687done:
3688        if(procData.hEvent)
3689        {
3690                OS_DeleteSemaphore(procData.hEvent);
3691        }
3692       
3693        return(err);
3694}
3695
3696DHL_RESULT DHL_PSI_PrintDvbBat( DVB_BAT *p_bat )
3697{
3698    DHL_RESULT err = DHL_OK;
3699    transport_stream_t *p_ts;
3700    int i;
3701   
3702    if (!p_bat)
3703        return (err);
3704       
3705    printf("BAT (Bouquet Association Table)\n");
3706    printf("    bouquet_id: 0x%04X\n", p_bat->bouquet_id);
3707    printf("    version_number: %d\n", p_bat->version_number);
3708    printf("    section_number: %d\n", p_bat->section_number);
3709    printf("    last_section_number: %d\n", p_bat->last_section_number);
3710   
3711    if ( p_bat->p_bouquet_name )
3712        printf("    bouquet_name: %s\n", p_bat->p_bouquet_name);
3713    else
3714        printf("    bouquet_name: (not found)\n");
3715       
3716    printf("    bouquet_descriptor_length: %d\n", p_bat->bouquet_descriptor_length );
3717    printf("    bouquet_descriptors\n");
3718    DHL_PSI_Dump(p_bat->bouquet_descriptors, p_bat->bouquet_descriptor_length);
3719    printf("    num_transport_stream: %d\n", p_bat->num_transport_stream);
3720    p_ts = p_bat->transport_streams;
3721   
3722    for (i=0; i<p_bat->num_transport_stream; i++)
3723    {
3724        printf("    transport_stream %d\n", i);
3725        printf("        transport_stream_id: 0x%04X\n", p_ts->transport_stream_id);
3726        printf("        original_network_id: 0x%04X\n", p_ts->original_network_id);
3727        if ( p_ts->p_service_list )
3728        {
3729            int n;
3730            dvb_service_t *p_service = p_ts->p_service_list->p_service;
3731           
3732            printf("        service_list (%d)\n", p_ts->p_service_list->numServices);
3733            for(n=0; n<p_ts->p_service_list->numServices; n++)
3734            {
3735                printf("        service #%d: service_id 0x%04X, service_type 0x%02X\n", n, 
3736                        p_service->service_id, p_service->service_type);
3737                p_service++;
3738            }
3739        }
3740       
3741        if ( p_ts->p_ts_info )
3742        {
3743            arib_ts_information_descriptor_t *p_ts_info = p_ts->p_ts_info;
3744           
3745            printf("        TS_info.remote_control_key_id = %d\n", p_ts_info->remote_control_key_id);
3746            if ( p_ts_info->ts_name_length && p_ts_info->ts_name )
3747            {
3748                int n;
3749
3750#ifndef CONV_TO_ASCII
3751#define CONV_TO_ASCII(x)    ( ((x) >= ' ' && (x) <= '~') ? (x) : '.' )
3752#endif
3753               
3754                printf("        TS_info.ts_name = ");
3755                for (n=0; n<p_ts_info->ts_name_length; n++)
3756                    printf("%c", CONV_TO_ASCII(p_ts_info->ts_name[n]));
3757                printf("\n");
3758            }
3759           
3760            if ( p_ts_info->transmission_type_count )
3761            {
3762                int n;
3763                arib_transmission_type_t *p_tx_type = p_ts_info->transmission_type;
3764               
3765                for (n=0; n<p_ts_info->transmission_type_count; n++)
3766                {
3767                    printf("        TS_info.tx_type[%d].type: 0x%02X (%s-%s) See ARIB TR-B14 Table 3\n", n, 
3768                                    p_tx_type->transmission_type_info,
3769                                    ((p_tx_type->transmission_type_info>>6)&3) == 0 ? "Type A" :
3770                                    ((p_tx_type->transmission_type_info>>6)&3) == 1 ? "Type B" :
3771                                    ((p_tx_type->transmission_type_info>>6)&3) == 2 ? "Type C" :"Reserved",
3772                                    ((p_tx_type->transmission_type_info>>4)&3) == 0 ? "64QAM" :
3773                                    ((p_tx_type->transmission_type_info>>4)&3) == 1 ? "16QAM" :
3774                                    ((p_tx_type->transmission_type_info>>4)&3) == 2 ? "QPSK" : "Reserved");
3775                   
3776                    if ( p_tx_type->number_of_service && p_tx_type->service_id )
3777                    {
3778                        int k;
3779                       
3780                        printf("        TS_info.tx_type[%d].service_id list\n", n);
3781                        for (k=0; k<p_tx_type->number_of_service; k++)
3782                        {
3783                            printf("            0x%04X\n", p_tx_type->service_id[k]);
3784                        }
3785                    }
3786                   
3787                    p_tx_type++;
3788                }
3789            }
3790        }
3791
3792        printf("        transport_descriptor_length: 0x%04X\n", p_ts->transport_descriptor_length);
3793        DHL_PSI_Dump(p_ts->transport_descriptors, p_ts->transport_descriptor_length);
3794       
3795        p_ts++;
3796    }
3797   
3798    return (err);
3799}
3800
3801#if 0
3802___Common_Data_Table___()
3803#endif
3804DHL_RESULT DHL_PSI_MonitorDvbCdt(       DHL_PSI_HANDLE sysInfo,
3805                                                                        DS_BOOL current_next_indicator,
3806                                                                        DS_BOOL eager,
3807//                                                                      DS_BOOL b_actual,
3808                                                                        PSIUpdateMode updateMode,
3809                                                                        PSIEventProc_f eventProc,
3810                                                                        DS_U32 userParam, 
3811                                                                        DHL_TBL_HANDLE *returnPSICtl)
3812{
3813        PSIMask_t               *pref;
3814        DHL_RESULT              err;
3815
3816        if ((err = DD_PSI_GetTIDPSIMask ( &pref,
3817                                                                          DVB_TID_common_data_section, 
3818                                                                          current_next_indicator)))
3819        {
3820                printf("DD_PSI_GetTIDPSIMask has returned error(0x%x)\n", err);
3821                return(err);
3822        }
3823
3824        if ((err = DD_PSI_MonitorPSIPid( sysInfo,
3825                                                                         DVB_PID_CDT, 
3826                                                                         eager ? eagerTableMode : tableMode, 
3827                                                                         updateMode,
3828                                                                         pref,
3829                                                                         /*MAX_PSI_MPEG_DATA*/1024,
3830                                                                         MAX_PSI_SECTIONS,
3831                                                                         eventProc,
3832                                                                         userParam,
3833                                                                         returnPSICtl)) ) 
3834    {
3835                printf("DD_PSI_MonitorPSIPid has returned error(0x%x)\n", err);                                         
3836                PSI_Free(pref);
3837        }
3838       
3839        return(err);
3840}
3841
3842DHL_RESULT DHL_PSI_ParseDvbCdt(DS_U8 **sectionArr, dvb_cdt_t **pp_cdt)
3843{
3844        DHL_RESULT err = DHL_OK;
3845        int i, k;
3846        DS_U16 *numDatas;
3847        int lenDatas;
3848        int numSections;
3849        int index;
3850        const DS_U8 *p;
3851        int len, slen;
3852        dvb_cdt_t *p_cdt = NULL;
3853        int version_number;
3854        int descriptors_loop_length;
3855        DS_BOOL current_next_indicator;
3856        memId_t                 memId = NULL;
3857        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
3858        data_module_byte_t      *p_data;
3859
3860        if (sectionArr == NULL || (pp_cdt == NULL)) 
3861        {
3862                return (DHL_FAIL_NULL_POINTER);
3863        }
3864
3865        if (sectionArr[0] == NULL) 
3866        {
3867                return (DHL_FAIL_NULL_POINTER);
3868        }
3869        else 
3870        {
3871                numSections = get_last_section_number(sectionArr[0]) + 1;
3872        }
3873
3874        /* now verify all other sections are present */
3875        for (i=1; i<numSections; i++) 
3876    {
3877                if (sectionArr[i] == NULL)
3878                {
3879                        return (DHL_FAIL_NULL_POINTER);
3880                }
3881        }
3882
3883        /* create the memChain */
3884        err = memChainCreate(&memId,&memSetup);
3885        if (err) {
3886                goto ParseExit;
3887        }
3888
3889        numDatas = (DS_U16 *)memChainAlloc(memId, sizeof(DS_U16)*numSections);
3890       
3891        /*
3892         * First pass, we verify section syntax and count the number of data_modul_byte.
3893         */
3894        for (i = 0; i < numSections; ++i)
3895        {
3896                p = sectionArr[i];
3897               
3898                if( p == NULL )
3899                {       
3900                    printf( "%s: NULL section", __func__);
3901                        return DHL_FAIL_NULL_POINTER;
3902                }
3903                       
3904                if ( (p[SECTION_TID] != DVB_TID_common_data_section) )
3905                {
3906                        /*
3907                         * This thing isn't a PAT. Stop right here.
3908                         */
3909                        printf("CDT: Bad table ID. (0x%02X)", p[SECTION_TID]);
3910                        err = DHL_FAIL_INVALID_TABLEID;
3911                        goto ParseExit;
3912                }
3913               
3914                if ((p[SECTION_LEN_HI] & 0x80) != 0x80) {
3915                        printf("CDT: section_syntax_indicator not set");
3916                }
3917               
3918        /*
3919         * Counts number of data_module_byte.
3920         */
3921
3922                slen = ((p[1]<<8) + p[2]) & 0xFFF;
3923
3924                descriptors_loop_length = ((p[11]<<9) + p[12]) & 0xFFF;
3925                lenDatas = slen - (10 + descriptors_loop_length + 4);
3926                p = &sectionArr[i][13+descriptors_loop_length];
3927
3928                numDatas[i] = 0;
3929
3930                for( k=0 ; k < lenDatas ; )
3931                {
3932                        int data_size;
3933
3934                        data_size = (p[k+5]<<8) + p[k+6];
3935                        if ( data_size )
3936                        {
3937                                numDatas[i]++;
3938                        }
3939
3940                        k += 7+data_size;
3941                }
3942        }
3943
3944        p_cdt = (dvb_cdt_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_cdt_t)*numSections+sizeof(memId_t))) + 1);
3945        checkMemoryError(p_cdt);
3946 
3947    /*
3948     * Now fill-out all the remaining fields over the all sections.
3949     */
3950        index = 0;
3951        p_cdt->descriptors = (DS_U8 *)NULL;
3952
3953        for (i = 0; i < numSections; ++i) 
3954        {
3955                DS_U8 last_section_number;
3956            int download_data_id;
3957                int original_network_id;
3958                int data_type;
3959           
3960                p = &sectionArr[i][0];
3961                len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
3962
3963                download_data_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]);
3964                version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> SECTION_VERSION_SHIFT;
3965                current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0;
3966                original_network_id = ((p[8]<<8) + p[9]);
3967                data_type = p[10];
3968        descriptors_loop_length = ((p[11]<<8) + p[12]) & 0xFFF;
3969        last_section_number = p[SECTION_NUM_LAST];
3970               
3971                if ( numDatas[i] )
3972                {
3973                        p_cdt[i].num_Datas = numDatas[i];
3974                        p_cdt[i].data_module_byte = (data_module_byte_t *)memChainAlloc(memId,sizeof(data_module_byte_t)*numDatas[i]);
3975                }
3976       
3977                p_cdt[i].download_data_id = download_data_id;
3978                p_cdt[i].version_number = version_number;
3979                p_cdt[i].last_section_number = last_section_number;
3980                p_cdt[i].original_network_id = original_network_id;
3981                p_cdt[i].data_type = data_type;
3982
3983#if 0
3984        //
3985        // Junku/091211
3986        // Logo transmission descriptor´Â CDT°¡ ¾Æ´Ñ SDT¿¡ Á¸ÀçÇÏ´Â descriptor.
3987        //
3988                if ( p_cdt[i].descriptors == (DS_U8 *)NULL && descriptors_loop_length )
3989                {
3990                        DS_U8 *p_desc = (DS_U8 *)NULL;
3991                       
3992                        p_cdt[i].descriptors_loop_length = descriptors_loop_length;
3993                        p_cdt[i].descriptors = (DS_U8 *)memChainAlloc(memId, descriptors_loop_length);
3994                        memcpy( p_cdt[i].descriptors, &p[13], descriptors_loop_length);
3995
3996                        err=GetMpegDescriptor( p_cdt[i].descriptors,
3997                                                                   descriptors_loop_length,
3998                                                                   ARIB_TAG_logo_transmission_descriptor,
3999                                                                   0, /* only find first one. */
4000                                                                   &p_desc );
4001                        if ( p_desc && !err )
4002                        {
4003                                DHL_PSI_ParseLogoTransmissionDescriptor( p_desc, memId, &(p_cdt[i].logo_tx_desc));
4004                        }
4005                        else
4006                        {
4007                                p_cdt[i].logo_tx_desc = (arib_logo_transmission_descriptor_t *)NULL;
4008                        }
4009                }
4010#endif
4011
4012                if ( i > 0 ) 
4013                {
4014                        if (p_cdt[i].download_data_id != download_data_id)
4015                                printf("CDT: Inconsistent download_data_id (0x%x, 0x%x)\n", p_cdt->download_data_id, download_data_id);
4016                        if (p_cdt[i].version_number != version_number)
4017                                printf("CDT: inconsistent version_number (0x%x, 0x%x)\n", p_cdt->version_number, version_number);
4018            if (p_cdt[i].original_network_id != original_network_id)
4019                printf("CDT: Inconsistent network_descriptor_length (0x%x, 0x%x)\n", p_cdt->original_network_id, original_network_id);
4020                        if (p_cdt[i].data_type != data_type)
4021                printf("CDT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_cdt->data_type, data_type);
4022                        if (p_cdt[i].last_section_number != last_section_number)
4023                printf("CDT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_cdt->last_section_number, last_section_number);
4024                }
4025               
4026                lenDatas = len - (10 + descriptors_loop_length + 4 + 3);
4027                p = &sectionArr[i][13+descriptors_loop_length];
4028           
4029                if ( !p_data && lenDatas )
4030            {
4031                printf("CDT: data_module_byte length is not NULL, but data_module_byte is NULL.\n");
4032                        err = DHL_FAIL_INVALID_TABLEID;
4033                goto ParseExit;
4034            }
4035           
4036                p_data = p_cdt[i].data_module_byte;
4037        p = &sectionArr[i][13+descriptors_loop_length];
4038        for( k=0 ; k < lenDatas ; )
4039        {
4040            int logo_type;
4041            int logo_id;
4042            int logo_version;
4043                        int data_size;
4044           
4045                        logo_type = p[k+0];
4046                        logo_id = ((p[k+1]<<8) + p[k+2]) & 0x1FF;
4047                        logo_version = ((p[k+3]<<8) + p[k+4]) & 0xFFF;
4048                        data_size = (p[k+5]<<8) + p[k+6];
4049
4050                        p_data->logo_type = logo_type;
4051                        p_data->logo_id = logo_id;
4052                        p_data->logo_version = logo_version;
4053                        p_data->data_size = data_size;
4054
4055            if ( p_data->data_size )
4056            {
4057                                p_data->data_byte = (DS_U8 *)memChainAlloc(memId, data_size);
4058
4059                                if ( !(p_data->data_byte) )
4060                                {
4061                                        err = DHL_FAIL_OUT_OF_RESOURCE;
4062                                        goto ParseExit;
4063                                }
4064
4065                                memcpy(p_data->data_byte, &p[k+7], data_size);
4066            }
4067            else
4068            {
4069                p_data->data_byte = (DS_U8 *)NULL;
4070            }
4071           
4072            k += 7+data_size;
4073            p_data++;
4074        }
4075        }
4076   
4077    err = DHL_OK;
4078        *(((memId_t *)p_cdt)-1) = memId;
4079        *pp_cdt = p_cdt;
4080        memId = 0;      /* Don't delete below */
4081
4082ParseExit:
4083        if (memId) 
4084        {
4085                /* delete the patSection memory */
4086                memChainDestroy(memId);
4087        }
4088
4089        return(err);
4090}
4091
4092DHL_RESULT DHL_PSI_GetDvbCdt( DHL_PSI_HANDLE sysInfo, DVB_CDT **pp_cdt, int timeOut )
4093{
4094    DHL_RESULT err = DHL_OK;
4095        void *returnPSICtl = NULL;
4096        PSIEventProcData_t      procData;
4097        int res = 0;
4098
4099        procData.desc = NULL;
4100        procData.err = (DS_U32)DHL_OK;
4101        /*creae a no-name , non-signaled event.*/
4102        //procData.hEvent = (DS_U32)(AtiCore_EventCreate( 0, _FALSE_ ));
4103        procData.hEvent = OS_CreateBinarySemaphore( "semPat0", 0, 0 );
4104       
4105    if (procData.hEvent == (OS_SEMAPHORE_ID)0)
4106    {
4107        printf ("DHL_PSI_GetPAT : OS_CreateBinarySemaphore() fails.\n");
4108        return DHL_FAIL_OUT_OF_RESOURCE;
4109    }   
4110
4111        if ((err = DHL_PSI_MonitorDvbCdt(sysInfo,
4112                                                  _TRUE_ /* current */,
4113                                                  _FALSE_ /* not eager */,
4114//                                                b_actual,
4115                                                  psiOneShot, 
4116                                                  hal_cbPSISyncEventProc,
4117                                                  (DS_U32)&procData,
4118                                                  &returnPSICtl))) 
4119    {
4120                goto done;
4121        }
4122
4123        //res = AtiCore_EventWait( procData.hEvent , _TRUE_ , timeOut );
4124        res = OS_TakeSemaphore_Wait( (OS_SEMAPHORE_ID)procData.hEvent, timeOut );
4125   
4126        if (res != 0)
4127    {
4128                #ifdef PSI_DGB
4129        printf("DHL_PSI_GetPAT : OS_TakeSemaphore TIMEOUT %d \n", timeOut);
4130        #endif
4131       
4132        #ifdef PSI_DBG
4133                printf("hal_cbPSISyncEventProc : reset procData->hEvent.\n");
4134                #endif
4135               
4136        err = DHL_FAIL_TIMEOUT;
4137        goto done2;
4138    }
4139       
4140        if ((err = (DHL_RESULT)(procData.err))) {
4141                printf("DHL_PSI_GetPAT : procData.err = %d \n",  err );
4142                goto done2;
4143        }
4144
4145        err = DHL_PSI_ParseDvbCdt(procData.desc->sectPtr, pp_cdt);
4146
4147done2:
4148        DHL_PSI_CancelMonitor(returnPSICtl);
4149        if( procData.desc )
4150            DD_PSI_FreePSIData(procData.desc);
4151   
4152done:
4153        if(procData.hEvent)
4154        {
4155                OS_DeleteSemaphore(procData.hEvent);
4156        }
4157       
4158        return(err);
4159}
4160
4161DHL_RESULT DHL_PSI_PrintDvbCdt( DVB_CDT *p_cdt )
4162{
4163    DHL_RESULT err = DHL_OK;
4164        data_module_byte_t *p_data;
4165        int numSections;
4166        int i, j, k;
4167   
4168    if (!p_cdt)
4169        return (err);
4170       
4171        numSections = p_cdt->last_section_number + 1;
4172        printf("CDT (Common Data Table)\n");
4173
4174        for ( i=0 ; i < numSections ; i++ )
4175        {
4176                printf("    download_data_id: 0x%04X\n", p_cdt[i].download_data_id);
4177                printf("    version_number: %d\n", p_cdt[i].version_number);
4178                printf("    section_number: %d\n", i);
4179                printf("    last_section_number: %d\n", p_cdt[i].last_section_number);
4180                printf("    original_network_id: 0x%04X\n", p_cdt[i].original_network_id);
4181                printf("    data_type: 0x%02X\n", p_cdt[i].data_type);
4182                printf("    descriptors_loop_length: %d\n", p_cdt[i].descriptors_loop_length );
4183                if ( p_cdt[i].descriptors_loop_length )
4184                {
4185                        printf("    descriptors\n\n");
4186                        DHL_PSI_Dump(p_cdt[i].descriptors, p_cdt[i].descriptors_loop_length);
4187                }
4188                else
4189                        printf("CDT:    descriptors is NULL.\n\n");
4190
4191#if 0
4192                if ( p_cdt[i].logo_tx_desc )
4193                {
4194                        arib_logo_transmission_descriptor_t *p_logo;
4195                        p_logo = p_cdt[i].logo_tx_desc;
4196                       
4197                        printf("    logo_transmission_descriptor\n");
4198
4199                        if ( p_logo->logo_transmission_type == 0x1 )
4200                        {
4201                                printf("    logo_id: 0x%04X\n", p_logo->logo_id);
4202                                printf("    logo_version: 0x%04X\n", p_logo->logo_version);
4203                                printf("    download_data_id: 0x%04X\n", p_logo->download_data_id);
4204                        }
4205                        else if ( p_logo->logo_transmission_type == 0x2 )
4206                        {
4207                                printf("    logo_id: 0x%04X\n", p_logo->logo_id);
4208                        }
4209                        else if ( p_logo->logo_transmission_type == 0x3 )
4210                        {
4211                                printf("    logo_char: %s\n", p_logo->logo_char);
4212                        }
4213                }
4214#endif
4215
4216                printf("    num_data_module_byte: %d\n", p_cdt[i].num_Datas);
4217                p_data = p_cdt[i].data_module_byte;
4218
4219                for ( j=0 ; j < p_cdt->num_Datas ; j++ )
4220                {
4221                        printf("        logo_type: 0x%02X\n", p_data->logo_type);
4222                        printf("        logo_id: 0x%02X\n", p_data->logo_id);
4223                        printf("        logo_version: 0x%04X\n", p_data->logo_version);
4224                        printf("        data_size: %d\n", p_data->data_size);
4225                        for ( k=0 ; k < p_data->data_size ; k++ )
4226                        {
4227                                printf("            data_byte[%d]: 0x%02X\n", k, p_data->data_byte[k]);
4228        //                      p_data->data_byte++;
4229                        }
4230
4231                        p_data++;
4232                }
4233
4234                printf("\n");
4235        }
4236   
4237    return (err);
4238}
4239
4240#if 0
4241___Descriptors___()
4242#endif
4243static void DHL_PSI_ParseEventGroupDescriptor(DS_U8 *p_desc, memId_t memId, arib_event_group_descriptor_t **pp_event_grp)
4244{
4245    DS_U8 *p = p_desc;
4246    arib_event_group_descriptor_t *p_event_grp;
4247    arib_event_t *p_event;
4248    arib_other_event_t *p_other_event;
4249    int i, len, off;
4250//    int numEvent;
4251   
4252    if (!p_desc || !pp_event_grp || !memId)
4253        return;
4254   
4255    len = p_desc[1];
4256    if (len<5)
4257        return;
4258   
4259    p_event_grp = (arib_event_group_descriptor_t *)memChainAlloc(memId, sizeof(arib_event_group_descriptor_t));
4260    p_event_grp->group_type = (p[2] >> 4) & 0x0F;
4261    p_event_grp->numEvents = p[2]&0x0F;
4262   
4263    off = 3 /*3=descriptor_tag+length+group_type + event_cnt*/;
4264    if ( p_event_grp->numEvents )
4265    {
4266        p_event = p_event_grp->p_event = (arib_event_t *)memChainAlloc(memId, sizeof(arib_event_t) * p_event_grp->numEvents);
4267        for (i=0; i<p_event_grp->numEvents && off <= (len+2); i++)
4268        {
4269            p_event->service_id = (p[0+off]<<8)+p[1+off];
4270            p_event->event_id   = (p[2+off]<<8)+p[3+off];
4271           
4272            off += 4;
4273            p_event++;
4274        }
4275    }
4276   
4277    p_event_grp->numOtherNetworkEvents = 0;
4278    if ( p_event_grp->group_type == 4 || p_event_grp->group_type == 5 )
4279    {
4280        p_event_grp->numOtherNetworkEvents = (len-off-2)/8;
4281        if (p_event_grp->numOtherNetworkEvents)
4282        {
4283            p_other_event = p_event_grp->p_other_event = (arib_other_event_t *)memChainAlloc(memId, sizeof(arib_other_event_t) * p_event_grp->numOtherNetworkEvents);
4284            for (i=0; i<p_event_grp->numOtherNetworkEvents; i++)
4285            {
4286                p_other_event->original_network_id = (p[0+off]<<8)+p[1+off];
4287                p_other_event->transport_stream_id = (p[2+off]<<8)+p[3+off];
4288                p_other_event->service_id          = (p[4+off]<<8)+p[5+off];
4289                p_other_event->event_id            = (p[6+off]<<8)+p[7+off];
4290               
4291                off += 8;
4292                p_other_event++;
4293            }
4294        }
4295    }
4296   
4297    *pp_event_grp = p_event_grp;
4298}
4299
4300void DHL_PSI_ParseLogicalChannelDescriptor(DS_U8 *p_desc, memId_t memId, logical_channel_descriptor_t **pp_lcd)
4301{
4302    DS_U8 *p;
4303    int i, len;
4304    int numServices;
4305    logical_channel_descriptor_t *p_lcd;
4306    logical_channel_t *p_lc;
4307   
4308    if (!p_desc || !pp_lcd || !memId)
4309        return;
4310   
4311    len = p_desc[1];
4312    if (len<4)
4313        return;
4314   
4315    p_lcd = (logical_channel_descriptor_t *)memChainAlloc(memId, sizeof(logical_channel_descriptor_t)+1);
4316
4317    numServices = (len / 4);
4318    p_lc = (logical_channel_t *)memChainAlloc(memId, sizeof(logical_channel_t)*numServices);
4319   
4320    p = &p_desc[2];
4321    p_lcd->numServices = numServices;
4322    p_lcd->p_lc = p_lc;
4323    for (i=0; i<numServices; i++)
4324    {
4325        p_lc->service_id = (p[0]<<8)+p[1];
4326        p_lc->visible = (p[2] & 0x80);
4327        p_lc->logical_channel_number = ((p[2]<<8)+p[3]) & 0x3FF;
4328       
4329        p += 4;
4330        p_lc++;
4331    }
4332   
4333    *pp_lcd = p_lcd;
4334   
4335    return;
4336}
4337
4338void DHL_PSI_ParseNetworkNameDescriptor(DS_U8 *p_desc, memId_t memId, DS_U8 **pp_network_name, DS_U8 *p_length)
4339{
4340    int len;
4341    DS_U8 *p_network_name;
4342   
4343    if (!p_desc || !p_network_name || !p_length)
4344        return;
4345   
4346    len = p_desc[1];
4347    p_network_name = (DS_U8 *)memChainAlloc( memId, len+1 );
4348    memcpy(p_network_name, &p_desc[2], len );
4349    p_network_name[len] = '\0';
4350   
4351    *pp_network_name = p_network_name;
4352    *p_length = len;
4353   
4354    return;
4355}
4356
4357void DHL_PSI_ParseServiceListDescriptor(DS_U8 *p_desc, memId_t memId, dvb_service_list_descriptor_t **pp_service_list)
4358{
4359    int i, len;
4360    int numServices;
4361    DS_U8 *p;
4362    dvb_service_list_descriptor_t *p_sld = (dvb_service_list_descriptor_t *)NULL;
4363    dvb_service_t *p_service = (dvb_service_t *)NULL;
4364   
4365    len = p_desc[1];
4366    p = &p_desc[2];
4367   
4368    numServices = len / 3;
4369   
4370    if (len % 3)
4371        printf("%s: descriptor length is invalid (%d)\n", __func__, len);
4372   
4373    p_sld = (dvb_service_list_descriptor_t *)memChainAlloc(memId, sizeof(dvb_service_list_descriptor_t));
4374    p_service = p_sld->p_service = (dvb_service_t *)memChainAlloc(memId, sizeof(dvb_service_t)*numServices);
4375   
4376    if ( !p_sld )
4377        return;
4378   
4379    if ( !(p_sld->p_service) )
4380        return;
4381   
4382    p_sld->numServices = numServices;
4383    for (i=0; i<numServices; i++)
4384    {
4385        p_service->service_id = (p[0]<<8)+p[1];
4386        p_service->service_type = p[2];
4387        p += 3;
4388        p_service++;
4389    }
4390   
4391    *pp_service_list = p_sld;
4392   
4393    return;
4394}
4395
4396void DHL_PSI_ParseServiceDescriptor(DS_U8 *p_desc, memId_t memId, dvb_service_descriptor_t **pp_service_desc)
4397{
4398    int provider_name_length;
4399    int service_name_length;
4400   
4401    dvb_service_descriptor_t *p_service = (dvb_service_descriptor_t *)NULL;
4402   
4403    if ( !p_desc || !pp_service_desc )
4404        return;
4405   
4406    p_service = (dvb_service_descriptor_t *)memChainAlloc(memId, sizeof(dvb_service_descriptor_t));
4407    if ( !p_service )
4408        return;
4409       
4410    p_service->service_type = p_desc[2];
4411   
4412    provider_name_length = p_service->i_provider_name_length = p_desc[3];
4413    if (provider_name_length)
4414    {
4415        p_service->p_provider_name = (DS_U8 *)memChainAlloc(memId, provider_name_length+1);
4416        memcpy( p_service->p_provider_name, &p_desc[4], provider_name_length );
4417        p_service->p_provider_name[provider_name_length] = '\0';
4418    }
4419    else
4420    {
4421        p_service->p_provider_name = (DS_U8 *)NULL;
4422    }
4423   
4424    service_name_length = p_service->i_service_name_length = p_desc[4+provider_name_length];
4425    if (service_name_length)
4426    {
4427        p_service->p_service_name = (DS_U8 *)memChainAlloc(memId, service_name_length+1);
4428        memcpy( p_service->p_service_name, &p_desc[5+provider_name_length], service_name_length );
4429        p_service->p_service_name[service_name_length] = '\0';
4430    }
4431    else
4432    {
4433        p_service->p_service_name = (DS_U8 *)NULL;
4434    }
4435   
4436    *pp_service_desc = p_service;
4437   
4438    return;
4439}
4440
4441void DHL_PSI_ParseShortEventDescriptor(DS_U8 *p_desc, memId_t memId, DS_U32 prefLangCode, dvb_short_event_descriptor_t **pp_short_event)
4442{
4443    dvb_short_event_descriptor_t *p_short_event;
4444    int event_name_length, text_length;
4445    DS_U32 ISO_639_language_code;
4446   
4447    if (!p_desc || !pp_short_event)
4448        return;
4449   
4450    if (p_desc[0] != DVB_TAG_short_event_descriptor || p_desc[1] < 5)
4451    {
4452        printf("%s: invalid tag or length, tag: 0x%x, length: 0x%x\n", __func__, p_desc[0], p_desc[1]);
4453        return;
4454    }
4455   
4456    ISO_639_language_code = (p_desc[2]<<16) + (p_desc[3]<<8) + p_desc[4];
4457    if ( prefLangCode && (prefLangCode != ISO_639_language_code) )
4458        return;
4459   
4460    p_short_event = (dvb_short_event_descriptor_t *)memChainAlloc(memId, sizeof(dvb_short_event_descriptor_t));
4461    if ( !p_short_event )
4462        return;
4463
4464    p_short_event->ISO_639_language_code = ISO_639_language_code;
4465    p_short_event->event_name_length = event_name_length = p_desc[5];
4466    p_short_event->p_event_name = (DS_U8 *)NULL;
4467    if (event_name_length)
4468    {
4469        p_short_event->p_event_name = (DS_U8 *)memChainAlloc(memId, event_name_length+1);
4470        SysASSERT(p_short_event->p_event_name);
4471        memcpy( p_short_event->p_event_name, &p_desc[6], event_name_length );
4472        p_short_event->p_event_name[event_name_length] = '\0';
4473    }
4474
4475    p_short_event->text_length = text_length = p_desc[6+event_name_length];
4476    p_short_event->p_text = (DS_U8 *)NULL;
4477    if (text_length)
4478    {
4479        p_short_event->p_text = (DS_U8 *)memChainAlloc(memId, text_length+1);
4480        SysASSERT(p_short_event->p_event_name);
4481        memcpy(p_short_event->p_text, &p_desc[7+event_name_length], text_length);
4482        p_short_event->p_text[text_length] = '\0';
4483    }
4484   
4485    *pp_short_event = p_short_event;
4486
4487    return;
4488}
4489
4490void DHL_PSI_ParseExtendedEventDescriptor(DS_U8 *p_desc, memId_t memId, DS_U32 prefLangCode, dvb_extended_event_descriptor_t **pp_extended_event)
4491{
4492    dvb_extended_event_descriptor_t *p_extended_event;
4493    DS_U32 ISO_639_language_code;
4494    int length_of_items, text_length;
4495    int i, numItems;
4496    DS_U8 *p = (DS_U8 *)NULL;
4497   
4498    if (!p_desc || !pp_extended_event)
4499        return;
4500   
4501    if (p_desc[0] != DVB_TAG_extended_event_descriptor || p_desc[1] < 6)
4502    {
4503        printf("%s: invalid tag or length, tag: 0x%x, length: 0x%x\n", __func__, p_desc[0], p_desc[1]);
4504        return;
4505    }
4506   
4507    ISO_639_language_code = (p_desc[3]<<16) + (p_desc[4]<<8) + (p_desc[5]);
4508    if ( prefLangCode && (prefLangCode != p_extended_event->ISO_639_language_code) )
4509        return;
4510   
4511    p_extended_event = (dvb_extended_event_descriptor_t *)memChainAlloc(memId, sizeof(dvb_extended_event_descriptor_t));
4512    if (!p_extended_event)
4513        return;
4514   
4515    p_extended_event->descriptor_number = (p_desc[2]>>4) & 0x0F;
4516    p_extended_event->last_descriptor_number = (p_desc[2]) & 0x0F;
4517    p_extended_event->ISO_639_language_code = ISO_639_language_code;
4518   
4519    length_of_items = p_desc[6];
4520    p_extended_event->numItems = 0;
4521    p_extended_event->items = (dvb_ext_event_item_t *)NULL;
4522   
4523    if (length_of_items)
4524    {
4525        int item_description_length;
4526        int item_length;
4527        dvb_ext_event_item_t *p_item;
4528       
4529        /*
4530         * Calculate number of items.
4531         */
4532        numItems = 0;
4533       
4534        p = &p_desc[7];
4535        for(i=0; i<length_of_items; /* i is incremented in the loop */)
4536        {
4537            item_description_length = p[i+0];
4538            item_length = p[i+item_description_length+1];
4539           
4540            i += item_description_length+item_length+2;
4541            numItems++;
4542        }
4543       
4544        p_extended_event->numItems = numItems;
4545        p_item = p_extended_event->items = (dvb_ext_event_item_t *)memChainAlloc(memId, sizeof(dvb_ext_event_item_t)*numItems);
4546        for(i=0; i<length_of_items; /* i is incremented in the loop */)
4547        {
4548            item_description_length = p[i+0];
4549            item_length = p[i+item_description_length+1];
4550           
4551            p_item->item_description_length = item_description_length;
4552            if (item_description_length)
4553            {
4554                p_item->p_item_description = (DS_U8 *)memChainAlloc(memId, item_description_length+1);
4555                memcpy(p_item->p_item_description, &p[i+1], item_description_length);
4556                p_item->p_item_description[item_description_length] = '\0';
4557            }
4558           
4559            p_item->item_length = item_length;
4560            if (item_length)
4561            {
4562                p_item->p_item_char = (DS_U8 *)memChainAlloc(memId, item_length+1);
4563                memcpy(p_item->p_item_char, &p[i+2+item_description_length], item_length);
4564                p_item->p_item_char[item_length] = '\0';
4565            }
4566                       
4567            i += item_description_length+item_length+2;
4568            p_item++;
4569        }
4570    }
4571   
4572    text_length = p_desc[7+length_of_items];
4573    p_extended_event->text_length = text_length;
4574    p_extended_event->p_text = (DS_U8 *)NULL;
4575    if (text_length)
4576    {
4577        p_extended_event->p_text = (DS_U8 *)memChainAlloc(memId, text_length);
4578        memcpy(p_extended_event->p_text, &p_desc[8+length_of_items], text_length);
4579    }
4580   
4581    *pp_extended_event = p_extended_event;
4582    return;
4583}
4584
4585void DHL_PSI_ParseParentalRatingDescriptor (DS_U8* p, dvb_parental_rating_descriptor_t **pp_desc)
4586{
4587        memId_t                     memId;
4588        memChainSetup_t         memSetup = {MEM_LIMIT,NULL,NULL};
4589        DS_U8                           length;
4590        DHL_RESULT                      err;
4591    dvb_parental_rating_descriptor_t *p_desc;
4592    dvb_parental_rating_entry_t *p_entry;
4593    int i, numEntries;
4594    DS_U8               *p_data;
4595   
4596        length = p[1];
4597   
4598        /* create the memChain */
4599        err = memChainCreate(&memId, &memSetup);
4600        if (err != DHL_OK)
4601                goto ParseDescriptorExit;
4602
4603        /* create the descriptor memory */
4604        p_desc = (dvb_parental_rating_descriptor_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_parental_rating_descriptor_t)+sizeof(memId_t))) + 1);
4605        if (p_desc == (dvb_parental_rating_descriptor_t *)NULL) 
4606        {
4607                err = DHL_FAIL_OUT_OF_RESOURCE;
4608                goto ParseDescriptorExit;
4609        }
4610   
4611    numEntries = length>>2;
4612    if (numEntries<=0)
4613        goto ParseDescriptorExit;
4614   
4615    p_entry = (dvb_parental_rating_entry_t *)memChainAlloc(memId, sizeof(dvb_parental_rating_entry_t)*numEntries);
4616    if (p_entry == (dvb_parental_rating_entry_t *)NULL) 
4617    {
4618                err = DHL_FAIL_OUT_OF_RESOURCE;
4619                goto ParseDescriptorExit;
4620        }
4621        p_desc->i_num_ratings = numEntries;
4622    p_desc->p_ratings = p_entry;
4623   
4624    p_data = &p[2];
4625    for (i=0; i<numEntries; i++)
4626    {
4627        p_entry->country_code = (p_data[0]<<16) + (p_data[1]<<8) + (p_data[2]<<0);
4628        p_entry->rating_value = p_data[3];
4629        p_data += 4;
4630        p_entry++;
4631    }
4632   
4633        *(((memId_t *)(p_desc))-1) = memId;
4634        memId = NULL;           /* so memChain not deleted */
4635    *pp_desc = p_desc;
4636   
4637ParseDescriptorExit:
4638        if (memId) {
4639                /* delete the descriptor memory */
4640                memChainDestroy(memId);
4641        }
4642       
4643        if (err)
4644        {
4645            printf("ERROR: %s returns %d!\n", __func__, err);
4646        }
4647}
4648
4649static void DHL_PSI_ParseParentalRatingDescriptorEx (DS_U8* p, memId_t memId, dvb_parental_rating_descriptor_t **pp_desc)
4650{
4651        //memId_t                           memId;
4652        //memChainSetup_t               memSetup = {MEM_LIMIT,NULL,NULL};
4653        DS_U8                           length;
4654        DHL_RESULT                      err=DHL_OK;
4655    dvb_parental_rating_descriptor_t *p_desc;
4656    dvb_parental_rating_entry_t *p_entry;
4657    int i, numEntries;
4658    DS_U8               *p_data;
4659   
4660        length = p[1];
4661   
4662#if 0
4663        /* create the memChain */
4664        err = memChainCreate(&memId, &memSetup);
4665        if (err != DHL_OK)
4666                goto ParseDescriptorExit;
4667#endif
4668
4669        /* create the descriptor memory */
4670        p_desc = (dvb_parental_rating_descriptor_t *)(memChainAlloc(memId,sizeof(dvb_parental_rating_descriptor_t)));
4671        if (p_desc == (dvb_parental_rating_descriptor_t *)NULL) 
4672        {
4673                err = DHL_FAIL_OUT_OF_RESOURCE;
4674                goto ParseDescriptorExit;
4675        }
4676   
4677    numEntries = length>>2;
4678    if (numEntries<=0)
4679        goto ParseDescriptorExit;
4680   
4681    p_entry = (dvb_parental_rating_entry_t *)memChainAlloc(memId, sizeof(dvb_parental_rating_entry_t)*numEntries);
4682    if (p_entry == (dvb_parental_rating_entry_t *)NULL) 
4683    {
4684                err = DHL_FAIL_OUT_OF_RESOURCE;
4685                goto ParseDescriptorExit;
4686        }
4687        p_desc->i_num_ratings = numEntries;
4688    p_desc->p_ratings = p_entry;
4689   
4690    p_data = &p[2];
4691    for (i=0; i<numEntries; i++)
4692    {
4693        p_entry->country_code = (p_data[0]<<16) + (p_data[1]<<8) + (p_data[2]<<0);
4694        p_entry->rating_value = p_data[3];
4695        p_data += 4;
4696        p_entry++;
4697    }
4698   
4699        *(((memId_t *)(p_desc))-1) = memId;
4700        memId = NULL;           /* so memChain not deleted */
4701    *pp_desc = p_desc;
4702   
4703ParseDescriptorExit:
4704        if (memId) {
4705                /* delete the descriptor memory */
4706                memChainDestroy(memId);
4707        }
4708       
4709        if (err)
4710        {
4711            printf("ERROR: %s returns %d!\n", __func__, err);
4712        }
4713}
4714
4715void DHL_PSI_ParseLocalTimeOffsetDescriptor( DS_U8 *p, int numItems, dvb_local_time_t *p_desc )
4716{
4717    int len, idx;
4718    int num_lto;
4719    dvb_local_time_t *p_lt;
4720    DS_U8 *puc;
4721   
4722    if ( !p || !p_desc )
4723        return;
4724   
4725    len = p[1];
4726    num_lto = len / 13;
4727   
4728    p_lt = p_desc;
4729    for (idx=0; idx<num_lto; idx++)
4730    {
4731        puc = &p[idx*13 + 2];
4732       
4733        p_lt->country_code = (puc[2]<<16)+(puc[1]<<8)+puc[0];
4734        p_lt->country_region_id = puc[3]>>2;
4735        p_lt->local_time_offset_polarity = puc[3] & 1;
4736        p_lt->local_time_offset = (puc[4]<<8)+puc[5];
4737        p_lt->time_of_change_date = (puc[6]<<8)+puc[7];
4738        p_lt->time_of_change_time = (puc[8]<<16)+(puc[9]<<8)+puc[10];
4739        p_lt->next_time_offset = (puc[11]<<8)+puc[12];
4740       
4741        p_lt++;
4742    }
4743}
4744
4745static int DHL_PSI_ParseTSInformationDescriptor(DS_U8* p, memId_t memId, arib_ts_information_descriptor_t **pp_ts_info)
4746{
4747    int len, i, j, off;
4748    int err = DHL_OK;
4749    arib_ts_information_descriptor_t *p_ts_info;
4750   
4751    len = p[1];
4752    if (len < 2)
4753        return DHL_FAIL_INVALID_SIZE;
4754   
4755    p_ts_info = (arib_ts_information_descriptor_t *)memChainAlloc(memId,sizeof(arib_ts_information_descriptor_t));
4756        if (p_ts_info == (arib_ts_information_descriptor_t *)NULL) 
4757        {
4758                err = DHL_FAIL_OUT_OF_RESOURCE;
4759                goto ParseDescriptorExit;
4760        }
4761   
4762    p_ts_info->remote_control_key_id = p[2];
4763    p_ts_info->ts_name_length = (p[3]>>2) & 0x3F;
4764    p_ts_info->transmission_type_count = p[3]&0x03;
4765   
4766    p_ts_info->ts_name = (DS_U8 *)NULL;
4767    if (p_ts_info->ts_name_length)
4768    {
4769        p_ts_info->ts_name = (DS_U8 *)memChainAlloc(memId, p_ts_info->ts_name_length+1);
4770        for (i=0; i<p_ts_info->ts_name_length; i++)
4771            p_ts_info->ts_name[i] = p[4+i];
4772        p_ts_info->ts_name[i] = '\0';
4773    }
4774    off = 4+p_ts_info->ts_name_length;
4775   
4776    p_ts_info->transmission_type = (arib_transmission_type_t *)NULL;
4777    if (p_ts_info->transmission_type_count)
4778    {
4779        arib_transmission_type_t *p_tx_type;
4780       
4781        p_tx_type = p_ts_info->transmission_type = (arib_transmission_type_t *)memChainAlloc(memId, sizeof(arib_transmission_type_t)*p_ts_info->transmission_type_count);
4782        if (p_tx_type == (arib_transmission_type_t *)NULL)
4783        {
4784                err = DHL_FAIL_OUT_OF_RESOURCE;
4785                goto ParseDescriptorExit;
4786        }
4787
4788        for (i=0; i<p_ts_info->transmission_type_count; i++)
4789        {
4790            p_tx_type->transmission_type_info = p[off];
4791            p_tx_type->number_of_service = p[off+1];
4792            p_tx_type->service_id = (DS_U16 *)NULL;
4793           
4794            off += 2;
4795            if (p_tx_type->number_of_service)
4796            {
4797                DS_U16 *p_service_id;
4798               
4799                p_service_id = p_tx_type->service_id = (DS_U16 *)memChainAlloc(memId, (p_tx_type->number_of_service) * sizeof(DS_U16));
4800                if (p_service_id == (DS_U16 *)NULL)
4801                {
4802                        err = DHL_FAIL_OUT_OF_RESOURCE;
4803                        goto ParseDescriptorExit;
4804                }
4805               
4806                for (j=0; j<p_tx_type->number_of_service; j++)
4807                {
4808                    *p_service_id = (p[off]<<8)+p[off+1];
4809                    p_service_id++;
4810                    off += 2;
4811                }
4812            }
4813            p_tx_type++;
4814        }
4815    }
4816   
4817    *pp_ts_info = p_ts_info;
4818   
4819ParseDescriptorExit:
4820    return err;
4821}
4822
4823static int DHL_PSI_ParseSystemManagementDescriptor(DS_U8* p, DS_U16* p_system_management_id)
4824{
4825    int len;
4826    DS_U16 system_mgmt_id;
4827   
4828    if (!p_system_management_id || !p)
4829        return -1;
4830       
4831    len = p[1];
4832    if (len<2)
4833        return -1;
4834   
4835    system_mgmt_id = (p[2]<<8) + p[3];
4836    *p_system_management_id = system_mgmt_id;
4837
4838    return 0;   
4839}
4840
4841void DHL_PSI_ParseBouquetNameDescriptor(DS_U8 *p_desc, memId_t memId, DS_U8 **pp_bouquet_name, DS_U8 *p_length)
4842{
4843    int len;
4844    DS_U8 *p_bouquet_name;
4845   
4846    if ( !p_desc || !p_bouquet_name || !p_length )
4847        return;
4848   
4849    len = p_desc[1];
4850    p_bouquet_name = (DS_U8 *)memChainAlloc( memId, len+1 );
4851    memcpy(p_bouquet_name, &p_desc[2], len );
4852    p_bouquet_name[len] = '\0';
4853   
4854    *pp_bouquet_name = p_bouquet_name;
4855   
4856    return;
4857}
4858
4859void DHL_PSI_ParseHierarchicalTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_hierarchical_transmission_descriptor_t **pp_hierarchical_transmission )
4860{
4861        int len;
4862        int err = DHL_OK;
4863        arib_hierarchical_transmission_descriptor_t *p_hierarchical_transmission;
4864
4865        len = p[1];
4866
4867        p_hierarchical_transmission = (arib_hierarchical_transmission_descriptor_t *)memChainAlloc(memId, sizeof(arib_hierarchical_transmission_descriptor_t));
4868
4869        if ( p_hierarchical_transmission == (arib_hierarchical_transmission_descriptor_t *)NULL )
4870        {
4871                err = DHL_FAIL_OUT_OF_RESOURCE;
4872                goto ParseDescriptorExit;
4873        }
4874
4875        if ( len < 3 )
4876        {
4877                return; // DHL_FAIL_OUT_OF_RESOURCE;
4878        }
4879
4880        p_hierarchical_transmission->quality_level = ( p[2] & 0x01 );
4881        p_hierarchical_transmission->reference_PID = (( p[3] << 8 ) + p[4] ) & 0x1FFF;
4882
4883        *pp_hierarchical_transmission = p_hierarchical_transmission;
4884
4885ParseDescriptorExit:
4886        if ( err )
4887        {
4888                printf("ERROR: %s returns %d!\n", __func__, err);
4889        }
4890        //      return err;
4891}
4892
4893void DHL_PSI_ParseDigitalCopyControlDescriptor(DS_U8* p, memId_t memId, arib_digital_copy_control_descriptor_t **pp_digital_copy_control)
4894{
4895    int i, len, component_control_length;
4896//      DS_U8 maximum_bitrate;
4897        DS_U8 maximum_bitrate_flag, component_control_flag;
4898    int err = DHL_OK;
4899    arib_digital_copy_control_descriptor_t *p_digital_copy_control;
4900   
4901    len = p[1];
4902    if ( len < 1 )
4903        return; // DHL_FAIL_INVALID_SIZE;
4904   
4905    p_digital_copy_control = (arib_digital_copy_control_descriptor_t *)memChainAlloc(memId,sizeof(arib_digital_copy_control_descriptor_t));
4906
4907        if (p_digital_copy_control == (arib_digital_copy_control_descriptor_t *)NULL) 
4908        {
4909                err = DHL_FAIL_OUT_OF_RESOURCE;
4910                goto ParseDescriptorExit;
4911        }
4912   
4913    p_digital_copy_control->digital_recording_control_data = ( p[2] & 0xC0 ) >> 6;
4914        maximum_bitrate_flag = ( p[2] & 0x20 ) >> 5;
4915        component_control_flag = ( p[2] & 0x10 ) >> 4;
4916        p_digital_copy_control->copy_control_type = ( p[2] & 0xC ) >> 2;
4917
4918        if ( p_digital_copy_control->copy_control_type != 0 )
4919        {
4920                p_digital_copy_control->APS_control_data = p[2] & 0x2;
4921        }
4922
4923        if ( maximum_bitrate_flag == 1 )
4924        {
4925                p_digital_copy_control->maximum_bitrate = p[3];
4926        }
4927
4928        if ( component_control_flag == 1 )
4929        {
4930                arib_component_control_t *p_component_control;
4931
4932                p_digital_copy_control->component_control = (arib_component_control_t *)NULL;
4933                p_component_control = p_digital_copy_control->component_control = (arib_component_control_t *)memChainAlloc(memId, sizeof(arib_component_control_t));
4934
4935                if ( p_component_control == (arib_component_control_t *)NULL )
4936                {
4937                        err = DHL_FAIL_OUT_OF_RESOURCE;
4938                        goto ParseDescriptorExit;
4939                }
4940
4941                component_control_length = p[4];
4942
4943                for ( i = 0 ; i < component_control_length ; i++ )
4944                {
4945                        p_component_control->component_tag = p[5+i];
4946                        p_component_control->component_digital_recording_control_data = ( p[6+i] & 0xC0 ) >> 6;
4947                        maximum_bitrate_flag = ( p[6+i] & 0x20 ) >> 5;
4948                        p_component_control->component_copy_control_type = ( p[6+i] & 0xC ) >>2;
4949
4950                        if ( p_component_control->component_copy_control_type != 0 )
4951                        {
4952                                p_component_control->component_APS_control_data = p[6+i] & 0x2;
4953                        }
4954
4955                        if ( maximum_bitrate_flag == 1 )
4956                        {
4957                                p_component_control->component_maximum_bitrate = p[7+i];
4958                                i = i+3;
4959                        }
4960                        else
4961                        {
4962                                i = i+2;
4963                        }
4964
4965                        p_component_control++;
4966                }
4967        }
4968
4969        *pp_digital_copy_control = p_digital_copy_control;
4970
4971ParseDescriptorExit:
4972        if ( err )
4973        {
4974                printf("ERROR: %s returns %d!\n", __func__, err);
4975        }
4976}
4977
4978void DHL_PSI_ParseNetworkIdentificationDescriptor( DS_U8 *p, memId_t memId, arib_network_identification_descriptor_t **pp_network_identification )
4979{
4980        int i, len;
4981        DS_U8 count;
4982        DHL_RESULT      err;
4983        arib_network_identification_descriptor_t *p_network_identification;
4984
4985        len = p[1];
4986
4987        if ( len <      7 )
4988                return;
4989
4990        p_network_identification = (arib_network_identification_descriptor_t *)memChainAlloc(memId, sizeof(arib_network_identification_descriptor_t));
4991
4992        if ( p_network_identification == (arib_network_identification_descriptor_t *)NULL )
4993        {
4994                err = DHL_FAIL_OUT_OF_RESOURCE;
4995                goto ParseDescriptorExit;
4996        }
4997
4998        p_network_identification->Country_code = ( p[2] << 16 ) + ( p[3] << 8 ) + p[4];
4999        p_network_identification->media_type = ( p[5] << 8 ) + p[6];
5000        p_network_identification->Network_id = ( p[7] << 8 ) + p[8];
5001
5002        count = len - 9;
5003
5004        if ( count > 9 )
5005        {
5006                DS_U8 *p_private_data;
5007
5008                p_private_data = p_network_identification->private_data = (DS_U8 *)memChainAlloc( memId, len-9 );
5009
5010                if ( p_private_data == (DS_U8 *)NULL )
5011                {
5012                        err = DHL_FAIL_OUT_OF_RESOURCE;
5013                        goto ParseDescriptorExit;
5014                }       
5015       
5016                for ( i = 0 ; i < count ; i++ )
5017                {
5018                        *p_private_data = (p[i+10]);
5019                        p_private_data++;
5020                }
5021        }
5022
5023        *pp_network_identification = p_network_identification;
5024
5025ParseDescriptorExit:
5026        if ( err )
5027        {
5028                printf("ERROR: %s returns %d!\n", __func__, err);
5029        }
5030}
5031
5032void DHL_PSI_ParsePartialTSTimeDescriptor( DS_U8 *p, memId_t memId, arib_partialTS_time_descriptor_t **pp_partialTS_time )
5033{
5034        int len;
5035        DHL_RESULT err;
5036        arib_partialTS_time_descriptor_t *p_partialTS_time;
5037
5038        len = p[1];
5039
5040        if ( len < 13 )
5041                return;
5042
5043        p_partialTS_time = (arib_partialTS_time_descriptor_t *)memChainAlloc(memId, sizeof(arib_partialTS_time_descriptor_t));
5044
5045        if ( p_partialTS_time == (arib_partialTS_time_descriptor_t *)NULL )
5046        {
5047                err = DHL_FAIL_OUT_OF_RESOURCE;
5048                goto ParseDescriptorExit;
5049        }
5050
5051        p_partialTS_time->Event_version_number = p[2];
5052        p_partialTS_time->Event_start_time = (( p[3] << 24 ) << 8 ) + ( p[4] << 24 ) + ( p[5] << 16 ) + ( p[6] << 8 ) + p[7];
5053        p_partialTS_time->Duration = ( p[8] << 16 ) + ( p[9] << 8 ) + p[10];
5054        p_partialTS_time->Offset = ( p[11] << 16 ) + ( p[12] << 8 ) + p[13];
5055        p_partialTS_time->Offset_flag = ( p[14] & 0x4 ) >> 2;
5056        p_partialTS_time->Other_descriptor_status = ( p[14] & 0x2 ) >> 1;
5057        p_partialTS_time->JST_time_flag = p[14] & 0x1;
5058
5059        if ( p_partialTS_time->JST_time_flag  == 1 )
5060        {
5061                p_partialTS_time->JST_time = (( p[15] << 24 ) << 8 ) + ( p[16] << 24 ) + ( p[17] << 16 ) + ( p[18] << 8 ) + p[19];
5062        }
5063
5064        *pp_partialTS_time = p_partialTS_time;
5065
5066ParseDescriptorExit:
5067        if ( err )
5068        {
5069                printf("ERROR: %s returns %d!\n", __func__, err);
5070        }
5071}
5072
5073void DHL_PSI_ParseAudioComponentDescriptor( DS_U8 *p, memId_t memId, arib_audio_component_descriptor_t **pp_audio_component )
5074{
5075        int i, len;
5076        DS_U8 count;
5077        DHL_RESULT err=0;
5078        arib_audio_component_descriptor_t *p_audio_component;
5079
5080        len = p[1];
5081
5082        if ( len < 8 )
5083                return;
5084
5085        p_audio_component = (arib_audio_component_descriptor_t *)memChainAlloc(memId, sizeof(arib_audio_component_descriptor_t));
5086
5087        if ( p_audio_component == (arib_audio_component_descriptor_t *)NULL )
5088        {
5089                err = DHL_FAIL_OUT_OF_RESOURCE;
5090                goto ParseDescriptorExit;
5091        }
5092
5093        p_audio_component->stream_content = ( p[2] & 0xF );
5094        p_audio_component->component_type = p[3];
5095        p_audio_component->component_tag = p[4];
5096        p_audio_component->stream_type = p[5];
5097        p_audio_component->simulcast_group_tag = p[6];
5098        p_audio_component->ES_multi_lingual_flag = ( p[7] & 0x80 ) >> 7;
5099        p_audio_component->main_component_flag = ( p[7] & 0x40 ) >> 6;
5100        p_audio_component->quality_indicator = ( p[7] & 0x30 ) >> 4;
5101        p_audio_component->sampling_rate = ( p[7] & 0xE ) >> 1;
5102        p_audio_component->ISO_639_language_code = ( p[8] << 16 ) + ( p[9] << 8 ) + p[10];
5103
5104        if ( p_audio_component->ES_multi_lingual_flag == 1 )
5105        {
5106        //      DS_U8 *p_text_char;
5107
5108                p_audio_component->ISO_639_language_code_2 = ( p[11] << 16 ) + ( p[12] << 8 ) + p[13];
5109                count = len - 12;
5110                p_audio_component->text_char = (DS_U8 *)memChainAlloc( memId, count+1 );
5111
5112                if ( p_audio_component->text_char == (DS_U8 *)NULL )
5113                {
5114                        err = DHL_FAIL_OUT_OF_RESOURCE;
5115                        goto ParseDescriptorExit;
5116                }       
5117
5118                for ( i = 0 ; i < count ; i++ )
5119                {
5120                        p_audio_component->text_char[i] = (p[i+14]);
5121                }
5122
5123                p_audio_component->text_char[i] = '\0';
5124        }
5125        else
5126        {
5127                count = len - 9;
5128                p_audio_component->text_char = (DS_U8 *)memChainAlloc( memId, count+1 );
5129
5130                if ( p_audio_component->text_char == (DS_U8 *)NULL )
5131                {
5132                        err = DHL_FAIL_OUT_OF_RESOURCE;
5133                        goto ParseDescriptorExit;
5134                }       
5135
5136                for ( i = 0 ; i < count ; i++ )
5137                {
5138                        p_audio_component->text_char[i] = (p[i+11]);
5139                }
5140
5141                p_audio_component->text_char[i] = '\0';
5142        }
5143
5144        *pp_audio_component = p_audio_component;
5145
5146ParseDescriptorExit:
5147        if ( err )
5148        {
5149                printf("ERROR: %s returns %d!\n", __func__, err);
5150        }
5151}
5152
5153void DHL_PSI_ParseHyperlinkDescriptor( DS_U8 *p, memId_t memId, arib_hyperlink_descriptor_t **pp_hyperlink )
5154{
5155        int i, j, k, len;
5156        DS_U8 count;
5157        DHL_RESULT err;
5158        arib_hyperlink_descriptor_t *p_hyperlink;
5159
5160        len = p[1];
5161
5162        if ( len < 2 )
5163                return;
5164
5165        p_hyperlink = (arib_hyperlink_descriptor_t *)memChainAlloc(memId, sizeof(arib_hyperlink_descriptor_t));
5166
5167        if ( p_hyperlink == (arib_hyperlink_descriptor_t *)NULL )
5168        {
5169                err = DHL_FAIL_OUT_OF_RESOURCE;
5170                goto ParseDescriptorExit;
5171        }
5172
5173        p_hyperlink->hyper_linkage_type = p[2];
5174        p_hyperlink->link_destination_type = p[3];
5175        p_hyperlink->selector_length = p[4];
5176
5177        if ( p_hyperlink->selector_length > 0 )
5178        {
5179                DS_U8 *p_selector_byte;
5180                DS_U8 *p_private_data;
5181
5182                p_selector_byte = p_hyperlink->selector_byte = (DS_U8 *)memChainAlloc( memId, p_hyperlink->selector_length);
5183
5184                if ( p_selector_byte == (DS_U8 *)NULL )
5185                {
5186                        err = DHL_FAIL_OUT_OF_RESOURCE;
5187                        goto ParseDescriptorExit;
5188                }
5189
5190                for ( i = 0 ; i < p_hyperlink->selector_length ; i++ )
5191                {
5192                        *p_selector_byte = (p[i+5]);
5193                        p_selector_byte++;
5194                }
5195
5196                count = len - ( 4 + i );
5197
5198                p_private_data = p_hyperlink->private_data = (DS_U8 *)memChainAlloc( memId, count );
5199
5200                if ( p_private_data == (DS_U8 *)NULL )
5201                {
5202                        err = DHL_FAIL_OUT_OF_RESOURCE;
5203                        goto ParseDescriptorExit;
5204                }
5205
5206                for ( j = 0 ; j < count ; j++ )
5207                {
5208                        *p_private_data = (p[i+j+6]);
5209                        p_private_data++;
5210                }
5211        }
5212        else
5213        {
5214                DS_U8 *p_private_data;
5215
5216                count = len - 3;
5217                p_private_data = p_hyperlink->private_data = (DS_U8 *)memChainAlloc( memId, count );
5218
5219                if ( p_private_data == (DS_U8 *)NULL )
5220                {
5221                        err = DHL_FAIL_OUT_OF_RESOURCE;
5222                        goto ParseDescriptorExit;
5223                }
5224
5225                for ( k = 0 ; k < count ; k++ )
5226                {
5227                        *p_private_data = (p[k+5]);
5228                        p_private_data++;
5229                }
5230        }
5231
5232        *pp_hyperlink = p_hyperlink;
5233       
5234ParseDescriptorExit:
5235        if ( err )
5236        {
5237                printf("ERROR: %s returns %d!\n", __func__, err);
5238        }
5239}
5240
5241void DHL_PSI_ParseTargetRegionDescriptor( DS_U8 *p, memId_t memId, arib_target_region_descriptor_t **pp_target_region )
5242{
5243        int i, len;
5244        DS_U8 count;
5245        DHL_RESULT err;
5246        arib_target_region_descriptor_t *p_target_region;
5247
5248        len = p[1];
5249
5250        if ( len < 0 )
5251                return;
5252
5253        p_target_region = (arib_target_region_descriptor_t *)memChainAlloc(memId, sizeof(arib_target_region_descriptor_t));
5254
5255        if ( p_target_region == (arib_target_region_descriptor_t *)NULL )
5256        {
5257                err = DHL_FAIL_OUT_OF_RESOURCE;
5258                goto ParseDescriptorExit;
5259        }
5260
5261        p_target_region->region_spec_type = p[2];
5262
5263        count = len - 1;
5264
5265        if ( count > 0 )
5266        {
5267                DS_U8 *p_target_region_spec;
5268
5269                p_target_region_spec = p_target_region->target_region_spec = (DS_U8 *)memChainAlloc( memId, count );
5270
5271                if ( p_target_region_spec == (DS_U8 *)NULL )
5272                {
5273                        err = DHL_FAIL_OUT_OF_RESOURCE;
5274                        goto ParseDescriptorExit;
5275                }
5276
5277                for ( i = 0 ; i < count ; i++ )
5278                {
5279                        *p_target_region_spec = p[i+3];
5280                        p_target_region_spec++;
5281                }
5282        }
5283
5284        *pp_target_region = p_target_region;
5285
5286ParseDescriptorExit:
5287        if ( err )
5288        {
5289                printf("ERROR: %s returns %d!\n", __func__, err);
5290        }
5291}
5292
5293void DHL_PSI_ParseDataContentDescriptor( DS_U8 *p, memId_t memId, arib_data_content_descriptor_t **pp_data_content )
5294{
5295        int i=0, j=0, k=0, len;
5296        DHL_RESULT err=0;
5297        arib_data_content_descriptor_t *p_data_content;
5298
5299        len = p[1];
5300
5301        if ( len < 8 )
5302                return;
5303
5304        p_data_content = (arib_data_content_descriptor_t *)memChainAlloc(memId, sizeof(arib_data_content_descriptor_t));
5305
5306        if ( p_data_content == (arib_data_content_descriptor_t *)NULL )
5307        {
5308                err = DHL_FAIL_OUT_OF_RESOURCE;
5309                goto ParseDescriptorExit;
5310        }
5311
5312        p_data_content->data_component_id = ( p[2] << 8 ) + p[3];
5313        p_data_content->entry_component = p[4];
5314        p_data_content->selector_length = p[5];
5315
5316        if ( p_data_content->selector_length > 0 )
5317        {
5318                DS_U8 *p_selector_byte;
5319
5320                p_selector_byte = p_data_content->selector_byte = (DS_U8 *)memChainAlloc( memId, p_data_content->selector_length );
5321
5322                if ( p_selector_byte == (DS_U8 *)NULL )
5323                {
5324                        err = DHL_FAIL_OUT_OF_RESOURCE;
5325                        goto ParseDescriptorExit;
5326                }
5327
5328                for ( i = 0 ; i < p_data_content->selector_length ; i++ )
5329                {
5330                        *p_selector_byte = p[i+6];
5331                        p_selector_byte++;
5332                }
5333        }
5334
5335        p_data_content->num_of_component_ref = p[i+6];
5336
5337        if ( p_data_content->num_of_component_ref > 0 )
5338        {
5339                DS_U8 *p_component_ref;
5340
5341                p_component_ref = p_data_content->component_ref = (DS_U8 *)memChainAlloc( memId, p_data_content->num_of_component_ref );
5342
5343                if ( p_component_ref == (DS_U8 *)NULL )
5344                {
5345                        err = DHL_FAIL_OUT_OF_RESOURCE;
5346                        goto ParseDescriptorExit;
5347                }
5348
5349                for ( j = 0 ; j < p_data_content->num_of_component_ref ; j++ )
5350                {
5351                        *p_component_ref = p[i+j+7];
5352                        p_component_ref++;
5353                }
5354        }
5355
5356        p_data_content->ISO_639_language_code = ( p[i+j+7] << 16 ) + ( p[i+j+8] << 8 ) + p[i+j+9];
5357        p_data_content->text_length = p[i+j+10];
5358
5359        if ( p_data_content->text_length > 0 )
5360        {
5361                p_data_content->text_char = (DS_U8 *)memChainAlloc( memId, p_data_content->text_length+1 );
5362
5363                if ( p_data_content->text_char == (DS_U8 *)NULL )
5364                {
5365                        err = DHL_FAIL_OUT_OF_RESOURCE;
5366                        goto ParseDescriptorExit;
5367                }
5368
5369                for ( k = 0 ; k < p_data_content->text_length ; k++ )
5370                {
5371                        p_data_content->text_char[k] = p[i+j+k+11];
5372                }
5373
5374                p_data_content->text_char[k] = '\0';
5375        }
5376
5377        *pp_data_content = p_data_content;
5378
5379ParseDescriptorExit:
5380        if ( err )
5381        {
5382                printf("ERROR: %s returns %d!\n", __func__, err);
5383        }
5384}
5385
5386void DHL_PSI_ParseVideoDecodeControlDescriptor( DS_U8 *p, memId_t memId, arib_video_decode_control_descriptor_t **pp_video_decode_control )
5387{
5388        int len;
5389        DHL_RESULT err;
5390        arib_video_decode_control_descriptor_t *p_video_decode_control;
5391
5392        len = p[1];
5393
5394        if ( len < 0 )
5395                return;
5396
5397        p_video_decode_control = (arib_video_decode_control_descriptor_t *)memChainAlloc(memId, sizeof(arib_video_decode_control_descriptor_t));
5398
5399        if ( p_video_decode_control == (arib_video_decode_control_descriptor_t *)NULL )
5400        {
5401                err = DHL_FAIL_OUT_OF_RESOURCE;
5402                goto ParseDescriptorExit;
5403        }
5404
5405        p_video_decode_control->still_picture_flag = ( p[2] & 0x80 ) >> 7;
5406        p_video_decode_control->sequence_end_code_flag = ( p[2] & 0x40 ) >> 6;
5407        p_video_decode_control->video_encode_format = ( p[2] & 0x3C ) >> 2;
5408
5409        *pp_video_decode_control = p_video_decode_control;
5410
5411ParseDescriptorExit:
5412        if ( err )
5413        {
5414                printf("ERROR: %s returns %d!\n", __func__, err);
5415        }
5416}
5417
5418void DHL_PSI_ParseLogoTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_logo_transmission_descriptor_t **pp_logo_transmission )
5419{
5420        int i, len;
5421        DS_U8 logo_char_length;
5422        DHL_RESULT err=DHL_OK;
5423        arib_logo_transmission_descriptor_t *p_logo_transmission;
5424
5425        len = p[1];
5426
5427        if ( len < 2 )
5428                return;
5429
5430        p_logo_transmission = (arib_logo_transmission_descriptor_t *)memChainAlloc(memId, sizeof(arib_logo_transmission_descriptor_t));
5431
5432        if ( p_logo_transmission == (arib_logo_transmission_descriptor_t *)NULL )
5433        {
5434                err = DHL_FAIL_OUT_OF_RESOURCE;
5435                goto ParseDescriptorExit;
5436        }
5437
5438        p_logo_transmission->logo_transmission_type = p[2];
5439
5440        if ( p_logo_transmission->logo_transmission_type == 0x01 )
5441        {
5442                p_logo_transmission->logo_id = (( p[3] & 0x1 ) << 8 ) + p[4];
5443                p_logo_transmission->logo_version = (( p[5] & 0x7 ) << 8 ) + p[6];
5444                p_logo_transmission->download_data_id = ( p[7] << 8 ) + p[8];
5445        }
5446        else if ( p_logo_transmission->logo_transmission_type == 0x02 )
5447        {
5448                p_logo_transmission->logo_id = (( p[3] & 0x1 ) << 8 ) + p[4]; 
5449        }
5450        else if ( p_logo_transmission->logo_transmission_type == 0x03 )
5451        {
5452                logo_char_length = len - 1;
5453
5454                p_logo_transmission->logo_char = (DS_U8 *)memChainAlloc( memId, logo_char_length+1 );
5455
5456                if ( p_logo_transmission->logo_char == (DS_U8 *)NULL )
5457                {
5458                        err = DHL_FAIL_OUT_OF_RESOURCE;
5459                        goto ParseDescriptorExit;
5460                }
5461
5462                for ( i = 0 ; i < logo_char_length ; i++ )
5463                {
5464                        p_logo_transmission->logo_char[i] = p[i+3];
5465                }
5466
5467                p_logo_transmission->logo_char[i] = '\0';
5468        }
5469
5470        *pp_logo_transmission = p_logo_transmission;
5471
5472ParseDescriptorExit:
5473        if ( err )
5474        {
5475                printf("ERROR: %s returns %d!\n", __func__, err);
5476        }
5477}
5478
5479void DHL_PSI_ParseBasicLocalEventDescriptor( DS_U8 *p, memId_t memId, arib_basic_local_event_descriptor_t **pp_basic_local_event )
5480{
5481        int i, len;
5482        int off = 0;
5483        DS_U8 component_tag_length;
5484        DHL_RESULT err;
5485        arib_basic_local_event_descriptor_t *p_basic_local_event;
5486
5487        len = p[1];
5488
5489        if ( len < 1 )
5490                return;
5491
5492        p_basic_local_event = (arib_basic_local_event_descriptor_t *)memChainAlloc(memId, sizeof(arib_basic_local_event_descriptor_t));
5493
5494        if ( p_basic_local_event == (arib_basic_local_event_descriptor_t *)NULL )
5495        {
5496                err = DHL_FAIL_OUT_OF_RESOURCE;
5497                goto ParseDescriptorExit;
5498        }
5499
5500        p_basic_local_event->segmentation_mode = p[2] & 0xF;
5501        p_basic_local_event->segmentation_info_length = p[3];
5502
5503        if ( p_basic_local_event->segmentation_mode == 0x0 )
5504        {
5505                component_tag_length = len - 2;
5506        }
5507        else if ( p_basic_local_event->segmentation_mode == 0x1 )
5508        {
5509                p_basic_local_event->start_time_NPT = ((( p[4] & 0x1 ) << 24 ) << 8 ) + ( p[5] << 24 ) + ( p[6] << 16 ) + ( p[7] << 8 ) + p[8];
5510                p_basic_local_event->end_time_NPT = ((( p[9] & 0x1 ) << 24 ) << 8 ) + ( p[10] << 24 ) + ( p[11] << 16 ) + ( p[12] << 8 ) + p[13];
5511                component_tag_length = len - 12;
5512                off = 14;
5513        }
5514        else if ( p_basic_local_event->segmentation_mode < 0x6 )
5515        {
5516                p_basic_local_event->start_time = ( p[4] << 16 ) + ( p[5] << 8 ) + p[6];
5517                p_basic_local_event->duration = ( p[7] << 16 ) + ( p[8] << 8 ) + p[9];
5518                component_tag_length = len - 8;
5519                off = 10;
5520
5521                if ( p_basic_local_event->segmentation_info_length == 10 )
5522                {
5523                        p_basic_local_event->start_time_extension = ( p[10] << 4 ) + (( p[11] & 0xF0 ) >> 4 );
5524                        p_basic_local_event->duration_extension = ( p[12] << 4 ) + (( p[13] & 0xF0 ) >> 4 );
5525                        component_tag_length = len - 12;
5526                        off = 14;
5527                }
5528        }
5529
5530        if ( component_tag_length > 0 )
5531        {
5532                p_basic_local_event->component_tag = (DS_U8 *)memChainAlloc( memId, component_tag_length );
5533
5534                if ( p_basic_local_event->component_tag == (DS_U8 *)NULL )
5535                {
5536                        err = DHL_FAIL_OUT_OF_RESOURCE;
5537                        goto ParseDescriptorExit;
5538                }
5539
5540                for ( i = 0 ; i < component_tag_length ; i++ )
5541                {
5542                        p_basic_local_event->component_tag[i] = p[i+off];
5543                }
5544        }
5545
5546        *pp_basic_local_event = p_basic_local_event;
5547
5548ParseDescriptorExit:
5549        if ( err )
5550        {
5551                printf("ERROR: %s returns %d!\n", __func__, err);
5552        }
5553}
5554
5555void DHL_PSI_ParseReferenceDescriptor( DS_U8 *p, memId_t memId, arib_reference_descriptor_t **pp_reference )
5556{
5557        int i, len, off;
5558        DS_U8 count  = 0;
5559        DHL_RESULT err;
5560        arib_reference_descriptor_t *p_reference;
5561
5562        len = p[1];
5563
5564        if ( len < 3 )
5565                return;
5566
5567        p_reference = (arib_reference_descriptor_t *)memChainAlloc(memId, sizeof(arib_reference_descriptor_t));
5568
5569        if ( p_reference == (arib_reference_descriptor_t *)NULL )
5570        {
5571                err = DHL_FAIL_OUT_OF_RESOURCE;
5572                goto ParseDescriptorExit;
5573        }
5574
5575        p_reference->information_provider_id = ( p[2] << 8 ) + p[3];
5576        p_reference->event_relation_id = ( p[4] << 8 ) + p[5];
5577
5578        count = len - 4;
5579        off = 6;
5580
5581        if ( count > 0 )
5582        {
5583                arib_reference_node_t *p_reference_node;
5584
5585                p_reference_node = p_reference->reference_node = (arib_reference_node_t *)memChainAlloc(memId, count);
5586
5587                if ( p_reference_node == (arib_reference_node_t *)NULL )
5588                {
5589                        err = DHL_FAIL_OUT_OF_RESOURCE;
5590                        goto ParseDescriptorExit;
5591                }
5592
5593                for ( i = 0 ; i < count ; i++ )
5594                {
5595                        p_reference_node->reference_node_id = p[off];
5596                        p_reference_node->reference_number = p[off+1];
5597                        p_reference_node->last_reference_number = p[off+2];
5598                        off += 3;
5599                        p_reference_node++;
5600                }
5601        }
5602
5603        *pp_reference = p_reference;
5604
5605ParseDescriptorExit:
5606        if ( err )
5607        {
5608                printf("ERROR: %s returns %d!\n", __func__, err);
5609        }
5610}
5611
5612void DHL_PSI_ParseNodeRelationDescriptor( DS_U8 *p, memId_t memId, arib_node_relation_descriptor_t **pp_node_relation )
5613{
5614        int len, off;
5615        DHL_RESULT err;
5616        arib_node_relation_descriptor_t *p_node_relation;
5617
5618        len = p[1];
5619
5620        if ( len < 3 )
5621                return;
5622
5623        p_node_relation = (arib_node_relation_descriptor_t *)memChainAlloc(memId, sizeof(arib_node_relation_descriptor_t));
5624
5625        if ( p_node_relation == (arib_node_relation_descriptor_t *)NULL )
5626        {
5627                err = DHL_FAIL_OUT_OF_RESOURCE;
5628                goto ParseDescriptorExit;
5629        }
5630
5631        p_node_relation->reference_type = ( p[2] & 0xF0 ) >> 4;
5632        p_node_relation->external_reference_flag = ( p[3] & 0x8 ) >> 3;
5633
5634        off = 4;
5635
5636        if ( p_node_relation->external_reference_flag == 1 )
5637        {
5638                p_node_relation->information_provider_id = p[off];
5639                p_node_relation->event_relation_id = p[off+1];
5640                off += 2;
5641        }
5642
5643        p_node_relation->reference_node_id = p[off];
5644        p_node_relation->reference_number = p[off+1];
5645
5646        *pp_node_relation = p_node_relation;
5647
5648ParseDescriptorExit:
5649        if ( err )
5650        {
5651                printf("ERROR: %s returns %d!\n", __func__, err);
5652        }
5653}
5654
5655void DHL_PSI_ParseShortNodeInformationDescriptor( DS_U8 *p, memId_t memId, arib_short_node_information_descriptor_t **pp_short_node_information )
5656{
5657        int len, node_name_length, text_length;
5658        DHL_RESULT err;
5659        arib_short_node_information_descriptor_t *p_short_node_information;
5660
5661        len = p[1];
5662
5663        if ( len < 4 )
5664                return;
5665
5666        p_short_node_information = (arib_short_node_information_descriptor_t *)memChainAlloc(memId, sizeof(arib_short_node_information_descriptor_t));
5667
5668        if ( p_short_node_information == (arib_short_node_information_descriptor_t *)NULL )
5669        {
5670                err = DHL_FAIL_OUT_OF_RESOURCE;
5671                goto ParseDescriptorExit;
5672        }
5673
5674        p_short_node_information->ISO_639_language_code = ( p[2] << 16 ) + ( p[3] << 8 ) + p[4];
5675        node_name_length = p[5];
5676        p_short_node_information->node_name_length = node_name_length;
5677        p_short_node_information->node_name_char = (DS_U8 *)NULL;
5678
5679        if ( node_name_length )
5680        {
5681                p_short_node_information->node_name_char = (DS_U8 *)memChainAlloc(memId, node_name_length);
5682                memcpy(p_short_node_information->node_name_char, &p[6], node_name_length);
5683        }
5684
5685        text_length = p[6 + node_name_length];
5686        p_short_node_information->text_length = text_length;
5687        p_short_node_information->text_char = (DS_U8 *)NULL;
5688
5689        if ( text_length )
5690        {
5691                p_short_node_information->text_char = (DS_U8 *)memChainAlloc(memId, text_length+1);
5692                memcpy(p_short_node_information->text_char, &p[7 + node_name_length], text_length);
5693        }
5694
5695        *pp_short_node_information = p_short_node_information;
5696
5697ParseDescriptorExit:
5698        if ( err )
5699        {
5700                printf("ERROR: %s returns %d!\n", __func__, err);
5701        }
5702}
5703
5704void DHL_PSI_ParseSTCReferenceDescriptor( DS_U8 *p, memId_t memId, arib_stc_reference_descriptor_t **pp_stc_reference )
5705{
5706        int len, off;
5707        DHL_RESULT err;
5708        arib_stc_reference_descriptor_t *p_stc_reference;
5709
5710        len = p[1];
5711
5712        if ( len < 0 )
5713                return;
5714
5715        p_stc_reference = (arib_stc_reference_descriptor_t *)memChainAlloc(memId, sizeof(arib_stc_reference_descriptor_t));
5716
5717        if ( p_stc_reference == (arib_stc_reference_descriptor_t *)NULL )
5718        {
5719                err = DHL_FAIL_OUT_OF_RESOURCE;
5720                goto ParseDescriptorExit;
5721        }
5722
5723        p_stc_reference->external_event_flag = ( p[2] & 0x10 ) >> 4;
5724        p_stc_reference->stc_reference_mode = ( p[2] & 0xF );
5725        off = 3;
5726
5727        if ( p_stc_reference->external_event_flag == 1 )
5728        {
5729                arib_external_event_t *p_external_event;
5730
5731                p_external_event = p_stc_reference->external_event = (arib_external_event_t *)memChainAlloc(memId, sizeof(arib_external_event_t));
5732
5733                if ( p_external_event == (arib_external_event_t *)NULL )
5734                {
5735                        err = DHL_FAIL_OUT_OF_RESOURCE;
5736                        goto ParseDescriptorExit;
5737                }
5738
5739                p_external_event->external_event_id = ( p[off] << 8 ) + p[off+1];
5740                p_external_event->external_service_id = ( p[off+2] << 8 ) + p[off+3];
5741                p_external_event->external_network_id = ( p[off+4] << 8 ) + p[off+5];
5742                off += 6;
5743        }
5744
5745        if ( p_stc_reference->stc_reference_mode == 0 )
5746        {
5747                ;
5748        }
5749        else if ( p_stc_reference->stc_reference_mode == 1 )
5750        {
5751                arib_stc_reference_mode1_t *p_stc_reference_mode1;
5752
5753                p_stc_reference_mode1 = p_stc_reference->stc_reference_mode1 = (arib_stc_reference_mode1_t *)memChainAlloc(memId, sizeof(arib_stc_reference_mode1_t));
5754               
5755                if ( p_stc_reference_mode1 == (arib_stc_reference_mode1_t *)NULL )
5756                {
5757                        err = DHL_FAIL_OUT_OF_RESOURCE;
5758                        goto ParseDescriptorExit;
5759                }
5760
5761                p_stc_reference_mode1->NPT_reference = ( p[off+1] << 24 ) + ( p[off+2] << 16 ) + ( p[off+3] << 8 ) + p[off+4];
5762                p_stc_reference_mode1->STC_reference = ( p[off+6] << 24 ) + ( p[off+7] << 16 ) + ( p[off+8] << 8 ) + p[off+9];
5763        }
5764        else if ( p_stc_reference->stc_reference_mode == 3 || p_stc_reference->stc_reference_mode == 5 )
5765        {
5766                arib_stc_reference_mode3_t *p_stc_reference_mode3;
5767
5768                p_stc_reference_mode3 = p_stc_reference->stc_reference_mode3 = (arib_stc_reference_mode3_t *)memChainAlloc(memId, sizeof(arib_stc_reference_mode3_t));
5769               
5770                if ( p_stc_reference_mode3 == (arib_stc_reference_mode3_t *)NULL )
5771                {
5772                        err = DHL_FAIL_OUT_OF_RESOURCE;
5773                        goto ParseDescriptorExit;
5774                }
5775
5776                p_stc_reference_mode3->time_reference = ( p[off] << 16 ) + ( p[off+1] << 8 ) + p[off+2];
5777                p_stc_reference_mode3->time_reference_extension = ( p[off+3] << 4 ) + (( p[off+4] & 0xF0 ) >> 4 );
5778                p_stc_reference_mode3->STC_reference = ( p[off+6] << 24 ) + ( p[off+7] << 16 ) + ( p[off+8] << 8 ) + p[off+9];
5779        }
5780
5781        *pp_stc_reference = p_stc_reference;
5782
5783ParseDescriptorExit:
5784        if ( err )
5785        {
5786                printf("ERROR: %s returns %d!\n", __func__, err);
5787        }
5788}
5789
5790void DHL_PSI_ParseSeriesDescriptor( DS_U8 *p, memId_t memId, arib_series_descriptor_t **pp_series )
5791{
5792        int len, name_length;
5793        DHL_RESULT err;
5794        arib_series_descriptor_t *p_series;
5795
5796        len = p[1];
5797
5798        if ( len < 7 )
5799                return;
5800
5801        p_series = (arib_series_descriptor_t *)memChainAlloc(memId, sizeof(arib_series_descriptor_t));
5802
5803        if ( p_series == (arib_series_descriptor_t *)NULL )
5804        {
5805                err = DHL_FAIL_OUT_OF_RESOURCE;
5806                goto ParseDescriptorExit;
5807        }
5808
5809        p_series->series_id = ( p[2] << 8 ) + p[3];
5810        p_series->repeat_label = ( p[4] & 0xF0 ) >> 4;
5811        p_series->program_pattern = ( p[4] &0x0E ) >> 1;
5812        p_series->expire_date_valid_flag =  p[4] & 0x1;
5813        p_series->expire_date = ( p[5] << 8 ) + p[6];
5814        p_series->episode_number = ( p[7] << 4 ) + (( p[8] & 0xF0 ) >> 4 );
5815        p_series->last_episode_number = (( p[8] & 0x0F ) << 4 ) + p[9];
5816
5817        name_length = len - 8;
5818
5819        p_series->series_name_char = (DS_U8 *)NULL;
5820
5821        if ( name_length )
5822        {
5823                p_series->series_name_char = (DS_U8 *)memChainAlloc(memId, name_length+1);
5824                memcpy(p_series->series_name_char, &p[10+name_length], name_length );
5825                p_series->series_name_char[name_length] = '\0';
5826        }
5827
5828        *pp_series = p_series;
5829
5830ParseDescriptorExit:
5831        if ( err )
5832        {
5833                printf("ERROR: %s returns %d!\n", __func__, err);
5834        }
5835}
5836
5837void DHL_PSI_ParseSIParameterDescriptor( DS_U8 *p_desc, memId_t memId, arib_si_parameter_descriptor_t **pp_si_parameter )
5838{
5839        const DS_U8 *p;
5840        int numTable;
5841        int lenTable;
5842        int i, j, len, off;
5843        DHL_RESULT err;
5844        arib_si_parameter_descriptor_t *p_si_parameter;
5845
5846        len = p_desc[1];
5847
5848        if ( len < 2 )
5849                return;
5850
5851        p_si_parameter = (arib_si_parameter_descriptor_t *)memChainAlloc(memId, sizeof(arib_si_parameter_descriptor_t));
5852
5853        if ( p_si_parameter == (arib_si_parameter_descriptor_t *)NULL )
5854        {
5855                err = DHL_FAIL_OUT_OF_RESOURCE;
5856                goto ParseDescriptorExit;
5857        }
5858
5859        p_si_parameter->parameter_version = p_desc[2];
5860        p_si_parameter->update_time = ( p_desc[3] << 8 ) + p_desc[4];
5861
5862        lenTable = len - 5;
5863        numTable = 0;
5864        p = &p_desc[5];
5865
5866        if ( lenTable > 0 )
5867        {
5868                for ( i=0 ; i<lenTable ; )
5869                {
5870                        int table_id;
5871                        int table_description_length;
5872
5873                        table_id = p[i+0];
5874                        table_description_length = p[i+1];
5875                       
5876                        if ( table_id )
5877                                numTable++;
5878
5879                        i += 2+table_description_length;
5880                }
5881        }
5882
5883        p_si_parameter->numTable = numTable;
5884        p_si_parameter->update_time = (p_desc[3]<<8) + p_desc[4];
5885        off = 5;
5886
5887        if ( numTable > 0 )
5888        {
5889                arib_table_description_t *p_table_description;
5890
5891                p_table_description = p_si_parameter->table_description = (arib_table_description_t *)memChainAlloc(memId, numTable*sizeof(arib_table_description_t));
5892                if ( p_table_description == (arib_table_description_t *)NULL )
5893                {
5894                        err = DHL_FAIL_OUT_OF_RESOURCE;
5895                        goto ParseDescriptorExit;
5896                }
5897                for ( i=0 ; i < numTable ; i++ )
5898                {
5899                        p_table_description->table_id = p_desc[off];
5900                        p_table_description->table_description_length = p_desc[off+1];
5901
5902                        off += 2;
5903
5904                        if ( p_table_description->table_description_length > 0 )
5905                        {
5906                                p_table_description->table_description_byte = (DS_U8 *)memChainAlloc(memId, p_table_description->table_description_length);
5907
5908                                for ( j=0 ; j < p_table_description->table_description_length ; j++ )
5909                                {
5910                                        p_table_description->table_description_byte[j] = p_desc[off+j];
5911                                }
5912                       
5913                                off += j;
5914                        }
5915                        else
5916                        {
5917                                p_table_description->table_description_byte = (DS_U8 *)NULL;
5918                        }
5919                       
5920                        p_table_description++;
5921                }
5922        }       
5923        else
5924        {
5925                p_si_parameter->table_description = (arib_table_description_t *)NULL;
5926        }
5927
5928        err = DHL_OK;
5929        *pp_si_parameter = p_si_parameter;
5930
5931ParseDescriptorExit:
5932        if ( err )
5933        {
5934                printf("ERROR: %s returns %d!\n", __func__, err);
5935        }
5936}
5937
5938void DHL_PSI_ParseBroadcasterNameDescriptor(DS_U8 *p, memId_t memId, DS_U8 **pp_broadcaster_name, DS_U8 *p_length)
5939{
5940    int len;
5941    DS_U8 *p_broadcaster_name;
5942   
5943    if (!p || !p_broadcaster_name || !p_length)
5944        return;
5945   
5946    len = p[1];
5947    p_broadcaster_name = (DS_U8 *)memChainAlloc( memId, len+1 );
5948    memcpy(p_broadcaster_name, &p[2], len );
5949    p_broadcaster_name[len] = '\0';
5950   
5951    *pp_broadcaster_name = p_broadcaster_name;
5952   
5953    return;
5954}
5955
5956void DHL_PSI_ParseComponentGroupDescriptor( DS_U8 *p, memId_t memId, arib_component_group_descriptor_t **pp_component_group )
5957{
5958        int i, j, len, off;
5959        int num_of_group;
5960        DHL_RESULT err;
5961        arib_component_group_descriptor_t *p_component_group;
5962
5963        len = p[1];
5964
5965        if ( len < 0 )
5966                return;
5967
5968        p_component_group = (arib_component_group_descriptor_t *)memChainAlloc(memId, sizeof(arib_component_group_descriptor_t));
5969
5970        if ( p_component_group == (arib_component_group_descriptor_t *)NULL )
5971        {
5972                err = DHL_FAIL_OUT_OF_RESOURCE;
5973                goto ParseDescriptorExit;
5974        }
5975
5976        p_component_group->component_group_type = ( p[2] & 0xE0 ) >> 5;
5977        p_component_group->total_bit_rate_flag = ( p[2] >> 4 ) & 0x1 ;
5978        num_of_group = p[2] & 0xF;
5979        p_component_group->num_of_group = num_of_group;
5980        off = 3;
5981
5982        if ( num_of_group )
5983        {
5984                int num_of_CA_unit, text_length;
5985                arib_group_t *p_group;
5986
5987                p_group = p_component_group->group = (arib_group_t *)memChainAlloc(memId, sizeof(arib_group_t));
5988
5989                if ( p_group == (arib_group_t *)NULL )
5990                {
5991                        err = DHL_FAIL_OUT_OF_RESOURCE;
5992                        goto ParseDescriptorExit;
5993                }
5994
5995                for ( i = 0 ; i < num_of_group ; i++ )
5996                {
5997                        p_group->component_group_id = ( p[off] >> 4 ) & 0xF;
5998                        num_of_CA_unit = p[off] & 0xF;
5999                        p_group->num_of_CA_unit = num_of_CA_unit;
6000                        off += 1;
6001
6002                        if ( num_of_CA_unit )
6003                        {
6004                                int num_of_component;
6005                                arib_unit_t *p_unit;
6006
6007                                p_unit = p_group->CA_unit = (arib_unit_t *)memChainAlloc(memId, sizeof(arib_unit_t));
6008
6009                                if ( p_unit == (arib_unit_t *)NULL )
6010                                {
6011                                        err = DHL_FAIL_OUT_OF_RESOURCE;
6012                                        goto ParseDescriptorExit;
6013                                }
6014
6015                                for ( j = 0 ; j < num_of_CA_unit ; j++ )
6016                                {
6017                                        p_unit->CA_unit_id = ( p[off] >> 4 ) & 0xF;
6018                                        p_unit->num_of_component = p[off] & 0xF;
6019                                        off += 1;
6020
6021                                        if ( p_unit->num_of_component )
6022                                        {
6023                                                p_unit->component_tag = (DS_U8 *)memChainAlloc(memId, p_unit->num_of_component);
6024                                                memcpy(p_unit->component_tag, &p[off], num_of_component);
6025                                                off += num_of_component;
6026                                        }
6027                                       
6028                                        p_unit++;
6029                                }       
6030                        }
6031
6032                        if ( p_component_group->total_bit_rate_flag == 1 )
6033                        {
6034                                p_group->total_bit_rate = p[off+1];
6035                                off += 1;
6036                        }
6037
6038                        text_length = p[off];
6039                        p_group->text_length = text_length;
6040                        off += 1;
6041                       
6042                        if ( text_length )
6043                        {
6044                                p_group->text_char = (DS_U8 *)memChainAlloc(memId, text_length+1);
6045                                memcpy(p_group->text_char, &p[off], text_length);
6046                                p_group->text_char[text_length] = '\0';
6047                                off += text_length;     
6048                        }
6049                       
6050                        p_group++;
6051                }
6052        }
6053
6054        *pp_component_group = p_component_group;
6055
6056ParseDescriptorExit:
6057        if ( err )
6058        {
6059                printf("ERROR: %s returns %d!\n", __func__, err);
6060        }
6061}
6062
6063void DHL_PSI_ParseSIPrimeTSDescriptor( DS_U8 *p, memId_t memId, arib_si_prime_ts_descriptor_t **pp_si_prime_ts )
6064{
6065        int len, table_len, off;
6066        DHL_RESULT err;
6067        arib_si_prime_ts_descriptor_t *p_si_prime_ts;
6068
6069        len = p[1];
6070
6071        if ( len < 6 )
6072                return;
6073
6074        p_si_prime_ts = (arib_si_prime_ts_descriptor_t *)memChainAlloc(memId, sizeof(arib_si_prime_ts_descriptor_t));
6075
6076        if ( p_si_prime_ts == (arib_si_prime_ts_descriptor_t *)NULL )
6077        {
6078                err = DHL_FAIL_OUT_OF_RESOURCE;
6079                goto ParseDescriptorExit;
6080        }
6081
6082        p_si_prime_ts->parameter_version= p[2];
6083        p_si_prime_ts->update_time = ( p[3] << 8 ) + p[4];
6084        p_si_prime_ts->SI_prime_ts_network_id = ( p[5] << 8 ) + p[6];
6085        p_si_prime_ts->SI_prime_ts_id = ( p[7] << 8 ) + p[8];
6086        table_len = len - 7;
6087        off = 9;
6088
6089        if ( table_len )
6090        {
6091                arib_table_description_t *p_table_description;
6092
6093                p_table_description = p_si_prime_ts->table_description = (arib_table_description_t *)memChainAlloc(memId, table_len);
6094               
6095                if ( p_table_description == (arib_table_description_t *)NULL )
6096                {
6097                        err = DHL_FAIL_OUT_OF_RESOURCE;
6098                        goto ParseDescriptorExit;
6099                }
6100
6101                while ( table_len > 2 )
6102                {
6103                        p_table_description->table_id = p[off];
6104                        p_table_description->table_description_length = p[off+1];
6105
6106                        off += 2;
6107
6108                        if ( p_table_description->table_description_length )
6109                        {
6110                                p_table_description->table_description_byte = (DS_U8 *)memChainAlloc(memId, p_table_description->table_description_length);
6111                                memcpy(p_table_description->table_description_byte, &p[off], p_table_description->table_description_length);
6112                                off += p_table_description->table_description_length;   
6113                        }
6114                       
6115                        table_len = table_len - ( 2 + p_table_description->table_description_length );
6116                        p_table_description++;
6117                }
6118        }       
6119
6120        *pp_si_prime_ts = p_si_prime_ts;
6121
6122ParseDescriptorExit:
6123        if ( err )
6124        {
6125                printf("ERROR: %s returns %d!\n", __func__, err);
6126        }
6127}
6128
6129void DHL_PSI_ParseBoardInformationDescriptor( DS_U8 *p, memId_t memId, arib_board_information_descriptor_t **pp_board_information )
6130{
6131        int len, off;
6132        DHL_RESULT err;
6133        arib_board_information_descriptor_t *p_board_information;
6134
6135        len = p[1];
6136
6137        if ( len < 1 )
6138                return;
6139
6140        p_board_information = (arib_board_information_descriptor_t *)memChainAlloc(memId, sizeof(arib_board_information_descriptor_t));
6141
6142        if ( p_board_information == (arib_board_information_descriptor_t *)NULL )
6143        {
6144                err = DHL_FAIL_OUT_OF_RESOURCE;
6145                goto ParseDescriptorExit;
6146        }
6147
6148        p_board_information->title_length = p[2];
6149        off = 3;
6150
6151        if ( p_board_information->title_length )
6152        {
6153                p_board_information->title_char = (DS_U8 *)memChainAlloc(memId, p_board_information->title_length + 1);
6154                memcpy(p_board_information->title_char, &p[off], p_board_information->title_length + 1);
6155                p_board_information->title_char[p_board_information->title_length] = '\0';
6156                off += p_board_information->title_length;
6157        }
6158
6159        p_board_information->text_length = p[off];
6160
6161        if ( p_board_information->text_length )
6162        {
6163                p_board_information->text_char = (DS_U8 *)memChainAlloc(memId, p_board_information->text_length + 1);
6164                memcpy(p_board_information->text_char, &p[off+1], p_board_information->text_length + 1);
6165                p_board_information->text_char[p_board_information->text_length] = '\0';
6166        }
6167
6168        *pp_board_information = p_board_information;
6169
6170ParseDescriptorExit:
6171        if ( err )
6172        {
6173                printf("ERROR: %s returns %d!\n", __func__, err);
6174        }
6175}
6176
6177void DHL_PSI_ParseLDTLinkageDescriptor( DS_U8 *p, memId_t memId, arib_ldt_linkage_descriptor_t **pp_ldt_linkage )
6178{
6179        int len, n, off;
6180        DHL_RESULT err;
6181        arib_ldt_linkage_descriptor_t *p_ldt_linkage;
6182
6183        len = p[1];
6184
6185        if ( len < 5 )
6186                return;
6187
6188        p_ldt_linkage = (arib_ldt_linkage_descriptor_t *)memChainAlloc(memId, sizeof(arib_ldt_linkage_descriptor_t));
6189
6190        if ( p_ldt_linkage == (arib_ldt_linkage_descriptor_t *)NULL )
6191        {
6192                err = DHL_FAIL_OUT_OF_RESOURCE;
6193                goto ParseDescriptorExit;
6194        }
6195
6196        p_ldt_linkage->original_service_id = ( p[2] << 8 ) | p[3];
6197        p_ldt_linkage->ts_id = ( p[4] << 8 ) + p[5];
6198        p_ldt_linkage->original_network_id = ( p[6] << 8 ) + p[7];
6199        n = len - 6;
6200        off = 9;
6201
6202        if ( n )
6203        {
6204                arib_linked_description_t *p_linked_description;
6205
6206                p_linked_description = p_ldt_linkage->linked_description = (arib_linked_description_t *)memChainAlloc(memId, n);
6207               
6208                if ( p_linked_description == (arib_linked_description_t *)NULL )
6209                {
6210                        err = DHL_FAIL_OUT_OF_RESOURCE;
6211                        goto ParseDescriptorExit;
6212                }
6213
6214                while ( n > 3 )
6215                {
6216                        p_linked_description->description_id = ( p[off] << 8 ) + p[off+1];
6217                        p_linked_description->description_id = ( p[off+2] & 0xF );
6218                        p_linked_description->user_defined = p[off+3];
6219                        off += 4;
6220                        n  -= 4;
6221                        p_linked_description++;
6222                }
6223        }       
6224
6225        *pp_ldt_linkage = p_ldt_linkage;
6226
6227ParseDescriptorExit:
6228        if ( err )
6229        {
6230                printf("ERROR: %s returns %d!\n", __func__, err);
6231        }
6232}
6233
6234void DHL_PSI_ParseConnectedTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_connected_transmission_descriptor_t **pp_connected_tx )
6235{
6236        int len, n;
6237        DHL_RESULT err;
6238        arib_connected_transmission_descriptor_t *p_connected_tx;
6239
6240        len = p[1];
6241
6242        if ( len < 2 )
6243                return;
6244
6245        p_connected_tx = (arib_connected_transmission_descriptor_t *)memChainAlloc(memId, sizeof(arib_connected_transmission_descriptor_t));
6246
6247        if ( p_connected_tx == (arib_connected_transmission_descriptor_t *)NULL )
6248        {
6249                err = DHL_FAIL_OUT_OF_RESOURCE;
6250                goto ParseDescriptorExit;
6251        }
6252
6253        p_connected_tx->connected_tx_group_id = ( p[2] << 8 ) + p[3];
6254        p_connected_tx->segment_type = ( p[4] >> 6 ) & 0x3;
6255        p_connected_tx->modulation_type_A = ( p[4] >> 4 ) & 0x3;
6256        p_connected_tx->modulation_type_B = ( p[4] >> 2 ) & 0x3;
6257
6258        n = len - 3;
6259
6260        if ( n )
6261        {
6262                p_connected_tx->additional_connected_tx_info = (DS_U8 *)memChainAlloc(memId, n);
6263                memcpy(p_connected_tx->additional_connected_tx_info, &p[5], n);
6264        }
6265
6266        *pp_connected_tx = p_connected_tx;
6267
6268ParseDescriptorExit:
6269        if ( err )
6270        {
6271                printf("ERROR: %s returns %d!\n", __func__, err);
6272        }
6273}
6274
6275void DHL_PSI_ParseContentAvailabilityDescriptor( DS_U8 *p, memId_t memId, arib_content_availability_descriptor_t **pp_content_availability )
6276{
6277        int len;
6278        DHL_RESULT err;
6279        arib_content_availability_descriptor_t *p_content_availability;
6280
6281        len = p[1];
6282
6283        if ( len < 0 )
6284                return;
6285
6286        p_content_availability = (arib_content_availability_descriptor_t *)memChainAlloc(memId, sizeof(arib_content_availability_descriptor_t));
6287
6288        if ( p_content_availability == (arib_content_availability_descriptor_t *)NULL )
6289        {
6290                err = DHL_FAIL_OUT_OF_RESOURCE;
6291                goto ParseDescriptorExit;
6292        }
6293
6294        p_content_availability->image_constraint_token = ( p[2] >> 5 ) & 0x1;
6295        p_content_availability->retention_mode = ( p[2] >> 4 ) & 0x1;
6296        p_content_availability->retention_state = ( p[2] >> 1 ) & 0x7;
6297        p_content_availability->encryption_mode = ( p[2] & 0x1 );
6298
6299        *pp_content_availability = p_content_availability;
6300
6301ParseDescriptorExit:
6302        if ( err )
6303        {
6304                printf("ERROR: %s returns %d!\n", __func__, err);
6305        }
6306}
6307
6308void DHL_PSI_ParseConditionalPlaybackDescriptor( DS_U8 *p, memId_t memId, arib_conditional_playback_descriptor_t **pp_conditional_playback )
6309{
6310        int len, n;
6311        DHL_RESULT err;
6312        arib_conditional_playback_descriptor_t *p_conditional_playback;
6313
6314        len = p[1];
6315
6316        if ( len < 3 )
6317                return;
6318
6319        p_conditional_playback = (arib_conditional_playback_descriptor_t *)memChainAlloc(memId, sizeof(arib_conditional_playback_descriptor_t));
6320
6321        if ( p_conditional_playback == (arib_conditional_playback_descriptor_t *)NULL )
6322        {
6323                err = DHL_FAIL_OUT_OF_RESOURCE;
6324                goto ParseDescriptorExit;
6325        }
6326
6327        p_conditional_playback->CA_system_id = ( p[2] << 8 ) + p[3];
6328        p_conditional_playback->private_data = ( p[4] >> 5 ) & 0x7;
6329        p_conditional_playback->CA_PID = (( p[4] << 4 ) & 0x1F ) + p[5];
6330
6331        n = len - 4;
6332
6333        if ( n )
6334        {
6335                p_conditional_playback->private_data_byte = (DS_U8 *)memChainAlloc(memId, n);
6336                memcpy(p_conditional_playback->private_data_byte, &p[6], n);
6337        }
6338
6339        *pp_conditional_playback = p_conditional_playback;
6340
6341ParseDescriptorExit:
6342        if ( err )
6343        {
6344                printf("ERROR: %s returns %d!\n", __func__, err);
6345        }
6346}
6347
6348void DHL_PSI_ParseTerrestrialDeliverySystemDescriptor( DS_U8 *p, memId_t memId, arib_terrestrial_delivery_system_descriptor_t **pp_terrestrial_delivery_system )
6349{
6350        int len, n;
6351        DHL_RESULT err;
6352        arib_terrestrial_delivery_system_descriptor_t *p_terrestrial_delivery_system;
6353
6354        len = p[1];
6355
6356        if ( len < 1 )
6357                return;
6358
6359        p_terrestrial_delivery_system = (arib_terrestrial_delivery_system_descriptor_t *)memChainAlloc(memId, sizeof(arib_terrestrial_delivery_system_descriptor_t));
6360
6361        if ( p_terrestrial_delivery_system == (arib_terrestrial_delivery_system_descriptor_t *)NULL )
6362        {
6363                err = DHL_FAIL_OUT_OF_RESOURCE;
6364                goto ParseDescriptorExit;
6365        }
6366
6367        p_terrestrial_delivery_system->area_code = ( p[2] << 4 ) + (( p[3] & 0xF0 ) >> 4);
6368        p_terrestrial_delivery_system->guard_interval = ( p[3] >> 2 ) & 0x3;
6369        p_terrestrial_delivery_system->tx_mode = ( p[3] & 0x3 );
6370
6371        n = len - 2;
6372
6373        if ( n )
6374        {
6375                p_terrestrial_delivery_system->frequency = (DS_U8 *)memChainAlloc(memId, n);
6376                memcpy(p_terrestrial_delivery_system->frequency, &p[4], n);
6377        }
6378
6379        *pp_terrestrial_delivery_system = p_terrestrial_delivery_system;
6380
6381ParseDescriptorExit:
6382        if ( err )
6383        {
6384                printf("ERROR: %s returns %d!\n", __func__, err);
6385        }
6386}
6387
6388void DHL_PSI_ParsePartialReceptionDescriptor(DS_U8 *p, memId_t memId, DS_U16 **pp_partial_reception, DS_U8 *p_length)
6389{
6390    int len;
6391    DS_U16 *p_partial_reception;
6392   
6393    if (!p || !p_partial_reception || !p_length)
6394        return;
6395   
6396    len = p[1];
6397    p_partial_reception = (DS_U16 *)memChainAlloc( memId, len );
6398    memcpy(p_partial_reception, &p[2], len );
6399   
6400    *pp_partial_reception = p_partial_reception;
6401   
6402    return;
6403}
6404
6405void DHL_PSI_ParseEmergencyInformationDescriptor(DS_U8 *p_desc, memId_t memId, arib_emergency_information_descriptor_t **pp_emergency_info)
6406{
6407    DS_U8 *p = p_desc;
6408    arib_emergency_information_descriptor_t *p_emergency_info;
6409    int i, j, k, len, off, area_len;
6410//    int numEvent;
6411   
6412    if (!p_desc || !pp_emergency_info || !memId)
6413        return;
6414   
6415    len = p_desc[1];
6416
6417    if (len<3)
6418        return;
6419   
6420        p_emergency_info = (arib_emergency_information_descriptor_t *)memChainAlloc(memId, sizeof(arib_emergency_information_descriptor_t));
6421
6422        if ( len )
6423        {
6424                off = 2;
6425
6426                for ( i = 0 ; i < len ; i++ )
6427                {
6428                        p_emergency_info->service_id = ( p[off+0] << 8 ) + p[off+1];
6429                        p_emergency_info->start_end_flag = ( p[off+2] >> 7 ) & 0x1;
6430                        p_emergency_info->signal_level = ( p[off+2] >> 6 ) & 0x1;
6431                        area_len = p[off+3];
6432                        p_emergency_info->area_code_length = area_len;
6433                        off += 4;
6434
6435                        if ( area_len )
6436                        {
6437                                for ( j=0, k=0 ; j < area_len ; j+=2, k++ )
6438                                {
6439                                        p_emergency_info->area_code[k] = ( p[off+0] << 4 ) + (( p[off+1] >> 4) & 0xF );
6440                                        p_emergency_info->area_code++;
6441                                        off += 2;
6442                                }
6443                        }
6444
6445                        p_emergency_info++;
6446                }
6447        }
6448
6449    *pp_emergency_info = p_emergency_info;
6450}
6451
6452void DHL_PSI_ParseDataComponentDescriptor(DS_U8 *p_desc, memId_t memId, arib_data_component_descriptor_t **pp_data_component)
6453{
6454        DS_U8 *p = p_desc;
6455        arib_data_component_descriptor_t *p_data_component;
6456        int len, numInfo;
6457
6458        if ( !p_desc || !pp_data_component || !memId )
6459                return;
6460
6461        len = p_desc[1];
6462
6463        if ( len < 2 )
6464                return;
6465
6466        p_data_component = (arib_data_component_descriptor_t *)memChainAlloc(memId, sizeof(arib_data_component_descriptor_t));
6467        p_data_component->data_component_id = (p[2] << 8) + p[3];
6468        numInfo = len - 2;
6469
6470        if ( numInfo )
6471        {
6472                p_data_component->additional_data_component_info = (DS_U8 *)memChainAlloc(memId, numInfo);
6473                memcpy(p_data_component->additional_data_component_info, &p[4], numInfo);
6474        }
6475
6476        *pp_data_component = p_data_component;
6477}
6478
6479void DHL_PSI_ParseExtendedBroadcasterDescriptor(DS_U8 *p_desc, memId_t memId, arib_extended_broadcaster_descriptor_t **pp_ex_broad)
6480{
6481    DS_U8 *p = p_desc;
6482    arib_extended_broadcaster_descriptor_t *p_ex_broad;
6483    int i, j, len, off;
6484    int num, numId;
6485   
6486    if (!p_desc || !pp_ex_broad || !memId)
6487        return;
6488   
6489    len = p_desc[1];
6490    if ( len<4 )
6491        return;
6492   
6493    p_ex_broad = (arib_extended_broadcaster_descriptor_t *)memChainAlloc(memId, sizeof(arib_extended_broadcaster_descriptor_t));
6494    p_ex_broad->broadcaster_type = (p[2] >> 4) & 0x0F;
6495   
6496    off = 3;
6497
6498        if ( p_ex_broad->broadcaster_type == 0x1 )
6499        {
6500                p_ex_broad->terrestrial_broadcaster_id = (p[off+0] << 8) + p[off+1];
6501                p_ex_broad->num_affiliation_id = (p[off+2] & 0xF0) >> 4;
6502                p_ex_broad->num_broadcaster_id = p[off+2] & 0xF;
6503                off += 3;
6504
6505                if ( p_ex_broad->num_affiliation_id )
6506                {
6507                        num = p_ex_broad->num_affiliation_id;
6508                        p_ex_broad->affiliation_id = (DS_U8 *)memChainAlloc(memId, num);
6509                        memcpy(p_ex_broad->affiliation_id, &p[off], num);
6510                        off += num;
6511                }
6512
6513                if ( p_ex_broad->num_broadcaster_id )
6514                {
6515                        numId = p_ex_broad->num_broadcaster_id;
6516                        p_ex_broad->origin_network_id = (DS_U16 *)memChainAlloc(memId, numId*2);
6517                        p_ex_broad->broadcaster_id = (DS_U8 *)memChainAlloc(memId, numId);
6518                       
6519                        for ( i=0, j=0 ; j < p_ex_broad->num_broadcaster_id ; i++, j+=3 )
6520                        {
6521                                p_ex_broad->origin_network_id[i] = (p[off+0] << 8) + p[off+1];
6522                                p_ex_broad->broadcaster_id[i] = p[off+2];
6523                                off += 3;
6524                                p_ex_broad->origin_network_id++;
6525                                p_ex_broad->broadcaster_id++;
6526                        }
6527                }
6528        }
6529        else if ( p_ex_broad->broadcaster_type == 0x2 )
6530        {
6531                p_ex_broad->terrestrial_broadcaster_id = (p[off+0] << 8) + p[off+1];
6532                p_ex_broad->num_affiliation_id = (p[off+2] >> 4) & 0xF;
6533                p_ex_broad->num_broadcaster_id = p[off+2] & 0xF;
6534                off += 3;
6535
6536                if ( p_ex_broad->num_affiliation_id )
6537                {
6538                        num = p_ex_broad->num_affiliation_id;
6539                        p_ex_broad->affiliation_id = (DS_U8 *)memChainAlloc(memId, num);
6540                        memcpy(p_ex_broad->affiliation_id, &p[off], num);
6541                        off += num;
6542                }
6543
6544                if ( p_ex_broad->num_broadcaster_id )
6545                {
6546                        numId = p_ex_broad->num_broadcaster_id;
6547                        p_ex_broad->origin_network_id = (DS_U16 *)memChainAlloc(memId, numId*2);
6548                        p_ex_broad->broadcaster_id = (DS_U8 *)memChainAlloc(memId, numId);
6549                       
6550                        for ( i=0, j=0 ; j < p_ex_broad->num_broadcaster_id ; i++, j+=3 )
6551                        {
6552                                p_ex_broad->origin_network_id[i] = (p[off+0] << 8) + p[off+1];
6553                                p_ex_broad->broadcaster_id[i] = p[off+2];
6554                                off += 3;
6555                                p_ex_broad->origin_network_id++;
6556                                p_ex_broad->broadcaster_id++;
6557                        }
6558                }
6559        }
6560        else
6561        {
6562                p_ex_broad->affiliation_id = (DS_U8 *)NULL;
6563                p_ex_broad->origin_network_id = (DS_U16 *)NULL;
6564                p_ex_broad->broadcaster_id = (DS_U8 *)NULL;
6565        }
6566
6567    *pp_ex_broad = p_ex_broad;
6568}
6569
6570void DHL_PSI_ParseServiceGroupDescriptor(DS_U8 *p_desc, memId_t memId, arib_service_group_descriptor_t **pp_service_grp)
6571{
6572        DS_U8 *p = p_desc;
6573        arib_service_group_descriptor_t *p_service_grp;
6574        int i, j, off, len, num;
6575
6576        if ( !p_desc || !pp_service_grp || !memId )
6577                return;
6578
6579        len = p_desc[1];
6580
6581        if ( len < 2 )
6582                return;
6583
6584        p_service_grp->service_grp_type = p[2];
6585        off = 3;
6586
6587        if ( p_service_grp->service_grp_type == 0x1 )
6588        {
6589                num = (len-1) / 4;
6590               
6591                if ( num )
6592                {
6593                        p_service_grp->pri_service_id = (DS_U16 *)memChainAlloc(memId, num);
6594                        p_service_grp->sub_service_id = (DS_U16 *)memChainAlloc(memId, num);
6595
6596                        for ( i=0, j=0 ; j < num ; j+=4, i++ )
6597                        {
6598                                p_service_grp->pri_service_id[i] = (p[off+0] << 8) + p[off+1];
6599                                p_service_grp->sub_service_id[i] = (p[off+2] << 8) + p[off+3];
6600                                off += 4;
6601                                p_service_grp->pri_service_id++;
6602                                p_service_grp->sub_service_id++;
6603                        }
6604                }
6605        }
6606
6607        *pp_service_grp = p_service_grp;
6608}
6609
6610void DHL_PSI_ParseDownloadContentDescriptor(DS_U8 *p, memId_t memId, arib_download_content_descriptor_t **pp_download)
6611{
6612        int i, j, k, len, off;
6613    int moduleInfolen, priDatalen;
6614        int textlen, numSubDesc;
6615        arib_download_content_descriptor_t *p_download;
6616        arib_compatibility_descriptor_t *p_comp;
6617        arib_comp_desc_type_t *p_desctype;
6618        arib_subdesc_t *p_subdesc;
6619        arib_text_lang_t *p_text;
6620        arib_module_t *p_module;
6621
6622        if ( !p || !pp_download || !memId )
6623                return;
6624
6625        len = p[1];
6626        p_download->reboot = (p[2] >> 7) & 0x1;
6627        p_download->add_on = (p[2] >> 6) & 0x1;
6628        p_download->comp_flag = (p[2] >> 5) &0x1;
6629        p_download->module_info_flag = (p[2] >> 4) & 0x1;
6630        p_download->text_info_flag = (p[2] >> 3) &0x1;
6631        p_download->component_size = (p[3] << 24) + (p[4] << 16) + (p[5] << 8) + p[6];
6632        p_download->download_id = (p[7] << 24) + (p[8] << 16) + (p[9] << 8) + p[10];
6633        p_download->time_out_value_DII = (p[11] << 24) + (p[12] << 16) + (p[13] << 8) + p[14];
6634        p_download->leak_rate = (p[15] << 14) + (p[16] << 6) + ((p[17] >> 6) & 0x3F);
6635        p_download->comp_tag = p[18];
6636        off = 19;
6637
6638        if ( p_download->comp_flag == 1 )
6639        {
6640                p_comp = p_download->comp_desc = (arib_compatibility_descriptor_t *)memChainAlloc(memId, sizeof(arib_compatibility_descriptor_t));
6641                p_comp->comp_len = (p[off+0] << 8) + p[off+1];
6642                p_comp->numDescriptor = (p[off+2] << 8) + p[off+3];
6643                off += 4;
6644                p_desctype = p_comp->desc_type = (arib_comp_desc_type_t *)memChainAlloc(memId, sizeof(arib_comp_desc_type_t));
6645
6646                if ( p_comp->numDescriptor )
6647                {
6648                        for ( i=0 ; i < p_comp->numDescriptor ; i++ )
6649                        {
6650                                p_desctype->desc_type = p[off+0];
6651                                p_desctype->len = p[off+1];
6652                                p_desctype->specifier_type = p[off+2];
6653                                p_desctype->specifier_data = (p[off+3] << 16) + (p[off+4] << 8) + p[off+5];
6654                                p_desctype->model = (p[off+6] << 8) + p[off+7];
6655                                p_desctype->version = (p[off+8] << 8) + p[off+9];
6656                                p_desctype->numSubDesc = p[off+10];
6657                                off += 11;
6658
6659                                if ( p_desctype->numSubDesc )
6660                                {
6661                                        p_subdesc = p_desctype->sub_desc = (arib_subdesc_t *)memChainAlloc(memId, sizeof(arib_subdesc_t));
6662
6663                                        for ( j=0 ; j < p_desctype->numSubDesc ; j++ )
6664                                        {
6665                                                p_subdesc->subDescType = p[off+0];
6666                                                numSubDesc = p[off+1];
6667                                                p_subdesc->subDesclen = numSubDesc;
6668                                                off += 2;
6669
6670                                                if ( p_subdesc->subDesclen )
6671                                                {
6672                                                        p_subdesc->addInfo = (DS_U8 *)memChainAlloc(memId, numSubDesc);
6673                                                        memcpy(p_subdesc->addInfo, &p[off], numSubDesc);
6674                                                        off += numSubDesc;
6675                                                }
6676
6677                                                p_subdesc++;
6678                                        }
6679                                }
6680
6681                                p_desctype++;
6682                        }
6683                }
6684               
6685        }
6686
6687        if ( p_download->module_info_flag == 1 )
6688        {
6689                p_download->numModules = p[off+0];
6690                off += 1;
6691                p_module = p_download->module = (arib_module_t *)memChainAlloc(memId, sizeof(arib_module_t));
6692
6693                if ( p_download->numModules )
6694                {
6695                        for ( k=0 ; k < p_download->numModules ; k++ )
6696                        {
6697                                p_module->module_id = (p[off+0] << 8) + p[off+1];
6698                                p_module->module_size = (p[off+2] << 24) + (p[off+3] << 16) + (p[off+4] << 8) + p[off+5];
6699                                moduleInfolen = p[off+6];
6700                                p_module->module_info_len = moduleInfolen;
6701                                off += 7;
6702
6703                                if ( moduleInfolen )
6704                                {
6705                                        p_module->module_info_byte = (DS_U8 *)memChainAlloc(memId, moduleInfolen);
6706                                        memcpy(p_module->module_info_byte, &p[off], moduleInfolen);
6707                                        off += moduleInfolen;
6708                                }
6709
6710                                p_module++;
6711                        }
6712                }
6713        }
6714       
6715        priDatalen = p[off];
6716        p_download->private_data_len = priDatalen;
6717        off += 1;
6718
6719        if ( priDatalen )
6720        {
6721                p_download->private_data_byte = (DS_U8 *)memChainAlloc(memId, priDatalen);
6722                memcpy(p_download->private_data_byte, &p[off], priDatalen);
6723                off += priDatalen;
6724        }       
6725       
6726        if ( p_download->text_info_flag == 1 )
6727        {
6728                p_text = (arib_text_lang_t *)memChainAlloc(memId, sizeof(arib_text_lang_t));
6729                p_text->ISO_639 = (p[off+0] << 16) + (p[off+1] << 8) + p[off+2];
6730                textlen = p[off+3];
6731                p_text->len = textlen;
6732                off += 4;
6733
6734                if ( textlen )
6735                {
6736                        p_text->text_char = (DS_U8 *)memChainAlloc(memId, textlen);
6737                        memcpy(p_text->text_char, &p[off], textlen);
6738                        off += textlen;
6739                }
6740        }
6741       
6742        *pp_download = p_download;
6743}
6744
6745void DHL_PSI_DecodeDate(DS_U16 date_in_mjd, DS_U16 *p_year, DS_U8 *p_month, DS_U8 *p_day)
6746{
6747    DS_U32 _y, _m, _d;
6748    DS_U32 _y_int, _m_int;
6749    DS_U16 y;
6750    DS_U8 m, d, k;
6751   
6752    if (!p_year || !p_month || !p_day)
6753        return;
6754   
6755    _y = ((date_in_mjd * 100) - 1507820)/36525;
6756    _y_int = (_y * 3652500)/10000;
6757    _y_int *= 10000;
6758   
6759    _m = ((date_in_mjd * 10000) - 149561000 - _y_int)/306001;
6760    _m_int = (_m * 306001)/10000;
6761    _m_int *= 10000;
6762   
6763    _d = ((date_in_mjd*10000) - 149560000 - _y_int - _m_int)/10000;
6764   
6765    if (_m == 14 || _m == 15)
6766        k = 1;
6767    else 
6768        k = 0;
6769   
6770    y = (_y+k)&0xFFFF;
6771    m = (_m-1-(k*12))&0xFF;
6772    d = (_d)&0xFF;
6773   
6774    if ( m>12 )
6775        m = 1;
6776   
6777    if ( d>31 )
6778        d = 31;
6779       
6780    *p_year = y+1900;
6781    *p_month = m;
6782    *p_day = d;
6783}
6784
6785static DS_U32 _ConvertMJD2UTC(DS_U16 Mjd, DS_U32 TimeInBCD)
6786{
6787    DS_U32 seconds_from_date=0;
6788    DS_U32 seconds_from_time=0;
6789   
6790    if ( Mjd && Mjd < (44238+6) )
6791    {
6792        /*
6793         * If Mjd is less than "6 Jan. 1980", then error.
6794         */
6795        return 0;
6796    }
6797   
6798    if (Mjd)
6799    {
6800        /*
6801         * Subtracts MJD from "44238+6" which is PSIP UTC 0.
6802         */
6803        seconds_from_date = (Mjd - (44238+6)) * 3600 * 24;
6804    }
6805   
6806    seconds_from_time  = (((TimeInBCD   )&0x0F)>>0);          /* second */
6807    seconds_from_time += (((TimeInBCD   )&0xF0)>>4)*10;         /* second */
6808    seconds_from_time += ((TimeInBCD>> 8)&0x0F) * 60;    /* minutes */
6809    seconds_from_time += ((TimeInBCD>>12)&0x0F) * 600;    /* minutes */
6810    seconds_from_time += ((TimeInBCD>>16)&0x0F) * 3600;  /* hours */
6811    seconds_from_time += ((TimeInBCD>>20)&0x0F) * 36000;  /* hours */
6812   
6813    return (seconds_from_date + seconds_from_time);
6814}
6815
6816#if 0
6817___Debugging_Routines___()
6818#endif
6819
6820void get_date(int date)
6821{
6822    DS_U16 y;
6823    DS_U8 m, d;
6824   
6825    printf("date: 0x%04X\n", date);
6826    DHL_PSI_DecodeDate(date, &y, &m, &d);
6827   
6828    printf("%d/%d/%d\n", y, m, d);
6829}
Note: See TracBrowser for help on using the repository browser.