source: svn/newcon3bcm2_21bu/BSEAV/lib/scte_18/ts_scte_18.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: 12.1 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2008, 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: ts_scte_18.c $
11 * $brcm_Revision: $
12 * $brcm_Date: $
13 *
14 * [File Description:]
15 *
16 * Revision History:
17 *
18 ***************************************************************************/
19#include "ts_scte_18.h"
20
21/* use my own one instead ctype.h */
22#define isprint(c)      (((c) >= 32) && ((c) < 127))
23
24BDBG_MODULE(ts_scte_18);
25
26#define TS_SCTE_18_EAS_EVENT_LENGTH(buf)        (buf[TS_SCTE_18_EAS_EVENT_CODE_LENGTH]);
27//#define SCTE_DBG
28#ifdef SCTE_DBG
29void TS_SCTE_18_PrintText(const uint8_t *buf, size_t size)
30{
31        CHECK(buf);
32        CHECK(size);
33
34        printf("'");       
35        do
36        {
37                if (isprint(*buf))
38                        printf("%c", *buf);
39                else
40                        printf(" ");
41                buf++;
42        } while (--size > 0);
43        printf("'");       
44}
45
46void TS_SCTE_18_DumpHeader(TS_SCTE_18_header *pHdr)
47{
48        int i;
49        uint8_t *p;
50
51        CHECK(pHdr);
52
53        printf("\n", pHdr->table_id);
54        printf("table_id        = 0x%2x\n", pHdr->table_id);
55        printf("section_length  = %d\n", pHdr->section_length);
56        printf("sequence_number = %d\n", pHdr->sequence_number);
57        printf("EAS_event_ID    = 0x%02x\n", pHdr->EAS_event_ID);
58        printf("originator_code = %c%c%c\n", (char)(pHdr->EAS_originator_code >> 16),
59                   (char)(pHdr->EAS_originator_code >> 8), (char)pHdr->EAS_originator_code);
60        printf("event_code_len  = %d\n", pHdr->EAS_event_code_length);
61        printf("nature_of_activa= %d\n", pHdr->nature_of_activation_text_length);
62        printf("alert_msg_time  = %d\n", pHdr->alert_message_time_remaining);   /* range 1 - 120 */
63        printf("event_start_time= %d\n", pHdr->event_start_time);
64        printf("event_duration  = %d\n", pHdr->event_duration);                                 /* minutes range 15 - 6000 */
65        printf("alert_priority  = %d\n", pHdr->alert_priority);
66        printf("details_OOB_s_ID= 0x%04x\n", pHdr->details_OOB_source_ID);
67        printf("details_major_ch= %d\n", pHdr->details_major_channel_number);   /* 10 bits */
68        printf("details_minor_ch= %d\n", pHdr->details_minor_channel_number);   /* 10 bits */
69        printf("audio_OOB_src_ID= 0x%04x\n", pHdr->audio_OOB_source_ID);
70        printf("alert_text_len  = %d\n", pHdr->alert_text_length);
71        printf("location_code_ct= %d\n", pHdr->location_code_count);                    /* for TS_SCTE_18_location_code structure */
72        printf("exception_count = %d\n", pHdr->exception_count);                                /* for TS_SCTE_18_exception */
73        printf("descriptors_len = %d\n", pHdr->descriptors_length);
74}
75
76void TS_SCTE_18_DumpPacket(uint8_t *pkt, TS_SCTE_18_header *pHdr)
77{
78        size_t ex_size;
79        CHECK(pkt);
80        CHECK(pHdr);
81
82        if (TS_SCTE_18_EAS_TABLE_ID == pHdr->table_id)
83        {
84                size_t size, j;
85                uint8_t *pOffset;
86
87                TS_SCTE_18_DumpHeader(pHdr);
88                if (pHdr->EAS_event_code_length)
89                {
90                        pOffset = TS_SCTE_18_getEASEventCodeOffset((const char *)pkt, &size);
91                        if (pOffset)
92                        {
93                                printf("%18s", "Event = ");
94                                TS_SCTE_18_PrintText(pOffset, size);
95                                printf("\n");
96                        }
97                }
98                if (pHdr->nature_of_activation_text_length)
99                {
100                        pOffset = TS_SCTE_18_getActivationTextOffset((const char *)pkt, &size);
101                        if (pOffset)
102                        {
103                                printf("%18s", "ActivationText = ");
104                                TS_SCTE_18_PrintText(pOffset, size);
105                                printf("\n");
106                        }
107                }
108                if (pHdr->alert_text_length)
109                {
110                        pOffset = TS_SCTE_18_getAlrtTextOffset((const char *)pkt, &size);
111                        if (pOffset)
112                        {
113                                printf("%18s", "AlertText = ");
114                                TS_SCTE_18_PrintText(pOffset, size);
115                                printf("\n");
116                        }
117                }
118                if (pHdr->location_code_count)
119                {
120                        pOffset = TS_SCTE_18_getLocationOffset((const char *)pkt, &size);
121                        if (pOffset)
122                        {
123                                TS_SCTE_18_location_code s;
124                                for (j = 0; j < pHdr->location_code_count; j++)
125                                {
126                                        if (TS_SCTE_18_getLocationCode(pOffset, j, &s))
127                                        {
128                                                printf("Loaction[%d]\n", j);
129                                                printf("\tstate=%d\n", s.state_code);
130                                                printf("\tcounty_subdivision=%d\n", s.county_subdivision);
131                                                printf("\tcounty_code=%d\n", s.county_code);
132                                                printf("\n");
133                                        }
134                                }
135                        }
136                }
137                if (pHdr->exception_count)
138                {
139                        pOffset = TS_SCTE_18_getExpectionOffset((const char *)pkt, &ex_size);
140                        if (pOffset)
141                        {
142                                TS_SCTE_18_exception s;
143                                for (j = 0; j < pHdr->exception_count; j++)
144                                {
145                                        if (TS_SCTE_18_getException(pOffset, j, &s))
146                                        {
147                                                printf("Exception[%d]\n", j);
148                                                printf("\tin_band_ref=%d\n", s.in_band_reference);
149                                                if (s.in_band_reference)
150                                                {
151                                                        printf("\tmajor channel num=%d\n", s.major_channel_number);
152                                                        printf("\tminor channel num=%d\n", s.minor_channel_number);
153                                                }
154                                                else
155                                                {
156                                                        pOffset += 3;
157                                                        printf("\tOOB Source ID=%04x\n", s.OOB_source_ID);
158                                                }
159                                                printf("\n");
160                                        }
161                                }
162                        }
163                }
164                if (pHdr->descriptors_length)
165                {
166                        printf("Descriptor length = %d\n", pHdr->descriptors_length);
167                        pOffset = TS_SCTE_18_getDescriptorOffset((const char *)pkt, &ex_size);
168                        if (pOffset)
169                        {
170
171                                TS_SCTE_18_in_band_channel_descriptor s;
172                                if (TS_SCTE_18_getInBandChannelDescriptor(pOffset, &s,ex_size))
173                                {
174                                        printf("In_Band_Channel_Descriptor\n");
175                                        printf("\texception_RF_channel=%d\n", s.exception_RF_channel);
176                                        printf("\texception_program_number=%d\n", s.exception_program_number);
177                                }
178                        }       
179                }
180        }
181        else
182                printf("%s: invalid table ID=%02x\n", __func__, pHdr->table_id);
183}
184#endif /* #ifdef BCM_DEBUG */
185
186int TS_SCTE_18_getSectionHeader( const uint8_t *pkt, size_t size, TS_SCTE_18_header *p_header )
187{
188        uint16_t tmp;
189        uint8_t *p;
190
191        /* assume that the length of the packet is checked */
192        p_header->table_id = pkt[TS_PSI_TABLE_ID_OFFSET];
193        CHECK(TS_SCTE_18_EAS_TABLE_ID == pkt[0]);
194
195        p_header->section_length = TS_PSI_GET_SECTION_LENGTH(pkt);
196        if ((p_header->section_length + 3) > size)
197        {
198                /* short packet */
199                return -1;
200        }
201        /* table extension ID */
202        tmp = (uint16_t)(TS_READ_16(&(pkt)[TS_PSI_TABLE_ID_EXT_OFFSET]));
203        CHECK(tmp == 0);
204
205        p_header->sequence_number = (uint8_t)((pkt[TS_PSI_CNI_OFFSET]>>1) & 0x1F);
206        //p_header->section_number = pkt[TS_PSI_SECTION_NUMBER_OFFSET];
207        //p_header->last_section_number = pkt[TS_PSI_LAST_SECTION_NUMBER_OFFSET];
208        //p_header->protocol_version = pkt[TS_SCTE_18_PROTOCOL_VERSION];
209
210        p_header->EAS_event_ID = (uint16_t)(TS_READ_16(&(pkt)[TS_SCTE_18_EAS_EVENT_ID]));       /* any field after it other than time_remaining changes */
211        p_header->EAS_originator_code = (uint32_t)(TS_READ_32(&(pkt)[TS_SCTE_18_EAS_ORIGINATOR_CODE])) & 0xffffff;      /* 3 bytes ASCII, like EAS, CIV, WXR and PEP */
212        p_header->EAS_event_code_length = TS_SCTE_18_EAS_EVENT_LENGTH(pkt);
213
214        /* skip EAS_event_code */
215        p = (uint8_t *)pkt;
216        p += (TS_SCTE_18_EAS_EVENT_CODE_LENGTH + p_header->EAS_event_code_length + 1);
217        p_header->nature_of_activation_text_length = *p; p += 1;
218
219        /* skip nature of activation text length */
220        p += p_header->nature_of_activation_text_length;
221
222        p_header->alert_message_time_remaining = *p; p += 1;
223        CHECK( p_header->alert_message_time_remaining <= 120);
224
225        p_header->event_start_time = (uint32_t)(TS_READ_32(p)); p += 4;
226        p_header->event_duration = (uint16_t)(TS_READ_16(p)); p += 2;
227        /*RLQ, note that 0 is allowed as infinity as well */
228        CHECK((0 == p_header->event_duration) || (p_header->event_duration >= 15 && p_header->event_duration <= 6000));
229        p_header->alert_priority = (uint16_t)(TS_READ_16(p)) & 0x0f; p += 2;
230
231        p_header->details_OOB_source_ID = (uint16_t)(TS_READ_16(p)); p += 2;
232        p_header->details_major_channel_number = (uint16_t)(TS_READ_16(p)) & 0x3ff; p += 2;
233        p_header->details_minor_channel_number = (uint16_t)(TS_READ_16(p)) & 0x3ff; p += 2;
234
235        p_header->audio_OOB_source_ID = (uint16_t)(TS_READ_16(p)); p += 2;
236        p_header->alert_text_length = (uint16_t)(TS_READ_16(p)); p += 2;
237        /* skip alert_text */
238        p += p_header->alert_text_length;
239
240        p_header->location_code_count = *p; p += 1; 
241
242        /* skip location_code */
243        p += (p_header->location_code_count * TS_SCTE_18_LOCATION_CODE_BYTES);
244
245        p_header->exception_count = *p; p += 1;
246
247        /* skip exception */
248        p += (p_header->exception_count * TS_SCTE_18_EXCEPTION_BYTES);
249
250        p_header->descriptors_length = (uint16_t)(TS_READ_16(p)) & 0x3ff; p += 2;
251
252        return 0;
253}
254
255uint8_t *TS_SCTE_18_getEASEventCodeOffset(const uint8_t *pkt, size_t *size)
256{
257        uint8_t *p;
258
259        /* assume that the length of the packet is checked */
260        CHECK(TS_SCTE_18_EAS_TABLE_ID == pkt[0]);
261        CHECK(size);
262
263        p = (uint8_t *)pkt;
264        /* get size */
265        *size = TS_SCTE_18_EAS_EVENT_LENGTH(p);
266        /* to code offset */
267        p += (TS_SCTE_18_EAS_EVENT_CODE_LENGTH + 1);
268        return p;
269}
270
271/* nature of activation test code offset */
272uint8_t *TS_SCTE_18_getActivationTextOffset(const uint8_t *pkt, size_t *size)
273{
274        uint16_t len;
275        uint8_t *p;
276
277        /* assume that the length of the packet is checked */
278        CHECK(TS_SCTE_18_EAS_TABLE_ID == pkt[0]);
279
280        /* skip EAS_event_code */
281        p = (uint8_t *)pkt;
282        len = TS_SCTE_18_EAS_EVENT_LENGTH(p);
283        p += (TS_SCTE_18_EAS_EVENT_CODE_LENGTH + len + 1);
284        *size = *p; 
285        p += 1; /* nature_of_activation_text_length */ 
286        return p;
287}
288
289uint8_t *TS_SCTE_18_getAlrtTextOffset(const uint8_t *pkt, size_t *size)
290{
291        uint16_t len;
292        uint8_t *p;
293
294        /* assume that the length of the packet is checked */
295        CHECK(TS_SCTE_18_EAS_TABLE_ID == pkt[0]);
296
297        /* skip EAS_event_code */
298        p = (uint8_t *)pkt;
299        len = TS_SCTE_18_EAS_EVENT_LENGTH(p);
300        p += (TS_SCTE_18_EAS_EVENT_CODE_LENGTH + len + 1);
301        len = *p; //p += 1;
302        /* skip nature of activation text length */
303        p += len + 18 ;
304
305        //p += (1 + 4 + 2 + 2 + 2 + 2 + 2 + 2);
306        //p += 17;
307
308        *size = (uint16_t)(TS_READ_16(p));
309        p += 2;
310
311        return p;
312}
313
314uint8_t *TS_SCTE_18_getLocationOffset(const uint8_t *pkt, size_t *size)
315{
316        uint16_t len;
317        uint8_t *p;
318
319        /* assume that the length of the packet is checked */
320        CHECK(TS_SCTE_18_EAS_TABLE_ID == pkt[0]);
321
322        /* skip EAS_event_code */
323        p = (uint8_t *)pkt;
324        len = TS_SCTE_18_EAS_EVENT_LENGTH(p);
325        p += (TS_SCTE_18_EAS_EVENT_CODE_LENGTH + len + 1);
326        len = *p;
327        p += len + 18;
328
329        len = (uint16_t)(TS_READ_16(p));
330        p += len + 2;
331
332        *size = *p;
333        p += 1;
334
335        return p;
336}
337
338uint8_t *TS_SCTE_18_getExpectionOffset(const uint8_t *pkt, size_t *size)
339{
340        uint8_t *p;
341
342        p = TS_SCTE_18_getLocationOffset(pkt, size);
343        p += (*size * TS_SCTE_18_LOCATION_CODE_BYTES);
344
345        *size = *p;
346        p += 1;
347
348        return p;
349}
350
351uint8_t *TS_SCTE_18_getDescriptorOffset(const uint8_t *pkt, size_t *size)
352{
353        uint8_t *p;
354
355        p = TS_SCTE_18_getExpectionOffset(pkt, size);
356        p += (*size * TS_SCTE_18_EXCEPTION_BYTES);
357
358        *size = (uint16_t)(TS_READ_16(p)) & 0x3ff; 
359        p += 2;
360
361        return p;
362}
363
364bool TS_SCTE_18_getLocationCode( const uint8_t *buf, int index, TS_SCTE_18_location_code *p_location )
365{
366        uint8_t *p = (uint8_t *)buf;
367
368        if (!p_location)
369                return 0;
370
371        p += index * TS_SCTE_18_LOCATION_CODE_BYTES;
372        p_location->state_code = *p++;
373        p_location->county_subdivision = (*p >> 4) & 0x0f;
374        p_location->county_code = (uint16_t)(TS_READ_16(p)) & 0x3ff;
375
376        return 1;
377}
378
379bool TS_SCTE_18_getException( const uint8_t *buf, int index, TS_SCTE_18_exception *p_exception )
380{
381        uint8_t *p = (uint8_t *)buf;
382
383        if (!p_exception)
384                return 0;
385
386        p += index * TS_SCTE_18_EXCEPTION_BYTES;
387        p_exception->in_band_reference = (*p >> 7) & 0x01; p++;
388        if (p_exception->in_band_reference)
389        {
390                p_exception->major_channel_number = (uint16_t)(TS_READ_16(p)) & 0x3ff; p += 2;
391                p_exception->minor_channel_number = (uint16_t)(TS_READ_16(p)) & 0x3ff;
392        }
393        else
394        {
395                p += 2;
396                p_exception->OOB_source_ID = (uint16_t)(TS_READ_16(p));
397        }
398        return 1;
399}
400
401bool TS_SCTE_18_getInBandChannelDescriptor(const uint8_t *buf, TS_SCTE_18_in_band_channel_descriptor *p_descriptor,size_t size)
402{
403        uint8_t *p = (uint8_t *)buf;
404        int length;
405        uint8_t *p_start = (uint8_t *)buf;
406        bool found = false;
407
408        if (!buf || !p_descriptor)
409                return 0;
410
411        /* if not in_band_exception_channel_descriptor */
412        while (((p - p_start) < size) && !found)
413        {
414                found = (IN_BAND_DETAILS_CHANNEL_DESCRIPTOR_TAG == *(p++));
415                length = *(p++);
416                if (!found)
417                        p += length;
418        }
419
420        if (!found)
421        {
422                return 0;
423        }       
424        p_descriptor->exception_RF_channel = *p++;
425        p_descriptor->exception_program_number = (uint16_t)(TS_READ_16(p)); 
426
427        return 1;
428}
429
430bool TS_SCTE_18_getInBandExceptionDescriptorCount(const uint8_t *buf, int *count)
431{
432        uint8_t *p = (uint8_t *)buf;
433
434        if (!buf)
435                return 0;
436
437        /* if not in_band_exception_channel_descriptor */
438        if (IN_BAND_EXCEPTION_CHANNEL_DESCRIPTOR_TAG != *p) {
439                return 0;
440        }
441
442        p += 2;
443        *count = (int)*p;
444
445        return 1;
446}
447
Note: See TracBrowser for help on using the repository browser.