close Warning: Can't use blame annotator:
No changeset 2 in the repository

source: svn/zasc/app_c/DST_Parser.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

File size: 100.4 KB
RevLine 
1#include "DST_Parser.h"
2
3#define DHL_FAIL_NULL_POINTER    0x02
4#define DHL_FAIL_INVALID_SIZE    0x07
5#define DHL_FAIL_INVALID_PARAM   0x08
6#define DHL_FAIL_OUT_OF_RESOURCE 0x0A
7#define DHL_FAIL_INVALID_TABLEID 0x23
8#define DHL_FAIL_INVALID_VERSION 0x24
9
10#ifndef SysASSERT
11#ifdef DTAR
12#define SysASSERT(cond)     do { if (!((cond)) { fprintf(stderr, "|%s:%d| ASSERT failed.\n", __FUNCTION__, __LINE__); } } while(0)
13#else
14#define SysASSERT(cond)
15#endif
16#endif
17
18#define checkMemoryError(p)                     if (p == 0) {err = DHL_FAIL_OUT_OF_RESOURCE ; goto ParseExit;}
19
20
21#if 0
22____MEM_CHAIN____()
23#endif
24
25typedef struct memElement {
26        void*                   userData;
27        struct memElement       *next;
28} memElement_t, *memElementPtr_t;
29
30typedef struct memChainHead {
31        memElementPtr_t element;
32} memChainHead_t, *memChainHeadPtr_t;
33
34typedef struct memChainHead* memId_t;
35
36/* API */
37#define memChainCreate(a)                 _memChainCreate((a), __func__, __LINE__)
38#define memChainDestroy(a)              _memChainDestroy((a), __func__, __LINE__)
39#define memChainAlloc(a, b)             _memChainAlloc((a), (b),  __func__, __LINE__)
40
41static int _memChainCreate (memId_t *memId, const char *func, int nLine)
42{
43        if (memId == 0) return DHL_FAIL_INVALID_PARAM;
44        memChainHeadPtr_t memChainHeadPtr = (memChainHeadPtr_t)_DST_OS_Calloc(sizeof(memChainHead_t), 1, func, nLine);
45        if (memChainHeadPtr == 0) return DHL_FAIL_OUT_OF_RESOURCE;
46        memChainHeadPtr->element = 0;
47        *memId = memChainHeadPtr; /* set instance */
48        return 0;
49}
50
51static void _memChainDestroy (memId_t memId, const char *func, int nLine)
52{
53        if (!memId) return;
54        memChainHeadPtr_t               memChainHeadPtr = (memChainHeadPtr_t)memId;
55        /* free the memElements */
56        memElementPtr_t currElem = memChainHeadPtr->element;
57        while (currElem != 0) {
58                memElementPtr_t prevElem = currElem;
59                currElem = currElem->next;
60                _DST_OS_Free(prevElem , func, nLine);
61        }
62        /* lastly, free the memChainHead */
63        _DST_OS_Free(memChainHeadPtr , func, nLine);
64}
65
66static void* _memChainAlloc (memId_t memId, DS_U32 size, const char *func, int nLine)
67{
68        memElementPtr_t memElementPtr = (memElementPtr_t)_DST_OS_Calloc(sizeof(memElement_t) + size + 8, 1, func, nLine);
69        if (memElementPtr == 0) return 0;
70
71        void *p = (void *)(((DS_U8 *)(memElementPtr) + sizeof(memElement_t)));
72        /* align on 64-bit boundary */
73        memElementPtr->userData = (void *)((DS_U32)(((DS_U8 *)p)+8) & ((~0) << 3));
74        void *rptr = memElementPtr->userData;
75        /* insert element in list */
76        memChainHeadPtr_t               memChainHeadPtr = (memChainHeadPtr_t)memId;
77        memElementPtr->next = memChainHeadPtr->element;
78        memChainHeadPtr->element = memElementPtr;
79        return (rptr);
80}
81
82#if 0
83____PAT____()
84#endif
85
86int DHL_PSI_ParsePAT( DS_U8 **sectionArr, MPEG_PAT **returnPat)
87{
88        if (sectionArr == 0 || sectionArr[0] == 0 || returnPat == 0) return (DHL_FAIL_NULL_POINTER);
89        int numSections = get_last_section_number(sectionArr[0]) + 1;
90
91        /* now verify all other sections are present */
92        int i;
93        for ( i = 1; i < numSections; i++) if (sectionArr[i] == 0) return (DHL_FAIL_NULL_POINTER);
94
95        int numPrograms = 0;
96        int err = 0;
97        for ( i = 0; i < numSections; ++i)
98        {
99                DS_U8 *p = sectionArr[i];
100                if (p[SECTION_TID] != PROGRAM_ASSOCIATION_SECTION)
101                {
102                        //This thing isn't a PAT. Stop right here.
103                        if (0) DST_Printf("PAT: Bad table ID.");
104                        err = DHL_FAIL_INVALID_TABLEID;
105                        break;
106                }
107                if ((p[SECTION_LEN_HI] & 0x80) != 0x80)
108                {
109                        if (0) DST_Printf("PAT: section_syntax_indicator not set");
110                }
111                if ((p[SECTION_LEN_HI] & 0x40) != 0x00)
112                {
113                        if (0) DST_Printf("PAT: private_indicator set");
114                }
115                if (i > p[SECTION_NUM_LAST])
116                {
117                        if (0) DST_Printf("PAT: last_section_number > section_number");
118                }
119                /*
120                 * The PAT has a fixed number of bytes in its main loop with no
121                 * descriptors. We have the standard 8 byte header and the trailing
122                 * 4 byte CRC. The rest should be an integral number of programs.
123                 */
124                int len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
125                if (len < 16 || (len - 12) % 4 != 0)
126                {
127                        if (0) DST_Printf("PAT: Inappropriate section length(%d)\n",len);
128                        //LEON_20050916 | ADD for add patch
129                        //      - hangup  when input abnormal PAT section.
130                        err = DHL_FAIL_INVALID_TABLEID;
131                        break;
132                }
133                int slots = (len - 12) / 4;
134                p += SECTION_HEADER_LENGTH;
135                int j;
136                for (j = 0; j < slots; ++j, p += 4) {
137                        int program_number = (p[0] << 8) + p[1];
138                        if (program_number != 0)
139                        {
140                                numPrograms++;
141                        }
142                }
143        }
144        if (err) return err;
145        /* create the memChain */
146        memId_t                 memId = 0;
147        err = memChainCreate(&memId);
148        if (err) return err;
149
150        MPEG_PAT *pat = (MPEG_PAT *)((memId_t *)(memChainAlloc(memId,sizeof(MPEG_PAT)+sizeof(memId_t))) + 1);
151        if (pat == 0)
152        {
153                memChainDestroy(memId);
154                return DHL_FAIL_OUT_OF_RESOURCE;
155        }
156
157        pat->programs = (MPEG_PAT_program *)memChainAlloc(memId,sizeof(MPEG_PAT_program)*numPrograms);
158        if (pat->programs == 0)
159        {
160                memChainDestroy(memId);
161                return DHL_FAIL_OUT_OF_RESOURCE;
162        }
163
164        pat->section_number = 0;
165        pat->last_section_number = 0;
166        pat->isWholePAT = true;
167
168        /*
169         * Second pass, we fill in the table.
170         * We assume that everything we verified or warned about above is still
171         * true. We already bailed out on fatal errors
172         */
173        int index = 0;
174        for ( i = 0; i < numSections; ++i)
175        {
176                DS_U8 *p = sectionArr[i];
177                int len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
178
179                int transport_stream_id = ((p[SECTION_TID_EXT_HI] << 8) |
180                                                                p[SECTION_TID_EXT_LO]);
181                int version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >>
182                                                        SECTION_VERSION_SHIFT;
183                bool current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0;
184
185                if (i == 0)
186                {
187                        pat->transport_stream_id = transport_stream_id;
188                        pat->version_number = version_number;
189                        pat->current_next_indicator = current_next_indicator;
190                }
191                else
192                {
193                        if (pat->transport_stream_id != transport_stream_id)
194                        {
195                                if (0) DST_Printf("PAT: Inconsistent transport_stream_id");
196                        }
197                        if(pat->version_number != version_number)
198                        {
199                                if (0) DST_Printf("ParsePAT: inconsistent version_number");
200                        }
201                        if(pat->current_next_indicator != current_next_indicator)
202                        {
203                                if (0) DST_Printf("ParsePAT: inconsistent current_next_indicator");
204                        }
205                }
206                int slots = (len - 12) / 4;
207                p += SECTION_HEADER_LENGTH;
208                int j;
209                for ( j = 0; j < slots; ++j, p += 4)
210                {
211                        int program_number = (p[0]<<8) + p[1];
212                        int pid = ((p[2]<<8) + p[3]) & PID_MASK;
213                        if (program_number == 0)
214                        {
215                                if (pat->networkPIDPresent)
216                                {
217                                        if (0) DST_Printf("PAT: More than one network_PID");
218                                }
219                                else
220                                {
221                                        pat->networkPIDPresent = true;
222                                        pat->network_PID = pid;
223                                }
224                        }
225                        else
226                        {
227                                bool bDuplicate = false;
228                                int k;
229                                for ( k = 0; k < index; ++k)
230                                {
231                                        if (pat->programs[k].program_number != program_number) continue;
232                                        if (0) DST_Printf("PAT: Duplicate program number");
233                                        bDuplicate = true;
234                                        break;
235                                }
236                                if (bDuplicate == false)
237                                {
238                                        pat->programs[index].program_number = program_number;
239                                        pat->programs[index].program_map_PID = pid;
240                                        index++;
241                                }
242                        }
243                }
244        }
245        pat->numPrograms = index;
246        *(((memId_t *)pat)-1) = memId;
247        *returnPat = pat;
248        return(err);
249}
250
251#if 0
252____SDT____()
253#endif
254
255static int GetMpegDescriptor (DS_U8 *descriptors, DS_U16 len, DS_U8 tag,
256                                                        DS_U16 instance, DS_U8 **descriptor)
257{
258        if (descriptors == 0 || len == 0 || descriptor == 0) return DHL_FAIL_INVALID_PARAM;
259
260        DS_U16 nCount = 0;
261        int nPos = 0;
262        while (nPos < len)
263        {
264                DS_U8 nTag = descriptors[nPos];
265                DS_U8 nLen = descriptors[nPos+1];
266                if (nPos + nLen + 2 > len) break; // ÀԷµȵ¥ÀÌÅÍÀÇ ¹üÀ§¸¦ ¹ù¾î³ª µ¥ÀÌÅͰ¡ Àִ°æ¿ì
267                if (nTag == tag)
268                {
269                        if (nCount == instance)
270                        {
271                                *descriptor = &descriptors[nPos];
272                                return 0;
273                        }
274                        nCount++;
275                }
276                nPos += (nLen + 2);
277        }
278        return DHL_FAIL_INVALID_PARAM;
279}
280
281static int GetMpegDescriptorCount (DS_U8 *descriptors, DS_U16 len, DS_U8 tag)
282{
283        if (descriptors == 0 || len == 0) return 0;
284
285        int nCount = 0;
286        int nPos = 0;
287        while (nPos < len)
288        {
289                DS_U8 nTag = descriptors[nPos];
290                DS_U8 nLen = descriptors[nPos+1];
291                if (nPos + nLen + 2 > len) break; // ÀԷµȵ¥ÀÌÅÍÀÇ ¹üÀ§¸¦ ¹ù¾î³ª µ¥ÀÌÅͰ¡ Àִ°æ¿ì
292                if (nTag == tag) nCount++;
293                nPos += (nLen + 2);
294        }
295        return nCount;
296}
297
298static void DHL_PSI_ParseServiceDescriptor(DS_U8 *p_desc, memId_t memId, dvb_service_descriptor_t **pp_service_desc)
299{
300        if ( !p_desc || !pp_service_desc ) return;
301        dvb_service_descriptor_t *p_service = (dvb_service_descriptor_t *)memChainAlloc(memId, sizeof(dvb_service_descriptor_t));
302        p_service->service_type = p_desc[2];
303  p_service->i_provider_name_length = p_desc[3];
304  p_service->p_provider_name = 0;
305  if (p_service->i_provider_name_length)
306  {
307                p_service->p_provider_name = (DS_U8 *)memChainAlloc(memId, p_service->i_provider_name_length);
308                memcpy( p_service->p_provider_name, &p_desc[4], p_service->i_provider_name_length );
309        }
310  p_service->i_service_name_length = p_desc[4+p_service->i_provider_name_length];
311  p_service->p_service_name = 0;
312        if (p_service->i_service_name_length)
313        {
314                p_service->p_service_name = (DS_U8 *)memChainAlloc(memId, p_service->i_service_name_length);
315                memcpy( p_service->p_service_name, &p_desc[5+p_service->i_provider_name_length], p_service->i_service_name_length );
316        }
317        *pp_service_desc = p_service;
318}
319
320static void DHL_PSI_ParseLogoTransmissionDescriptor( DS_U8 *p, memId_t memId, arib_logo_transmission_descriptor_t **pp_logo_transmission )
321{
322        DS_U8 len = p[1];
323        if (len < 2) return;
324        arib_logo_transmission_descriptor_t *p_logo_transmission = (arib_logo_transmission_descriptor_t *)memChainAlloc(memId, sizeof(arib_logo_transmission_descriptor_t));
325        p_logo_transmission->logo_transmission_type = p[2];
326        switch (p_logo_transmission->logo_transmission_type)
327        {
328                case 0x01:
329                        p_logo_transmission->logo_id = (( p[3] & 0x1 ) << 8 ) + p[4];
330                        p_logo_transmission->logo_version = (( p[5] & 0x7 ) << 8 ) + p[6];
331                        p_logo_transmission->download_data_id = ( p[7] << 8 ) + p[8];
332                        break;
333                case 0x02:
334                        p_logo_transmission->logo_id = (( p[3] & 0x1 ) << 8 ) + p[4];
335                        break;
336                case 0x03:
337                        p_logo_transmission->logo_char = (DS_U8 *)memChainAlloc(memId, len-1);
338                        memcpy(p_logo_transmission->logo_char, &p[3], len-2);
339                        p_logo_transmission->logo_char[len-2] = 0; // make null terminate
340                        break;
341        }
342        *pp_logo_transmission = p_logo_transmission;
343}
344
345int DHL_PSI_ParseDvbSdt(DS_U8 **sectionArr, bool b_actual, dvb_sdt_t **pp_sdt)
346{
347        if (!sectionArr || !pp_sdt || !sectionArr[0]) return DHL_FAIL_NULL_POINTER;
348        int numSections = get_last_section_number(sectionArr[0]) + 1;
349        /* now verify all other sections are present */
350        int i;
351        for ( i = 1; i < numSections; i++) if (sectionArr[i] == 0) return DHL_FAIL_NULL_POINTER;
352        // First pass, we verify section syntax and count the number of programs
353        int numChannels = 0;
354        for ( i = 0; i < numSections; ++i)
355        {
356                DS_U8 *p = sectionArr[i];
357                if ( (b_actual && p[SECTION_TID] != DVB_TID_service_description_section_actual) ||
358                        (!b_actual && p[SECTION_TID] != DVB_TID_service_description_section_other) )
359                {
360                        if (0) DST_Printf("SDT: Bad table ID. (0x%02X)\n", p[SECTION_TID]);
361                        return DHL_FAIL_INVALID_TABLEID;
362                }
363                if ((p[SECTION_LEN_HI] & 0x80) != 0x80) if (0) DST_Printf("SDT: section_syntax_indicator not set\n");
364
365                int len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3 - 4; // + header - crc
366                int nPos = 11;
367                while (len - nPos >= 5)
368                {
369                        numChannels++;
370                        DS_U16 descriptor_length = ((p[nPos+3]<<8)+p[nPos+4]) & 0xFFF;
371                        nPos += (descriptor_length + 5);
372                }
373        }
374        /* create the memChain */
375        memId_t                 memId = 0;
376        if (memChainCreate(&memId)) return DHL_FAIL_OUT_OF_RESOURCE;
377
378        dvb_sdt_t *p_sdt = (dvb_sdt_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_sdt_t)+sizeof(memId_t))) + 1);
379        if (!p_sdt)
380        {
381                memChainDestroy(memId);
382                return DHL_FAIL_OUT_OF_RESOURCE;
383        }
384        p_sdt->numServices = numChannels;
385        p_sdt->services = 0;
386        if (numChannels)
387        {
388                p_sdt->services = (dvb_sdt_service_t *)memChainAlloc(memId,sizeof(dvb_sdt_service_t)*numChannels);
389                if (!p_sdt->services)
390                {
391                        memChainDestroy(memId);
392                        return DHL_FAIL_OUT_OF_RESOURCE;
393                }
394        }
395        // Now fill-out all the remaining fields over the all sections.
396        int index = 0;
397//      int i;
398        for ( i = 0; i < numSections; ++i)
399        {
400                DS_U8 *p = sectionArr[i];
401                if (i == 0) /* First section */
402                {
403                        p_sdt->transport_stream_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]);
404                        p_sdt->version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> SECTION_VERSION_SHIFT;
405                        p_sdt->original_network_id = ((p[8]<<8) + p[9]);
406                        p_sdt->section_number = p[SECTION_NUM];
407                        p_sdt->last_section_number = p[SECTION_NUM_LAST];
408                }
409                int len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3 - 4;// + header - crc
410                int nPos = 11;
411                while (len - nPos >= 5)
412                {
413                        dvb_sdt_service_t *p_service = &p_sdt->services[index];
414      p_service->service_id                 = ((p[nPos+0]<<8)+p[nPos+1]);
415      p_service->EIT_user_defined_flags     = (p[nPos+2]>>2) & 0x07;
416      p_service->EIT_schedule_flag          = (p[nPos+2] & 0x02) ? true : false;
417      p_service->EIT_present_following_flag = (p[nPos+2] & 0x01) ? true : false;
418      p_service->running_status             = (p[nPos+3]>>5) & 0x07;
419      p_service->free_CA_mode               = ((p[nPos+3]>>4) & 0x01) ? true : false;
420      p_service->descriptor_length          = ((p[nPos+3]<<8)+p[nPos+4]) & 0xFFF;
421      p_service->descriptors = 0;
422      if (p_service->descriptor_length)
423      {
424        p_service->descriptors = (DS_U8 *)memChainAlloc( memId, p_service->descriptor_length);
425                if (!p_service->descriptors)
426                                {
427                                        memChainDestroy(memId);
428                                        return DHL_FAIL_OUT_OF_RESOURCE;
429                                }
430                                memcpy(p_service->descriptors, &p[nPos+5], p_service->descriptor_length);
431        }
432      DS_U8* p_desc = 0;
433      int err=GetMpegDescriptor(p_service->descriptors, p_service->descriptor_length, DVB_TAG_service_descriptor, 0, &p_desc);
434      p_service->p_service_desc = 0;
435      if ( p_desc && err == 0 ) DHL_PSI_ParseServiceDescriptor( p_desc, memId, &(p_service->p_service_desc) );
436      // Parse service_descriptor if available.
437                        p_desc = 0;
438                        err=GetMpegDescriptor( p_service->descriptors, p_service->descriptor_length, ARIB_TAG_logo_transmission_descriptor, 0, &p_desc );
439                        p_service->logo_tx_desc = 0;
440                        if ( p_desc && err == 0 ) DHL_PSI_ParseLogoTransmissionDescriptor( p_desc, memId, &(p_service->logo_tx_desc) );
441
442                        index++;
443                        nPos += (p_service->descriptor_length + 5);
444                }
445        }
446        *(((memId_t *)p_sdt)-1) = memId;
447        *pp_sdt = p_sdt;
448        return 0;
449}
450
451void DHL_PSI_FreeMpegSection (void *sectionPtr)
452{
453        if (sectionPtr) memChainDestroy(*(((memId_t *)sectionPtr)-1));
454}
455
456void DHL_PSI_ParseNetworkNameDescriptor(DS_U8 *p_desc, memId_t memId, DS_U8 **pp_network_name, DS_U8 *p_length)
457{
458        if (!p_desc || !pp_network_name || !p_length) return;
459        *p_length = p_desc[1];
460        *pp_network_name = (DS_U8 *)memChainAlloc( memId, *p_length);
461        memcpy(*pp_network_name, &p_desc[2], *p_length);
462}
463
464static int DHL_PSI_ParseSystemManagementDescriptor(DS_U8* p, DS_U16* p_system_management_id)
465{
466        if (!p_system_management_id || !p || p[1] < 2) return -1;
467        *p_system_management_id = (p[2]<<8) + p[3];
468        return 0;
469}
470
471static void DHL_PSI_ParseServiceListDescriptor(DS_U8 *p_desc, memId_t memId, dvb_service_list_descriptor_t **pp_service_list)
472{
473        (*pp_service_list) = 0;
474        if (p_desc[1] < 3) return;
475        (*pp_service_list) = (dvb_service_list_descriptor_t *)memChainAlloc(memId, sizeof(dvb_service_list_descriptor_t));
476  (*pp_service_list)->numServices = p_desc[1]/3;
477  (*pp_service_list)->p_service = (dvb_service_t *)memChainAlloc(memId, sizeof(dvb_service_t)*((*pp_service_list)->numServices));
478  int i;
479  for ( i=0; i < (*pp_service_list)->numServices; i++)
480  {
481        (*pp_service_list)->p_service[i].service_id = (p_desc[i*3+2] << 8) + p_desc[i*3+3];
482        (*pp_service_list)->p_service[i].service_type = p_desc[i*3+4];
483        }
484}
485
486static int DHL_PSI_ParseTSInformationDescriptor(DS_U8* p, memId_t memId, arib_ts_information_descriptor_t **pp_ts_info)
487{
488        if (p[1] < 2) return DHL_FAIL_INVALID_SIZE;
489
490        arib_ts_information_descriptor_t *p_ts_info = *pp_ts_info = (arib_ts_information_descriptor_t *)memChainAlloc(memId,sizeof(arib_ts_information_descriptor_t));
491        p_ts_info->remote_control_key_id = p[2];
492        p_ts_info->ts_name_length = (p[3]>>2) & 0x3F;
493        p_ts_info->transmission_type_count = p[3]&0x03;
494
495        if (p_ts_info->ts_name_length)
496        {
497                p_ts_info->ts_name = (DS_U8 *)memChainAlloc(memId, p_ts_info->ts_name_length);
498                memcpy(p_ts_info->ts_name, &p[4], p_ts_info->ts_name_length);
499        }
500
501        if (!p_ts_info->transmission_type_count) return 0;
502
503        arib_transmission_type_t *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);
504        int off = 4 + p_ts_info->ts_name_length;
505        int i;
506        for ( i=0; i < p_ts_info->transmission_type_count; i++)
507        {
508                p_tx_type[i].transmission_type_info = p[off];
509                p_tx_type[i].number_of_service = p[off+1];
510                p_tx_type[i].service_id = 0;
511                off += 2;
512                if (p_tx_type[i].number_of_service)
513                {
514                        DS_U16 *p_service_id = p_tx_type[i].service_id = (DS_U16 *)memChainAlloc(memId, (p_tx_type[i].number_of_service) * sizeof(DS_U16));
515                        int j;
516                        for ( j=0; j <p_tx_type[i].number_of_service; j++)
517                        {
518                                p_service_id[j] = (p[off]<<8)+p[off+1];
519                                off += 2;
520                        }
521                }
522        }
523        return 0;
524}
525
526
527int DHL_PSI_ParseDvbNit(DS_U8 **sectionArr, bool b_actual, dvb_nit_t **pp_nit)
528{
529        if (!sectionArr || !pp_nit || !sectionArr[0]) return DHL_FAIL_NULL_POINTER;
530        int numSections = get_last_section_number(sectionArr[0]) + 1;
531        /* now verify all other sections are present */
532        int i;
533        for ( i=1; i<numSections; i++) if (sectionArr[i] == 0) return (DHL_FAIL_NULL_POINTER);
534
535        // First pass, we verify section syntax and count the number of programs
536        int numStreams = 0;
537        for ( i = 0; i < numSections; ++i)
538        {
539                DS_U8* p = sectionArr[i];
540
541                if ( (b_actual && p[SECTION_TID] != DVB_TID_network_information_section_actual) ||
542                     (!b_actual && p[SECTION_TID] != DVB_TID_network_information_section_other) )
543                {
544                        if (0) DST_Printf("NIT: Bad table ID. (0x%02X)", p[SECTION_TID]);
545                        return  DHL_FAIL_INVALID_TABLEID;
546                }
547
548                if ((p[SECTION_LEN_HI] & 0x80) != 0x80) if (0) DST_Printf("NIT: section_syntax_indicator not set");
549
550                // Counts number of transport_stream.
551                int network_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF;
552                int transport_loop_length = ((p[10+network_descriptor_length]<<8) + p[11+network_descriptor_length]) & 0xFFF;
553                p = &sectionArr[i][12+network_descriptor_length];
554                int k;
555                for( k=0; k<transport_loop_length; )
556                {
557                        int original_network_id = ((p[k+2]<<8)+p[k+3]);
558                        if (original_network_id) numStreams++;
559                        int transport_descriptor_length = ((p[k+4]<<8)+p[k+5]) & 0xFFF;
560                        k += (6+transport_descriptor_length);
561                }
562        }
563
564        /* create the memChain */
565        memId_t memId = 0;
566        if (memChainCreate(&memId)) return DHL_FAIL_OUT_OF_RESOURCE;
567
568        dvb_nit_t *p_nit = (dvb_nit_t *)memChainAlloc(memId, sizeof(dvb_nit_t));
569        if (!p_nit)
570        {
571                memChainDestroy(memId);
572                return DHL_FAIL_OUT_OF_RESOURCE;
573        }
574  p_nit->num_transport_stream = numStreams;
575        if (numStreams)
576        {
577                p_nit->transport_streams = (transport_stream_t *)memChainAlloc(memId,sizeof(transport_stream_t)*numStreams);
578                if (!p_nit->transport_streams)
579                {
580                        memChainDestroy(memId);
581                        return DHL_FAIL_OUT_OF_RESOURCE;
582                }
583        }
584
585        // Now fill-out all the remaining fields over the all sections.
586        transport_stream_t *p_ts = p_nit->transport_streams;
587        for ( i = 0; i < numSections; ++i)
588        {
589                DS_U8* p = sectionArr[i];
590                int network_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]);
591                int version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> SECTION_VERSION_SHIFT;
592    int network_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF;
593    int last_section_number = p[SECTION_NUM_LAST];
594
595                if (i == 0) /* First section */
596                {
597                        p_nit->network_id = network_id;
598                        p_nit->version_number = version_number;
599                        p_nit->section_number = p[SECTION_NUM];
600                        p_nit->last_section_number = last_section_number;
601                        p_nit->network_descriptor_length = network_descriptor_length;
602                        if (network_descriptor_length)
603                        {
604                        DS_U8 *p_desc = 0;
605                        p_nit->network_descriptors = (DS_U8 *)memChainAlloc(memId, network_descriptor_length);
606                        memcpy(p_nit->network_descriptors, &p[10], network_descriptor_length);
607                                int err=GetMpegDescriptor(p_nit->network_descriptors, network_descriptor_length, DVB_TAG_network_name_descriptor, 0, &p_desc);
608        if (!err) DHL_PSI_ParseNetworkNameDescriptor( p_desc, memId, &(p_nit->p_network_name), &(p_nit->network_name_length) );
609        err=GetMpegDescriptor( p_nit->network_descriptors, network_descriptor_length, ARIB_TAG_system_management_descriptor, 0, &p_desc );
610        if (!err)
611        {
612                if (!DHL_PSI_ParseSystemManagementDescriptor( p_desc, &p_nit->system_management_id ))
613                        p_nit->b_system_management_id = true;
614        }
615      }
616                }
617                int transport_loop_length = ((p[10+network_descriptor_length]<<8) + p[11+network_descriptor_length]) & 0xFFF;
618                p = &sectionArr[i][12+network_descriptor_length];
619                int k;
620                for( k=0; k < transport_loop_length; )
621                {
622                        int original_network_id = ((p[k+2]<<8)+p[k+3]);
623                        int transport_descriptor_length = ((p[k+4]<<8)+p[k+5]) & 0xFFF;
624                        if (original_network_id)
625                        {
626                          p_ts->transport_stream_id = ((p[k+0]<<8)+p[k+1]);
627                          p_ts->original_network_id = original_network_id;
628                          p_ts->transport_descriptor_length = transport_descriptor_length;
629                          if ( transport_descriptor_length )
630                          {
631                                p_ts->transport_descriptors = (DS_U8 *)memChainAlloc( memId, transport_descriptor_length);
632                                if (!p_ts->transport_descriptors)
633                                        {
634                                                memChainDestroy(memId);
635                                                return DHL_FAIL_OUT_OF_RESOURCE;
636                                        }
637                            memcpy( p_ts->transport_descriptors, &p[k+6], transport_descriptor_length);
638                            DS_U8* p_desc = 0;
639                            int err=GetMpegDescriptor( p_ts->transport_descriptors, transport_descriptor_length,
640                                                 DVB_TAG_service_list_descriptor, 0, &p_desc );
641                                if (!err) DHL_PSI_ParseServiceListDescriptor( p_desc, memId, &(p_ts->p_service_list) );
642                                err=GetMpegDescriptor( p_ts->transport_descriptors, transport_descriptor_length,
643                                                 ARIB_TAG_ts_information_descriptor, 0, &p_desc );
644                                if (!err) DHL_PSI_ParseTSInformationDescriptor( p_desc, memId, &(p_ts->p_ts_info) );
645                          }
646                          p_ts++;
647                        }
648                  k += (6+transport_descriptor_length);
649                }
650        }
651        *(((memId_t *)p_nit)-1) = memId;
652        *pp_nit = p_nit;
653        return 0;
654}
655
656static void DHL_PSI_ParseSIParameterDescriptor( DS_U8 *p, memId_t memId, arib_si_parameter_descriptor_t **pp_si_parameter )
657{
658        *pp_si_parameter = 0;
659        if ( p[1] < 3 ) return;
660
661        arib_si_parameter_descriptor_t *p_si_parameter = *pp_si_parameter = (arib_si_parameter_descriptor_t *)memChainAlloc(memId, sizeof(arib_si_parameter_descriptor_t));
662        p_si_parameter->parameter_version = p[2];
663        p_si_parameter->update_time = ( p[3] << 8 ) + p[4];
664        if ( p[1] < 5) return;
665        int numTable = 0;
666        int i;
667        for ( i = 5; i <= p[1];)
668        {
669                int table_id = p[i];
670                int table_description_length = p[i+1];
671                if (table_id) numTable++;
672                i += (2+table_description_length);
673        }
674        if (numTable == 0) return;
675        p_si_parameter->numTable = numTable;
676        arib_table_description_t *p_table_description = p_si_parameter->table_description = (arib_table_description_t *)memChainAlloc(memId, numTable*sizeof(arib_table_description_t));
677        for ( i = 5; i <= p[1];)
678        {
679                int table_id = p[i];
680                int table_description_length = p[i+1];
681                if (table_id)
682                {
683                        p_table_description->table_id = table_id;
684                        p_table_description->table_description_length = table_description_length;
685                        if (p_table_description->table_description_length)
686                        {
687                                p_table_description->table_description_byte = (DS_U8 *)memChainAlloc(memId, p_table_description->table_description_length);
688                                memcpy(p_table_description->table_description_byte, &p[i+2], p_table_description->table_description_length);
689                        }
690                        p_table_description++;
691                }
692                i += (2+table_description_length);
693        }
694}
695
696static void DHL_PSI_ParseExtendedBroadcasterDescriptor(DS_U8 *p_desc, memId_t memId, arib_extended_broadcaster_descriptor_t **pp_ex_broad)
697{
698    DS_U8 *p = p_desc;
699    arib_extended_broadcaster_descriptor_t *p_ex_broad;
700    int i, j, len, off;
701    int num, numId;
702
703    if (!p_desc || !pp_ex_broad || !memId)
704        return;
705
706    len = p_desc[1];
707    if ( len<4 )
708        return;
709
710    p_ex_broad = (arib_extended_broadcaster_descriptor_t *)memChainAlloc(memId, sizeof(arib_extended_broadcaster_descriptor_t));
711    p_ex_broad->broadcaster_type = (p[2] >> 4) & 0x0F;
712
713    off = 3;
714
715        if ( p_ex_broad->broadcaster_type == 0x1 )
716        {
717                p_ex_broad->terrestrial_broadcaster_id = (p[off+0] << 8) + p[off+1];
718                p_ex_broad->num_affiliation_id = (p[off+2] & 0xF0) >> 4;
719                p_ex_broad->num_broadcaster_id = p[off+2] & 0xF;
720                off += 3;
721
722                if ( p_ex_broad->num_affiliation_id )
723                {
724                        num = p_ex_broad->num_affiliation_id;
725                        p_ex_broad->affiliation_id = (DS_U8 *)memChainAlloc(memId, num);
726                        memcpy(p_ex_broad->affiliation_id, &p[off], num);
727                        off += num;
728                }
729
730                if ( p_ex_broad->num_broadcaster_id )
731                {
732                        numId = p_ex_broad->num_broadcaster_id;
733                        p_ex_broad->origin_network_id = (DS_U16 *)memChainAlloc(memId, numId*2);
734                        p_ex_broad->broadcaster_id = (DS_U8 *)memChainAlloc(memId, numId);
735
736                        for ( i=0, j=0 ; j < p_ex_broad->num_broadcaster_id ; i++, j+=3 )
737                        {
738                                p_ex_broad->origin_network_id[i] = (p[off+0] << 8) + p[off+1];
739                                p_ex_broad->broadcaster_id[i] = p[off+2];
740                                off += 3;
741                                p_ex_broad->origin_network_id++;
742                                p_ex_broad->broadcaster_id++;
743                        }
744                }
745        }
746        else if ( p_ex_broad->broadcaster_type == 0x2 )
747        {
748                p_ex_broad->terrestrial_broadcaster_id = (p[off+0] << 8) + p[off+1];
749                p_ex_broad->num_affiliation_id = (p[off+2] >> 4) & 0xF;
750                p_ex_broad->num_broadcaster_id = p[off+2] & 0xF;
751                off += 3;
752
753                if ( p_ex_broad->num_affiliation_id )
754                {
755                        num = p_ex_broad->num_affiliation_id;
756                        p_ex_broad->affiliation_id = (DS_U8 *)memChainAlloc(memId, num);
757                        memcpy(p_ex_broad->affiliation_id, &p[off], num);
758                        off += num;
759                }
760
761                if ( p_ex_broad->num_broadcaster_id )
762                {
763                        numId = p_ex_broad->num_broadcaster_id;
764                        p_ex_broad->origin_network_id = (DS_U16 *)memChainAlloc(memId, numId*2);
765                        p_ex_broad->broadcaster_id = (DS_U8 *)memChainAlloc(memId, numId);
766
767                        for ( i=0, j=0 ; j < p_ex_broad->num_broadcaster_id ; i++, j+=3 )
768                        {
769                                p_ex_broad->origin_network_id[i] = (p[off+0] << 8) + p[off+1];
770                                p_ex_broad->broadcaster_id[i] = p[off+2];
771                                off += 3;
772                                p_ex_broad->origin_network_id++;
773                                p_ex_broad->broadcaster_id++;
774                        }
775                }
776        }
777        else
778        {
779                p_ex_broad->affiliation_id = (DS_U8 *)0;
780                p_ex_broad->origin_network_id = (DS_U16 *)0;
781                p_ex_broad->broadcaster_id = (DS_U8 *)0;
782        }
783
784    *pp_ex_broad = p_ex_broad;
785}
786
787int DHL_PSI_ParseDvbBit(DS_U8 **sectionArr, dvb_bit_t **pp_bit)
788{
789        int err = 0;
790        int i, k;
791        int len, lenBroadcaster;
792        int numBroadcaster;
793        int numSections;
794//      int index;
795        const DS_U8 *p;
796        dvb_bit_t *p_bit = 0;
797        int version_number;
798        int first_descriptor_length;
799//      bool current_next_indicator;
800//      bool broadcast_view_propriety;
801        memId_t                 memId = 0;
802//      memChainSetup_t         memSetup = {MEM_LIMIT,0,0};
803    broadcaster_t *p_broadcaster;
804
805        if ((sectionArr == 0) || (pp_bit == 0))
806        {
807                return (DHL_FAIL_NULL_POINTER);
808        }
809
810        if (sectionArr[0] == 0)
811        {
812                return (DHL_FAIL_NULL_POINTER);
813        }
814        else
815        {
816                numSections = get_last_section_number(sectionArr[0]) + 1;
817        }
818
819        /* now verify all other sections are present */
820        for (i=1; i<numSections; i++)
821    {
822                if (sectionArr[i] == 0) {
823                        return (DHL_FAIL_NULL_POINTER);
824                }
825        }
826
827        /*
828         * First pass, we verify section syntax and count the number of broadcaster.
829         */
830        numBroadcaster = 0;
831        for (i = 0; i < numSections; ++i)
832        {
833                p = sectionArr[i];
834
835                if( p == 0 )
836                {
837                    if (0) DST_Printf( "%s: 0 section", __func__);
838                        return DHL_FAIL_NULL_POINTER;
839                }
840
841                if ( p[SECTION_TID] != DVB_TID_broadcaster_information_section )
842                {
843                        /*
844                         * This thing isn't a PAT. Stop right here.
845                         */
846                        if (0) DST_Printf("BIT: Bad table ID. (0x%02X)", p[SECTION_TID]);
847                        err = DHL_FAIL_INVALID_TABLEID;
848                        goto ParseExit;
849                }
850
851                if ((p[SECTION_LEN_HI] & 0x80) != 0x80)
852                {
853                        if (0) DST_Printf("BIT: section_syntax_indicator not set");
854                }
855
856                len = ((p[1]<<8) + p[2]) & 0xFFF;
857
858        /*
859         * Counts number of broadcaster.
860         */
861//              broadcast_view_propriety = ((p[8] >> 4) & 0x1);
862                first_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF;
863                lenBroadcaster = len - (7+first_descriptor_length+4);
864                p = &sectionArr[i][10+first_descriptor_length];
865
866                for ( k=0 ; k < lenBroadcaster ; )
867                {
868                        int broadcaster_id;
869                        int broadcaster_descriptor_length;
870
871                        broadcaster_id = p[k+0];
872                        broadcaster_descriptor_length = ((p[k+1]<<8) + p[k+2]) & 0xFFF;
873
874                        if ( broadcaster_id )
875                                numBroadcaster++;
876
877                        k += 3+broadcaster_descriptor_length;
878                }
879        }
880
881        /* create the memChain */
882        err = memChainCreate(&memId);
883
884        if (err)
885        {
886                goto ParseExit;
887        }
888
889        p_bit = (dvb_bit_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_bit_t)+sizeof(memId_t))) + 1);
890        checkMemoryError(p_bit);
891
892    p_bit->num_broadcaster = numBroadcaster;
893
894    if ( numBroadcaster > 0 )
895    {
896        p_bit->broadcaster = (broadcaster_t *)memChainAlloc(memId,sizeof(broadcaster_t)*numBroadcaster);
897        checkMemoryError(p_bit->broadcaster);
898    }
899    else
900    {
901        p_bit->broadcaster = (broadcaster_t *)0;
902    }
903
904    /*
905     * Now fill-out all the remaining fields over the all sections.
906     */
907//      index = 0;
908        p_bit->first_descriptors = (DS_U8 *)0;
909        p_broadcaster = p_bit->broadcaster;
910
911        for (i = 0 ; i < numSections ; ++i)
912        {
913            DS_U8 last_section_number;
914            int original_network_id;
915
916                p = &sectionArr[i][0];
917                len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3; // lenth + 3 ( p[0] (TID) + p[1] + p[2] )
918
919                original_network_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]);
920                version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >>
921                                                        SECTION_VERSION_SHIFT;
922//              current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0;
923        first_descriptor_length = ((p[8]<<8) + p[9]) & 0xFFF;
924        last_section_number = p[SECTION_NUM_LAST];
925
926                if (i == 0)
927                {
928                    /* First section */
929                        p_bit->original_network_id = original_network_id;
930                        p_bit->version_number = version_number;
931                        p_bit->section_number = p[SECTION_NUM];
932                        p_bit->last_section_number = last_section_number;
933
934                        if ( p_bit->first_descriptors == (DS_U8 *)0 && first_descriptor_length )
935                        {
936                                DS_U8 *p_desc = (DS_U8 *)0;
937
938                                p_bit->first_descriptor_length = first_descriptor_length;
939                                p_bit->first_descriptors = (DS_U8 *)memChainAlloc(memId, first_descriptor_length);
940                                memcpy(p_bit->first_descriptors, &p[10], first_descriptor_length);
941                                /*
942                                 * Parse SI Parameter Descriptor
943                                 */
944                                err = GetMpegDescriptor( p_bit->first_descriptors,
945                                                                 first_descriptor_length,
946                                                                                 ARIB_TAG_si_parameter_descriptor,
947                                                                                 0, /* only find first one. */
948                                                                                 &p_desc );
949
950                                if ( p_desc && !err )
951                                {
952                                        DHL_PSI_ParseSIParameterDescriptor( p_desc, memId, &(p_bit->p_si_parameter));
953                                }
954                                else
955                                {
956//                                      if (0) DST_Printf("BIT: cannot find si_parameter descriptor.\n");
957                                        p_bit->p_si_parameter = (arib_si_parameter_descriptor_t *)0;
958                                }
959
960                        }
961                }
962                else
963                {
964                        if (p_bit->original_network_id != original_network_id)
965                                if (0) DST_Printf("BIT: Inconsistent original_network_id (0x%x, 0x%x)\n", p_bit->original_network_id, original_network_id);
966                        if (p_bit->version_number != version_number)
967                                if (0) DST_Printf("BIT: inconsistent version_number (0x%x, 0x%x)\n", p_bit->version_number, version_number);
968            if (p_bit->first_descriptor_length != first_descriptor_length)
969                if (0) DST_Printf("BIT: Inconsistent first_descriptor_length (0x%x, 0x%x)\n", p_bit->first_descriptor_length, first_descriptor_length );
970            if (p_bit->last_section_number != last_section_number )
971                if (0) DST_Printf("BIT: Inconsistent last_section_number (0x%x, 0x%x)\n", p_bit->last_section_number, last_section_number);
972                }
973
974            lenBroadcaster = len - first_descriptor_length - 4 - 3 - 7;
975
976                if ( !p_broadcaster && lenBroadcaster )
977                {
978                        if (0) DST_Printf("BIT: broadcaster length is not 0, but broadcaster is 0.\n");
979                err = DHL_FAIL_INVALID_TABLEID;
980                goto ParseExit;
981
982                }
983
984                p = &sectionArr[i][10+first_descriptor_length];
985
986                for ( k = 0 ; k < lenBroadcaster ; )
987                {
988                        int broadcaster_id;
989                        int broadcaster_descriptor_length;
990
991                        broadcaster_id = p[k+0];
992                        broadcaster_descriptor_length = ((p[k+1]<<8) + p[k+2]) & 0xFFF;
993                        p_broadcaster->broadcaster_id = broadcaster_id;
994                        p_broadcaster->broadcaster_descriptor_length = broadcaster_descriptor_length;
995
996                        if ( broadcaster_descriptor_length )
997                        {
998                                DS_U8 *p_desc = (DS_U8 *)0;
999
1000                                p_broadcaster->broadcaster_descriptors = (DS_U8 *)memChainAlloc(memId, broadcaster_descriptor_length);
1001
1002                                if ( !(p_broadcaster->broadcaster_descriptors) )
1003                                {
1004                                        err = DHL_FAIL_OUT_OF_RESOURCE;
1005                                        goto ParseExit;
1006                                }
1007
1008                                memcpy(p_broadcaster->broadcaster_descriptors, &p[k+3], broadcaster_descriptor_length);
1009
1010                                /*
1011                                 * Parse Extended Broadcaster Descriptor
1012                                 */
1013                                err = GetMpegDescriptor( p_broadcaster->broadcaster_descriptors,
1014                                                                 broadcaster_descriptor_length,
1015                                                                                 ARIB_TAG_extended_broadcaster_descriptor,
1016                                                                                 0, /* only find first one. */
1017                                                                                 &p_desc );
1018
1019                                if ( p_desc && !err )
1020                                {
1021                                        DHL_PSI_ParseExtendedBroadcasterDescriptor(p_desc, memId, &(p_broadcaster->p_ex_broad));
1022                                }
1023                                else
1024                                {
1025//                                      if (0) DST_Printf("BIT: cannot find extended_broadcaster descriptor.\n");
1026                                        p_broadcaster->p_ex_broad = (arib_extended_broadcaster_descriptor_t *)0;
1027                                }
1028
1029                                p_desc = (DS_U8 *)0;
1030
1031                                /*
1032                                 * Parse SI Parameter Descriptor
1033                                 */
1034                                err = GetMpegDescriptor( p_broadcaster->broadcaster_descriptors,
1035                                                                 broadcaster_descriptor_length,
1036                                                                                 ARIB_TAG_si_parameter_descriptor,
1037                                                                                 0, /* only find first one. */
1038                                                                                 &p_desc );
1039
1040                                if ( p_desc && !err )
1041                                {
1042                                        DHL_PSI_ParseSIParameterDescriptor( p_desc, memId, &(p_broadcaster->p_si_parameter));
1043                                }
1044                                else
1045                                {
1046//                                      if (0) DST_Printf("BIT: cannot find si_parameter descriptor.\n");
1047                                        p_broadcaster->p_si_parameter = (arib_si_parameter_descriptor_t *)0;
1048                                }
1049                        }
1050            else
1051            {
1052                                p_broadcaster->broadcaster_descriptors = (DS_U8 *)0;
1053                                p_broadcaster->p_ex_broad = (arib_extended_broadcaster_descriptor_t *)0;
1054                                p_broadcaster->p_si_parameter = (arib_si_parameter_descriptor_t *)0;
1055            }
1056
1057            k += 3+broadcaster_descriptor_length;
1058            p_broadcaster++;
1059        }
1060        }
1061
1062    err = 0;
1063        *(((memId_t *)p_bit)-1) = memId;
1064        if (0) DST_Printf("p_bit = 0x%x\n",(int)memId);
1065        *pp_bit = p_bit;
1066        memId = 0;      /* Don't delete below */
1067
1068ParseExit:
1069        if (memId)
1070        {
1071                /* delete the patSection memory */
1072                memChainDestroy(memId);
1073        }
1074
1075        return(err);
1076}
1077
1078static void DHL_PSI_ParseLocalTimeOffsetDescriptor( DS_U8 *p, int numItems, dvb_local_time_t *p_desc )
1079{
1080    int len, idx;
1081    int num_lto;
1082    dvb_local_time_t *p_lt;
1083    DS_U8 *puc;
1084
1085    if ( !p || !p_desc )
1086        return;
1087
1088    len = p[1];
1089    num_lto = len / 13;
1090
1091    p_lt = p_desc;
1092    for (idx=0; idx<num_lto; idx++)
1093    {
1094        puc = &p[idx*13 + 2];
1095
1096        p_lt->country_code = (puc[2]<<16)+(puc[1]<<8)+puc[0];
1097        p_lt->country_region_id = puc[3]>>2;
1098        p_lt->local_time_offset_polarity = puc[3] & 1;
1099        p_lt->local_time_offset = (puc[4]<<8)+puc[5];
1100        p_lt->time_of_change_date = (puc[6]<<8)+puc[7];
1101        p_lt->time_of_change_time = (puc[8]<<16)+(puc[9]<<8)+puc[10];
1102        p_lt->next_time_offset = (puc[11]<<8)+puc[12];
1103
1104        p_lt++;
1105    }
1106}
1107
1108int DHL_PSI_ParseDvbTot(DS_U8 *sectionArr, dvb_tot_t **pp_tot)
1109{
1110        int err = 0;
1111        const DS_U8 *p;
1112        int len, descriptor_length;
1113        dvb_tot_t *p_tot = 0;
1114        memId_t                 memId = 0;
1115//      memChainSetup_t         memSetup = {MEM_LIMIT,0,0};
1116
1117        if (sectionArr == 0 || (pp_tot == 0))
1118        {
1119                return (DHL_FAIL_NULL_POINTER);
1120        }
1121
1122    p = sectionArr;
1123        if ( p[SECTION_TID] != DVB_TID_time_offset_section )
1124        {
1125                /*
1126                 * This thing isn't a TDT. Stop right here.
1127                 */
1128                if (0) DST_Printf("TOT: Bad table ID. (0x%02X)\n", p[SECTION_TID]);
1129                err = DHL_FAIL_INVALID_TABLEID;
1130                goto ParseExit;
1131        }
1132
1133        if ((p[SECTION_LEN_HI] & 0x80) != 0x00) {
1134                if (0) DST_Printf("TOT: section_syntax_indicator set\n");
1135        }
1136
1137        len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
1138    if ( len < 8 )
1139    {
1140                err = DHL_FAIL_INVALID_TABLEID;
1141        goto ParseExit;
1142    }
1143
1144        /* create the memChain */
1145        err = memChainCreate(&memId);
1146        if (err) {
1147                goto ParseExit;
1148        }
1149
1150        p_tot = (dvb_tot_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_tot_t)+sizeof(memId_t))) + 1);
1151        checkMemoryError(p_tot);
1152
1153    p_tot->date = (p[3]<<8)+p[4];
1154    p_tot->time = (p[5]<<16)+(p[6]<<8)+p[7];
1155
1156    p_tot->p_lto = (dvb_local_time_offset_descriptor_t *)0;
1157    p_tot->descriptor_length = 0;
1158    p_tot->descriptors = (DS_U8 *)0;
1159    if ( len >= 11 )
1160    {
1161        DS_U8 *p_desc = (DS_U8 *)0;
1162        dvb_local_time_t *p_lt;
1163        int numLocaltime;
1164
1165        descriptor_length = ((p[8]<<8)+p[9]) & 0xFFF;
1166        if ( descriptor_length > 1024 )
1167        {
1168            if (0) DST_Printf("TOT: too long descriptor length %d\n", descriptor_length);
1169            goto NoDescExit;
1170        }
1171
1172        /*
1173         * Counts number of local_time.
1174         */
1175        err=GetMpegDescriptor( (DS_U8 *)&p[10],
1176                       descriptor_length,
1177                       DVB_TAG_local_time_offset_descriptor,
1178                       0,
1179                       &p_desc );
1180        if (err==0 && p_desc)
1181        {
1182            numLocaltime = p_desc[1] / 13;
1183            if (numLocaltime <= 0)
1184                goto NoDescExit;
1185
1186            p_tot->p_lto = (dvb_local_time_offset_descriptor_t *)memChainAlloc(memId, sizeof(dvb_local_time_offset_descriptor_t));
1187            checkMemoryError(p_tot->p_lto);
1188
1189            p_lt = p_tot->p_lto->p_local_time = (dvb_local_time_t *)memChainAlloc(memId, sizeof(dvb_local_time_t)*numLocaltime);
1190            checkMemoryError(p_tot->p_lto->p_local_time);
1191
1192            p_tot->p_lto->i_num_local_time = numLocaltime;
1193            DHL_PSI_ParseLocalTimeOffsetDescriptor( p_desc, numLocaltime, p_lt );
1194        }
1195        else
1196        {
1197            if (0) DST_Printf("TOT: cannot find local_time_offset descriptor.\n");
1198        }
1199    }
1200
1201NoDescExit:
1202    err = 0;
1203        *(((memId_t *)p_tot)-1) = memId;
1204        *pp_tot = p_tot;
1205        memId = 0;      /* Don't delete below */
1206
1207ParseExit:
1208
1209        if (memId)
1210        {
1211                /* delete the patSection memory */
1212                memChainDestroy(memId);
1213        }
1214
1215        return(err);
1216}
1217
1218static void DHL_PSI_ParseDataContentDescriptor( DS_U8 *p, memId_t memId, arib_data_content_descriptor_t **pp_data_content )
1219{
1220        int i=0, j=0, k=0, len;
1221        int err=0;
1222        arib_data_content_descriptor_t *p_data_content;
1223
1224        len = p[1];
1225
1226        if ( len < 8 )
1227                return;
1228
1229        p_data_content = (arib_data_content_descriptor_t *)memChainAlloc(memId, sizeof(arib_data_content_descriptor_t));
1230
1231        if ( p_data_content == (arib_data_content_descriptor_t *)0 )
1232        {
1233                err = DHL_FAIL_OUT_OF_RESOURCE;
1234                goto ParseDescriptorExit;
1235        }
1236
1237        p_data_content->data_component_id = ( p[2] << 8 ) + p[3];
1238        p_data_content->entry_component = p[4];
1239        p_data_content->selector_length = p[5];
1240
1241        if ( p_data_content->selector_length > 0 )
1242        {
1243                DS_U8 *p_selector_byte;
1244
1245                p_selector_byte = p_data_content->selector_byte = (DS_U8 *)memChainAlloc( memId, p_data_content->selector_length );
1246
1247                if ( p_selector_byte == (DS_U8 *)0 )
1248                {
1249                        err = DHL_FAIL_OUT_OF_RESOURCE;
1250                        goto ParseDescriptorExit;
1251                }
1252
1253                for ( i = 0 ; i < p_data_content->selector_length ; i++ )
1254                {
1255                        *p_selector_byte = p[i+6];
1256                        p_selector_byte++;
1257                }
1258        }
1259
1260        p_data_content->num_of_component_ref = p[i+6];
1261
1262        if ( p_data_content->num_of_component_ref > 0 )
1263        {
1264                DS_U8 *p_component_ref;
1265
1266                p_component_ref = p_data_content->component_ref = (DS_U8 *)memChainAlloc( memId, p_data_content->num_of_component_ref );
1267
1268                if ( p_component_ref == (DS_U8 *)0 )
1269                {
1270                        err = DHL_FAIL_OUT_OF_RESOURCE;
1271                        goto ParseDescriptorExit;
1272                }
1273
1274                for ( j = 0 ; j < p_data_content->num_of_component_ref ; j++ )
1275                {
1276                        *p_component_ref = p[i+j+7];
1277                        p_component_ref++;
1278                }
1279        }
1280
1281        p_data_content->ISO_639_language_code = ( p[i+j+7] << 16 ) + ( p[i+j+8] << 8 ) + p[i+j+9];
1282        p_data_content->text_length = p[i+j+10];
1283
1284        if ( p_data_content->text_length > 0 )
1285        {
1286                p_data_content->text_char = (DS_U8 *)memChainAlloc( memId, p_data_content->text_length+1 );
1287
1288                if ( p_data_content->text_char == (DS_U8 *)0 )
1289                {
1290                        err = DHL_FAIL_OUT_OF_RESOURCE;
1291                        goto ParseDescriptorExit;
1292                }
1293
1294                for ( k = 0 ; k < p_data_content->text_length ; k++ )
1295                {
1296                        p_data_content->text_char[k] = p[i+j+k+11];
1297                }
1298
1299                p_data_content->text_char[k] = '\0';
1300        }
1301
1302        *pp_data_content = p_data_content;
1303
1304ParseDescriptorExit:
1305        if ( err )
1306        {
1307                if (0) DST_Printf("ERROR: %s returns %d!\n", __func__, err);
1308        }
1309}
1310
1311static void DHL_PSI_ParseShortEventDescriptor(DS_U8 *p_desc, memId_t memId, dvb_short_event_descriptor_t **pp_short_event)
1312{
1313    dvb_short_event_descriptor_t *p_short_event;
1314    int event_name_length, text_length;
1315    DS_U32 ISO_639_language_code;
1316
1317    if (!p_desc || !pp_short_event)
1318        return;
1319
1320    if (p_desc[0] != DVB_TAG_short_event_descriptor || p_desc[1] < 5)
1321    {
1322        if (0) DST_Printf("%s: invalid tag or length, tag: 0x%x, length: 0x%x\n", __func__, p_desc[0], p_desc[1]);
1323        return;
1324    }
1325
1326    ISO_639_language_code = (p_desc[2]<<16) + (p_desc[3]<<8) + p_desc[4];
1327
1328    p_short_event = (dvb_short_event_descriptor_t *)memChainAlloc(memId, sizeof(dvb_short_event_descriptor_t));
1329    if ( !p_short_event )
1330        return;
1331
1332    p_short_event->ISO_639_language_code = ISO_639_language_code;
1333    p_short_event->event_name_length = event_name_length = p_desc[5];
1334    p_short_event->p_event_name = (DS_U8 *)0;
1335    if (event_name_length)
1336    {
1337        p_short_event->p_event_name = (DS_U8 *)memChainAlloc(memId, event_name_length+1);
1338        SysASSERT(p_short_event->p_event_name);
1339        memcpy( p_short_event->p_event_name, &p_desc[6], event_name_length );
1340        p_short_event->p_event_name[event_name_length] = '\0';
1341    }
1342
1343    p_short_event->text_length = text_length = p_desc[6+event_name_length];
1344    p_short_event->p_text = (DS_U8 *)0;
1345    if (text_length)
1346    {
1347        p_short_event->p_text = (DS_U8 *)memChainAlloc(memId, text_length+1);
1348        SysASSERT(p_short_event->p_event_name);
1349        memcpy(p_short_event->p_text, &p_desc[7+event_name_length], text_length);
1350        p_short_event->p_text[text_length] = '\0';
1351    }
1352
1353    *pp_short_event = p_short_event;
1354
1355    return;
1356}
1357
1358static void DHL_PSI_ParseAudioComponentDescriptor( DS_U8 *p, memId_t memId, arib_audio_component_descriptor_t **pp_audio_component )
1359{
1360        int i, len;
1361        DS_U8 count;
1362        int err=0;
1363        arib_audio_component_descriptor_t *p_audio_component;
1364
1365        len = p[1];
1366
1367        if ( len < 8 )
1368                return;
1369
1370        p_audio_component = (arib_audio_component_descriptor_t *)memChainAlloc(memId, sizeof(arib_audio_component_descriptor_t));
1371
1372        if ( p_audio_component == (arib_audio_component_descriptor_t *)0 )
1373        {
1374                err = DHL_FAIL_OUT_OF_RESOURCE;
1375                goto ParseDescriptorExit;
1376        }
1377
1378        p_audio_component->stream_content = ( p[2] & 0xF );
1379        p_audio_component->component_type = p[3];
1380        p_audio_component->component_tag = p[4];
1381        p_audio_component->stream_type = p[5];
1382        p_audio_component->simulcast_group_tag = p[6];
1383        p_audio_component->ES_multi_lingual_flag = ( p[7] & 0x80 ) >> 7;
1384        p_audio_component->main_component_flag = ( p[7] & 0x40 ) >> 6;
1385        p_audio_component->quality_indicator = ( p[7] & 0x30 ) >> 4;
1386        p_audio_component->sampling_rate = ( p[7] & 0xE ) >> 1;
1387        p_audio_component->ISO_639_language_code = ( p[8] << 16 ) + ( p[9] << 8 ) + p[10];
1388
1389        if ( p_audio_component->ES_multi_lingual_flag == 1 )
1390        {
1391        //      DS_U8 *p_text_char;
1392
1393                p_audio_component->ISO_639_language_code_2 = ( p[11] << 16 ) + ( p[12] << 8 ) + p[13];
1394                count = len - 12;
1395                p_audio_component->text_char = (DS_U8 *)memChainAlloc( memId, count+1 );
1396
1397                if ( p_audio_component->text_char == (DS_U8 *)0 )
1398                {
1399                        err = DHL_FAIL_OUT_OF_RESOURCE;
1400                        goto ParseDescriptorExit;
1401                }
1402
1403                for ( i = 0 ; i < count ; i++ )
1404                {
1405                        p_audio_component->text_char[i] = (p[i+14]);
1406                }
1407
1408                p_audio_component->text_char[i] = '\0';
1409        }
1410        else
1411        {
1412                count = len - 9;
1413                p_audio_component->text_char = (DS_U8 *)memChainAlloc( memId, count+1 );
1414
1415                if ( p_audio_component->text_char == (DS_U8 *)0 )
1416                {
1417                        err = DHL_FAIL_OUT_OF_RESOURCE;
1418                        goto ParseDescriptorExit;
1419                }
1420
1421                for ( i = 0 ; i < count ; i++ )
1422                {
1423                        p_audio_component->text_char[i] = (p[i+11]);
1424                }
1425
1426                p_audio_component->text_char[i] = '\0';
1427        }
1428
1429        *pp_audio_component = p_audio_component;
1430
1431ParseDescriptorExit:
1432        if ( err )
1433        {
1434                if (0) DST_Printf("ERROR: %s returns %d!\n", __func__, err);
1435        }
1436}
1437
1438static void DHL_PSI_ParseExtendedEventDescriptor(DS_U8 *p_desc, memId_t memId, dvb_extended_event_descriptor_t **pp_extended_event)
1439{
1440    dvb_extended_event_descriptor_t *p_extended_event;
1441    DS_U32 ISO_639_language_code;
1442    int length_of_items, text_length;
1443    int i, numItems;
1444    DS_U8 *p = (DS_U8 *)0;
1445
1446    if (!p_desc || !pp_extended_event)
1447        return;
1448
1449    if (p_desc[0] != DVB_TAG_extended_event_descriptor || p_desc[1] < 6)
1450    {
1451        if (0) DST_Printf("%s: invalid tag or length, tag: 0x%x, length: 0x%x\n", __func__, p_desc[0], p_desc[1]);
1452        return;
1453    }
1454
1455    ISO_639_language_code = (p_desc[3]<<16) + (p_desc[4]<<8) + (p_desc[5]);
1456
1457    p_extended_event = (dvb_extended_event_descriptor_t *)memChainAlloc(memId, sizeof(dvb_extended_event_descriptor_t));
1458    if (!p_extended_event)
1459        return;
1460
1461    p_extended_event->descriptor_number = (p_desc[2]>>4) & 0x0F;
1462    p_extended_event->last_descriptor_number = (p_desc[2]) & 0x0F;
1463    p_extended_event->ISO_639_language_code = ISO_639_language_code;
1464
1465    length_of_items = p_desc[6];
1466    p_extended_event->numItems = 0;
1467    p_extended_event->items = (dvb_ext_event_item_t *)0;
1468
1469    if (length_of_items)
1470    {
1471        int item_description_length;
1472        int item_length;
1473        dvb_ext_event_item_t *p_item;
1474
1475        /*
1476         * Calculate number of items.
1477         */
1478        numItems = 0;
1479
1480        p = &p_desc[7];
1481        for(i=0; i<length_of_items; /* i is incremented in the loop */)
1482        {
1483            item_description_length = p[i+0];
1484            item_length = p[i+item_description_length+1];
1485
1486            i += item_description_length+item_length+2;
1487            numItems++;
1488        }
1489
1490        p_extended_event->numItems = numItems;
1491        p_item = p_extended_event->items = (dvb_ext_event_item_t *)memChainAlloc(memId, sizeof(dvb_ext_event_item_t)*numItems);
1492        for(i=0; i<length_of_items; /* i is incremented in the loop */)
1493        {
1494            item_description_length = p[i+0];
1495            item_length = p[i+item_description_length+1];
1496
1497            p_item->item_description_length = item_description_length;
1498            if (item_description_length)
1499            {
1500                p_item->p_item_description = (DS_U8 *)memChainAlloc(memId, item_description_length+1);
1501                memcpy(p_item->p_item_description, &p[i+1], item_description_length);
1502                p_item->p_item_description[item_description_length] = '\0';
1503            }
1504
1505            p_item->item_length = item_length;
1506            if (item_length)
1507            {
1508                p_item->p_item_char = (DS_U8 *)memChainAlloc(memId, item_length+1);
1509                memcpy(p_item->p_item_char, &p[i+2+item_description_length], item_length);
1510                p_item->p_item_char[item_length] = '\0';
1511            }
1512
1513            i += item_description_length+item_length+2;
1514            p_item++;
1515        }
1516    }
1517
1518    text_length = p_desc[7+length_of_items];
1519    p_extended_event->text_length = text_length;
1520    p_extended_event->p_text = (DS_U8 *)0;
1521    if (text_length)
1522    {
1523        p_extended_event->p_text = (DS_U8 *)memChainAlloc(memId, text_length);
1524        memcpy(p_extended_event->p_text, &p_desc[8+length_of_items], text_length);
1525    }
1526
1527    *pp_extended_event = p_extended_event;
1528    return;
1529}
1530
1531static void DHL_PSI_ParseParentalRatingDescriptorEx (DS_U8* p, memId_t memId, dvb_parental_rating_descriptor_t **pp_desc)
1532{
1533        //memId_t                           memId;
1534        //memChainSetup_t               memSetup = {MEM_LIMIT,0,0};
1535        DS_U8                           length;
1536        int                     err=0;
1537    dvb_parental_rating_descriptor_t *p_desc;
1538    dvb_parental_rating_entry_t *p_entry;
1539    int i, numEntries;
1540    DS_U8               *p_data;
1541
1542        length = p[1];
1543
1544#if 0
1545        /* create the memChain */
1546        err = memChainCreate(&memId);
1547        if (err != 0)
1548                goto ParseDescriptorExit;
1549#endif
1550
1551        /* create the descriptor memory */
1552        p_desc = (dvb_parental_rating_descriptor_t *)(memChainAlloc(memId,sizeof(dvb_parental_rating_descriptor_t)));
1553        if (p_desc == (dvb_parental_rating_descriptor_t *)0)
1554        {
1555                err = DHL_FAIL_OUT_OF_RESOURCE;
1556                goto ParseDescriptorExit;
1557        }
1558
1559    numEntries = length>>2;
1560    if (numEntries<=0)
1561        goto ParseDescriptorExit;
1562
1563    p_entry = (dvb_parental_rating_entry_t *)memChainAlloc(memId, sizeof(dvb_parental_rating_entry_t)*numEntries);
1564    if (p_entry == (dvb_parental_rating_entry_t *)0)
1565    {
1566                err = DHL_FAIL_OUT_OF_RESOURCE;
1567                goto ParseDescriptorExit;
1568        }
1569        p_desc->i_num_ratings = numEntries;
1570    p_desc->p_ratings = p_entry;
1571
1572    p_data = &p[2];
1573    for (i=0; i<numEntries; i++)
1574    {
1575        p_entry->country_code = (p_data[0]<<16) + (p_data[1]<<8) + (p_data[2]<<0);
1576        p_entry->rating_value = p_data[3];
1577        p_data += 4;
1578        p_entry++;
1579    }
1580
1581        *(((memId_t *)(p_desc))-1) = memId;
1582        memId = 0;              /* so memChain not deleted */
1583    *pp_desc = p_desc;
1584
1585ParseDescriptorExit:
1586        if (memId) {
1587                /* delete the descriptor memory */
1588                memChainDestroy(memId);
1589        }
1590
1591        if (err)
1592        {
1593            if (0) DST_Printf("ERROR: %s returns %d!\n", __func__, err);
1594        }
1595}
1596
1597static void DHL_PSI_ParseEventGroupDescriptor(DS_U8 *p_desc, memId_t memId, arib_event_group_descriptor_t **pp_event_grp)
1598{
1599    DS_U8 *p = p_desc;
1600    arib_event_group_descriptor_t *p_event_grp;
1601    arib_event_t *p_event;
1602    arib_other_event_t *p_other_event;
1603    int i, len, off;
1604//    int numEvent;
1605
1606    if (!p_desc || !pp_event_grp || !memId)
1607        return;
1608
1609    len = p_desc[1];
1610    if (len<5)
1611        return;
1612
1613    p_event_grp = (arib_event_group_descriptor_t *)memChainAlloc(memId, sizeof(arib_event_group_descriptor_t));
1614    p_event_grp->group_type = (p[2] >> 4) & 0x0F;
1615    p_event_grp->numEvents = p[2]&0x0F;
1616
1617    off = 3 /*3=descriptor_tag+length+group_type + event_cnt*/;
1618    if ( p_event_grp->numEvents )
1619    {
1620        p_event = p_event_grp->p_event = (arib_event_t *)memChainAlloc(memId, sizeof(arib_event_t) * p_event_grp->numEvents);
1621        for (i=0; i<p_event_grp->numEvents && off <= (len+2); i++)
1622        {
1623            p_event->service_id = (p[0+off]<<8)+p[1+off];
1624            p_event->event_id   = (p[2+off]<<8)+p[3+off];
1625
1626            off += 4;
1627            p_event++;
1628        }
1629    }
1630
1631    p_event_grp->numOtherNetworkEvents = 0;
1632    if ( p_event_grp->group_type == 4 || p_event_grp->group_type == 5 )
1633    {
1634        p_event_grp->numOtherNetworkEvents = (len-off-2)/8;
1635        if (p_event_grp->numOtherNetworkEvents)
1636        {
1637            p_other_event = p_event_grp->p_other_event = (arib_other_event_t *)memChainAlloc(memId, sizeof(arib_other_event_t) * p_event_grp->numOtherNetworkEvents);
1638            for (i=0; i<p_event_grp->numOtherNetworkEvents; i++)
1639            {
1640                p_other_event->original_network_id = (p[0+off]<<8)+p[1+off];
1641                p_other_event->transport_stream_id = (p[2+off]<<8)+p[3+off];
1642                p_other_event->service_id          = (p[4+off]<<8)+p[5+off];
1643                p_other_event->event_id            = (p[6+off]<<8)+p[7+off];
1644
1645                off += 8;
1646                p_other_event++;
1647            }
1648        }
1649    }
1650
1651    *pp_event_grp = p_event_grp;
1652}
1653
1654int DHL_PSI_ParseDvbEit(DS_U8 **sectionArr, DVB_EIT **pp_eit)
1655{
1656        if (!sectionArr || !sectionArr[0] || !pp_eit) return DHL_FAIL_NULL_POINTER;
1657        *pp_eit = 0;
1658        // 2013.10.07 section ¸ðµå·Î EIT¸¦ ¹ÞÀ¸¹Ç·Î Ç×»ó section °¹¼ö´Â 1ÀÌ´Ù.
1659        int numSections = 1; //get_last_section_number(sectionArr[0]) + 1;
1660        // First pass, we verify section syntax and count the number of events.
1661        int numEvents = 0;
1662        int i;
1663        for ( i = 0; i < numSections; ++i)
1664        {
1665                if (!sectionArr[i]) break;
1666                DS_U8* p = sectionArr[i];
1667                if ((p[SECTION_LEN_HI] & 0x80) != 0x80) if (0) DST_Printf("EIT: section_syntax_indicator not set\n");
1668                int len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
1669                DS_U16 service_id = (p[SECTION_TID_EXT_HI] << 8) + p[SECTION_TID_EXT_LO];
1670                if (service_id == 0) continue;
1671                // Counts number of services.
1672                int event_length = len - 14/*table_id to last_table_id*/ - 4/*crc_32*/;
1673                if ( event_length < 12 ) continue; // No events are available for this section.
1674                p = &sectionArr[i][14];
1675                int k;
1676                for( k=0; (k+12+4)<event_length; )
1677                {
1678                        int descriptor_loop_length = ((p[k+10]<<8)+p[k+11]) & 0xFFF;
1679                        numEvents++;
1680                        k += 12+descriptor_loop_length;
1681                }
1682        }
1683        if (numEvents == 0) return 0;
1684        // if (0) DST_Printf("EIT: numEvents: %d\n", numEvents);
1685
1686        // create the memChain
1687        memId_t memId = 0;
1688        if (memChainCreate(&memId)) return DHL_FAIL_OUT_OF_RESOURCE;
1689
1690        dvb_eit_t* p_eit = (dvb_eit_t *)((memId_t *)(memChainAlloc(memId,sizeof(dvb_eit_t)+sizeof(memId_t))) + 1);
1691        if (p_eit == 0)
1692        {
1693                memChainDestroy(memId);
1694                return DHL_FAIL_OUT_OF_RESOURCE;
1695        }
1696        dvb_eit_event_t *p_event = p_eit->eit_events = (dvb_eit_event_t *)memChainAlloc(memId,sizeof(dvb_eit_event_t)*numEvents);
1697  if (p_eit->eit_events == 0)
1698        {
1699                memChainDestroy(memId);
1700                return DHL_FAIL_OUT_OF_RESOURCE;
1701        }
1702        p_eit->numEvents = numEvents;
1703
1704        // Now fill-out all the remaining fields over the all sections.
1705//      int index = 0;
1706        for ( i = 0; i < numSections; ++i)
1707        {
1708                if(!sectionArr[i]) break;
1709                DS_U8* p = sectionArr[i];
1710                int len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
1711                DS_U16 service_id = ((p[SECTION_TID_EXT_HI] << 8) | p[SECTION_TID_EXT_LO]);
1712                if (service_id == 0) continue;
1713                DS_U8 version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >> SECTION_VERSION_SHIFT;
1714                DS_U8 last_section_number = p[SECTION_NUM_LAST];
1715                DS_U8 table_id = p[SECTION_TID];
1716                DS_U16 transport_stream_id = ((p[8]<<8) + p[9]);
1717                DS_U16 original_network_id = ((p[10]<<8) + p[11]);
1718                DS_U8 segment_last_section_number = p[12];
1719                DS_U8 last_table_id = p[13];
1720
1721                if (i == 0)
1722                {
1723                        p_eit->table_id                    = table_id;
1724                        p_eit->service_id                  = service_id;
1725                        p_eit->version_number              = version_number;
1726                        p_eit->section_number              = p[6];
1727                        p_eit->last_section_number         = last_section_number;
1728                        p_eit->segment_last_section_number = segment_last_section_number;
1729                        p_eit->transport_stream_id         = transport_stream_id;
1730                        p_eit->original_network_id         = original_network_id;
1731                        p_eit->last_table_id               = last_table_id;
1732                }
1733                int event_length = len - 14/*table_id to last_table_id*/ - 4/*crc_32*/;
1734                if ( event_length < 12 ) continue; // No events are available for this section.
1735                p = &sectionArr[i][14];
1736                int k;
1737                for( k=0; (k+12+4)<event_length; )
1738                {
1739                        int descriptor_length = p_event->descriptor_length = ((p[k+10]<<8)+p[k+11]) & 0xFFF;
1740                        p_event->event_id = (p[k+0]<<8)+p[k+1];
1741                        p_event->start_date = (p[k+2]<<8)+p[k+3];
1742                        p_event->start_time = (p[k+4]<<16)+(p[k+5]<<8)+p[k+6];
1743                        p_event->duration = (p[k+7]<<16)+(p[k+8]<<8)+p[k+9];
1744                        p_event->running_status = (p[k+10]>>5) & 0x07;
1745                        p_event->free_CA_mode = (p[k+10]>>4) & 0x01;
1746      if (p_event->descriptor_length)
1747      {
1748        DS_U8 *p_desc_sect = p_event->descriptors = (DS_U8*)memChainAlloc(memId, p_event->descriptor_length);
1749        memcpy(p_event->descriptors, &p[k+12], p_event->descriptor_length);
1750       
1751        // ShortEventDescriptor°¡ 2°³ ÀÌ»óÀÎ °æ¿ì¸¦ À§ÇÏ¿© ¾øÀ» ¶§ ±îÁö ã¾Æ¼­ Parse.
1752        p_event->numShortEvents = GetMpegDescriptorCount(p_desc_sect, descriptor_length, DVB_TAG_short_event_descriptor);
1753        p_event->pp_short_event = (dvb_short_event_descriptor_t **)memChainAlloc(memId, sizeof(dvb_short_event_descriptor_t *) * p_event->numShortEvents);
1754        int m;
1755        for ( m = 0; m < p_event->numShortEvents; m++)
1756        {
1757                DS_U8* p_desc = 0;
1758                if (GetMpegDescriptor( p_desc_sect, descriptor_length, DVB_TAG_short_event_descriptor, m, &p_desc )) continue;
1759                DHL_PSI_ParseShortEventDescriptor(p_desc, memId, &p_event->pp_short_event[m]);
1760        }
1761
1762        // extended_event_descriptor°¡ 2°³ ÀÌ»óÀÎ °æ¿ì¸¦ À§ÇÏ¿© ¾øÀ» ¶§ ±îÁö ã¾Æ¼­ Parse.
1763        p_event->numExtendedEvents = GetMpegDescriptorCount(p_desc_sect, descriptor_length, DVB_TAG_extended_event_descriptor);
1764        p_event->pp_extended_event = (dvb_extended_event_descriptor_t **)memChainAlloc(memId, sizeof(dvb_extended_event_descriptor_t *) * p_event->numExtendedEvents);
1765        for ( m = 0; m < p_event->numExtendedEvents; m++)
1766        {
1767                DS_U8* p_desc = 0;
1768                if (GetMpegDescriptor( p_desc_sect, descriptor_length, DVB_TAG_extended_event_descriptor, m, &p_desc )) continue;
1769                DHL_PSI_ParseExtendedEventDescriptor(p_desc, memId, &p_event->pp_extended_event[m]);
1770        }
1771
1772        // Find Parental_Rating descriptor.
1773        p_event->numParentalRating = GetMpegDescriptorCount(p_desc_sect, descriptor_length, DVB_TAG_parental_rating_descriptor);
1774        p_event->pp_pr_desc = (dvb_parental_rating_descriptor_t **)memChainAlloc(memId, sizeof(dvb_parental_rating_descriptor_t *) * p_event->numParentalRating);
1775        for ( m = 0; m < p_event->numParentalRating; m++)
1776        {
1777                DS_U8* p_desc = 0;
1778                if (GetMpegDescriptor( p_desc_sect, descriptor_length, DVB_TAG_parental_rating_descriptor, m, &p_desc )) continue;
1779                DHL_PSI_ParseParentalRatingDescriptorEx(p_desc, memId, &p_event->pp_pr_desc[m]);
1780        }
1781
1782        // Find Event Group descriptor.
1783        DS_U8* p_desc = 0;
1784        if (!GetMpegDescriptor( p_desc_sect, descriptor_length, ARIB_TAG_event_group_descriptor, 0, &p_desc ))
1785        {
1786                DHL_PSI_ParseEventGroupDescriptor( p_desc, memId, &p_event->p_event_group );
1787        }
1788
1789        // Find Audio component descriptor.
1790        p_event->numAudioComponent = GetMpegDescriptorCount(p_desc_sect, descriptor_length, ARIB_TAG_audio_component_descriptor);
1791        p_event->pp_audio_component = (arib_audio_component_descriptor_t **)memChainAlloc(memId, sizeof(arib_audio_component_descriptor_t *) * p_event->numAudioComponent);
1792        for ( m = 0; m < p_event->numAudioComponent; m++)
1793        {
1794                DS_U8* p_desc = 0;
1795                if (GetMpegDescriptor( p_desc_sect, descriptor_length, ARIB_TAG_audio_component_descriptor, m, &p_desc )) continue;
1796                DHL_PSI_ParseAudioComponentDescriptor(p_desc, memId, &p_event->pp_audio_component[m]);
1797        }
1798
1799        // Data component descriptor
1800        p_event->numDataContent = GetMpegDescriptorCount(p_desc_sect, descriptor_length, ARIB_TAG_data_content_descriptor);
1801        p_event->pp_data_content = (arib_data_content_descriptor_t **)memChainAlloc(memId, sizeof(arib_data_content_descriptor_t *) * p_event->numDataContent);
1802        for ( m = 0; m < p_event->numDataContent; m++)
1803        {
1804                DS_U8* p_desc = 0;
1805                if (GetMpegDescriptor( p_desc_sect, descriptor_length, ARIB_TAG_data_content_descriptor, m, &p_desc )) continue;
1806                DHL_PSI_ParseDataContentDescriptor(p_desc, memId, &p_event->pp_data_content[m]);
1807        }
1808      }
1809      k += 12+descriptor_length;
1810      p_event++;
1811    }
1812        }
1813        *(((memId_t *)p_eit)-1) = memId;
1814        *pp_eit = p_eit;
1815        return 0;
1816}
1817
1818static int DHL_PSI_ParseStreamIdentifierDescriptor(DS_U8 *p, DS_U8 *p_component_tag)
1819{
1820        if (p[1] < 1) return -1;
1821        *p_component_tag = p[2];
1822        return 0;
1823}
1824
1825int DHL_PSI_ParsePMT( DS_U8 *section, MPEG_PMT **returnPmt)
1826{
1827        int err = 0;
1828        DS_S32 j, k;
1829//      DS_S32 index;
1830        DS_S32 numStreams;
1831        DS_S32 len, len2;
1832        MPEG_PMT *pmt;
1833        DS_S32 program_info_length, es_info_length;
1834//      memChainSetup_t         memSetup = {MEM_LIMIT,0,0};
1835        memId_t                 memId = 0;
1836        const DS_U8 *p;
1837        DS_U8 *q;
1838        int pmtSize = 0;
1839
1840        if( section == 0 || returnPmt == 0 )
1841                return DHL_FAIL_NULL_POINTER;
1842        /*
1843         * First pass, we verify section syntax and count the number of streams
1844         */
1845        p = section;
1846
1847        numStreams = 0;
1848        if (p[SECTION_TID] != TS_PROGRAM_MAP_SECTION) {
1849                /*
1850                 * This thing isn't a PMT. Stop right here.
1851                 */
1852                if (0) DST_Printf("PMT: Bad table ID.");
1853                err = DHL_FAIL_INVALID_TABLEID;
1854                goto ParseExit;
1855        }
1856        if ((p[SECTION_LEN_HI] & 0x80) != 0x80) {
1857                if (0) DST_Printf("PAT: section_syntax_indicator not set");
1858        }
1859        if ((p[SECTION_LEN_HI] & 0x40) != 0x00) {
1860                if (0) DST_Printf("PAT: private_indicator set");
1861        }
1862        len = (((p[SECTION_LEN_HI] & 0x0F) << 8) | p[SECTION_LEN_LO]) + 3;
1863        if (p[SECTION_NUM] != 0) {
1864                if (0) DST_Printf("PMT: section_number != 0");
1865        }
1866        if (p[SECTION_NUM_LAST] != 0) {
1867                if (0) DST_Printf("PAT: last_section_number != 0");
1868        }
1869        program_info_length = ((p[10]<<8) + p[11]) & 0x0FFF;
1870        if (program_info_length & 0x0C00) {
1871                if (0) DST_Printf("PMT: first 2 bits of program_info_length not 00");
1872        }
1873        len2 = len - program_info_length - 16;
1874        if (len2 < 0) {
1875                if (0) DST_Printf("PMT: program descriptors extend beyond section");
1876                err = DHL_FAIL_INVALID_PARAM;
1877                goto ParseExit;
1878        }
1879        p += program_info_length + 12;
1880        while (len2 > 0) {
1881                if (len2 < 5) {
1882                        if (0) DST_Printf("PMT: junk bytes at end of table");
1883                        break;
1884                }
1885                es_info_length = ((p[3]<<8) + p[4]) & 0x0FFF;
1886                if (es_info_length & 0x0C00) {
1887                        if (0) DST_Printf("PMT: first 2 bits of ES_info_length not 00");
1888                }
1889                if (len2 - es_info_length < 5) {
1890                        if (0) DST_Printf("PMT: elementary stream descriptors extend beyond section");
1891                        break;
1892                }
1893                /*
1894                 * This is a hack to repair corrupted PMT's which we have received
1895                 */
1896                {
1897                        DS_S32/*BK2003.11.18 <-DS_U32 by cafrii*/ hlen = es_info_length;
1898                        DS_U8 *hp = (DS_U8 *)&p[5];
1899                        DS_U32 dtype, dlen;
1900                        while(hlen > 0) {
1901                                dtype = hp[0];
1902                                dlen = hp[1];
1903                                if (dtype == 10 && dlen == 3) {
1904                                        hp[1] = 4;
1905                                        es_info_length++;
1906                                        ((DS_U8 *)p)[3] = es_info_length>>8;
1907                                        ((DS_U8 *)p)[4] = es_info_length&255;
1908                                        break;
1909                                }
1910                                hp += (dlen+2);
1911                                hlen -= (dlen+2);
1912                        }
1913                }
1914                /*
1915                 * End corrupted PMT hack
1916                 */
1917                len2 = len2 - es_info_length - 5;
1918                p += es_info_length + 5;
1919                numStreams++;
1920        }
1921        /*
1922         * At this point, numStreams has the number of streams, which we can
1923         * base the size of the PMT from.
1924         */
1925        /* create the memChain */
1926        err = memChainCreate(&memId);
1927        if (err) {
1928                goto ParseExit;
1929        }
1930        /* allocate memory for pmtSection */
1931        pmtSize = MPEG_PMTSize(numStreams);
1932        pmt = (MPEG_PMT *)((memId_t *)(memChainAlloc(memId, pmtSize + sizeof(memId_t))) + 1);
1933        checkMemoryError(pmt);
1934
1935        /*
1936         * Second pass, we fill in the table.
1937         * We assume that everything we verified or warned about above is still
1938         * true. We already bailed out on fatal errors
1939         */
1940//      index = 0;
1941        p = section;
1942/*      pmt->PID = desc->pid;*/
1943        pmt->program_number = ((p[SECTION_TID_EXT_HI] << 8) |
1944                                                        p[SECTION_TID_EXT_LO]);
1945        pmt->version_number = (p[SECTION_VERSION] & SECTION_VERSION_MASK) >>
1946                                                         SECTION_VERSION_SHIFT;
1947        pmt->current_next_indicator = (p[SECTION_VERSION] & SECTION_CNI_MASK) != 0;
1948        pmt->PCR_PID = ((p[8] << 8) | p[9]) & PID_MASK;
1949        pmt->numStreams = numStreams;
1950
1951        len2 = len - program_info_length - 16;
1952
1953        p += 12;
1954        pmt->descriptor_length = program_info_length;
1955        pmt->descriptors = (DS_U8 *)memChainAlloc(memId,program_info_length*sizeof(DS_U8));
1956        checkMemoryError(pmt->descriptors);
1957        for (j=0; j<program_info_length; j++) {
1958                pmt->descriptors[j]             = *p++;
1959        }
1960
1961        for (j = 0; j < numStreams; ++j) {
1962                pmt->streams[j].stream_type = p[0];
1963                pmt->streams[j].elementary_PID = ((p[1]<<8) | p[2]) & PID_MASK;
1964                es_info_length = ((p[3]<<8) + p[4]) & 0x0FFF;
1965                p += 5;
1966                pmt->streams[j].descriptor_length = es_info_length;
1967                pmt->streams[j].descriptors = (DS_U8 *)memChainAlloc(memId,es_info_length*sizeof(DS_U8));
1968                checkMemoryError(pmt->streams[j].descriptors);
1969                for (k=0; k<es_info_length; k++) {
1970                        pmt->streams[j].descriptors[k]  = *p++;
1971                }
1972//              if (GetMpegDescriptor(pmt->streams[j].descriptors,es_info_length,
1973//                      video_stream_tag,0/*instance*/,&q) == 0) {
1974//                      DHL_PSI_ParseVideoStreamDescriptor(q,memId,&pmt->streams[j].videoStreamDescriptor);
1975//              }
1976//              if (GetMpegDescriptor(pmt->streams[j].descriptors,es_info_length,
1977//                      video_decode_control_tag,0/*instance*/,&q) == 0) {
1978//                      DHL_PSI_ParseVideoDecodeControlDescriptor(q,memId,&pmt->streams[j].videoDecodeControlDescriptor);
1979//              }
1980        pmt->streams[j].b_component_tag_valid = false;
1981                if (GetMpegDescriptor(pmt->streams[j].descriptors,es_info_length,
1982                    DVB_TAG_stream_identifier_descriptor, 0, &q)==0) {
1983                    if ( DHL_PSI_ParseStreamIdentifierDescriptor(q,&(pmt->streams[j].component_tag)) == 0 )
1984                        pmt->streams[j].b_component_tag_valid = true;
1985                }
1986        }
1987        *(((memId_t *)pmt)-1) = memId;
1988        *returnPmt = pmt;
1989        memId = 0;                              /* Don't delete below */
1990
1991ParseExit:
1992        if (memId) {
1993                /* delete the patSection memory */
1994                memChainDestroy(memId);
1995        }
1996
1997
1998
1999        return(err);
2000}
2001
2002
2003/*==============================================================================
2004        DHL_RESULT ParseTVCTSection (DS_U8 *section, tvctSectionPtr_t *tvctSectionPtr)
2005
2006        *section:               Pointer to the first byte of the section.
2007        *tvctSectionPtr:        Return pointer to a parsed TVCT section.
2008
2009Parses an TVCT section and returns the decoded section via the provided
2010handle.
2011==============================================================================*/
2012static int DHL_PSI_ParseTVCTSection (DS_U8 *section, tvctSectionPtr_t *tvctSectionPtr)
2013{
2014//      T();
2015        if (get_section_syntax_indicator(section) == 0)
2016        {
2017                if (0) DST_Printf("TVCT: section_syntax_indicator not set\n");
2018        }
2019        if (get_private_indicator(section) == 0)
2020        {
2021                if (0) DST_Printf("TVCT: private_indicator not set\n");
2022        }
2023
2024        int err = 0;
2025        DS_U16 section_length = get_section_length(section);
2026        if (0) DST_Printf("section_length=%d\n", section_length);
2027        if (section_length > 1021) 
2028        {
2029                if (0) DST_Printf("TVCT: section_length=%d\n",section_length);
2030                return DHL_FAIL_INVALID_PARAM;
2031        }
2032
2033        memId_t memId = (memId_t)0; /* create the memChain */
2034        err = memChainCreate(&memId);
2035        if (err)
2036        {
2037                return DHL_FAIL_OUT_OF_RESOURCE;
2038        }
2039        /* allocate memory for tvctSection */
2040        tvctSectionPtr_t tvctSectPtr = (tvctSectionPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(tvctSection_t)+sizeof(memId_t))) + 1);
2041//      checkMemoryError(tvctSectPtr);
2042
2043        DS_U8 *p = section+3;
2044        /* parse section */
2045        tvctSectPtr->transport_stream_id                = p[0] * 256 + p[1];
2046        tvctSectPtr->version_number                     =  (p[2] >> 1) & 0x3F;
2047        tvctSectPtr->current_next_indicator             = p[2] & 0x01;
2048        tvctSectPtr->section_number                     = p[3];
2049        tvctSectPtr->last_section_number                = p[4];
2050
2051        DS_U8 protocol_version          = p[5];
2052
2053        if (protocol_version > 0)
2054        {
2055                if (0) DST_Printf("TVCT : invalid protocol version.(0x%x).\r\n" , protocol_version );
2056                if (memId) memChainDestroy(memId);
2057                return DHL_FAIL_INVALID_VERSION;
2058        }
2059       
2060        int count_i = tvctSectPtr->num_channels_in_section = p[6];
2061        if (0) DST_Printf("tvctSectPtr->num_channels_in_section=%d\n" , tvctSectPtr->num_channels_in_section );
2062        if( count_i > 0 )
2063        {
2064                tvctSectPtr->channel = (tvctChannelPtr_t)memChainAlloc(memId,count_i*sizeof(tvctChannel_t));
2065                checkMemoryError(tvctSectPtr->channel);
2066        }
2067       
2068        p = p+7;
2069        int i;
2070        for ( i=0; i<count_i; i++)
2071        {
2072                int j;
2073                for ( j=0; j<7; j++)
2074                {
2075                        tvctSectPtr->channel[i].short_name[j]   = p[j*2] * 256 + p[j*2+1];
2076                }
2077                tvctSectPtr->channel[i].major_channel_number    = (p[14] & 0x0F) * 64 + ((p[15] >> 2) & 0x3F);
2078                tvctSectPtr->channel[i].minor_channel_number = (p[15] & 0x03) * 256 + p[16];
2079               
2080                //if (0) DST_Printf("tvctSectPtr->channel[i].major_channel_number == %d\n",tvctSectPtr->channel[i].major_channel_number);
2081                //if (0) DST_Printf("tvctSectPtr->channel[i].minor_channel_number == %d\n",tvctSectPtr->channel[i].minor_channel_number);
2082               
2083                tvctSectPtr->channel[i].modulation_mode         = (modulation_mode_k)p[17];
2084                tvctSectPtr->channel[i].carrier_frequency               = p[18] * 0x1000000 + p[19] * 0x10000 + p[20] * 0x100 + p[21];
2085                tvctSectPtr->channel[i].channel_TSID            = p[22] * 0x100 + p[23];
2086                tvctSectPtr->channel[i].program_number          = p[24] * 0x100 + p[25];
2087                tvctSectPtr->channel[i].ETM_location            = (ETM_location_k)((p[26] >> 6) & 0x03);
2088                tvctSectPtr->channel[i].access_controlled               = (p[26] >> 5) & 0x01;
2089                tvctSectPtr->channel[i].hidden                  = (p[26] >> 4) & 0x01;
2090                tvctSectPtr->channel[i].show_guide                      = (p[26] >> 1) & 0x01;
2091                tvctSectPtr->channel[i].service_type            = (service_type_k)(p[27]& 0x3F);
2092                tvctSectPtr->channel[i].source_id                       = p[28] * 256 + p[29];
2093                int count_j = tvctSectPtr->channel[i].descriptor_length = (p[30]&0x03) * 256 + p[31];
2094                tvctSectPtr->channel[i].descriptors = (DS_U8 *)memChainAlloc(memId,count_j);
2095                checkMemoryError(tvctSectPtr->channel[i].descriptors);
2096                //if (0) DST_Printf("tvctSectPtr->channel[i].descriptor_lengthr == %d\n",tvctSectPtr->channel[i].descriptor_length);
2097                for ( j=0; j<count_j; j++)
2098                {
2099                        tvctSectPtr->channel[i].descriptors[j]  = p[32+j];
2100                }
2101                p = p + 32 + count_j;
2102        }
2103        count_i = tvctSectPtr->additional_descriptor_length     = (p[0]&0x03) * 256 + p[1];
2104        tvctSectPtr->additional_descriptors = (DS_U8 *)memChainAlloc(memId,count_i);
2105        checkMemoryError(tvctSectPtr->additional_descriptors);
2106
2107        for ( i=0; i<count_i; i++)
2108        {
2109                tvctSectPtr->additional_descriptors[i]          = p[2+i];
2110        }
2111       
2112        /* parsing complete */
2113        *(((memId_t *)tvctSectPtr)-1) = memId;
2114        memId = (memId_t)0;             /* so memChain not deleted */
2115ParseExit:
2116//      if (bits) {
2117//              /* clean up the bitBuffer */
2118//              bitBufferDestroy(bits);
2119//      }
2120        if (memId) {
2121                /* delete the tvctSection memory */
2122                memChainDestroy(memId);
2123        }
2124       
2125        *tvctSectionPtr = tvctSectPtr;
2126        return (err);
2127}
2128
2129/*==============================================================================
2130DHL_RESULT DHL_PSI_ParseTVCT (DS_U8 **sectionArr, tvctPtr_t *tvctPtr)
2131
2132        **sectionArr:   Array of pointers to all TVCT sections.
2133        *tvctPtr:               Returned pointer to the parsed TVCT.
2134
2135Parses an TVCT and returns the parsed table via the return pointer.
2136==============================================================================*/
2137int DHL_PSI_ParseTVCT (DS_U8 **sectionArr, tvctPtr_t *tvctPtr)
2138{
2139//      T();
2140        if (sectionArr == 0)
2141        {
2142                if (0) DST_Printf("%s|%d|sectionArr == 0\n", __func__, __LINE__);
2143                return (DHL_FAIL_NULL_POINTER);
2144        }
2145        if (sectionArr[0] == 0)
2146        {
2147                if (0) DST_Printf("%s|%d|sectionArr[0] == 0\n", __func__, __LINE__);
2148                return (DHL_FAIL_NULL_POINTER);
2149        }
2150        if (tvctPtr == 0)
2151        {
2152                if (0) DST_Printf("%s|%d|tvctPtr == 0\n", __func__, __LINE__);
2153                return (DHL_FAIL_NULL_POINTER);
2154        }
2155        *tvctPtr = 0;
2156
2157        DS_U8 numSections = get_last_section_number(sectionArr[0]) + 1;
2158        if (0) DST_Printf("numSections = %d\n", numSections);
2159        int i;
2160        for ( i=1; i < numSections; i++) /* now verify all other sections are present */
2161        {
2162                if (sectionArr[i] == 0)
2163                {
2164                        if (0) DST_Printf("%s|%d|null section found.\n", __func__, __LINE__);
2165                        return (DHL_FAIL_NULL_POINTER);
2166                }
2167        }
2168        for(  i=0; i < numSections; i++ ) /*chech the protocol_version of each secion.*/
2169        {
2170                if( sectionArr[i][8] != 0x00 )
2171                {
2172                        if (0) DST_Printf("%s|%d|invalid protocol version\n", __func__, __LINE__);
2173                        return DHL_FAIL_INVALID_VERSION;
2174                }
2175        }
2176
2177        /* create the memChain */
2178        memId_t memId = (memId_t)0;
2179        int err = memChainCreate(&memId);
2180        if (err)
2181        {
2182                if (0) DST_Printf("%s|%d|memChainCreate fail\n", __func__, __LINE__);
2183                return DHL_FAIL_OUT_OF_RESOURCE;
2184        }
2185        /* allocate memory for tvct */
2186        *tvctPtr = (tvctPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(tvct_t)+sizeof(memId_t))) + 1);
2187//      checkMemoryError(*tvctPtr);
2188
2189        /* Get the total number of channels in all sections */
2190        DS_U16 numChannels = 0;
2191        for ( i=0; i<numSections; i++)
2192        {
2193                numChannels += sectionArr[i][9];
2194        }
2195
2196        (*tvctPtr)->numChannels = numChannels;
2197
2198        /* allocate space in tvct for channels */
2199        (*tvctPtr)->channel = (tvctChannelPtr_t)memChainAlloc(memId,numChannels*sizeof(tvctChannel_t));
2200        checkMemoryError((*tvctPtr)->channel);
2201
2202//      #ifdef PSI_DBG
2203//      if (0) DST_Printf("DHL_PSI_ParseTVCT, numSection = %d\r\n", numSections);
2204//      #endif
2205
2206        /* Parse each section and copy channels */
2207        numChannels = 0;
2208        for ( i=0; i<numSections; i++)
2209        {
2210                /* Parse the section */
2211                tvctSectionPtr_t tvctSectPtr = 0;
2212                if (DHL_PSI_ParseTVCTSection(sectionArr[i], &tvctSectPtr) != 0)
2213                {
2214                        err = DHL_FAIL_OUT_OF_RESOURCE;
2215                        goto ParseExit;
2216                }
2217
2218                if (i == 0)
2219                {
2220                        /* duplicate fields copied once */
2221                        (*tvctPtr)->transport_stream_id = tvctSectPtr->transport_stream_id;
2222                        (*tvctPtr)->version_number = tvctSectPtr->version_number;
2223
2224                        /* allocate space for descriptors and copy (if any) */
2225                        if (tvctSectPtr->additional_descriptor_length > 0)
2226                        {
2227                                (*tvctPtr)->additional_descriptors = (DS_U8 *)memChainAlloc(memId,tvctSectPtr->additional_descriptor_length);
2228                                if ((*tvctPtr)->additional_descriptors == 0)
2229                                {
2230                                        DHL_PSI_FreeMpegSection(tvctSectPtr);
2231                                        err = DHL_FAIL_OUT_OF_RESOURCE;
2232                                        goto ParseExit;
2233                                }
2234
2235                                (*tvctPtr)->additional_descriptor_length = tvctSectPtr->additional_descriptor_length;
2236                                memcpy((*tvctPtr)->additional_descriptors, tvctSectPtr->additional_descriptors, (*tvctPtr)->additional_descriptor_length);
2237                        }
2238                }
2239                int j;
2240                for ( j=0; j<tvctSectPtr->num_channels_in_section; j++)
2241                {
2242                        memcpy(&((*tvctPtr)->channel[numChannels]), &(tvctSectPtr->channel[j]), sizeof(tvctChannel_t));
2243                        /* allocate space for descriptors and copy (if any) */
2244                        if (tvctSectPtr->channel[j].descriptor_length > 0)
2245                        {
2246                                (*tvctPtr)->channel[numChannels].descriptors = (DS_U8 *)memChainAlloc(memId,tvctSectPtr->channel[j].descriptor_length*sizeof(DS_U8));
2247                                if ((*tvctPtr)->channel[numChannels].descriptors == 0)
2248                                {
2249                                        DHL_PSI_FreeMpegSection(tvctSectPtr);
2250                                        err = DHL_FAIL_OUT_OF_RESOURCE;
2251                                        goto ParseExit;
2252                                }
2253                                memcpy((*tvctPtr)->channel[numChannels].descriptors,tvctSectPtr->channel[j].descriptors, (*tvctPtr)->channel[numChannels].descriptor_length);
2254                        }
2255                        numChannels++;
2256                }
2257                DHL_PSI_FreeMpegSection(tvctSectPtr);
2258        }
2259
2260        /* parsing complete */
2261        *(((memId_t *)(*tvctPtr))-1) = memId;
2262        memId = 0;              /* so memChain not deleted */
2263
2264ParseExit:
2265        if (memId) {
2266                /* delete the tvct memory */
2267                memChainDestroy(memId);
2268        }
2269        return (err);
2270}
2271
2272/*==============================================================================
2273ParseCaptionServiceDescriptor
2274        *p:                     Pointer to the un-parsed descriptor.
2275        *descripPtr             Pointer to parsed descriptor passed here.
2276
2277 Parses the descriptor and passes the result back via the descripPtr variable.
2278==============================================================================*/
2279int DHL_PSI_ParseCaptionServiceDescriptor (DS_U8* p, captionServiceDescriptorPtr_t *descripPtr)
2280{
2281        memId_t                 memId;
2282        if (memChainCreate(&memId)) return DHL_FAIL_OUT_OF_RESOURCE; /* create the memChain */
2283        /* create the descriptor memory */
2284        *descripPtr = (captionServiceDescriptorPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(captionServiceDescriptor_t)+sizeof(memId_t))) + 1);
2285        if (*descripPtr == 0) 
2286        {
2287                memChainDestroy(memId);
2288                return DHL_FAIL_OUT_OF_RESOURCE;
2289        }
2290        /* parse the descriptor */
2291        int count_i = (*descripPtr)->number_of_services  = p[2] & 0x1F;
2292        if (0) DST_Printf("count_i = %d\n", count_i);
2293        (*descripPtr)->service = (captionServicePtr_t)memChainAlloc(memId,count_i*sizeof(captionService_t));
2294        if ((*descripPtr)->service == 0) 
2295        {
2296                memChainDestroy(memId);
2297                return DHL_FAIL_OUT_OF_RESOURCE;
2298        }
2299        int nPos = 3;   
2300        int i;
2301        for ( i=0; i<count_i; i++) {
2302                (*descripPtr)->service[i].language[0] = p[nPos++];
2303                (*descripPtr)->service[i].language[1] = p[nPos++];
2304                (*descripPtr)->service[i].language[2] = p[nPos++];
2305                (*descripPtr)->service[i].language[3] = 0; 
2306                (*descripPtr)->service[i].cc_type = (cc_type_k)((p[nPos] >> 7) & 0x01);
2307                if ((*descripPtr)->service[i].cc_type == cct_line21) 
2308                {
2309                        (*descripPtr)->service[i].cc_id.line21_field    = (line21_field_k)(p[nPos] &0x01);
2310                }
2311                else 
2312                {
2313                        (*descripPtr)->service[i].cc_id.caption_service_number  = (p[nPos] &0x3F);
2314                }
2315                nPos++;
2316                (*descripPtr)->service[i].easy_reader           = (p[nPos] >> 7) & 0x01;
2317                (*descripPtr)->service[i].wide_aspect_ratio     = (p[nPos] >> 6) & 0x01;
2318                (*descripPtr)->service[i].korean_code          = (p[nPos] >> 5) & 0x01;
2319                nPos += 2;
2320        }
2321
2322        /* parsing complete */
2323        *(((memId_t *)(*descripPtr))-1) = memId;
2324        memId = 0;              /* so memChain not deleted */
2325
2326//ParseDescriptorExit:
2327        memChainDestroy(memId);  /* delete the descriptor memory */
2328        return 0;
2329}
2330
2331/*==============================================================================
2332void DHL_PSI_FreeMpegDescriptor (void *descriptorPtr)
2333
2334        descriptorPtr           Pointer to a parsed descriptor.
2335
2336Frees the memory associated with a parsed descriptor.
2337==============================================================================*/
2338void DHL_PSI_FreeMpegDescriptor (void *descriptorPtr)
2339{
2340        if(descriptorPtr ) memChainDestroy(*(((memId_t *)descriptorPtr)-1));
2341}
2342
2343/*==============================================================================
2344ParseAc3AudioStreamDescriptor
2345
2346        *p:                     Pointer to the un-parsed descriptor.
2347        *descripPtr             Pointer to parsed descriptor passed here.
2348
2349 Parses the descriptor and passes the result back via the descripPtr variable.
2350==============================================================================*/
2351int DHL_PSI_ParseAc3AudioStreamDescriptor (DS_U8* p, ac3AudioStreamDescriptorPtr_t *descripPtr)
2352{
2353        /* create the memChain */
2354        memId_t                 memId;
2355        if (memChainCreate(&memId)) return DHL_FAIL_OUT_OF_RESOURCE;
2356        /* create the descriptor memory */
2357        *descripPtr = (ac3AudioStreamDescriptorPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(ac3AudioStreamDescriptor_t)+sizeof(memId_t))) + 1);
2358        if (*descripPtr == 0)
2359        {
2360                memChainDestroy(memId);
2361                return DHL_FAIL_OUT_OF_RESOURCE;
2362        }
2363
2364        /* parse the descriptor */
2365        DS_U8 length = p[1];
2366        (*descripPtr)->sample_rate_code                         = (sample_rate_code_k)((p[2] >> 5) & 0x07);
2367        (*descripPtr)->bsid                                             =         (p[2] & 0x1F);
2368        (*descripPtr)->bit_rate_code                                    = (bit_rate_code_k) ((p[3] >> 2) & 0x3F);
2369        (*descripPtr)->surround_mode                                    = (surround_mode_k)(p[3] & 0x03);
2370        (*descripPtr)->bsmod                                            = (bit_stream_mode_k)((p[4] >> 5) & 0x07);
2371        (*descripPtr)->num_channels                                     = (num_channels_k)((p[4] >> 1) & 0x0F);
2372        (*descripPtr)->full_svc                                         = (p[4] & 0x01);
2373        int nPos = 5;
2374        if (length > 3) {
2375                (*descripPtr)->additional_elements1                     = true;
2376                (*descripPtr)->langcod                                  = (language_code_k)p[nPos++];
2377
2378                /* compute length of lang2 field */
2379                DS_U8 lang2_len = (*descripPtr)->num_channels == nc_acmod_1_1 ? 1 : 0;
2380       
2381                if (length > 4 && lang2_len) {
2382                        (*descripPtr)->langcod2                         = (language_code_k)p[nPos++];
2383                }
2384               
2385                if (length > 4+lang2_len) {
2386                        (*descripPtr)->additional_elements2             = true;
2387                        if ((*descripPtr)->bsmod < 2) {
2388                                (*descripPtr)->bsmod_ext.mainid = (p[nPos++] >> 5) & 0x07;
2389                        }
2390                        else {
2391                                (*descripPtr)->bsmod_ext.asvcflags      = (p[nPos++] >> 5);
2392                        }
2393
2394                        if (length > 5+lang2_len) {             
2395                                DS_U16 count_i = (*descripPtr)->textlen = (p[nPos] >> 1) & 0x7F;
2396                                (*descripPtr)->text_code                = (text_code_k)(p[nPos++] & 0x01);
2397                                (*descripPtr)->text = 0;
2398                                if (count_i > 0)
2399                                {
2400                                        (*descripPtr)->text = (DS_U8 *)memChainAlloc(memId,count_i*sizeof(DS_U8));
2401                                        if ((*descripPtr)->text == 0) 
2402                                        {
2403                                                memChainDestroy(memId);
2404                                                return DHL_FAIL_OUT_OF_RESOURCE;
2405                                        }
2406                                        int i;
2407                                        for ( i=0; i<count_i; i++) 
2408                                        {
2409                                                (*descripPtr)->text[i]          = p[nPos++];
2410                                        }
2411                                }
2412                                (*descripPtr)->langflag = 0;
2413                                (*descripPtr)->langflag_2 = 0;
2414                                (*descripPtr)->language[0] = 0;
2415                                (*descripPtr)->language[1] = 0;
2416                                (*descripPtr)->language[2] = 0;
2417                                (*descripPtr)->language[3] = 0;
2418                                (*descripPtr)->language2[0] = 0;
2419                                (*descripPtr)->language2[1] = 0;
2420                                (*descripPtr)->language2[2] = 0;
2421                                (*descripPtr)->language2[3] = 0;
2422                                if (length > 5+lang2_len+1+count_i)
2423                                {
2424                                        /* see if we have 0, 1, or 2 ISO 639 language fields */
2425                                        (*descripPtr)->langflag = (p[nPos] >> 7) & 0x01;
2426                                        (*descripPtr)->langflag_2 =(p[nPos] >> 6) & 0x01;
2427                                        nPos++;
2428                                        int lang639_len = 6 + lang2_len + 1 + count_i;
2429                                        if (((*descripPtr)->langflag) &&
2430                                                (length >= lang639_len + 3))
2431                                        {
2432                                                lang639_len += 3;       /* so lang2 is independent! */
2433                                                (*descripPtr)->language[0] =p[nPos++]; 
2434                                                (*descripPtr)->language[1] =p[nPos++]; 
2435                                                (*descripPtr)->language[2] =p[nPos++]; 
2436                                                (*descripPtr)->language[3] = 0;
2437                                        }
2438
2439                                        if (((*descripPtr)->langflag_2) &&
2440                                                (length >= lang639_len + 3))
2441                                        {
2442                                                (*descripPtr)->language2[0] = p[nPos++]; 
2443                                                (*descripPtr)->language2[1] = p[nPos++]; 
2444                                                (*descripPtr)->language2[2] = p[nPos++]; 
2445                                                (*descripPtr)->language2[3] = 0; 
2446                                        }
2447                                }
2448                        }
2449                }
2450        }
2451
2452        /* Ignore remaining 'additional_info' bytes */
2453
2454        /* parsing complete */
2455        *(((memId_t *)(*descripPtr))-1) = memId;
2456        memId = 0;              /* so memChain not deleted */
2457
2458// ParseDescriptorExit:
2459//      if (bits) {
2460//              /* delete the bitBuffer */
2461//              bitBufferDestroy(bits);
2462//      }
2463        if (memId) {
2464                /* delete the descriptor memory */
2465                memChainDestroy(memId);
2466        }
2467        return 0;
2468}
2469
2470/*==============================================================================
2471DHL_RESULT DHL_PSI_ParseMGTSection (DS_U8 *section, mgtSectionPtr_t *mgtSectionPtr)
2472
2473        *section:               Pointer to the first byte of the section.
2474        *mgtSectionPtr: Return pointer to a parsed MGT section.
2475
2476Parses an MGT section and returns the decoded section via the provided
2477handle.
2478==============================================================================*/
2479int DHL_PSI_ParseMGTSection (DS_U8 *section, mgtSectionPtr_t *mgtSectionPtr)
2480{
2481        if (get_section_syntax_indicator(section) == 0) 
2482        {
2483                if (0) DST_Printf("MGT: section_syntax_indicator not set\n");
2484        }
2485        if (get_private_indicator(section) == 0) 
2486        {
2487                if (0) DST_Printf("MGT: private_indicator not set\n");
2488        }
2489
2490        int section_length = get_section_length(section);
2491        if (section_length > 4093) 
2492        {
2493                if (0) DST_Printf("MGT: section_length=%d\n",section_length);
2494                return DHL_FAIL_INVALID_PARAM;
2495        }
2496
2497        /* create the memChain */
2498        memId_t                 memId;
2499        if (memChainCreate(&memId)) 
2500        {
2501                return DHL_FAIL_OUT_OF_RESOURCE;
2502        }
2503        /* allocate memory for mgtSection */
2504        mgtSectionPtr_t  mgtSectPtr = (mgtSectionPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(mgtSection_t)+sizeof(memId_t))) + 1);
2505        if (mgtSectPtr == 0)
2506        {
2507                memChainDestroy(memId);
2508                return DHL_FAIL_OUT_OF_RESOURCE;
2509        }
2510
2511        DS_U8 *p = section;
2512       
2513       
2514       
2515        /* parse section */
2516        DS_U16 table_id_extension = p[3]*256+p[4];//(p[nPos++]*256) + p[nPos++];
2517        if (table_id_extension != 0x0000) {
2518                /*if (0) DST_Printf("MGT: table_id_extension != 0x0000");*/
2519        }
2520        if (0) DST_Printf("table_id_extension=%d\n",table_id_extension);
2521        mgtSectPtr->version_number      = (p[5] >> 1) & 0x1F;
2522
2523        int current_next_indicator = p[5]&0x01;
2524        if (0) DST_Printf("mgtSectPtr->version_number=%d\n",mgtSectPtr->version_number);
2525        if (0) DST_Printf("current_next_indicator=%d\n",current_next_indicator);
2526       
2527        if (current_next_indicator != 1) {
2528                if (0) DST_Printf("MGT: current_next_indicator != 1\n");
2529        }
2530        int section_number              = p[6];
2531        if (0) DST_Printf("section_number=%d\n",section_number);
2532        if (section_number != 0x00)
2533        {
2534                if (0) DST_Printf("MGT: section_number != 0x00\n");
2535        }
2536        int last_section_number = p[7];
2537        if (0) DST_Printf("last_section_number=%d\n",last_section_number);
2538        if (last_section_number != 0x00)
2539        {
2540                if (0) DST_Printf("MGT: last_section_number != 0x00\n");
2541        }
2542        int protocol_version            = p[8];
2543        if (0) DST_Printf("protocol_version=%d\n",protocol_version);
2544        if (protocol_version > 0x00/* PSIP_PROTOCOL_VERSION*/) 
2545        {
2546                memChainDestroy(memId);
2547                return DHL_FAIL_INVALID_VERSION;
2548        }
2549
2550        int count_i = mgtSectPtr->tables_defined        = p[9]*256 + p[10];
2551        mgtSectPtr->table = (mgtTablePtr_t)memChainAlloc(memId,count_i*sizeof(mgtTable_t));
2552        if (mgtSectPtr->table == 0)
2553        {
2554                memChainDestroy(memId);
2555                return DHL_FAIL_OUT_OF_RESOURCE;
2556        }
2557        int nPos = 11;
2558        int i;
2559        for ( i=0; i<count_i; i++) 
2560        {
2561                if (0) DST_Printf("%d\n", i);
2562                mgtSectPtr->table[i].table_type                 = (table_type_k)(p[nPos]*256 + p[nPos+1]);
2563                nPos += 2;
2564                mgtSectPtr->table[i].table_type_PID                     = (p[nPos]&0x1F)*256 + p[nPos+1];
2565                nPos += 2;
2566                mgtSectPtr->table[i].table_type_version_number  = p[nPos++]&0x1F;
2567                mgtSectPtr->table[i].number_bytes                       = p[nPos] * 0x1000000 + p[nPos+1] * 0x10000 + p[nPos+2] * 0x100 + p[nPos+3];
2568                nPos += 4;
2569                int count_j = mgtSectPtr->table[i].descriptor_length= (p[nPos]&0x0F)*256 + p[nPos+1];
2570                nPos += 2;
2571                mgtSectPtr->table[i].descriptors = (DS_U8 *)memChainAlloc(memId,count_j);
2572                if (mgtSectPtr->table[i].descriptors == 0)
2573                {
2574                        memChainDestroy(memId);
2575                        return DHL_FAIL_OUT_OF_RESOURCE;
2576                }
2577                int j;
2578                for ( j=0; j<count_j; j++) 
2579                {
2580                        mgtSectPtr->table[i].descriptors[j]             = p[nPos++];
2581                }
2582        }
2583        count_i = mgtSectPtr->descriptor_length                 = (p[nPos]&0x0F)*256 + p[nPos+1];
2584        nPos += 2;
2585        mgtSectPtr->descriptors = (DS_U8 *)memChainAlloc(memId,count_i);
2586        if (mgtSectPtr->descriptors == 0)
2587        {
2588                memChainDestroy(memId);
2589                return DHL_FAIL_OUT_OF_RESOURCE;
2590        }
2591
2592        for ( i=0; i<count_i; i++) 
2593        {
2594                mgtSectPtr->descriptors[i]                              = p[nPos++];
2595        }
2596
2597        mgtSectPtr->CRC32                                               = p[nPos] * 0x1000000 + p[nPos+1] * 0x10000 + p[nPos+2] * 0x100 + p[nPos+3];
2598        nPos += 4;
2599        /* parsing complete */
2600        *(((memId_t *)mgtSectPtr)-1) = memId;
2601        memId = 0;              /* so memChain not deleted */
2602
2603//ParseExit:
2604        memChainDestroy(memId);
2605        *mgtSectionPtr = mgtSectPtr;
2606        return 0;
2607}
2608
2609#if EPG_SUPPORT
2610/*==============================================================================
2611DHL_RESULT DHL_PSI_ParseEIT (DS_U8 **sectionArr, eitPtr_t *eitPtr)
2612
2613        **sectionArr:   Array of pointers to all EIT sections.
2614        *eitPtr:                Returned pointer to the parsed EIT.
2615
2616Parses an EIT and returns the parsed table via the return pointer.
2617==============================================================================*/
2618int DHL_PSI_ParseEIT (DS_U8 **sectionArr, eitPtr_t *eitPtr)
2619{
2620//      DS_U8                           numSections;
2621//      DS_U16                  numEvents;
2622//      DS_U16                  section_length;
2623//      DS_U8                           protocol_version;
2624//      DS_U16                  i,j,k;
2625//      DS_U16                  count_j, count_k;
2626//      memChainSetup_t         memSetup = {MEM_LIMIT,0,0};
2627//      memId_t                 memId = 0;
2628//      bitBufferPtr_t                          bits = 0;
2629//      DHL_RESULT                      err;
2630
2631        if (sectionArr == 0 || (eitPtr == 0)) 
2632        {
2633                return (DHL_FAIL_NULL_POINTER);
2634        }
2635        if (sectionArr[0] == 0) 
2636        {
2637                return (DHL_FAIL_NULL_POINTER);
2638        }
2639        int numSections = get_last_section_number(sectionArr[0]) + 1;
2640
2641        /* now verify all other sections are present */
2642        int i;
2643        for ( i=1; i<numSections; i++) 
2644        {
2645                if (sectionArr[i] == 0) 
2646                {
2647                        if (0) DST_Printf("EIT : null section found.\r\n");
2648                        return (DHL_FAIL_NULL_POINTER);
2649                }
2650        }
2651
2652/*check protocol version of each section.*/
2653        for (  i=0; i< numSections ; i++ )
2654        {
2655                if(sectionArr[i][8] != 0/*PSIP_PROTOCOL_VERSION*/) 
2656                {
2657                        if (0) DST_Printf("EIT : invalid Protocol Version.\r\n");               
2658                        return DHL_FAIL_INVALID_VERSION;
2659                }
2660        }
2661        /* create the memChain */
2662        memId_t                 memId = 0;
2663        if (memChainCreate(&memId)) 
2664        {
2665                return DHL_FAIL_OUT_OF_RESOURCE;
2666        }
2667        /* allocate memory for eit */
2668        *eitPtr = (eitPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(eit_t)+sizeof(memId_t))) + 1);
2669        if (eitPtr == 0)
2670        {
2671                memChainDestroy(memId);
2672                return DHL_FAIL_OUT_OF_RESOURCE;
2673        }
2674
2675        /* Get the total number of channels in all sections */
2676        int numEvents = 0;
2677        for ( i=0; i<numSections; i++) 
2678        {
2679                numEvents += sectionArr[i][9];
2680        }
2681
2682        (*eitPtr)->numEvents = numEvents;
2683
2684        /* allocate space in eit for events */
2685        (*eitPtr)->event = (eitEventPtr_t)memChainAlloc(memId,numEvents*sizeof(eitEvent_t));
2686        if ((*eitPtr)->event == 0)
2687        {
2688                memChainDestroy(memId);
2689                return DHL_FAIL_OUT_OF_RESOURCE;
2690        }
2691
2692        /* Parse each section and copy channels */
2693        numEvents = 0;
2694        for ( i=0; i<numSections; i++) 
2695        {
2696                /* create the bitBuffer */
2697                //int section_length = get_section_length(sectionArr[i]);
2698                //err = bitBufferCreate(&bits,&(sectionArr[i][3]),section_length);
2699                //if (err) {
2700                //      goto ParseExit;
2701                //}
2702                DS_U8 *p = &sectionArr[i][3];
2703                /* Parse the section */
2704                (*eitPtr)->source_id                    = p[0] * 256 + p[1];
2705                //bitBufferSkipBits(bits,2);    /* reserved */
2706                (*eitPtr)->version_number               = (p[2] >> 1) & 0x1F; 
2707                //bitBufferSkipBits(bits,1);    /* current_next_indicator */
2708                //bitBufferSkipBits(bits,8);    /* section_number */
2709                //bitBufferSkipBits(bits,8);    /* last_section_number */
2710                int protocol_version                            = p[5];
2711                if (protocol_version > 0/*PSIP_PROTOCOL_VERSION*/) 
2712                {
2713                        memChainDestroy(memId);
2714                        return DHL_FAIL_INVALID_VERSION;
2715                }
2716                int count_j                                     = p[6];//bitBufferGetBits(bits,8);
2717                int nPos = 7;
2718                int j;
2719                for ( j=0; j<count_j; j++) {
2720                        //bitBufferSkipBits(bits,2);    /* reserved */
2721                        (*eitPtr)->event[numEvents].event_id            =  (p[nPos]&0x3F)*0x100 + p[nPos+1]; //bitBufferGetBits(bits,14);
2722                        nPos += 2;
2723                        (*eitPtr)->event[numEvents].start_time          = p[nPos] * 0x1000000 + p[nPos+1] * 0x10000 + p[nPos+2] * 0x100 + p[nPos+3];//bitBufferGetBits(bits,32);
2724                        nPos += 4;
2725                        //bitBufferSkipBits(bits,2);    /* reserved */
2726                        (*eitPtr)->event[numEvents].ETM_location                = (ETM_location_k)((p[nPos] >> 4) & 0x03); //(ETM_location_k)bitBufferGetBits(bits,2);
2727                        (*eitPtr)->event[numEvents].length_in_seconds   = (p[nPos]&0x0F) * 0x10000 + p[nPos+1] * 0x100 + p[nPos+2];//bitBufferGetBits(bits,20);
2728                        nPos += 3;
2729                        int count_k = (*eitPtr)->event[numEvents].title_length  = p[nPos]; //bitBufferGetBits(bits,8);
2730                        nPos += 1;
2731                        (*eitPtr)->event[numEvents].title = (DS_U8 *)memChainAlloc(memId, count_k);
2732                        //checkMemoryError((*eitPtr)->event[numEvents].title);
2733                        if ((*eitPtr)->event[numEvents].title  == 0)
2734                        {
2735                                memChainDestroy(memId);
2736                                return DHL_FAIL_OUT_OF_RESOURCE;
2737                        }
2738                        int k;
2739                        for ( k=0; k<count_k; k++)
2740                        {
2741                                (*eitPtr)->event[numEvents].title[k]    =  p[nPos++];
2742                        }
2743
2744                        //bitBufferSkipBits(bits,4);    /* reserved */
2745                        count_k = (*eitPtr)->event[numEvents].descriptor_length= (p[nPos]&0x0F) * 0x100 + p[nPos+1] ;//bitBufferGetBits(bits,12);
2746                        nPos += 2;
2747                        (*eitPtr)->event[numEvents].descriptors = (DS_U8 *)memChainAlloc(memId,count_k);
2748                        if ((*eitPtr)->event[numEvents].descriptors  == 0)
2749                        {
2750                                memChainDestroy(memId);
2751                                return DHL_FAIL_OUT_OF_RESOURCE;
2752                        }
2753//                      int k;
2754                        for ( k=0; k<count_k; k++) {
2755                                (*eitPtr)->event[numEvents].descriptors[k]= p[nPos++];
2756                        }
2757
2758                        numEvents++;
2759                }
2760
2761//              bitBufferDestroy(bits);
2762//              bits = 0;
2763        }
2764
2765        /* parsing complete */
2766        *(((memId_t *)(*eitPtr))-1) = memId;
2767        memId = 0;              /* so memChain not deleted */
2768
2769//ParseExit:
2770//      if (bits) {
2771//              bitBufferDestroy(bits);
2772//      }
2773        if (memId) {
2774                /* delete the cvct memory */
2775                memChainDestroy(memId);
2776        }
2777        return 0;
2778}
2779
2780#endif
2781
2782#if EPG_SUPPORT
2783/*==============================================================================
2784DHL_RESULT DHL_PSI_ParseETTSection (DS_U8 *section, ettSectionPtr_t *ettSectionPtr)
2785
2786        *section:               Pointer to the first byte of the section.
2787        *ettSectionPtr: Return pointer to a parsed ETT section.
2788
2789Parses an ETT section and returns the decoded section via the provided
2790handle.
2791==============================================================================*/
2792int DHL_PSI_ParseETTSection (DS_U8 *section, ettSectionPtr_t *ettSectionPtr)
2793{
2794        if (get_section_syntax_indicator(section) == 0) 
2795        {
2796                if (0) DST_Printf("ETT: section_syntax_indicator not set\n");
2797        }
2798        if (get_private_indicator(section) == 0) 
2799        {
2800                if (0) DST_Printf("ETT: private_indicator not set\n");
2801        }
2802
2803        int section_length = get_section_length(section);
2804        if (section_length > 4093) 
2805        {
2806                if (0) DST_Printf("ETT: section_length=%d\n",section_length);
2807                return DHL_FAIL_INVALID_PARAM;
2808        }
2809
2810        /* create the memChain */
2811        memId_t                 memId = 0;
2812        if (memChainCreate(&memId)) 
2813        {
2814                return DHL_FAIL_OUT_OF_RESOURCE;
2815        }
2816        /* allocate memory for ettSection */
2817        ettSectionPtr_t ettSectPtr = (ettSectionPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(ettSection_t)+sizeof(memId_t))) + 1);
2818        //checkMemoryError(ettSectPtr);
2819        if (ettSectPtr  == 0)
2820        {
2821                memChainDestroy(memId);
2822                return DHL_FAIL_OUT_OF_RESOURCE;
2823        }
2824
2825        /* parse section */
2826        DS_U8 *p = &section[3];
2827        int table_id_extension  = p[0] * 0x100 + p[1];
2828        if (table_id_extension != 0x0000) {
2829                /*if (0) DST_Printf("ETT: table_id_extension != 0x0000\n");*/
2830        }
2831        ettSectPtr->version_number              = (p[2]>>1)&0x1F;
2832        int current_next_indicator                      = p[2] & 0x01;
2833        if (current_next_indicator != 1) 
2834        {
2835                if (0) DST_Printf("ETT: current_next_indicator != 1\n");
2836        }
2837        int section_number                              = p[3];
2838        //if (0) DST_Printf("section_number=%d\n",section_number);
2839        if (section_number != 0x00) 
2840        {
2841                if (0) DST_Printf("ETT: section_number != 0x00\n");
2842        }
2843        int last_section_number                 = p[4];
2844        //if (0) DST_Printf("last_section_number=%d\n",last_section_number);
2845        if (last_section_number != 0x00)
2846        {
2847                if (0) DST_Printf("ETT: last_section_number != 0x00\n");
2848        }
2849        int protocol_version            = p[5];
2850        //if (0) DST_Printf("protocol_version=%d\n",protocol_version);
2851        //T();
2852        if (protocol_version > 0/*PSIP_PROTOCOL_VERSION*/) 
2853        {
2854                memChainDestroy(memId);
2855                return DHL_FAIL_INVALID_VERSION;
2856        }
2857
2858        ettSectPtr->ETM_id                      = p[6]*0x1000000 + p[7]*0x10000 + p[8]*0x100 + p[9];
2859        //if (0) DST_Printf("ettSectPtr->ETM_id=%d\n",ettSectPtr->ETM_id);
2860        int count_i = ettSectPtr->extended_text_message_length = section_length - 14;
2861        ettSectPtr->extended_text_message = (DS_U8 *)memChainAlloc(memId, count_i);
2862        if (ettSectPtr->extended_text_message  == 0)
2863        {
2864                memChainDestroy(memId);
2865                return DHL_FAIL_OUT_OF_RESOURCE;
2866        }
2867        int i;
2868        for ( i=0; i<count_i; i++)
2869        {
2870                ettSectPtr->extended_text_message[i] = p[10+i];
2871        }
2872
2873        /* parsing complete */
2874        *(((memId_t *)ettSectPtr)-1) = memId;
2875        memId = 0;              /* so memChain not deleted */
2876
2877        if (memId) {
2878                /* delete the cvctSection memory */
2879                memChainDestroy(memId);
2880        }
2881       
2882        *ettSectionPtr = ettSectPtr;
2883        return 0;
2884}
2885
2886#endif
2887
2888#if CVCT_SUPPORT
2889/*==============================================================================
2890DHL_RESULT DHL_PSI_ParseCVCTSection (DS_U8 *section, cvctSectionPtr_t *cvctSectionPtr)
2891
2892        *section:               Pointer to the first byte of the section.
2893        *cvctSectionPtr:        Return pointer to a parsed CVCT section.
2894
2895Parses an CVCT section and returns the decoded section via the provided
2896handle.
2897==============================================================================*/
2898static int DHL_PSI_ParseCVCTSection (DS_U8 *section, cvctSectionPtr_t *cvctSectionPtr)
2899{
2900//      cvctSectionPtr_t                cvctSectPtr = 0;
2901//      memChainSetup_t         memSetup = {MEM_LIMIT,0,0};
2902//      DS_U16                  section_length;
2903//      DS_U8                           protocol_version;
2904//     
2905//      bitBufferPtr_t                          bits = 0;
2906//      DS_S32                          count_i,count_j;
2907//      DS_S32                          i,j;
2908//      DHL_RESULT                      err = DHL_OK;
2909
2910        if (get_section_syntax_indicator(section) == 0)
2911        {
2912                if (0) DST_Printf("CVCT: section_syntax_indicator not set\n");
2913        }
2914        if (get_private_indicator(section) == 0) 
2915        {
2916                if (0) DST_Printf("CVCT: private_indicator not set\n");
2917        }
2918
2919        DS_U16 section_length = get_section_length(section);
2920        if (section_length > 1021) 
2921        {
2922                if (0) DST_Printf("CVCT: section_length=%d\n",section_length);
2923                return DHL_FAIL_INVALID_PARAM;
2924        }
2925        memId_t                 memId = 0;
2926        if (memChainCreate(&memId)) /* create the memChain */
2927        {
2928                return DHL_FAIL_OUT_OF_RESOURCE;
2929        }
2930        /* allocate memory for cvctSection */
2931        cvctSectionPtr_t cvctSectPtr = (cvctSectionPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(cvctSection_t)+sizeof(memId_t))) + 1);
2932        if (cvctSectPtr == 0)
2933        {
2934                        memChainDestroy(memId);
2935                        return DHL_FAIL_OUT_OF_RESOURCE;
2936        }
2937        DS_U8 *p = section + 3;
2938        /* parse section */
2939        cvctSectPtr->transport_stream_id                = p[0] * 0x100 + p[1];
2940        //bitBufferSkipBits(bits,2);    /* reserved */
2941        cvctSectPtr->version_number                     = (p[2] >> 1) & 0x1F;
2942        cvctSectPtr->current_next_indicator             = p[2] & 0x01;
2943        cvctSectPtr->section_number                     = p[3];
2944        cvctSectPtr->last_section_number                = p[4];
2945
2946        DS_U8 protocol_version          = p[5];
2947        if (protocol_version > 0 /*PSIP_PROTOCOL_VERSION*/) 
2948        {
2949                memChainDestroy(memId);
2950                return DHL_FAIL_INVALID_VERSION;
2951        }
2952
2953        int count_i = cvctSectPtr->num_channels_in_section      = p[6];
2954        cvctSectPtr->channel = (cvctChannelPtr_t)memChainAlloc(memId,count_i*sizeof(cvctChannel_t));
2955        if (cvctSectPtr->channel == 0)
2956        {
2957                        memChainDestroy(memId);
2958                        return DHL_FAIL_OUT_OF_RESOURCE;
2959        }
2960        p += 7;
2961        int nPos = 0;
2962        int i;
2963        for ( i=0; i<count_i; i++)
2964        {
2965                int j;
2966                for ( j=0; j<7; j++)
2967                {
2968                        cvctSectPtr->channel[i].short_name[j]   = p[nPos] * 0x100 + p[nPos+1];
2969                        nPos+=2;
2970                }
2971                //bitBufferSkipBits(bits,4);    /* reserved */
2972                cvctSectPtr->channel[i].major_channel_number    = ((p[nPos] >> 4) & 0x0F) * 0x40 + ((p[nPos+1] >> 2) & 0x3F);
2973#ifdef ENABLE_SYNTAX_CHECKING
2974                if (cvctSectPtr->channel[i].major_channel_number < CABL_MAJOR_CHAN_MIN || cvctSectPtr->channel[i].major_channel_number > CABL_MAJOR_CHAN_MAX) {
2975                        if (0) DST_Printf("CVCT: major_channel_number=%d\n",cvctSectPtr->channel[i].major_channel_number);
2976                        err = DHL_FAIL_INVALID_PARAM;
2977                        goto ParseExit;
2978                }
2979#endif /* ENABLE_SYNTAX_CHECKING */
2980                cvctSectPtr->channel[i].minor_channel_number    = (p[nPos+1] & 0x03) * 0x100 + p[nPos+2];
2981#ifdef ENABLE_SYNTAX_CHECKING
2982                if (cvctSectPtr->channel[i].minor_channel_number > CABL_MINOR_CHAN_MAX) {
2983                        if (0) DST_Printf("CVCT: minor_channel_number=%d\n",cvctSectPtr->channel[i].minor_channel_number);
2984                        err = DHL_FAIL_INVALID_PARAM;
2985                        goto ParseExit;
2986                }
2987#endif /* ENABLE_SYNTAX_CHECKING */
2988                nPos+=3;
2989                cvctSectPtr->channel[i].modulation_mode         = (modulation_mode_k)p[nPos++];
2990                cvctSectPtr->channel[i].carrier_frequency               = p[nPos] * 0x1000000 + p[nPos+1] * 0x10000 + p[nPos+2] * 0x100 + p[nPos+3];
2991                nPos+=4;
2992                cvctSectPtr->channel[i].channel_TSID            = p[nPos] * 0x100 + p[nPos+1];
2993                nPos+=2;
2994                cvctSectPtr->channel[i].program_number          = p[nPos] * 0x100 + p[nPos+1];
2995                nPos+=2;
2996                cvctSectPtr->channel[i].ETM_location            = (ETM_location_k)((p[nPos] >> 6) & 0x03);
2997                cvctSectPtr->channel[i].access_controlled               = ((p[nPos] >> 5) & 0x01);
2998                cvctSectPtr->channel[i].hidden                  =  ((p[nPos] >> 4) & 0x01);
2999                cvctSectPtr->channel[i].path_select                     = (path_select_k) ((p[nPos] >> 3) & 0x01);
3000                cvctSectPtr->channel[i].out_of_band                     =  ((p[nPos] >> 2) & 0x01);
3001                cvctSectPtr->channel[i].show_guide                      =  ((p[nPos] >> 1) & 0x01);
3002                //bitBufferSkipBits(bits,3);    /* reserved */
3003                nPos++;
3004                cvctSectPtr->channel[i].service_type            = (service_type_k)(p[nPos++] & 0x3F);
3005                cvctSectPtr->channel[i].source_id                       = p[nPos] * 0x100 + p[nPos+1];
3006                nPos+=2;
3007                //bitBufferSkipBits(bits,6);    /* reserved */
3008                int count_j = cvctSectPtr->channel[i].descriptor_length = (p[nPos]&0x03) * 0x100 + p[nPos+1];
3009                nPos+=2;
3010                cvctSectPtr->channel[i].descriptors = (DS_U8 *)memChainAlloc(memId,count_j);
3011                if (cvctSectPtr->channel[i].descriptors == 0)
3012                {
3013                                memChainDestroy(memId);
3014                                return DHL_FAIL_OUT_OF_RESOURCE;
3015                }
3016//              int j;
3017                for ( j=0; j<count_j; j++) {
3018                        cvctSectPtr->channel[i].descriptors[j]  = p[nPos++];
3019                }
3020        }
3021        //bitBufferSkipBits(bits,6);    /* reserved */
3022        cvctSectPtr->additional_descriptors = (DS_U8 *)memChainAlloc(memId,count_i);
3023        if (cvctSectPtr->additional_descriptors == 0)
3024        {
3025                        memChainDestroy(memId);
3026                        return DHL_FAIL_OUT_OF_RESOURCE;
3027        }
3028
3029        for ( i=0; i<count_i; i++) {
3030                cvctSectPtr->additional_descriptors[i]          = p[nPos++];
3031        }
3032
3033        /* parsing complete */
3034        *(((memId_t *)cvctSectPtr)-1) = memId;
3035        memId = 0;              /* so memChain not deleted */
3036
3037//ParseExit:
3038
3039        if (memId) {
3040                /* delete the cvctSection memory */
3041                memChainDestroy(memId);
3042        }
3043       
3044        *cvctSectionPtr = cvctSectPtr;
3045        return 0;
3046}
3047#endif
3048
3049#if CVCT_SUPPORT
3050/*==============================================================================
3051DHL_RESULT DHL_PSI_ParseCVCT (DS_U8 **sectionArr, cvctPtr_t *cvctPtr)
3052
3053        **sectionArr:   Array of pointers to all CVCT sections.
3054        *cvctPtr:               Returned pointer to the parsed CVCT.
3055
3056Parses an CVCT and returns the parsed table via the return pointer.
3057==============================================================================*/
3058int DHL_PSI_ParseCVCT (DS_U8 **sectionArr, cvctPtr_t *cvctPtr)
3059{
3060//      DS_U8                           numSections;
3061//      DS_U16                          numChannels;
3062//     
3063//      DS_U16                  i,j;
3064//      memChainSetup_t         memSetup = {MEM_LIMIT_BIG,0,0};
3065//      memId_t                 memId = 0;
3066//      DHL_RESULT                      err;
3067
3068
3069        if (sectionArr == 0 || (cvctPtr == 0)) 
3070        {
3071                return (DHL_FAIL_NULL_POINTER);
3072        }
3073
3074        if (sectionArr[0] == 0) 
3075        {
3076                return (DHL_FAIL_NULL_POINTER);
3077        }
3078        DS_U8 numSections = get_last_section_number(sectionArr[0]) + 1;
3079
3080        /* now verify all other sections are present */
3081        int i;
3082        for ( i=1; i<numSections; i++)
3083        {
3084                if (sectionArr[i] == 0) 
3085                {
3086                        if (0) DST_Printf("CVCT :  invalid section found.\r\n");       
3087                        return (DHL_FAIL_NULL_POINTER);
3088                }
3089        }
3090
3091        /*check protocol version of each section.*/
3092        for ( i=0; i< numSections ; i++ )
3093        {
3094                if(sectionArr[i][8] != 0/*PSIP_PROTOCOL_VERSION*/) 
3095                {
3096                        if (0) DST_Printf("CVCT : invalid Protocol Version.\r\n");             
3097                        return DHL_FAIL_INVALID_VERSION;
3098                }
3099        }
3100
3101        memId_t memId = (memId_t)0;
3102        if (memChainCreate(&memId)) /* create the memChain */
3103        {
3104                return DHL_FAIL_OUT_OF_RESOURCE;
3105        }
3106        /* allocate memory for cvct */
3107        *cvctPtr = (cvctPtr_t)((memId_t *)(memChainAlloc(memId,sizeof(cvct_t)+sizeof(memId_t))) + 1);
3108        if (*cvctPtr == 0)
3109        {
3110                        memChainDestroy(memId);
3111                        return DHL_FAIL_OUT_OF_RESOURCE;
3112        }
3113
3114        /* Get the total number of channels in all sections */
3115        DS_U16 numChannels = 0;
3116       
3117        for ( i=0; i<numSections; i++)
3118        {
3119                numChannels += sectionArr[i][9];
3120        }
3121
3122        (*cvctPtr)->numChannels = numChannels;
3123
3124        /* allocate space in cvct for channels */
3125        (*cvctPtr)->channel = (cvctChannelPtr_t)memChainAlloc(memId,numChannels*sizeof(cvctChannel_t));
3126        if ((*cvctPtr)->channel == 0)
3127        {
3128                        memChainDestroy(memId);
3129                        return DHL_FAIL_OUT_OF_RESOURCE;
3130        }
3131
3132        /* Parse each section and copy channels */
3133        numChannels = 0;
3134        for ( i=0; i<numSections; i++) {
3135                /* Parse the section */
3136                cvctSectionPtr_t                cvctSectPtr = 0;
3137                int err = DHL_PSI_ParseCVCTSection(sectionArr[i], &cvctSectPtr);
3138                if (err != 0)
3139                {
3140                        memChainDestroy(memId);
3141                        return err;
3142                }
3143
3144                if (i == 0) {
3145                        /* duplicate fields copied once */     
3146                        (*cvctPtr)->transport_stream_id = cvctSectPtr->transport_stream_id;
3147                        (*cvctPtr)->version_number = cvctSectPtr->version_number;
3148
3149                        /* allocate space for descriptors and copy (if any) */
3150                        if (cvctSectPtr->additional_descriptor_length > 0) 
3151                        {
3152                                (*cvctPtr)->additional_descriptors = (DS_U8 *)memChainAlloc(memId,cvctSectPtr->additional_descriptor_length*sizeof(DS_U8));
3153                                if ((*cvctPtr)->additional_descriptors == 0) 
3154                                {
3155                                        DHL_PSI_FreeMpegSection(cvctSectPtr);
3156                                        memChainDestroy(memId);
3157                                        return DHL_FAIL_OUT_OF_RESOURCE;
3158                                }
3159                                memcpy((*cvctPtr)->additional_descriptors,cvctSectPtr->additional_descriptors, (*cvctPtr)->additional_descriptor_length);
3160                        }
3161                }
3162                int j;
3163                for ( j=0; j<cvctSectPtr->num_channels_in_section; j++) 
3164                {
3165                        memcpy(&((*cvctPtr)->channel[numChannels]), &(cvctSectPtr->channel[j]), sizeof(cvctChannel_t));
3166
3167                        /* allocate space for descriptors and copy (if any) */
3168                        if (cvctSectPtr->channel[j].descriptor_length > 0)
3169                        {
3170                                (*cvctPtr)->channel[numChannels].descriptors = (DS_U8 *)memChainAlloc(memId,cvctSectPtr->channel[j].descriptor_length*sizeof(DS_U8));
3171                                if ((*cvctPtr)->channel[numChannels].descriptors == 0) 
3172                                {
3173                                        DHL_PSI_FreeMpegSection(cvctSectPtr);
3174                                        memChainDestroy(memId);
3175                                        return DHL_FAIL_OUT_OF_RESOURCE;
3176                                }
3177
3178                                /*memcpy((*cvctPtr)->channel[numChannels].descriptors,cvctSectPtr->channel[j].descriptors, (*cvctPtr)->channel[j].descriptor_length);*/
3179                                /*cafrii 030910, bugfix*/
3180                                memcpy((*cvctPtr)->channel[numChannels].descriptors,cvctSectPtr->channel[j].descriptors, (*cvctPtr)->channel[numChannels].descriptor_length);
3181                        }
3182                        numChannels++;
3183                }
3184                DHL_PSI_FreeMpegSection(cvctSectPtr);
3185        }
3186
3187        /* parsing complete */
3188        *(((memId_t *)(*cvctPtr))-1) = memId;
3189        memId = 0;              /* so memChain not deleted */
3190
3191//ParseExit:
3192        if (memId) {
3193                /* delete the cvct memory */
3194                memChainDestroy(memId);
3195        }
3196        return 0;
3197}
3198#endif
Note: See TracBrowser for help on using the repository browser.