source: svn/trunk/newcon3bcm2_21bu/dta/src/dvb/dvb_sdt.c @ 2

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

first commit

  • Property svn:executable set to *
File size: 5.3 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2011, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile:  $
11 * $brcm_Revision:  $
12 * $brcm_Date: $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log:  $
19 *
20 ****************************************************************************/
21
22#include "bstd.h"
23#include "bkni.h"
24#include "ts_priv.h"
25#include "ts_psi.h"
26#include "ministd.h"
27#include "dvb_parser.h"
28
29#include "si.h"
30#include "si_util.h"
31
32BDBG_MODULE(dvb_sdt);
33
34#define MAX_NUM_STREAM 32
35
36static uint8_t sdt_stream_cnt ;
37static uint16_t sdt_stream_id[MAX_NUM_STREAM];
38static uint8_t sdt_version_num[MAX_NUM_STREAM];
39static uint8_t sdt_last_section[MAX_NUM_STREAM];
40static uint32_t sdt_section_mask[MAX_NUM_STREAM][8];
41
42static sdt_map_t sdt_map;
43static dvb_sdt_cb_t *sdt_cb = NULL;
44
45#ifdef BCM_DEBUG
46static void dump_sdt_map(void);
47#endif
48
49void dvb_sdt_init(dvb_sdt_cb_t *cb)
50{
51        int i,j;
52       
53        sdt_cb = cb;
54        BKNI_Memset(&sdt_map, 0, sizeof(sdt_map));
55        sdt_stream_cnt = 0;
56        for (i=0; i<MAX_NUM_STREAM; i++) {
57                sdt_stream_id[i] = 0xFFFF;
58                sdt_version_num[i] = MAX_NUM_STREAM;
59                sdt_last_section[i] = 0;
60                for (j=0; j<8; j++)
61                        sdt_section_mask[i][j] = 0;
62        }
63}
64
65int dvb_sdt_parse(const uint8_t *sdt_buf, size_t *psize)
66{
67        uint16_t section_len, data_len, stream_id, original_network_id, desc_loop_len;
68        uint8_t version_num, section_number, last_section;
69        uint8_t tid;
70        struct bit_state_t bs;
71        int st_idx;
72
73        sdt_t *p_sdt;
74       
75        BDBG_ASSERT((sdt_buf && psize));
76        BDBG_MSG(("%s: enter", __func__));
77
78        bs.bindex = 0;
79        bs.data = (unsigned char *)sdt_buf;
80
81        tid = get_bits(8, &bs); 
82        if ((DVB_TID_SDT_ACT != tid) && (DVB_TID_SDT_OTH != tid)) {
83                BDBG_WRN(("%s: Invalid SD Table ID (0x%02x)", __func__, tid));
84                return 0;
85        }
86
87        get_bits(4, &bs);       
88        section_len = get_bits(12, &bs);
89
90        if (*psize < (section_len + 3)) {
91                BDBG_WRN(("%s: incomplete section", __func__));
92                return 0;
93        }
94
95        stream_id = get_bits(16, &bs);
96        get_bits(2, &bs); /* skip reserved */
97        version_num = get_bits(5, &bs);
98        get_bits(1, &bs); /* skip current_next_indicator */
99        section_number = get_bits(8, &bs);
100        last_section = get_bits(8, &bs);
101        original_network_id = get_bits(16, &bs);
102        get_bits(8, &bs); /* skip reserved_future_use */
103
104        for (st_idx=0; st_idx<sdt_stream_cnt; st_idx++) {
105                if (sdt_stream_id[st_idx] == stream_id) {
106                        break;
107                }
108        }
109
110        if (st_idx == sdt_stream_cnt) {
111                sdt_stream_id[st_idx] = stream_id;
112                sdt_stream_cnt++;
113        }
114
115        if (version_num != sdt_version_num[st_idx]) {
116                SI_Init_Section_Mask((unsigned long *)sdt_section_mask[st_idx], last_section);
117                sdt_last_section[st_idx] = last_section;
118        }
119        else if (SI_Chk_Section_mask((unsigned long *)sdt_section_mask[st_idx], section_number)) {
120                return 0;
121        }
122
123        BDBG_WRN(("SDT updated to %d->%d: stream_id:%x", sdt_version_num[st_idx], version_num, stream_id));
124        /* TODO:: update (not from initial value ) */
125
126        sdt_version_num[st_idx] = version_num;
127        SI_Set_Section_mask((unsigned long *)sdt_section_mask[st_idx], section_number);
128
129        data_len = section_len + 3 - DVB_SDT_LEN - 4; /* crc */ 
130
131        /* services */
132        while (data_len>0) {
133                p_sdt = &sdt_map.sdt[sdt_map.num_sdt];
134                BKNI_Memset(p_sdt, 0, sizeof(sdt_t));
135       
136                p_sdt->stream_id = stream_id;
137                p_sdt->service_id = get_bits(16, &bs);
138                get_bits(6, &bs); /* skip reserved_future_use */
139                p_sdt->eit_schedule_flag = get_bits(1, &bs);
140                p_sdt->eit_pf_flag = get_bits(1, &bs);
141                p_sdt->running_status = get_bits(3, &bs);
142                p_sdt->free_ca_mode = get_bits(1, &bs);
143                desc_loop_len = get_bits(12, &bs);
144
145                BDBG_MSG(("SDT [%d] service_id-0x%x, eit_sched:%d, eit_pf:%d, running:%d, ca:%d",
146                        sdt_map.num_sdt, p_sdt->service_id, p_sdt->eit_schedule_flag, p_sdt->eit_pf_flag,
147                        p_sdt->running_status, p_sdt->free_ca_mode));
148
149                p_sdt->frequency = dvb_find_frequency_for_stream_id(stream_id);
150                if (p_sdt->frequency) {
151                        dvb_parse_descriptors((uint8_t *)&sdt_buf[bs.bindex/8], desc_loop_len, DVB_TID_SDT_ACT, p_sdt);
152                        bs.bindex = bs.bindex + desc_loop_len*8;
153                        data_len -= desc_loop_len + DVB_SDT_DESCR_LEN;
154                        sdt_map.num_sdt++;
155
156                        if (sdt_cb && sdt_cb->cb) {
157                                sdt_cb->cb(p_sdt, sdt_cb->data);
158                        }
159                }
160                else {
161                        BDBG_WRN(("Frequency entry wasn't defined.."));
162                        bs.bindex = bs.bindex + desc_loop_len*8;
163                        data_len -= desc_loop_len + DVB_SDT_DESCR_LEN;
164                }
165        }
166
167#ifdef BCM_DEBUG
168        dump_sdt_map(); 
169#endif
170        /* crc */
171        BDBG_MSG(("%s: leave", __func__));
172
173        return 1;
174}
175
176bool dvb_sdt_complete(int num_stream)
177{
178        int i;
179        int result;     
180        if (sdt_stream_cnt < num_stream) { /* sdt info for all streams are not delivered yet */
181                return false;
182        }
183
184        for (i=0; i<sdt_stream_cnt; i++) { /* for each SDT, check all sections are delivered */
185                result = SI_Chk_Section_complete((unsigned long *)sdt_section_mask[i], sdt_last_section[i]);
186                if (result != SI_SUCCESS) return false;
187        }
188        return true;
189}
190
191#ifdef BCM_DEBUG
192static void dump_sdt_map(void)
193{
194        int i;
195
196        BDBG_WRN(("%d SDT entry", sdt_map.num_sdt));
197        for (i=0; i<sdt_map.num_sdt; i++) {
198                BDBG_MSG(("[%02d] %06d KHz, 0x%04x service %04x, %s",
199                        i, sdt_map.sdt[i].frequency, sdt_map.sdt[i].stream_id,
200                        sdt_map.sdt[i].service_id, sdt_map.sdt[i].service_name));
201        }
202}
203#endif
Note: See TracBrowser for help on using the repository browser.