source: svn/trunk/newcon3bcm2_21bu/BSEAV/lib/scte65/aeit/si_aeit.c

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

first commit

  • Property svn:executable set to *
File size: 20.4 KB
Line 
1/***************************************************************
2**
3** Broadcom Corp. Confidential
4** Copyright 2003-2008 Broadcom Corp. All Rights Reserved.
5**
6** THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED
7** SOFTWARE LICENSE AGREEMENT BETWEEN THE USER AND BROADCOM.
8** YOU HAVE NO RIGHT TO USE OR EXPLOIT THIS MATERIAL EXCEPT
9** SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
10**
11** File:                si_aeit.c
12** Description: function that parses the AEIT
13**              table section. And keeps track of all the events.
14**
15** Created: 03/08/2001
16**
17** REVISION:
18**
19** $Log: $
20**
21**
22****************************************************************/
23
24#include "si.h"
25#include "si_os.h"
26#include "si_dbg.h"
27#include "si_util.h"
28#include "si_list.h"
29#include "si_aeit.h"
30#include "si_mgt.h"
31#include "si_descriptors.h"
32
33
34/* local function prototypes. */
35static SI_AEIT_SOURCE *SI_AEIT_Create_Source (void);
36static SI_AEIT_EVENT *SI_AEIT_Create_Event (void);
37static SI_RET_CODE SI_AEIT_Ins_Source (SI_AEIT_SLOT *slot, SI_AEIT_SOURCE *new_source);
38static SI_RET_CODE SI_AEIT_Ins_Event (SI_AEIT_SOURCE *source, SI_AEIT_EVENT *new_event);
39
40
41extern struct aeit_slot_list head_aeit_slot, current_aeit0_slot;                /* always point to AEIT-0 */
42extern SI_mutex m_aeit;
43
44
45/*********************************************************************/
46/* Function : SI_AEIT_Create_Slot                                                                        */
47/* Description : Function to allocate the space for an instance of   */
48/*                               AEIT-n. Corresponding to events happening                       */
49/*               in different channels(source) during a particular 3 */
50/*                               hour period of a day.                                                           */
51/* Input : None.                                                                                                 */
52/* Output : pointer to the AEIT-n instance structure allocated. Will */
53/*                      return NULL if out of memory.                                                    */
54/*********************************************************************/
55SI_AEIT_SLOT *SI_AEIT_Create_Slot (void)
56{
57        SI_AEIT_SLOT * slot;
58        int     i;
59       
60        slot = (SI_AEIT_SLOT *)SI_alloc(sizeof(SI_AEIT_SLOT));
61        if (slot == NULL)
62        {
63                SI_DBG_PRINT(E_SI_ERR_MSG,("Failed to allocate an AEIT slot!!!\n"));
64                return NULL;
65        }
66
67        SI_LST_D_INIT_ENTRY(&(slot->slot_link));
68        SI_LST_D_INIT(&(slot->aeit_source));
69
70        for (i=0; i<8; i++)
71                slot->section_mask[i] = 0;
72
73        slot->version_number = 0xff;
74               
75        return slot;
76}
77
78/*********************************************************************/
79/* Function : SI_AEIT_Create_Source                                                                      */
80/* Description : Function to allocate the space for the event link       */
81/*                               list of a paticular channel(source) within an           */
82/*                               instance (slot) of AEIT-n.                                                      */
83/* Input : None.                                                                                                 */
84/* Output : pointer to the channel (source) structure within an          */
85/*                      AEIT-n instance (slot). Will return NULL if out of               */
86/*                      memory.                                                                                                  */
87/*********************************************************************/
88static SI_AEIT_SOURCE *SI_AEIT_Create_Source (void)
89{
90        SI_AEIT_SOURCE * source;
91       
92        source = (SI_AEIT_SOURCE *)SI_alloc(sizeof(SI_AEIT_SOURCE));
93        if (source == NULL)
94        {
95                SI_DBG_PRINT(E_SI_ERR_MSG,("Failed to allocate an AEIT source!!!\n"));
96                return NULL;
97        }
98
99        SI_LST_D_INIT_ENTRY(&(source->source_link));
100        SI_LST_D_INIT(&(source->aeit_event));
101
102        return source;
103}
104
105/*********************************************************************/
106/* Function : SI_AEIT_Create_Event                                                                       */
107/* Description : Function to allocate the space for an actual event  */
108/*                               structure that forms the event link                             */
109/*                               list of a paticular channel(source) within an           */
110/*                               instance (slot) of AEIT-n.                                                      */
111/* Input : None.                                                                                                 */
112/* Output : pointer to the event structure for a channel (source)        */
113/*                      within an AEIT-n instance (slot). Will return NULL if    */
114/*                      out of memory.                                                                                   */
115/*********************************************************************/
116static SI_AEIT_EVENT *SI_AEIT_Create_Event (void)
117{
118        SI_AEIT_EVENT * event;
119       
120        event = (SI_AEIT_EVENT *)SI_alloc(sizeof(SI_AEIT_EVENT));
121        if (event == NULL)
122        {
123                SI_DBG_PRINT(E_SI_ERR_MSG,("Failed to allocate an AEIT event!!!\n"));
124                return NULL;
125        }
126
127        event->title_text = NULL;
128        SI_LST_D_INIT_ENTRY(&(event->event_link));
129
130        return event;
131}
132
133
134/*********************************************************************/
135/* Function : SI_AEIT_Clear_Slot                                                                         */
136/* Description : Function to clear the contents for an instance of   */
137/*                               AEIT-n. This is used when a new version of AEIT-n       */
138/*                               is received. It shall free all the structure            */
139/*                               allocated for the source and events. But not free       */
140/*                               the slot itself.                                                                        */
141/* Input : Slot structure pointer allocated for AEIT-n.                          */
142/* Output : SI_RET_CODE                                                                                          */
143/*********************************************************************/
144SI_RET_CODE SI_AEIT_Clear_Slot (SI_AEIT_SLOT * slot)
145{
146        struct aeit_source_list  *source_list; /* head of source list. */
147        struct aeit_event_list  *event_list; /* head of event list. */
148        SI_AEIT_EVENT * event;
149        SI_AEIT_SOURCE * source;
150        unsigned long i;
151       
152        if (slot)
153        {
154                source_list = &(slot->aeit_source);
155                /* recursively free all sources in slot. */
156                while ((source = SI_LST_D_FIRST(source_list)))
157                {
158                        /* recursively free all events in sources. */
159                        event_list = &(source->aeit_event);
160                        while ((event = SI_LST_D_FIRST(event_list)))
161                        {
162                                /* free the event title, event link, and event itself. */
163                                SI_free(event->title_text);
164                                SI_LST_D_REMOVE_HEAD(event_list, event_link); /* event_list will be updated. */
165                                SI_free(event);
166                        }
167
168                        /* free the source link and source */ 
169                        SI_LST_D_REMOVE_HEAD(source_list, source_link);  /* source_list will be updated. */
170                        SI_free(source);
171                }
172
173                /* just to be sure. Should not need to do it. */
174                SI_LST_D_INIT(&(slot->aeit_source));
175
176                for (i=0; i<8; i++)
177                        slot->section_mask[i] = 0;
178               
179                slot->version_number = 0xff;
180               
181        }
182       
183        return SI_SUCCESS;
184}
185
186/*********************************************************************/
187/* Function : SI_AEIT_Ins_Source                                                                         */
188/* Description : Function to insert a newly received channel(source) */
189/*                               structure into an instance (slot) of AEIT-n table.      */
190/*                               The channel(source) link list is sorted by              */
191/*                               source_ID in incrementing order.                                        */
192/* Input : SI_AEIT_SLOT *slot : points to the existing AEIT-n(slot)  */
193/*                                      instance structure.                                                      */
194/*                 SI_AEIT_SOURCE *new_source : points to the newly received */
195/*                                      channel event link list.                                                 */
196/* Output : SI_RET_CODE.                                                                                         */
197/*********************************************************************/
198static SI_RET_CODE SI_AEIT_Ins_Source (SI_AEIT_SLOT *slot, SI_AEIT_SOURCE *new_source)
199{
200        struct aeit_source_list  *source_list; /* head of source list. */
201        struct aeit_event_list  *event_list; /* head of event list. */
202        SI_AEIT_SOURCE *source;
203        SI_AEIT_EVENT *event;
204       
205        if (slot == NULL)
206        {
207                SI_DBG_PRINT(E_SI_ERR_MSG,("No Valid slot allocated!!!\n"));
208                return SI_NULL_POINTER;
209        }
210
211        if (new_source == NULL)
212        {
213                SI_DBG_PRINT(E_SI_ERR_MSG,("source is not yet allocated!!!\n"));
214                return SI_NULL_POINTER;
215        }
216
217        source_list = &(slot->aeit_source);
218        source = SI_LST_D_FIRST(source_list);
219        /* find the place to insert the new source link. */
220        if (source == NULL)
221        {
222                /* if the source list is empty */
223                SI_LST_D_INSERT_HEAD(source_list, new_source, source_link);
224                return SI_SUCCESS;
225        }
226       
227        while (source->source_ID <= new_source->source_ID)
228        {
229                if (new_source->source_ID == source->source_ID)
230                {
231                        /* if the source already exists, I don't know how possible this is, since it means
232                                that the AEIT table will carry events of the same channel in different sections.
233                                Well, the spec does not say it is not possible. so we have to waste some code to
234                                handle it.
235                        */
236                        event_list = &(new_source->aeit_event);
237                        event = SI_LST_D_FIRST(event_list);
238                        while (event)
239                        {
240                                /* insert event into source structure. */
241                                SI_AEIT_Ins_Event(source, event);
242                                event = SI_LST_D_NEXT(event, event_link);
243                        }
244                        /* finally we need to free the source. */
245                        SI_free(new_source);
246                        return SI_SUCCESS;
247                }
248
249                if (SI_LST_D_NEXT(source, source_link))
250                        source = SI_LST_D_NEXT(source, source_link);
251                else
252                {
253                        /* we arrived at the end of list. */
254                        SI_LST_D_INSERT_AFTER(source, new_source, source_link);
255                        return SI_SUCCESS;
256                }
257        }
258
259        /* when we get to this point, the source_list points to the point BEFORE which the new source
260                will be inserted.
261        */
262        SI_LST_D_INSERT_BEFORE(source_list, source, new_source, source_link);   
263       
264        return SI_SUCCESS;
265}
266
267
268/*********************************************************************/
269/* Function : SI_AEIT_Ins_Event                                                                          */
270/* Description : Function to insert a newly received event               */
271/*                               structure into the event link                                           */
272/*                               list for a paticular channel(source) within an          */
273/*                               instance (slot) of AEIT-n. The link list of events      */
274/*                               is sorted by the starting time of an event.             */
275/* Input : SI_AEIT_SOURCE *source : points to the existing                       */
276/*                                      channel(source) event link list.                         */
277/*                 SI_AEIT_EVENT *new_event : points to the newly received       */
278/*                                      event for a channel(source) to be inserted into  */
279/*                                      the above source structure.                                              */
280/* Output : SI_RET_CODE.                                                                                         */
281/*********************************************************************/
282static SI_RET_CODE SI_AEIT_Ins_Event (SI_AEIT_SOURCE *source, SI_AEIT_EVENT *new_event)
283{
284        struct aeit_event_list  *event_list; /* head of event list. */
285        SI_AEIT_EVENT *event;
286       
287        if (source == NULL)
288        {
289                SI_DBG_PRINT(E_SI_ERR_MSG,("source is not yet allocated!!!\n"));
290                return SI_NULL_POINTER;
291        }
292
293        if (new_event == NULL)
294        {
295                SI_DBG_PRINT(E_SI_ERR_MSG,("new event is not yet allocated!!!\n"));
296                return SI_NULL_POINTER;
297        }
298
299        event_list = &(source->aeit_event);
300        if ( (event = SI_LST_D_FIRST(event_list)) == NULL)
301        {
302                /* if event list is original empty. */
303                SI_LST_D_INSERT_HEAD(event_list, new_event, event_link);
304                return SI_SUCCESS;
305        }
306
307        /* find the event that starts later than the new event. */
308        while (event->start_time < new_event->start_time)
309        {
310                if (SI_LST_D_NEXT(event, event_link) == NULL)  /* end of list */
311                {
312                        SI_LST_D_INSERT_AFTER(event, new_event, event_link);
313                        return SI_SUCCESS;
314                }
315                event = SI_LST_D_NEXT(event, event_link);
316        }
317
318        /* at this point, we just insert before the current event. */
319        SI_LST_D_INSERT_BEFORE(event_list, event, new_event, event_link);
320
321        return SI_SUCCESS;
322}
323
324
325/*********************************************************************
326 Function : SI_AEIT_Parse       
327 Description : Function to parse a newly received AEIT-n table and put
328                                it into the AEIT-n slot link list created by MGT parse.
329                                Before we create the AEIT-n slot from MGT, we simply
330                                ignore the AEIT-n table.
331 Input : unsigned char *aeit_table : newly received aeit table data.                                             
332 Output : SI_RET_CODE.                                                                                   
333**********************************************************************/
334SI_RET_CODE SI_AEIT_Parse (unsigned char *aeit_table)
335{
336        unsigned long temp, i, j;
337        unsigned long section_length, version_number;
338        unsigned long MGT_tag, section_number, last_section_number, num_sources_in_section, num_events;
339        unsigned long desc_start, len;
340        unsigned long desc_tag, desc_len;
341        unsigned char *current;
342        SI_AEIT_SLOT *slot;
343        SI_AEIT_SOURCE *source;
344        SI_AEIT_EVENT *event;
345        SI_RET_CODE result;
346
347        temp = *(aeit_table);
348        if (temp != SI_AEIT_TABLE_ID)
349        {
350                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT Table ID error!!! %x\n", temp));
351                return SI_TABLE_ID_ERROR;
352        }
353
354        /* calculate and check section length. */
355        section_length = SI_Construct_Data(aeit_table, 
356                                AEIT_SECTION_LENGTH_BYTE_INDX,
357                                AEIT_SECTION_LENGTH_BYTE_NUM,
358                                AEIT_SECTION_LENGTH_SHIFT,
359                                AEIT_SECTION_LENGTH_MASK);
360        section_length += AEIT_SECTION_LENGTH_BYTE_INDX+AEIT_SECTION_LENGTH_BYTE_NUM;
361        if (section_length > SI_LONG_SECTION_LENGTH)
362        {
363                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT Table section length error!!! %x\n", section_length));
364                return SI_SECTION_LENGTH_ERROR;
365        }
366       
367        /* We do the CRC check here to verify the contents of this section. */
368        if (SI_CRC32_Check(aeit_table, section_length) != SI_SUCCESS)
369        {
370                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT Table section CRC error!!!\n"));
371                return SI_CRC_ERROR;
372        }
373
374        /* check to make sure AEIT_subtype is zero. */
375        temp = SI_Construct_Data(aeit_table, 
376                                AEIT_AEIT_SUBTYPE_BYTE_INDX,
377                                AEIT_AEIT_SUBTYPE_BYTE_NUM,
378                                AEIT_AEIT_SUBTYPE_SHIFT,
379                                AEIT_AEIT_SUBTYPE_MASK);
380        if (temp != SI_CURRENT_AEIT_SUBTYPE)
381        {
382                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT Table AEIT_subtype Not what we can handle, Ignore the table!!! %x\n", temp));
383                return SI_PROTOCOL_VER_ERROR;
384        }
385       
386        /* get MGT_tag. */
387        MGT_tag = SI_Construct_Data(aeit_table, 
388                                AEIT_MGT_TAG_BYTE_INDX,
389                                AEIT_MGT_TAG_BYTE_NUM,
390                                AEIT_MGT_TAG_SHIFT,
391                                AEIT_MGT_TAG_MASK);
392
393        /* lock mutex for AEIT table access. */
394        SI_mutex_lock(m_aeit);
395
396        /* search for the AEIT-n slot link list for the MGT_tag. */
397        if ((slot = SI_LST_D_FIRST(&current_aeit0_slot)) ==NULL)
398        {
399                SI_mutex_unlock(m_aeit);
400                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT-n slot link list not generated from MGT yet, Ignore the table!!!\n"));
401                return SI_AEIT_LIST_NOT_READY;
402        }
403        while (slot)
404        {
405                if (slot->MGT_tag == MGT_tag)
406                        break;
407                slot = SI_LST_D_NEXT(slot, slot_link);
408        }
409
410        if (slot == NULL)
411        {
412                SI_mutex_unlock(m_aeit);
413                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT-n slot link list does not contain the slot that matches the MGT_tag, Ignore the table!!\n"));
414                return SI_AEIT_LIST_NOT_READY;
415        }
416
417        /* look at current_next_indicator. It should be 1 for AEIT. */
418        temp = SI_Construct_Data(aeit_table, 
419                                AEIT_CURRENT_NEXT_INDICATOR_BYTE_INDX,
420                                AEIT_CURRENT_NEXT_INDICATOR_BYTE_NUM,
421                                AEIT_CURRENT_NEXT_INDICATOR_SHIFT,
422                                AEIT_CURRENT_NEXT_INDICATOR_MASK);
423        if (temp != 1)
424        {
425                SI_mutex_unlock(m_aeit);
426                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT Table current_next_indicator not one!!! %x\n", temp));
427                return SI_CURRENT_NEXT_INDICATOR_ERROR;
428        }
429
430        /* now we know where the slot is in the link list, See if we need to update. */
431        version_number = SI_Construct_Data(aeit_table, 
432                                                AEIT_VERSION_NUMBER_BYTE_INDX,
433                                                AEIT_VERSION_NUMBER_BYTE_NUM,
434                                                AEIT_VERSION_NUMBER_SHIFT,
435                                                AEIT_VERSION_NUMBER_MASK);
436        section_number = SI_Construct_Data(aeit_table, 
437                                                AEIT_SECTION_NUMBER_BYTE_INDX,
438                                                AEIT_SECTION_NUMBER_BYTE_NUM,
439                                                AEIT_SECTION_NUMBER_SHIFT,
440                                                AEIT_SECTION_NUMBER_MASK);
441        if (slot->version_number == version_number)
442        {
443                /* the same version number. Now check if the section number has already be processed. */
444                if (SI_Chk_Section_mask(&(slot->section_mask[0]), section_number))
445                {
446                        /* section already processed, we are done! */
447                        SI_mutex_unlock(m_aeit);
448                        return SI_SUCCESS;
449                }
450        }
451        else
452        {
453                /* different version number. The slot should have already been init by MGT parse. */
454                SI_DBG_PRINT(E_SI_DBG_MSG,("New AEIT Table received!\n"));
455                if (slot->MGT_version_number != version_number)
456                {
457                        /* this should not happen, but what the heck..... */
458                        SI_DBG_PRINT(E_SI_WRN_MSG,("AEIT-n slot mgt version does not match new version, reinit slot!!\n"));
459                        temp = slot->pid; /* at least trust the pid. */
460                        SI_AEIT_Clear_Slot(slot);
461                        slot->MGT_tag = MGT_tag;
462                        slot->MGT_version_number = version_number;
463                        slot->pid = temp;
464                }
465                slot->version_number = version_number;
466                /* init section mask. */
467                last_section_number = SI_Construct_Data(aeit_table, 
468                                                        AEIT_LAST_SECTION_NUMBER_BYTE_INDX,
469                                                        AEIT_LAST_SECTION_NUMBER_BYTE_NUM,
470                                                        AEIT_LAST_SECTION_NUMBER_SHIFT,
471                                                        AEIT_LAST_SECTION_NUMBER_MASK);
472                SI_Init_Section_Mask(&(slot->section_mask[0]), last_section_number);
473        }
474
475        /* update section mask here. */
476        SI_Set_Section_mask(&(slot->section_mask[0]), section_number);
477       
478        /* new AEIT table section received!!! */
479        SI_DBG_PRINT(E_SI_DBG_MSG,("New AEIT Table section received!\n"));
480
481        num_sources_in_section = SI_Construct_Data(aeit_table, 
482                                                        AEIT_NUM_SOURCES_IN_SECTION_BYTE_INDX,
483                                                        AEIT_NUM_SOURCES_IN_SECTION_BYTE_NUM,
484                                                        AEIT_NUM_SOURCES_IN_SECTION_SHIFT,
485                                                        AEIT_NUM_SOURCES_IN_SECTION_MASK);
486
487        current = aeit_table + AEIT_NUM_SOURCES_IN_SECTION_BYTE_INDX + 
488                                                        AEIT_NUM_SOURCES_IN_SECTION_BYTE_NUM; /* points to first source byte. */
489        for (i=0; i<num_sources_in_section; i++)
490        {
491                if ((source = SI_AEIT_Create_Source()) == NULL)
492                {
493                        SI_mutex_unlock(m_aeit);
494                        SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT cannot create source structure!!!\n"));
495                        return SI_NO_MEMORY;
496                }
497                source->source_ID = SI_Construct_Data(current, 
498                                                        AEIT_SOURCE_ID_BYTE_INDX,
499                                                        AEIT_SOURCE_ID_BYTE_NUM,
500                                                        AEIT_SOURCE_ID_SHIFT,
501                                                        AEIT_SOURCE_ID_MASK);
502                num_events = SI_Construct_Data(current, 
503                                                AEIT_NUM_EVENTS_BYTE_INDX,
504                                                AEIT_NUM_EVENTS_BYTE_NUM,
505                                                AEIT_NUM_EVENTS_SHIFT,
506                                                AEIT_NUM_EVENTS_MASK);
507                current += AEIT_NUM_EVENTS_BYTE_INDX+AEIT_NUM_EVENTS_BYTE_NUM; /* points to 1st event byte. */
508                for (j=0; j<num_events; j++)
509                {
510                        /* create and stuff the event structure. */
511                        if ((event = SI_AEIT_Create_Event()) == NULL)
512                        {
513                                SI_mutex_unlock(m_aeit);
514                                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT cannot create event structure!!!\n"));
515                                return SI_NO_MEMORY;
516                        }
517                        event->event_ID = SI_Construct_Data(current, 
518                                                        AEIT_EVENT_ID_BYTE_INDX,
519                                                        AEIT_EVENT_ID_BYTE_NUM,
520                                                        AEIT_EVENT_ID_SHIFT,
521                                                        AEIT_EVENT_ID_MASK);
522                        event->start_time = SI_Construct_Data(current, 
523                                                        AEIT_START_TIME_BYTE_INDX,
524                                                        AEIT_START_TIME_BYTE_NUM,
525                                                        AEIT_START_TIME_SHIFT,
526                                                        AEIT_START_TIME_MASK);
527                        event->ETM_present = SI_Construct_Data(current, 
528                                                        AEIT_ETM_PRESENT_BYTE_INDX,
529                                                        AEIT_ETM_PRESENT_BYTE_NUM,
530                                                        AEIT_ETM_PRESENT_SHIFT,
531                                                        AEIT_ETM_PRESENT_MASK);
532                        event->duration = SI_Construct_Data(current, 
533                                                        AEIT_DURATION_BYTE_INDX,
534                                                        AEIT_DURATION_BYTE_NUM,
535                                                        AEIT_DURATION_SHIFT,
536                                                        AEIT_DURATION_MASK);
537                        event->title_length = SI_Construct_Data(current, 
538                                                        AEIT_TITLE_LENGTH_BYTE_INDX,
539                                                        AEIT_TITLE_LENGTH_BYTE_NUM,
540                                                        AEIT_TITLE_LENGTH_SHIFT,
541                                                        AEIT_TITLE_LENGTH_MASK);
542                        if ((event->title_text = (unsigned char *)SI_alloc(event->title_length)) == NULL)
543                        {
544                                SI_mutex_unlock(m_aeit);
545                                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT cannot allocate mem for event title!!!\n"));
546                                return SI_NO_MEMORY;
547                        }
548                        current += AEIT_TITLE_LENGTH_BYTE_INDX+AEIT_TITLE_LENGTH_BYTE_NUM; /* points to title text. */
549                        SI_memcpy(event->title_text, current, event->title_length);
550                        current += event->title_length; /* points to desc length. */
551
552                        desc_len = SI_Construct_Data(current, 
553                                                        AEIT_DESC_LENGTH_BYTE_INDX,
554                                                        AEIT_DESC_LENGTH_BYTE_NUM,
555                                                        AEIT_DESC_LENGTH_SHIFT,
556                                                        AEIT_DESC_LENGTH_MASK);
557                                                       
558                        /* TBD Not processing descriptors yet. */
559                        current += AEIT_DESC_LENGTH_BYTE_INDX+AEIT_DESC_LENGTH_BYTE_NUM; /* point to the 1st desc. */
560                        desc_start = 0;
561                        while (desc_start < desc_len)
562                        {
563                                desc_tag = *(current++);
564                                len = *(current++);
565                                switch (desc_tag)
566                                {
567                                        case SI_DESC_AC3_AUDIO:
568                                                SI_DBG_PRINT(E_SI_DBG_MSG,("AEIT Table have AC3 descriptor.\n"));
569                                        break;
570
571                                        case SI_DESC_CAPTION_SERVICE:
572                                                SI_DBG_PRINT(E_SI_DBG_MSG,("AEIT Table have caption descriptor.\n"));
573                                        break;
574
575                                        case SI_DESC_CONTENT_ADVISORY:
576                                                SI_DBG_PRINT(E_SI_DBG_MSG,("AEIT Table have content advisory descriptor.\n"));
577                                        break;
578
579                                        case SI_DESC_STUFFING:
580                                                SI_DBG_PRINT(E_SI_DBG_MSG,("AEIT Table have stuffing descriptor.\n"));
581                                        break;
582
583                                        default:
584                                                if (desc_tag >= SI_DESC_USER_PRIVATE)
585                                                {
586                                                        SI_DBG_PRINT(E_SI_WRN_MSG,("AEIT Table have user private descriptor. And we don't know what to do with it.\n"));
587                                                }
588                                                else
589                                                {
590                                                        SI_mutex_unlock(m_aeit);
591                                                        SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT Table have bad descriptor %x!\n", desc_tag));
592                                                        return SI_DESCRIPTOR_ERROR;
593                                                }
594                                        break;
595                                }
596                                current += len;
597
598                                desc_start += len+2; /* plus the tag and length. */
599                        }
600
601                        /* verify descriptor length. */
602                        if (desc_start != desc_len)
603                        {
604                                SI_mutex_unlock(m_aeit);
605                                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT Table descriptor length error!\n"));
606                                return SI_DESCRIPTOR_ERROR;
607                        }
608
609                        /* insert event into event link list for this channel */
610                        if ((result = SI_AEIT_Ins_Event (source, event)) != SI_SUCCESS)
611                        {
612                                SI_mutex_unlock(m_aeit);
613                                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT cannot insert event!!!\n"));
614                                return result;
615                        }
616                }
617
618                /* insert the source structure into AEIT-n source link list. */
619                if ((result = SI_AEIT_Ins_Source(slot,source)) != SI_SUCCESS)
620                {
621                        SI_mutex_unlock(m_aeit);
622                        SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT cannot insert source!!!\n"));
623                        return result;
624                }
625        }
626
627        /* unlock mutex for AEIT table access. */
628        SI_mutex_unlock(m_aeit);
629       
630        if (((unsigned long)current - (unsigned long)aeit_table) != (section_length - SI_CRC_LENGTH))
631        {
632                SI_DBG_PRINT(E_SI_ERR_MSG,("AEIT Table length error!\n"));
633                return SI_SECTION_LENGTH_ERROR;
634        }
635       
636        return SI_SUCCESS;
637}
638
Note: See TracBrowser for help on using the repository browser.