source: svn/trunk/newcon3bcm2_21bu/dta/src/dvb/dvb_eit.c @ 28

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

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 10.5 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_eit);
33
34/* TODO:: schedule event is not handled... */
35
36typedef enum eit_entry_state_t
37{
38        eEIT_ENTRY_NEW,
39        eEIT_ENTRY_UPDATE,
40        eEIT_ENTRY_SAME
41} eit_entry_state_t ;
42
43static eit_map_t eit_map;
44static eit_sched_map_t eit_sched_map;
45
46static eit_entry_state_t dvb_eit_check_ver(
47        uint16_t stream_id, uint16_t service_id, uint8_t version_num, uint8_t cur_section, uint8_t sched_idx, bool fp);
48
49void dvb_eit_init(void)
50{
51        eit_map.num_eit = 0;
52        BLST_D_INIT(&eit_map.eit_list.list);
53
54        eit_sched_map.num_eit = 0;
55        BLST_D_INIT(&eit_sched_map.eit_list.list);
56}
57       
58int dvb_eit_parse(const uint8_t *eit_buf, size_t *psize)
59{
60        uint16_t section_len, stream_id, orig_network_id, service_id, parsed, desc_len;
61        uint8_t version_num, section_num, last_section, seg_last_section, last_table_id;
62       
63        eit_entry_t *p_eit_entry;
64        eit_sched_entry_t *p_eit_sched_entry;
65
66        uint16_t event_id;
67        uint32_t start_time;
68        uint32_t duration;
69        uint8_t tid, sched_idx=0;
70        uint16_t idx;
71               
72        eit_t *p_eit;
73        bool add = false, sched = false;
74#ifdef BCM_DEBUG
75        b_tm s_tm;
76#endif
77        eit_entry_state_t eit_state;
78        struct bit_state_t bs;
79
80        int i;
81
82        BDBG_ASSERT((eit_buf&&psize));
83        BDBG_MSG(("%s: enter", __func__));
84
85        if (!dvb_get_cur_time()) {
86                BDBG_MSG(("time information is not delivered yet"));
87                return 0;
88        }
89
90        bs.bindex = 0;
91        bs.data = (unsigned char *)eit_buf;
92
93        tid = get_bits(8, &bs);
94        //if (tid == DVB_TID_EIT_SCH_ACT) {
95        if ((tid >= DVB_TID_EIT_SCH_ACT) && (tid <= (DVB_TID_EIT_SCH_OTH+0x0F))) {
96                /* scheduled event */
97                sched_idx = (tid&0x0F);
98                sched = true;
99        }
100        else if ((DVB_TID_EIT_ACT != tid) && (DVB_TID_EIT_OTH != tid)) {
101                BDBG_WRN(("%s: Invalid EIT table Id (0x%02x)", __func__, tid));
102                return 0;
103        }
104
105        get_bits(4, &bs); /* skip section_syntax_indicator,reserved */
106        section_len = get_bits(12, &bs);
107        if (*psize < (section_len+3)) {
108                BDBG_WRN(("%s: incomplete eit section", __func__));
109                return 0;
110        }
111        service_id = get_bits(16, &bs);
112        get_bits(2, &bs); /* skip reserved */
113        version_num = get_bits(5, &bs);
114        get_bits(1, &bs); /* skip current_next_indicator */
115        section_num = get_bits(8, &bs);
116        last_section = get_bits(8, &bs);
117        stream_id = get_bits(16, &bs);
118        orig_network_id = get_bits(16, &bs);
119
120        seg_last_section = get_bits(8, &bs);
121        last_table_id = get_bits(8, &bs);
122        eit_state = dvb_eit_check_ver(stream_id, service_id, version_num, section_num, sched_idx, !sched);
123        if (eit_state == eEIT_ENTRY_SAME) {
124                BDBG_MSG(("same eit table for 0x%x (ver:%x)", service_id, version_num));
125                return 1;
126        }
127
128        if (eit_state == eEIT_ENTRY_NEW) {
129                if (!sched) {
130                        p_eit_entry = (eit_entry_t *)BKNI_Malloc(sizeof(eit_entry_t));
131                        if (!p_eit_entry) {
132                                BDBG_ERR(("memory allocation failed..:%s %d", __FUNCTION__, __LINE__));
133                                return 0;
134                        }
135                        BKNI_Memset(p_eit_entry, 0, sizeof(eit_entry_t));
136                        add = true;
137                        p_eit_entry->eit_present.event_id = 0xFFFF;
138                        p_eit_entry->eit_following.event_id = 0xFFFF;
139                        p_eit_entry->version = version_num;
140                        p_eit_entry->service_id = service_id;
141                        p_eit_entry->stream_id = stream_id;
142                        SI_Init_Section_Mask((unsigned long *)p_eit_entry->section_mask, last_section);
143                }
144                else {
145                        p_eit_sched_entry = (eit_sched_entry_t *)BKNI_Malloc(sizeof(eit_sched_entry_t));
146                        if (!p_eit_sched_entry) {
147                                BDBG_ERR(("memory allocation failed:.. %s %d for (0x%x)", __FUNCTION__, __LINE__, service_id));
148                                return 0;
149                        }
150                        BKNI_Memset(p_eit_sched_entry, 0, sizeof(eit_sched_entry_t));
151                        add = true;
152                        for (i=0; i<MAX_SCHED_ENTRY; i++) {
153                                p_eit_sched_entry->eit_sched[i].event_id = 0xFFFF;
154                        }
155                        p_eit_sched_entry->count = 0;
156                        p_eit_sched_entry->version[sched_idx] = version_num;
157                        p_eit_sched_entry->service_id = service_id;
158                        p_eit_sched_entry->stream_id = stream_id;
159                        SI_Init_Section_Mask((unsigned long *)p_eit_sched_entry->section_mask[sched_idx], last_section);
160                }
161        }
162        else{
163                if (!sched)     
164                        p_eit_entry = dvb_eit_get_entry(stream_id, service_id);
165                else {
166                        p_eit_sched_entry = dvb_eit_get_sched_entry(stream_id, service_id);
167                        p_eit_sched_entry->version[sched_idx] = version_num;
168                        SI_Init_Section_Mask((unsigned long *)p_eit_sched_entry->section_mask[sched_idx], last_section);
169                }
170        }
171
172        if (!sched) {
173                SI_Set_Section_mask((unsigned long *)p_eit_entry->section_mask, section_num);
174        } else {
175                SI_Set_Section_mask((unsigned long *)p_eit_sched_entry->section_mask[sched_idx], section_num);
176        }
177
178        parsed = DVB_EIT_LEN + 4; /* exclude crc */
179        while (parsed < section_len)
180        {
181                event_id = get_bits(16, &bs);
182                idx = bs.bindex/8;
183                start_time = MJD_TO_TIME(eit_buf[idx], eit_buf[idx+1]) + 
184                        BCD_TO_SEC(eit_buf[idx+2], eit_buf[idx+3], eit_buf[idx+4]);
185                duration = BCD_TO_SEC(eit_buf[idx+5], eit_buf[idx+6], eit_buf[idx+7]);
186                bs.bindex += 64;
187
188                if (!sched) {
189                        /* find the present or following */
190                        if ((start_time <= dvb_get_cur_time()) && (start_time+duration >= dvb_get_cur_time())) {
191                                p_eit = &p_eit_entry->eit_present;
192                        }
193                        else {
194                                p_eit = &p_eit_entry->eit_following;
195                        }
196                } 
197                else {
198                        if (p_eit_sched_entry->count >= MAX_SCHED_ENTRY) {
199                                break;
200                        }
201
202                        if (p_eit_sched_entry->count==0) {
203                                p_eit = &p_eit_sched_entry->eit_sched[p_eit_sched_entry->count];
204                                p_eit_sched_entry->count++;
205                        }
206                        else {
207                                for (i=0; i<p_eit_sched_entry->count; i++) {
208                                        if (p_eit_sched_entry->eit_sched[i].event_id == event_id)
209                                                break;
210                                }
211                                p_eit = &p_eit_sched_entry->eit_sched[i];
212                                if (i == p_eit_sched_entry->count) {
213                                        p_eit_sched_entry->count++;
214                                }
215                        }
216                }
217       
218                BKNI_Memset(p_eit, 0, sizeof(eit_t));
219                p_eit->event_id = event_id;
220                p_eit->start_time = start_time;
221                p_eit->duration = duration;
222                p_eit->running_status = get_bits(3, &bs);
223                p_eit->free_ca_mode = get_bits(1, &bs);
224
225                parsed += 10;
226                if (parsed>=section_len)
227                        break;
228
229                desc_len = get_bits(12, &bs);
230                dvb_parse_descriptors((uint8_t *)&eit_buf[bs.bindex/8], desc_len, DVB_TID_EIT_ACT, (void *)p_eit);
231
232#ifdef BCM_DEBUG
233        utctime(p_eit->start_time, &s_tm);
234                BDBG_MSG(("%c [%d:%d]s:0x%04x 0x%04x %02d/%02d/%04d %02d:%02d:%02d %dm (%d) %s (%s) %d",
235                        sched?'S':'C', section_num, last_section,
236                        service_id, p_eit->event_id, s_tm.tm_mon+1, s_tm.tm_mday, s_tm.tm_year+1980,
237                        s_tm.tm_hour, s_tm.tm_min, s_tm.tm_sec, p_eit->duration/60, sched?eit_sched_map.num_eit:eit_map.num_eit,
238                        p_eit->event_name, add?"new":"update", sched?p_eit_sched_entry->count:0));
239#endif
240
241                bs.bindex = bs.bindex + desc_len*8;
242                parsed += desc_len + 2;
243        }
244
245        if (add) {
246                if (!sched) {
247                        BLST_D_INSERT_HEAD(&eit_map.eit_list.list, p_eit_entry, link);
248                        eit_map.num_eit++;
249                }
250                else {
251                        BLST_D_INSERT_HEAD(&eit_sched_map.eit_list.list, p_eit_sched_entry, link);
252                        eit_sched_map.num_eit++;
253                }
254        }
255        return 1;
256}
257
258//void dvb_get_current_event(vch_t vch, int *eit_cnt, eit_t *p_eit_cur, eit_t *p_eit_next)
259void dvb_get_current_event(vch_t vch, int *eit_cnt, eit_t *p_eit)
260{
261        eit_entry_t *p_entry;
262
263        *eit_cnt = 0;
264        for (p_entry = BLST_D_FIRST(&eit_map.eit_list.list); p_entry; p_entry = BLST_D_NEXT(p_entry, link)) {
265                if (p_entry->service_id == vch.program_num) {
266       
267                        if (p_entry->eit_present.event_id == 0xFFFF) {
268                                *eit_cnt = 0;
269                        }
270                        else {
271                                BKNI_Memcpy(&p_eit[0], &p_entry->eit_present, sizeof(eit_t));
272                        //      *p_eit_cur = p_entry->eit_present;
273                                if (p_entry->eit_following.event_id != 0xFFFF) {
274                                        *eit_cnt = 2;
275                        //              *p_eit_next = p_entry->eit_following;
276                                        BKNI_Memcpy(&p_eit[1], &p_entry->eit_following, sizeof(eit_t));
277                                }
278                                else {
279                                        *eit_cnt = 1;
280                                }
281                        }
282                        break;
283                }
284        }
285}
286
287eit_entry_t *dvb_eit_get_entry(uint16_t stream_id, uint16_t service_id)
288{
289        eit_entry_t *p_entry;
290
291        for (p_entry = BLST_D_FIRST(&eit_map.eit_list.list); p_entry; p_entry = BLST_D_NEXT(p_entry, link)) {
292                if ((p_entry->stream_id == stream_id) && (p_entry->service_id == service_id)) {
293                        break;
294                }
295        }
296        return p_entry;
297}
298
299eit_sched_entry_t *dvb_eit_get_sched_entry(uint16_t stream_id, uint16_t service_id)
300{
301        eit_sched_entry_t *p_entry;
302
303        for (p_entry = BLST_D_FIRST(&eit_sched_map.eit_list.list); p_entry; p_entry = BLST_D_NEXT(p_entry, link)) {
304                if ((p_entry->stream_id == stream_id) && (p_entry->service_id == service_id)) {
305                        break;
306                }
307        }
308        return p_entry;
309}
310
311static eit_entry_state_t dvb_eit_check_ver(
312        uint16_t stream_id, /* stream id */
313        uint16_t service_id, /* service id in the stream_id */
314        uint8_t version_num, /* section version number */
315        uint8_t cur_section, /* current section number */
316        uint8_t sched_idx, /* idx for sched event depending on table id*/
317        bool fp /* present following */)
318{
319        if (fp) {
320                eit_entry_t *p_entry;
321                for (p_entry=BLST_D_FIRST(&eit_map.eit_list.list); p_entry; p_entry = BLST_D_NEXT(p_entry, link)) {
322                        if ( (p_entry->service_id == service_id) && (p_entry->stream_id == stream_id)) {
323                                if (p_entry->version != version_num) {
324                                        BDBG_MSG(("CEIT version updated from (0x%x) %x -> %x", service_id, p_entry->version, version_num));
325                                        BLST_D_REMOVE(&eit_map.eit_list.list, p_entry, link);
326                                        BKNI_Free(p_entry);
327                                        p_entry = NULL;
328                                        eit_map.num_eit--;
329                                        break;
330                                }
331                                else if ( SI_Chk_Section_mask((unsigned long *)p_entry->section_mask, cur_section)) { 
332                                        return eEIT_ENTRY_SAME;
333                                }
334                                else {
335                                        return eEIT_ENTRY_UPDATE;
336                                }
337                        }
338                }
339        }
340        else {
341                eit_sched_entry_t *p_entry;
342                for (p_entry=BLST_D_FIRST(&eit_sched_map.eit_list.list); p_entry; p_entry = BLST_D_NEXT(p_entry, link)) {
343                        if ( (p_entry->service_id == service_id) && (p_entry->stream_id == stream_id)) {
344                                if (p_entry->version[sched_idx] != version_num) {
345                                        BDBG_MSG(("SEIT(%d) version updated for (0x%x) %x -> %x", sched_idx, service_id, p_entry->version[sched_idx], version_num));
346#if 0
347                                        BLST_D_REMOVE(&eit_sched_map.eit_list.list, p_entry, link);
348                                        BKNI_Free(p_entry);
349                                        p_entry = NULL;
350                                        eit_sched_map.num_eit--;
351#endif
352                                        return eEIT_ENTRY_UPDATE;
353                                }
354                                else if (SI_Chk_Section_mask((unsigned long *)p_entry->section_mask[sched_idx], cur_section)) {
355                                        return eEIT_ENTRY_SAME;
356                                }
357                                else {
358                                        return eEIT_ENTRY_UPDATE;
359                                }
360                        }
361                }
362        }
363        return eEIT_ENTRY_NEW;
364}
365
Note: See TracBrowser for help on using the repository browser.