source: svn/newcon3bcm2_21bu/BSEAV/lib/scte65/rrt/si_rrt.c @ 44

Last change on this file since 44 was 44, checked in by megakiss, 11 years ago

광주방송 OTC 주파수 369Mhz로 변경

  • Property svn:executable set to *
File size: 15.8 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_rrt.c
12** Description: function that parses the RRT
13**              table section.
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_rrt.h"
30#include "si_descriptors.h"
31
32
33/* local function prototypes. */
34static SI_RRT_REGION * SI_RRT_Create_Region (unsigned char region);
35static SI_RET_CODE  SI_RRT_Clear_Region (SI_RRT_REGION * rrt_region);
36static SI_RRT_REGION * SI_RRT_Find_Region (unsigned char region);
37
38
39struct rrt_region_list RRT_Regions;
40unsigned char Total_RRT_Regions;
41
42SI_mutex m_rrt;
43
44
45void SI_RRT_Init(void)
46{
47        SI_LST_D_INIT(&RRT_Regions);
48        Total_RRT_Regions = 0;
49        SI_mutex_init(m_rrt);
50
51}
52
53/*********************************************************************
54 Function : SI_RRT_Create_Region                                                                         
55 Description : Function to allocate the space for an instance of
56                                 RRT.                                                           
57 Input : unsigned char region : the rating region number.       
58 Output : pointer to the RRT instance structure allocated. Will
59                        return NULL if out of memory.                                                   
60**********************************************************************/
61static SI_RRT_REGION * SI_RRT_Create_Region (unsigned char region)
62{
63        SI_RRT_REGION * rrt_region;
64        int     i;
65       
66        rrt_region = (SI_RRT_REGION *)SI_alloc(sizeof(SI_RRT_REGION));
67        if (rrt_region == NULL)
68        {
69                SI_DBG_PRINT(E_SI_ERR_MSG,("Failed to allocate an RRT instance!!!\n"));
70                return NULL;
71        }
72
73        SI_LST_D_INIT_ENTRY(&(rrt_region->rrt_link));
74        rrt_region->rating_region = region;
75        rrt_region->rating_region_name_text = NULL;
76        rrt_region->rrt_dimensions = NULL;
77        rrt_region->dimensions_defined = 0;
78        rrt_region->rating_region_name_length = 0;
79       
80        rrt_region->version_number = 0xff;
81       
82        SI_LST_D_INSERT_HEAD(&RRT_Regions, rrt_region, rrt_link);
83
84        Total_RRT_Regions++;
85               
86        return rrt_region;
87}
88
89
90/*********************************************************************
91 Function : SI_RRT_Clear_Region                                                                 
92 Description : Function to clear an instance of  RRT.                                                           
93 Input : SI_RRT_REGION * rrt_region, points to the RRT instance
94                                structure to be cleared.                                                                                                 
95 Output : SI_RET_CODE                                                   
96**********************************************************************/
97static SI_RET_CODE  SI_RRT_Clear_Region (SI_RRT_REGION * rrt_region)
98{
99        int i,j;
100
101        if (rrt_region)
102        {
103                for (i=0; i<rrt_region->dimensions_defined; i++)
104                {
105                        for (j=0; j<rrt_region->rrt_dimensions->values_defined; j++)
106                        {
107                                SI_free(rrt_region->rrt_dimensions->rrt_values->abbrev_rating_value_text);
108                                SI_free(rrt_region->rrt_dimensions->rrt_values->rating_value_text);
109                        }
110                        SI_free(rrt_region->rrt_dimensions->rrt_values);
111                        SI_free(rrt_region->rrt_dimensions->dimension_name_text);
112                }
113                if (rrt_region->rrt_dimensions)
114                        SI_free(rrt_region->rrt_dimensions);
115                if (rrt_region->rating_region_name_text)
116                        SI_free(rrt_region->rating_region_name_text);
117        }
118       
119        return SI_SUCCESS;
120}
121
122
123/*********************************************************************
124 Function : SI_RRT_Find_Region                                                                   
125 Description : Function find instance of RRT of which the rating
126                                region matches the specified one.                                                               
127 Input : unsigned char region, rating region to match.                                                                                           
128 Output : SI_RRT_REGION * points to the RRT instance structure that matches
129                        the rating regoin code. NULL if no match can be found.
130**********************************************************************/
131static SI_RRT_REGION * SI_RRT_Find_Region (unsigned char region)
132{
133        SI_RRT_REGION * rrt_region;
134
135        rrt_region = SI_LST_D_FIRST(&RRT_Regions);
136        while (rrt_region)
137        {
138                if (rrt_region->rating_region == region)
139                        return rrt_region;
140                rrt_region = SI_LST_D_NEXT(rrt_region, rrt_link);
141        }
142
143        return NULL;
144}
145
146
147/**********************************************************************
148 Function : SI_RRT_parse                                                                                         
149 Description : Function to parse the RRT table. It will create and
150                                 keep track of RRT instances.                   
151 Input : rrt_table, point to the rrt table data.         
152 Output : Success code.                                                                 
153***********************************************************************/
154SI_RET_CODE SI_RRT_parse (unsigned char * rrt_table)
155{
156        unsigned long temp, i, j, k;
157        unsigned long section_length;
158        unsigned long CRC_start;
159        unsigned long tot_desc_len, offset;
160        unsigned long desc_tag, desc_len;
161        unsigned char region;
162        unsigned char *current;
163        SI_RRT_REGION *rrt_region;
164        SI_RET_CODE result;
165
166        SI_DBG_PRINT(E_SI_DBG_MSG,("RRT Table received.\n"));
167
168        temp = *rrt_table;
169        if (temp != SI_RRT_TABLE_ID)
170        {
171                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT Table ID error!!! %x\n", temp));
172                return SI_TABLE_ID_ERROR;
173        }
174
175        /* calculate and check section length. */
176        section_length = SI_Construct_Data(rrt_table, 
177                                RRT_SECTION_LENGTH_BYTE_INDX,
178                                RRT_SECTION_LENGTH_BYTE_NUM,
179                                RRT_SECTION_LENGTH_SHIFT,
180                                RRT_SECTION_LENGTH_MASK);
181        SI_DBG_PRINT(E_SI_DBG_MSG,("section len %x\n", section_length));       
182        section_length += RRT_SECTION_LENGTH_BYTE_INDX+RRT_SECTION_LENGTH_BYTE_NUM;
183        if (section_length > SI_NORMAL_SECTION_LENGTH)
184        {
185                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT Table section length error!!! %x\n", section_length));
186                return SI_SECTION_LENGTH_ERROR;
187        }
188       
189        /* We do the CRC check here to verify the contents of this section. */
190        if (SI_CRC32_Check(rrt_table, section_length) != SI_SUCCESS)
191        {
192                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT Table section CRC error!!!\n"));
193                //QY NEED TO FIX   return SI_CRC_ERROR;
194        }
195
196        /* check to make sure protocol version is zero. */
197        temp = SI_Construct_Data(rrt_table, 
198                                RRT_PROTOCOL_VERSION_BYTE_INDX,
199                                RRT_PROTOCOL_VERSION_BYTE_NUM,
200                                RRT_PROTOCOL_VERSION_SHIFT,
201                                RRT_PROTOCOL_VERSION_MASK);
202        if (temp != SI_CURRENT_PROTOCOL_VERSION)
203        {
204                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT Table PROTOCOL version error!!! %x\n", temp));
205                return SI_PROTOCOL_VER_ERROR;
206        }
207       
208        /* make sure that section_number and last_section_number are both 0. */
209        temp = SI_Construct_Data(rrt_table, 
210                                RRT_SECTION_NUMBER_BYTE_INDX,
211                                RRT_SECTION_NUMBER_BYTE_NUM,
212                                RRT_SECTION_NUMBER_SHIFT,
213                                RRT_SECTION_NUMBER_MASK);
214        if (temp != 0)
215        {
216                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT Table section_number not zero!!! %x\n", temp));
217                return SI_SECTION_NUMBER_ERROR;
218        }
219        temp = SI_Construct_Data(rrt_table, 
220                                RRT_LAST_SECTION_NUMBER_BYTE_INDX,
221                                RRT_LAST_SECTION_NUMBER_BYTE_NUM,
222                                RRT_LAST_SECTION_NUMBER_SHIFT,
223                                RRT_LAST_SECTION_NUMBER_MASK);
224        if (temp != 0)
225        {
226                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT Table last_section_number not zero!!! %x\n", temp));
227                return SI_SECTION_NUMBER_ERROR;
228        }
229
230        /* look at current_next_indicator. It should be 1 for RRT. */
231        temp = SI_Construct_Data(rrt_table, 
232                                RRT_CURRENT_NEXT_INDICATOR_BYTE_INDX,
233                                RRT_CURRENT_NEXT_INDICATOR_BYTE_NUM,
234                                RRT_CURRENT_NEXT_INDICATOR_SHIFT,
235                                RRT_CURRENT_NEXT_INDICATOR_MASK);
236        if (temp != 1)
237        {
238                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT Table current_next_indicator not one!!! %x\n", temp));
239                return SI_CURRENT_NEXT_INDICATOR_ERROR;
240        }
241
242        /* check to see if we already have the region. */
243        region = SI_Construct_Data(rrt_table, 
244                                RRT_RATING_REGION_BYTE_INDX,
245                                RRT_RATING_REGION_BYTE_NUM,
246                                RRT_RATING_REGION_SHIFT,
247                                RRT_RATING_REGION_MASK);
248
249        /* locking mutex for data access. */
250        SI_mutex_lock(m_rrt);
251       
252        if ((rrt_region = SI_RRT_Find_Region(region)) == NULL)
253        {
254                /* we do not have this rating region defined yet. */
255                if ((rrt_region = SI_RRT_Create_Region(region)) == NULL)
256                {
257                        SI_mutex_unlock(m_rrt);
258                        return SI_NO_MEMORY;
259                }
260        }
261       
262        SI_DBG_PRINT(E_SI_DBG_MSG,("RRT region %x.\n", region));
263
264        /* Now check the version number and decide whether we want to update or not */
265        temp = SI_Construct_Data(rrt_table, 
266                                RRT_VERSION_NUMBER_BYTE_INDX,
267                                RRT_VERSION_NUMBER_BYTE_NUM,
268                                RRT_VERSION_NUMBER_SHIFT,
269                                RRT_VERSION_NUMBER_MASK);
270        if (rrt_region->version_number == temp)
271        {
272                SI_mutex_unlock(m_rrt);
273                return SI_SUCCESS; /* do not need to do anything when it is the same version */
274        }
275        rrt_region->version_number = temp;
276
277        /* new RRT table received!!! */
278        SI_DBG_PRINT(E_SI_DBG_MSG,("New RRT Table received! Deleting the old one.\n"));
279       
280        SI_RRT_Clear_Region (rrt_region);
281
282        /* get rating region name. */
283        rrt_region->rating_region_name_length = SI_Construct_Data(rrt_table, 
284                                                                                RRT_REGION_NAME_LENGTH_BYTE_INDX,
285                                                                                RRT_REGION_NAME_LENGTH_BYTE_NUM,
286                                                                                RRT_REGION_NAME_LENGTH_SHIFT,
287                                                                                RRT_REGION_NAME_LENGTH_MASK);
288        rrt_region->rating_region_name_text = (char *)SI_alloc(rrt_region->rating_region_name_length);
289        if (rrt_region->rating_region_name_text == NULL)
290        {
291                SI_mutex_unlock(m_rrt);
292                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT failed to alloc rating region name text!!!\n"));
293                return SI_NO_MEMORY;
294        }
295        current = rrt_table + RRT_REGION_NAME_LENGTH_BYTE_INDX+RRT_REGION_NAME_LENGTH_BYTE_NUM;
296        SI_memcpy(rrt_region->rating_region_name_text, current, rrt_region->rating_region_name_length);
297        current += rrt_region->rating_region_name_length;
298
299        /* debug print for region name!!! */
300        SI_DBG_PRINT(E_SI_DBG_MSG,("RRT region name:\n"));
301        for (k=0; k<rrt_region->rating_region_name_length; k++)
302                if (k>7)
303                        SI_DBG_PRINT(E_SI_DBG_MSG,("%c", (char)rrt_region->rating_region_name_text[k]));
304        SI_DBG_PRINT(E_SI_DBG_MSG,("\n"));
305
306        /* get the dimension number. */
307        rrt_region->dimensions_defined = SI_Construct_Data(current, 
308                                                                                RRT_DIMENSIONS_DEFINED_BYTE_INDX,
309                                                                                RRT_DIMENSIONS_DEFINED_BYTE_NUM,
310                                                                                RRT_DIMENSIONS_DEFINED_SHIFT,
311                                                                                RRT_DIMENSIONS_DEFINED_MASK);
312        current += RRT_DIMENSIONS_DEFINED_BYTE_NUM;
313        /* create dimensions. */
314        rrt_region->rrt_dimensions = (SI_RRT_DIMENSION *)SI_alloc(rrt_region->dimensions_defined*sizeof(SI_RRT_DIMENSION));
315        if (rrt_region->rrt_dimensions == NULL)
316        {
317                SI_mutex_unlock(m_rrt);
318                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT failed to alloc rating region dimensions text!!!\n"));
319                return SI_NO_MEMORY;
320        }
321
322        /* go through all dimensions. */
323        for (i=0; i<rrt_region->dimensions_defined; i++)
324        {
325                rrt_region->rrt_dimensions[i].dimension_name_length = SI_Construct_Data(current, 
326                                                                                                                        RRT_DIMENSION_NAME_LENGTH_BYTE_INDX,
327                                                                                                                        RRT_DIMENSION_NAME_LENGTH_BYTE_NUM,
328                                                                                                                        RRT_DIMENSION_NAME_LENGTH_SHIFT,
329                                                                                                                        RRT_DIMENSION_NAME_LENGTH_MASK);
330                current += RRT_DIMENSION_NAME_LENGTH_BYTE_INDX+RRT_DIMENSION_NAME_LENGTH_BYTE_NUM;
331                rrt_region->rrt_dimensions[i].dimension_name_text = (char *)SI_alloc(rrt_region->rrt_dimensions[i].dimension_name_length);
332                if (rrt_region->rrt_dimensions[i].dimension_name_text == NULL)
333                {
334                        SI_mutex_unlock(m_rrt);
335                        SI_DBG_PRINT(E_SI_ERR_MSG,("RRT failed to alloc rating dimemsion name text!!!\n"));
336                        return SI_NO_MEMORY;
337                }
338                SI_memcpy(rrt_region->rrt_dimensions[i].dimension_name_text, current, rrt_region->rrt_dimensions[i].dimension_name_length);
339                current += rrt_region->rrt_dimensions[i].dimension_name_length;
340                rrt_region->rrt_dimensions[i].graduated_scale = SI_Construct_Data(current, 
341                                                                                                                RRT_GRADUATED_SCALE_BYTE_INDX,
342                                                                                                                RRT_GRADUATED_SCALE_BYTE_NUM,
343                                                                                                                RRT_GRADUATED_SCALE_SHIFT,
344                                                                                                                RRT_GRADUATED_SCALE_MASK);
345                rrt_region->rrt_dimensions[i].values_defined = SI_Construct_Data(current, 
346                                                                                                                RRT_VALUES_DEFINED_BYTE_INDX,
347                                                                                                                RRT_VALUES_DEFINED_BYTE_NUM,
348                                                                                                                RRT_VALUES_DEFINED_SHIFT,
349                                                                                                                RRT_VALUES_DEFINED_MASK);
350                current += RRT_VALUES_DEFINED_BYTE_INDX+RRT_VALUES_DEFINED_BYTE_NUM;
351
352                /* debug print for dimension name!!! */
353                SI_DBG_PRINT(E_SI_DBG_MSG,("RRT dimension name: "));
354                for (k=0; k<rrt_region->rrt_dimensions[i].dimension_name_length; k++)
355                        if (k>7)
356                                SI_DBG_PRINT(E_SI_DBG_MSG,("%c", (char)rrt_region->rrt_dimensions[i].dimension_name_text[k]));
357                SI_DBG_PRINT(E_SI_DBG_MSG,("\n"));
358
359                /* create the values structure. */
360                rrt_region->rrt_dimensions[i].rrt_values = (SI_RRT_VALUE *)SI_alloc(rrt_region->rrt_dimensions[i].values_defined*sizeof(SI_RRT_VALUE));
361                if (rrt_region->rrt_dimensions[i].rrt_values == NULL)
362                {
363                        SI_mutex_unlock(m_rrt);
364                        SI_DBG_PRINT(E_SI_ERR_MSG,("RRT failed to alloc rating region value structure!!!\n"));
365                        return SI_NO_MEMORY;
366                }
367
368                /* go through all values. */
369                for (j=0; j<rrt_region->rrt_dimensions[i].values_defined; j++)
370                {
371                        /* abbrev rating value text. */
372                        rrt_region->rrt_dimensions[i].rrt_values[j].abbrev_rating_value_length = 
373                                                SI_Construct_Data(current, 
374                                                                                        RRT_ABBREV_VALUE_LENGTH_BYTE_INDX,
375                                                                                        RRT_ABBREV_VALUE_LENGTH_BYTE_NUM,
376                                                                                        RRT_ABBREV_VALUE_LENGTH_SHIFT,
377                                                                                        RRT_ABBREV_VALUE_LENGTH_MASK);
378                        current += RRT_ABBREV_VALUE_LENGTH_BYTE_INDX+RRT_ABBREV_VALUE_LENGTH_BYTE_NUM;
379                        rrt_region->rrt_dimensions[i].rrt_values[j].abbrev_rating_value_text = (char *)SI_alloc(rrt_region->rrt_dimensions[i].rrt_values[j].abbrev_rating_value_length);
380                        if (rrt_region->rrt_dimensions[i].rrt_values[j].abbrev_rating_value_text == NULL)
381                        {
382                                SI_mutex_unlock(m_rrt);
383                                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT failed to alloc abbrev rating value text!!!\n"));
384                                return SI_NO_MEMORY;
385                        }
386                        SI_memcpy(rrt_region->rrt_dimensions[i].rrt_values[j].abbrev_rating_value_text, current, 
387                                rrt_region->rrt_dimensions[i].rrt_values[j].abbrev_rating_value_length );
388                        current += rrt_region->rrt_dimensions[i].rrt_values[j].abbrev_rating_value_length;
389
390                        /* full rating value text. */
391                        rrt_region->rrt_dimensions[i].rrt_values[j].rating_value_length = 
392                                                SI_Construct_Data(current, 
393                                                                                        RRT_VALUE_LENGTH_BYTE_INDX,
394                                                                                        RRT_VALUE_LENGTH_BYTE_NUM,
395                                                                                        RRT_VALUE_LENGTH_SHIFT,
396                                                                                        RRT_VALUE_LENGTH_MASK);
397                        current += RRT_VALUE_LENGTH_BYTE_NUM;
398                        rrt_region->rrt_dimensions[i].rrt_values[j].rating_value_text = (char *)SI_alloc(rrt_region->rrt_dimensions[i].rrt_values[j].rating_value_length);
399                        if (rrt_region->rrt_dimensions[i].rrt_values[j].rating_value_text == NULL)
400                        {
401                                SI_mutex_unlock(m_rrt);
402                                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT failed to alloc rating value text!!!\n"));
403                                return SI_NO_MEMORY;
404                        }
405                        SI_memcpy(rrt_region->rrt_dimensions[i].rrt_values[j].rating_value_text, current, 
406                                rrt_region->rrt_dimensions[i].rrt_values[j].rating_value_length );
407                        current += rrt_region->rrt_dimensions[i].rrt_values[j].rating_value_length;
408
409                        /* debug print for rate value!!! */
410                        for (k=0; k<rrt_region->rrt_dimensions[i].rrt_values[j].abbrev_rating_value_length; k++)
411                                if (k>7)
412                                        SI_DBG_PRINT(E_SI_DBG_MSG,("%c", (char)rrt_region->rrt_dimensions[i].rrt_values[j].abbrev_rating_value_text[k]));
413                        SI_DBG_PRINT(E_SI_DBG_MSG,(",   "));
414                        for (k=0; k<rrt_region->rrt_dimensions[i].rrt_values[j].rating_value_length; k++)
415                                if (k>7)
416                                        SI_DBG_PRINT(E_SI_DBG_MSG,("%c", (char)rrt_region->rrt_dimensions[i].rrt_values[j].rating_value_text[k]));
417                        SI_DBG_PRINT(E_SI_DBG_MSG,("\n"));
418
419                }
420        }
421
422        /* unlock mutex for data access. */
423        SI_mutex_unlock(m_rrt);
424
425
426        /* we only process stuffing descriptor for now. */
427        tot_desc_len = SI_Construct_Data(current, 
428                                        RRT_DESCRIPTORS_LENGTH_BYTE_INDX,
429                                        RRT_DESCRIPTORS_LENGTH_BYTE_NUM,
430                                        RRT_DESCRIPTORS_LENGTH_SHIFT,
431                                        RRT_DESCRIPTORS_LENGTH_MASK);
432        current += RRT_DESCRIPTORS_LENGTH_BYTE_INDX+RRT_DESCRIPTORS_LENGTH_BYTE_NUM;
433
434        offset = 0;
435        while (offset < tot_desc_len)
436        {
437                if (*(current++) != SI_DESC_STUFFING)
438                        SI_DBG_PRINT(E_SI_WRN_MSG,("RRT descriptor %x received! Ignoring!\n", desc_tag));
439
440                desc_len = *(current++);
441                current += desc_len;
442                offset += desc_len+2;
443        }
444
445        if (offset != tot_desc_len)
446        {
447                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT Table section descriptor length error!!!\n"));
448                return SI_DESCRIPTOR_ERROR;
449        }
450       
451        temp = (unsigned long)(current - rrt_table);
452        if (temp != section_length-SI_CRC_LENGTH)
453        {
454                SI_DBG_PRINT(E_SI_ERR_MSG,("RRT Table section length error!!!\n"));
455                return SI_SECTION_LENGTH_ERROR;
456        }
457
458        return SI_SUCCESS;
459}
Note: See TracBrowser for help on using the repository browser.