source: svn/trunk/zasc/app/DST_Parser.cpp @ 22

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

1.phkim

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