source: svn/newcon3bcm2_21bu/BSEAV/lib/scte65/lvct/si_lvct.c

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

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

  • Property svn:executable set to *
File size: 18.3 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_lvct.c
12** Description: function that parses the L-VCT table sections and
13**                              keeps track of all the virtual channel link lists.
14**
15** Created: 03/08/2001
16**
17** REVISION:
18**
19** $Log: $
20**
21**
22****************************************************************/
23#include "si.h"
24#include "si_os.h"
25#include "si_dbg.h"
26#include "si_util.h"
27#include "si_list.h"
28#include "si_vct.h"
29#include "si_lvct.h"
30#include "si_descriptors.h"
31
32/* local function prototypes. */
33static SI_LVCT_CHANNEL * SI_LVCT_Create_Channel (void);
34static unsigned char SI_LVCT_Compare_channel(SI_LVCT_CHANNEL *chan1, SI_LVCT_CHANNEL *chan2);
35static SI_RET_CODE SI_LVCT_Free_Channel(SI_LVCT_CHANNEL *channel);
36static SI_RET_CODE SI_LVCT_Free_List(void);
37static SI_RET_CODE SI_LVCT_Ins_Channel(SI_LVCT_CHANNEL *new_channel);
38
39
40struct lvct_channel_list LVCT_channels;      /*LVCT_2_channels*/
41unsigned long Total_LVCT_Channels;
42unsigned char LVCT_version_number;
43unsigned long LVCT_section_mask[8];
44SI_mutex m_lvct;
45
46void SI_LVCT_Init(void)
47{
48        unsigned long i;
49       
50        SI_LST_D_INIT(&LVCT_channels);
51        Total_LVCT_Channels = 0;
52        LVCT_version_number = 0xff;
53        for (i=0; i<8; i++)
54                LVCT_section_mask[i] = 0;
55        SI_mutex_init(m_lvct);
56}
57
58/*********************************************************************
59 Function : SI_LVCT_Create_Channel                                                                       
60 Description : Function to allocate the space for an L-VCT channel.                                                             
61 Input : none. 
62 Output : pointer to the L-VCT channel structure allocated. Will
63                        return NULL if out of memory.                                                   
64**********************************************************************/
65static SI_LVCT_CHANNEL * SI_LVCT_Create_Channel (void)
66{
67        SI_LVCT_CHANNEL * lvct_channel;
68        int     i;
69       
70        lvct_channel = (SI_LVCT_CHANNEL *)SI_alloc(sizeof(SI_LVCT_CHANNEL));
71        if (lvct_channel == NULL)
72        {
73                SI_DBG_PRINT(E_SI_ERR_MSG,("Failed to allocate an L-VCT channel!!!\n"));
74                return NULL;
75        }
76
77        SI_LST_D_INIT_ENTRY(&(lvct_channel->chan_link));
78        lvct_channel->ext_name_len = 0;
79        lvct_channel->ext_name = NULL;
80        lvct_channel->num_of_ts_serv = 0;
81        lvct_channel->time_shifted = NULL;
82
83        return lvct_channel;
84}
85
86/*********************************************************************
87 Function : SI_LVCT_Compare_Channel                                                                     
88 Description : Function to compare an LVCT channel to another to see
89                                if the virtual channel numbers are equal, greater or less.
90 Input : SI_LVCT_CHANNEL *chan1.        pointer to one LVCT channel struct
91                 SI_LVCT_CHANNEL *chan2.        pointer to second LVCT channel struct
92 Output : 0 if the chan1 number is smaller, 1 if equal, 2 if chan1 is
93                        greater.                                                       
94**********************************************************************/
95static unsigned char SI_LVCT_Compare_channel(SI_LVCT_CHANNEL *chan1, SI_LVCT_CHANNEL *chan2)
96{
97        if (chan1->vcn_mode != chan2->vcn_mode)
98                if (chan1->vcn_mode == ONE_PART)
99                        return 0;
100                else
101                        return 2;
102        /* both channels are one or two part. */
103        if (chan1->vcn_mode == ONE_PART)
104        {
105                if (chan1->channum1 == chan2->channum1)
106                        return 1;
107                else if (chan1->channum1 > chan2->channum1)
108                        return 2;
109        }
110        else
111        {
112                if (chan1->channum1 == chan2->channum1)
113                {
114                        if (chan1->channum2 == chan2->channum2)
115                                return 1;
116                        else if (chan1->channum2 > chan2->channum2)
117                                return 2;
118                       
119                }
120                else if (chan1->channum1 > chan2->channum1)
121                        return 2;
122        }
123
124        return 0;
125}
126
127
128/*********************************************************************
129 Function : SI_LVCT_Free_Channel                                                                         
130 Description : Function to free an LVCT channel from the LVCT
131                                channel list. the channel structure will be freed but 
132                                not removed from the channel list. WE ASSUME THAT WHEN
133                                CALLING THIS FUNCTION, THE CHANNEL HAS NOT BEEN ADDED
134                                TO THE LIST YET!!!
135 Input : SI_LVCT_CHANNEL *channel.      pointer to  LVCT channel
136                        structure to be freed.
137 Output : SI_RET_CODE.                                                 
138**********************************************************************/
139static SI_RET_CODE SI_LVCT_Free_Channel(SI_LVCT_CHANNEL *channel)
140{
141        if (channel)
142        {
143                if (channel->ext_name)
144                        SI_free(channel->ext_name);
145                if (channel->time_shifted)
146                        SI_free(channel->time_shifted);
147
148                SI_free(channel);
149        }
150
151        return SI_SUCCESS;
152}
153
154
155/*********************************************************************
156 Function : SI_LVCT_Free_List                                                                   
157 Description : Function to free the whole LVCT channel list.
158 Input : None.
159 Output : SI_RET_CODE.                                                 
160**********************************************************************/
161static SI_RET_CODE SI_LVCT_Free_List(void)
162{
163        SI_LVCT_CHANNEL *channel;
164
165        SI_mutex_lock(m_lvct);
166        while ((channel = SI_LST_D_FIRST(&LVCT_channels)))
167        {
168                SI_LST_D_REMOVE_HEAD(&LVCT_channels, chan_link);
169                SI_LVCT_Free_Channel(channel);
170                Total_LVCT_Channels--;
171        }
172
173        Total_LVCT_Channels = 0;  /* just to be sure. */
174        SI_mutex_unlock(m_lvct);
175       
176        return SI_SUCCESS;
177}
178
179
180/*********************************************************************
181 Function : SI_LVCT_Ins_Channel                                                                 
182 Description : Function to insert an LVCT channel into the LVCT
183                                channel list. The order is that two part numbers
184                                are after the one part numbers and within each part
185                                the channels are sorted in incrementing order.
186 Input : SI_LVCT_CHANNEL *new_channel.  pointer to new LVCT channel
187                        structure to be inserted.
188 Output : SI_RET_CODE.                                                 
189**********************************************************************/
190static SI_RET_CODE SI_LVCT_Ins_Channel(SI_LVCT_CHANNEL *new_channel)
191{
192        SI_LVCT_CHANNEL * channel;
193        unsigned char comp;
194        int     i;
195
196        SI_mutex_lock(m_lvct);
197
198        channel = SI_LST_D_FIRST(&LVCT_channels);
199        /* if the list is empty, just put the new channel in. */
200        if (channel == NULL)
201        {
202                SI_LST_D_INSERT_HEAD(&LVCT_channels, new_channel, chan_link);
203                Total_LVCT_Channels++;
204                SI_mutex_unlock(m_lvct);
205                return SI_SUCCESS;
206        }
207
208        /* search for the the place to insert. */
209        while ((comp = SI_LVCT_Compare_channel(new_channel, channel)) == 2 && SI_LST_D_NEXT(channel, chan_link))
210                channel = SI_LST_D_NEXT(channel, chan_link);
211
212        if (comp == 2)
213        {
214                /* we got to the end of list. insert after current element. */
215                SI_LST_D_INSERT_AFTER(channel, new_channel, chan_link);
216                Total_LVCT_Channels++;
217        }
218        else if (comp == 0)
219        {
220                /* insert before the current element. */
221                SI_LST_D_INSERT_BEFORE(&LVCT_channels, channel, new_channel, chan_link);
222                Total_LVCT_Channels++;
223        }
224        else
225        {
226                /* equal! It should not happen. But if it does, simply keep it and free the new one. */
227                SI_DBG_PRINT(E_SI_WRN_MSG,("LVCT the channel already exists! keeping it and free newbie!\n"));
228                SI_LVCT_Free_Channel(new_channel);
229        }
230       
231        SI_mutex_unlock(m_lvct);
232
233        return SI_SUCCESS;     
234}
235
236
237/*********************************************************************
238 Function : SI_LVCT_Parse       
239 Description : Function to parse a newly received LVCT table section and
240                                put it into the LVCT channel link list
241 Input : unsigned char *lvct_table : newly received LVCT table data.                                             
242 Output : SI_RET_CODE.                                                                                   
243**********************************************************************/
244SI_RET_CODE SI_LVCT_Parse (unsigned char *lvct_table)
245{
246        unsigned long temp, i, j, offset;
247        unsigned long section_length, version_number;
248        unsigned long section_number, last_section_number, num_channels_in_section;
249        unsigned long desc_start;
250        unsigned long desc_tag, desc_len, len;
251        unsigned short major_num, minor_num;
252        unsigned char *current;
253        SI_LVCT_CHANNEL * channel;
254        SI_RET_CODE result;
255
256        SI_DBG_PRINT(E_SI_DBG_MSG,("LVCT Table received.\n"));
257
258        temp = *lvct_table;
259        if (temp != SI_LVCT_TABLE_ID)
260        {
261                SI_DBG_PRINT(E_SI_ERR_MSG,("LVCT Table ID error!!! %x\n", temp));
262                return SI_TABLE_ID_ERROR;
263        }
264
265        /* calculate and check section length. */
266        section_length = SI_Construct_Data(lvct_table, 
267                                LVCT_SECTION_LENGTH_BYTE_INDX,
268                                LVCT_SECTION_LENGTH_BYTE_NUM,
269                                LVCT_SECTION_LENGTH_SHIFT,
270                                LVCT_SECTION_LENGTH_MASK);
271        section_length += LVCT_SECTION_LENGTH_BYTE_INDX+LVCT_SECTION_LENGTH_BYTE_NUM;
272        if (section_length > SI_LONG_SECTION_LENGTH)
273        {
274                SI_DBG_PRINT(E_SI_ERR_MSG,("LVCT Table section length error!!! %x\n", section_length));
275                return SI_SECTION_LENGTH_ERROR;
276        }
277       
278        /* We do the CRC check here to verify the contents of this section. */
279        if (SI_CRC32_Check(lvct_table, section_length) != SI_SUCCESS)
280        {
281                SI_DBG_PRINT(E_SI_ERR_MSG,("LVCT Table section CRC error!!!\n"));
282                return SI_CRC_ERROR;
283        }
284
285        /* look at current_next_indicator. It should be 1 for AEIT. */
286        temp = SI_Construct_Data(lvct_table, 
287                                LVCT_CURRENT_NEXT_INDICATOR_BYTE_INDX,
288                                LVCT_CURRENT_NEXT_INDICATOR_BYTE_NUM,
289                                LVCT_CURRENT_NEXT_INDICATOR_SHIFT,
290                                LVCT_CURRENT_NEXT_INDICATOR_MASK);
291        if (temp != 1)
292        {
293                SI_DBG_PRINT(E_SI_DBG_MSG,("LVCT Table current_next_indicator not one. discarding it.%x\n", temp));
294                return SI_SUCCESS;
295        }
296
297        /* check to make sure protocol version is zero. */
298        temp = SI_Construct_Data(lvct_table, 
299                                LVCT_PROTOCOL_VERSION_BYTE_INDX,
300                                LVCT_PROTOCOL_VERSION_BYTE_NUM,
301                                LVCT_PROTOCOL_VERSION_SHIFT,
302                                LVCT_PROTOCOL_VERSION_MASK);
303        if (temp != SI_CURRENT_PROTOCOL_VERSION)
304        {
305                SI_DBG_PRINT(E_SI_ERR_MSG,("LVCT Table PROTOCOL version error!!! %x\n", temp));
306                return SI_PROTOCOL_VER_ERROR;
307        }
308       
309        /* now we know where the slot is in the link list, See if we need to update. */
310        version_number = SI_Construct_Data(lvct_table, 
311                                                LVCT_VERSION_NUMBER_BYTE_INDX,
312                                                LVCT_VERSION_NUMBER_BYTE_NUM,
313                                                LVCT_VERSION_NUMBER_SHIFT,
314                                                LVCT_VERSION_NUMBER_MASK);
315        section_number = SI_Construct_Data(lvct_table, 
316                                                LVCT_SECTION_NUMBER_BYTE_INDX,
317                                                LVCT_SECTION_NUMBER_BYTE_NUM,
318                                                LVCT_SECTION_NUMBER_SHIFT,
319                                                LVCT_SECTION_NUMBER_MASK);
320
321        if (LVCT_version_number == version_number)
322        {
323                /* the same version number. Now check if the section number has already be processed. */
324                if (SI_Chk_Section_mask(LVCT_section_mask, section_number))
325                {
326                        /* section already processed, we are done! */
327                        SI_DBG_PRINT(E_SI_DBG_MSG,("LVCT Table section does not need to be updated!\n"));
328                        return SI_SUCCESS;
329                }
330                else
331                        SI_DBG_PRINT(E_SI_DBG_MSG,("New LVCT Table section received!\n"));
332        }
333        else
334        {
335                /* different version number. free the old channel link list. */
336                SI_DBG_PRINT(E_SI_DBG_MSG,("New LVCT Table version received!\n"));
337                /* init section mask. */
338                last_section_number = SI_Construct_Data(lvct_table, 
339                                                        LVCT_LAST_SECTION_NUMBER_BYTE_INDX,
340                                                        LVCT_LAST_SECTION_NUMBER_BYTE_NUM,
341                                                        LVCT_LAST_SECTION_NUMBER_SHIFT,
342                                                        LVCT_LAST_SECTION_NUMBER_MASK);
343                SI_Init_Section_Mask(LVCT_section_mask, last_section_number);
344                LVCT_version_number = version_number;
345                /* free the old list. */
346                SI_LVCT_Free_List();
347        }
348
349        /* update section mask here. */
350        SI_Set_Section_mask(LVCT_section_mask, section_number);
351       
352        num_channels_in_section = SI_Construct_Data(lvct_table, 
353                                                        LVCT_NUM_CHANNELS_BYTE_INDX,
354                                                        LVCT_NUM_CHANNELS_BYTE_NUM,
355                                                        LVCT_NUM_CHANNELS_SHIFT,
356                                                        LVCT_NUM_CHANNELS_MASK);
357
358        /* get channels one by one. */
359        current = lvct_table+LVCT_NUM_CHANNELS_BYTE_INDX+LVCT_NUM_CHANNELS_BYTE_NUM;
360        for (i=0; i<num_channels_in_section; i++)
361        {
362                /* create the channel link. */
363                if ((channel = SI_LVCT_Create_Channel()) == NULL)
364                        return SI_NO_MEMORY;
365
366                /* get the short name. */
367                for (j=0; j<LVCT_SHORT_NAME_LENGTH; j++)
368                {
369                        channel->short_name[j] = ((((unsigned short)(*(current++)))<<8)&0xff00);
370                        channel->short_name[j] |= (((unsigned short)(*(current++)))&0x00ff);
371                }
372
373                /* get channel number(s). */
374                major_num = SI_Construct_Data(current, 
375                                        LVCT_MAJOR_NUMBER_BYTE_INDX,
376                                        LVCT_MAJOR_NUMBER_BYTE_NUM,
377                                        LVCT_MAJOR_NUMBER_SHIFT,
378                                        LVCT_MAJOR_NUMBER_MASK);
379                minor_num = SI_Construct_Data(current, 
380                                        LVCT_MINOR_NUMBER_BYTE_INDX,
381                                        LVCT_MINOR_NUMBER_BYTE_NUM,
382                                        LVCT_MINOR_NUMBER_SHIFT,
383                                        LVCT_MINOR_NUMBER_MASK);
384                if ((major_num&0x03f0) == 0x03f0)
385                {
386                        channel->vcn_mode = ONE_PART;
387                        channel->channum1 = ((major_num&0x0f)<<10) + minor_num;
388                        SI_DBG_PRINT(E_SI_DBG_MSG,("Channel %x: ", channel->channum1));
389                }
390                else
391                {
392                        channel->vcn_mode = TWO_PART;
393                        channel->channum1 = major_num;
394                        channel->channum2 = minor_num;
395                        SI_DBG_PRINT(E_SI_DBG_MSG,("Channel %x-%x: ", channel->channum1, channel->channum2));
396                }
397
398                for (j=0; j<LVCT_SHORT_NAME_LENGTH; j++)
399                        SI_DBG_PRINT(E_SI_DBG_MSG,("%c", (channel->short_name[j]&0xff)));
400       
401                /* get other parameters. */
402                channel->mod_mode = SI_Construct_Data(current, 
403                                                        LVCT_MODULATION_MODE_BYTE_INDX,
404                                                        LVCT_MODULATION_MODE_BYTE_NUM,
405                                                        LVCT_MODULATION_MODE_SHIFT,
406                                                        LVCT_MODULATION_MODE_MASK);
407                channel->carrier_freq = SI_Construct_Data(current, 
408                                                        LVCT_CARRIER_FREQUENCY_BYTE_INDX,
409                                                        LVCT_CARRIER_FREQUENCY_BYTE_NUM,
410                                                        LVCT_CARRIER_FREQUENCY_SHIFT,
411                                                        LVCT_CARRIER_FREQUENCY_MASK);
412                channel->tsid = SI_Construct_Data(current, 
413                                                        LVCT_CHANNEL_TSID_BYTE_INDX,
414                                                        LVCT_CHANNEL_TSID_BYTE_NUM,
415                                                        LVCT_CHANNEL_TSID_SHIFT,
416                                                        LVCT_CHANNEL_TSID_MASK);
417                channel->program_num = SI_Construct_Data(current, 
418                                                        LVCT_PROGRAM_NUMBER_BYTE_INDX,
419                                                        LVCT_PROGRAM_NUMBER_BYTE_NUM,
420                                                        LVCT_PROGRAM_NUMBER_SHIFT,
421                                                        LVCT_PROGRAM_NUMBER_MASK);
422                channel->chanbits = SI_Construct_Data(current, 
423                                                        LVCT_CHANNEL_BITS_BYTE_INDX,
424                                                        LVCT_CHANNEL_BITS_BYTE_NUM,
425                                                        LVCT_CHANNEL_BITS_SHIFT,
426                                                        LVCT_CHANNEL_BITS_MASK);
427                channel->serv_type = SI_Construct_Data(current, 
428                                                        LVCT_SERVICE_TYPE_BYTE_INDX,
429                                                        LVCT_SERVICE_TYPE_BYTE_NUM,
430                                                        LVCT_SERVICE_TYPE_SHIFT,
431                                                        LVCT_SERVICE_TYPE_MASK);
432                channel->source_ID = SI_Construct_Data(current, 
433                                                        LVCT_SOURCE_ID_BYTE_INDX,
434                                                        LVCT_SOURCE_ID_BYTE_NUM,
435                                                        LVCT_SOURCE_ID_SHIFT,
436                                                        LVCT_SOURCE_ID_MASK);
437
438                SI_DBG_PRINT(E_SI_DBG_MSG,("mod %x, carrire %x hz, tsid %x, prog %x, serv type %x, src id %x ", channel->mod_mode,channel->carrier_freq,channel->tsid,channel->program_num,channel->serv_type,channel->source_ID));
439                SI_DBG_PRINT(E_SI_DBG_MSG,("\n"));
440
441                /* get descriptor length. */
442                desc_len = SI_Construct_Data(current, 
443                                        LVCT_DESC_LENGTH_BYTE_INDX,
444                                        LVCT_DESC_LENGTH_BYTE_NUM,
445                                        LVCT_DESC_LENGTH_SHIFT,
446                                        LVCT_DESC_LENGTH_MASK);
447
448                /* go through all descriptors. */
449                current += LVCT_DESC_LENGTH_BYTE_INDX+LVCT_DESC_LENGTH_BYTE_NUM;
450                offset = 0;
451                while (offset < desc_len)
452                {
453                        desc_tag = *(current++); /* points to desc len. */
454                        len = *(current++); /* point to first desc data. */
455                        switch(desc_tag)
456                        {
457                                case SI_DESC_EXTENDED_CHANNEL_NAME:
458                                        SI_DBG_PRINT(E_SI_DBG_MSG,("LVCT Table: ext channel name descriptor received.\n"));
459                                        channel->ext_name_len = len;
460                                        if ((channel->ext_name = SI_alloc(channel->ext_name_len)) == NULL)
461                                        {
462                                                SI_DBG_PRINT(E_SI_ERR_MSG,("LVCT Table failed to alloc mem for channel ext name!!!\n"));
463                                                SI_LVCT_Free_Channel(channel);
464                                                return SI_NO_MEMORY;
465                                        }
466                                        SI_memcpy(channel->ext_name, current, len);
467                                        current += len;  /* point to next desc. */
468                                        offset += len;
469                                break;
470                                case SI_DESC_TIME_SHIFTED_SERVICE:
471                                        SI_DBG_PRINT(E_SI_DBG_MSG,("LVCT Table: Time shifted descriptor received.\n"));
472                                        channel->num_of_ts_serv = SI_Construct_Data(current, 
473                                                                                        DESC_TSS_NUM_OF_SERV_BYTE_INDEX,
474                                                                                        DESC_TSS_NUM_OF_SERV_BYTE_NUM,
475                                                                                        DESC_TSS_NUM_OF_SERV_SHIFT,
476                                                                                        DESC_TSS_NUM_OF_SERV_MASK);
477                                        current += DESC_TSS_NUM_OF_SERV_BYTE_INDEX+DESC_TSS_NUM_OF_SERV_BYTE_NUM;
478                                        offset += DESC_TSS_NUM_OF_SERV_BYTE_INDEX+DESC_TSS_NUM_OF_SERV_BYTE_NUM;
479                                        if ( (channel->time_shifted = SI_alloc(channel->num_of_ts_serv*sizeof(TIME_SHIFT_SERV))) == NULL)
480                                        {
481                                                SI_DBG_PRINT(E_SI_ERR_MSG,("LVCT Table failed to alloc mem for time shift serv!!!\n"));
482                                                SI_LVCT_Free_Channel(channel);
483                                                return SI_NO_MEMORY;
484                                        }
485                                        for (j=0; j<channel->num_of_ts_serv; j++)
486                                        {
487                                                channel->time_shifted[j].time_shift = SI_Construct_Data(current, 
488                                                                                                                        DESC_TSS_TIME_SHIFT_BYTE_INDEX,
489                                                                                                                        DESC_TSS_TIME_SHIFT_BYTE_NUM,
490                                                                                                                        DESC_TSS_TIME_SHIFT_SHIFT,
491                                                                                                                        DESC_TSS_TIME_SHIFT_MASK);
492                                                major_num = SI_Construct_Data(current, 
493                                                                        DESC_TSS_MAJOR_NUM_BYTE_INDEX,
494                                                                        DESC_TSS_MAJOR_NUM_BYTE_NUM,
495                                                                        DESC_TSS_MAJOR_NUM_SHIFT,
496                                                                        DESC_TSS_MAJOR_NUM_MASK);
497                                                minor_num = SI_Construct_Data(current, 
498                                                                        DESC_TSS_MINOR_NUM_BYTE_INDEX,
499                                                                        DESC_TSS_MINOR_NUM_BYTE_NUM,
500                                                                        DESC_TSS_MINOR_NUM_SHIFT,
501                                                                        DESC_TSS_MINOR_NUM_MASK);
502                                                if ((major_num&0x03f0) == 0x03f0)
503                                                {
504                                                        channel->time_shifted[j].vcn_mode = ONE_PART;
505                                                        channel->time_shifted[j].channum1 = ((major_num&0x0f)<<10) + minor_num;
506                                                }
507                                                else
508                                                {
509                                                        channel->time_shifted[j].vcn_mode = TWO_PART;
510                                                        channel->time_shifted[j].channum1 = major_num;
511                                                        channel->time_shifted[j].channum2 = minor_num;
512                                                }
513                                                current += DESC_TSS_MINOR_NUM_BYTE_INDEX+DESC_TSS_MINOR_NUM_BYTE_NUM;
514                                                offset += DESC_TSS_MINOR_NUM_BYTE_INDEX+DESC_TSS_MINOR_NUM_BYTE_NUM;
515                                        }
516                                break;
517                                default:
518                                        if(desc_tag != SI_DESC_STUFFING)
519                                                SI_DBG_PRINT(E_SI_WRN_MSG,("LVCT channel descriptor %x received!\n", desc_tag));
520                                        current += len;  /* point to next desc. */
521                                        offset += len;
522                                break;
523                        }
524                }
525
526                /* make sure descriptor len works out. */
527                if (offset != desc_len)
528                {
529                        SI_DBG_PRINT(E_SI_ERR_MSG,("LVCT Table channel descriptor error!!!\n"));
530                        SI_LVCT_Free_Channel(channel);
531                        return SI_DESCRIPTOR_ERROR;
532                }
533
534                /* insert the channel in the list. */
535                SI_LVCT_Ins_Channel(channel);
536        }
537
538        /* TBD just skip the table descriptors and check for length. */
539        desc_len = SI_Construct_Data(current, 
540                                LVCT_ADD_DESC_LENGTH_BYTE_INDX,
541                                LVCT_ADD_DESC_LENGTH_BYTE_NUM,
542                                LVCT_ADD_DESC_LENGTH_SHIFT,
543                                LVCT_ADD_DESC_LENGTH_MASK);
544        current += LVCT_ADD_DESC_LENGTH_BYTE_INDX+LVCT_ADD_DESC_LENGTH_BYTE_NUM;
545        offset = 0;
546        while (offset < desc_len)
547        {
548                if ((desc_tag = *(current++)) != SI_DESC_STUFFING)
549                        SI_DBG_PRINT(E_SI_WRN_MSG,("LVCT table descriptor %x received! Ignoring!\n", desc_tag));
550
551                len = *(current++);
552                current += len;
553                offset += len+2;
554        }
555
556        if (offset != desc_len)
557        {
558                SI_DBG_PRINT(E_SI_ERR_MSG,("LVCT Table section descriptor length error!!!\n"));
559                return SI_DESCRIPTOR_ERROR;
560        }
561
562        if ((unsigned long)(current-lvct_table) != section_length-SI_CRC_LENGTH)
563        {
564                SI_DBG_PRINT(E_SI_ERR_MSG,("LVCT Table length error!!!\n"));
565                return SI_SECTION_LENGTH_ERROR;
566        }
567       
568        return SI_SUCCESS;
569}
Note: See TracBrowser for help on using the repository browser.