| 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 "ch_map.h" |
|---|
| 28 | #include "dvb_parser.h" |
|---|
| 29 | #include "dvb_descriptor.h" |
|---|
| 30 | |
|---|
| 31 | BDBG_MODULE(dvb_descriptor); |
|---|
| 32 | |
|---|
| 33 | static unsigned char* constellation_str[] = {"QPSK", "QAM_16", "QAM_16", "Undefined"}; |
|---|
| 34 | static unsigned char* modulation_str[] = {"Undefined", "QAM_16", "QAM_32", "QAM_64", "QAM_128", "QAM_256"}; |
|---|
| 35 | |
|---|
| 36 | static void dvb_parse_descriptor(uint8_t *buf, desc_hdr_t *hdr); |
|---|
| 37 | static void dump_dvb_content(uint8_t content); |
|---|
| 38 | |
|---|
| 39 | void dvb_parse_descriptors(uint8_t *buf, uint16_t length, uint8_t table_id, void *entry) |
|---|
| 40 | { |
|---|
| 41 | uint16_t parsed = 0; |
|---|
| 42 | // uint8_t *ptr = buf; |
|---|
| 43 | uint8_t desc_tag, len; |
|---|
| 44 | int i; |
|---|
| 45 | struct bit_state_t bs; |
|---|
| 46 | |
|---|
| 47 | bs.bindex = 0; |
|---|
| 48 | bs.data = (unsigned char *)buf; |
|---|
| 49 | |
|---|
| 50 | if (!entry) { /* don't need to parse */ |
|---|
| 51 | return; |
|---|
| 52 | } |
|---|
| 53 | while (parsed < length) |
|---|
| 54 | { |
|---|
| 55 | desc_tag = buf[bs.bindex/8]; |
|---|
| 56 | |
|---|
| 57 | switch (table_id) |
|---|
| 58 | { |
|---|
| 59 | case DVB_TID_NIT_ACT: |
|---|
| 60 | { |
|---|
| 61 | nit_t *nit_entry = entry; |
|---|
| 62 | if (desc_tag == TS_PSI_DT_DVB_CableDelivery) |
|---|
| 63 | { |
|---|
| 64 | cable_delivery_desc_t desc; |
|---|
| 65 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 66 | nit_entry->type = desc_tag; |
|---|
| 67 | nit_entry->frequency = desc.frequency; |
|---|
| 68 | nit_entry->modulation = desc.modulation; |
|---|
| 69 | switch (desc.modulation) { |
|---|
| 70 | case 0x01: /* 16 QAM */ |
|---|
| 71 | nit_entry->modulation = eDVB_QAM_16; break; |
|---|
| 72 | case 0x02: /* 32 QAM */ |
|---|
| 73 | nit_entry->modulation = eDVB_QAM_32; break; |
|---|
| 74 | case 0x03: /* 64 QAM */ |
|---|
| 75 | nit_entry->modulation = eDVB_QAM_64; break; |
|---|
| 76 | case 0x04: /* 128 QAM */ |
|---|
| 77 | nit_entry->modulation = eDVB_QAM_128; break; |
|---|
| 78 | case 0x05: /* 256 QAM */ |
|---|
| 79 | nit_entry->modulation = eDVB_QAM_256; break; |
|---|
| 80 | default: |
|---|
| 81 | nit_entry->modulation = eDVB_QAM_Scan; break; |
|---|
| 82 | } |
|---|
| 83 | nit_entry->symbol_rate = desc.symbol_rate; |
|---|
| 84 | nit_entry->code_rate = desc.code_rate; |
|---|
| 85 | if (desc.modulation>5) desc.modulation = 0; |
|---|
| 86 | |
|---|
| 87 | BDBG_WRN(("cable: freq=%d KHz, modulation:%s, symbol_rate:%d Ksymbols", |
|---|
| 88 | desc.frequency, modulation_str[desc.modulation], desc.symbol_rate)); |
|---|
| 89 | } |
|---|
| 90 | else if (desc_tag == TS_PSI_DT_DVB_TerrestrialDeliverySystem) |
|---|
| 91 | { |
|---|
| 92 | terrestrial_delivery_desc_t desc; |
|---|
| 93 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 94 | nit_entry->type = desc_tag; |
|---|
| 95 | nit_entry->frequency = desc.frequency; |
|---|
| 96 | switch (desc.constellation) { |
|---|
| 97 | case 0x01: /* 16 QAM */ |
|---|
| 98 | nit_entry->modulation = eDVB_QAM_16; break; |
|---|
| 99 | case 0x02: /* 64 QAM */ |
|---|
| 100 | nit_entry->modulation = eDVB_QAM_64; break; |
|---|
| 101 | case 0x00: /* QPSK */ |
|---|
| 102 | default: |
|---|
| 103 | nit_entry->modulation = eDVB_QAM_Scan; break; |
|---|
| 104 | } |
|---|
| 105 | nit_entry->bandwidth = desc.bandwidth; |
|---|
| 106 | if (desc.constellation>2) desc.constellation = 3; |
|---|
| 107 | BDBG_WRN(("Terrestrial : %d khz, bandwidth:%d, constellation:%s", |
|---|
| 108 | desc.frequency, desc.bandwidth, constellation_str[desc.constellation])); |
|---|
| 109 | |
|---|
| 110 | } |
|---|
| 111 | else if (desc_tag == TS_PSI_DT_DVB_ServiceList) |
|---|
| 112 | { |
|---|
| 113 | service_list_desc_t desc; |
|---|
| 114 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 115 | nit_entry->program_cnt = desc.num_list; |
|---|
| 116 | for (i=0; i<desc.num_list; i++) { |
|---|
| 117 | nit_entry->program_id[i] = desc.service_id[i]; |
|---|
| 118 | } |
|---|
| 119 | } |
|---|
| 120 | else if (desc_tag == TS_PSI_DT_DVB_FrequencyList) |
|---|
| 121 | { |
|---|
| 122 | freq_list_desc_t desc; |
|---|
| 123 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 124 | } |
|---|
| 125 | else if (desc_tag == TS_PSI_DT_DVB_SatelliteDelivery) |
|---|
| 126 | { |
|---|
| 127 | satellite_delivery_desc_t desc; |
|---|
| 128 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 129 | } |
|---|
| 130 | else { |
|---|
| 131 | dvb_parse_descriptor(&buf[bs.bindex/8], NULL); |
|---|
| 132 | } |
|---|
| 133 | break; |
|---|
| 134 | } |
|---|
| 135 | case DVB_TID_SDT_ACT: |
|---|
| 136 | { |
|---|
| 137 | sdt_t *sdt_entry = (sdt_t *)entry; |
|---|
| 138 | if (desc_tag == TS_PSI_DT_DVB_Service) { |
|---|
| 139 | service_desc_t desc; |
|---|
| 140 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 141 | sdt_entry->service_type = desc.service_type; |
|---|
| 142 | if (desc.provider_name[0]) |
|---|
| 143 | BKNI_Memcpy(sdt_entry->provider_name, desc.provider_name, MAX_NAME_LEN); |
|---|
| 144 | if (desc.service_name[0]) |
|---|
| 145 | BKNI_Memcpy(sdt_entry->service_name, desc.service_name, MAX_NAME_LEN); |
|---|
| 146 | } |
|---|
| 147 | else if (desc_tag == TS_PSI_DT_DVB_CA_Indentifier) { |
|---|
| 148 | ca_desc_t desc; |
|---|
| 149 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc) ; |
|---|
| 150 | } |
|---|
| 151 | break; |
|---|
| 152 | } |
|---|
| 153 | case DVB_TID_EIT_ACT: |
|---|
| 154 | { |
|---|
| 155 | eit_t *eit_entry = (eit_t *)entry; |
|---|
| 156 | if (desc_tag == TS_PSI_DT_DVB_ShortEvent) { |
|---|
| 157 | short_event_desc_t desc; |
|---|
| 158 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 159 | |
|---|
| 160 | if (desc.event_name[0]) |
|---|
| 161 | BKNI_Memcpy(eit_entry->event_name, desc.event_name, strlen(desc.event_name)); |
|---|
| 162 | if (desc.event_text[0]) |
|---|
| 163 | BKNI_Memcpy(eit_entry->event_text, desc.event_text, strlen(desc.event_text)); |
|---|
| 164 | } |
|---|
| 165 | else if (desc_tag == TS_PSI_DT_DVB_ParentalRating) { |
|---|
| 166 | rating_desc_t desc; |
|---|
| 167 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 168 | BKNI_Memcpy(eit_entry->rating_code, desc.country_code, 3); |
|---|
| 169 | eit_entry->rating_age = desc.rating; |
|---|
| 170 | } |
|---|
| 171 | else if (desc_tag == TS_PSI_DT_DVB_ExtendedEvent) { |
|---|
| 172 | extend_event_desc_t desc; |
|---|
| 173 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 174 | } |
|---|
| 175 | else if (desc_tag == TS_PSI_DT_DVB_TimeShiftedEvent) { |
|---|
| 176 | timeshift_event_desc_t desc; |
|---|
| 177 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 178 | } |
|---|
| 179 | else if (desc_tag == TS_PSI_DT_DVB_Component) { |
|---|
| 180 | component_desc_t desc; |
|---|
| 181 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 182 | } |
|---|
| 183 | else if (desc_tag == TS_PSI_DT_DVB_Content) { |
|---|
| 184 | content_desc_t desc; |
|---|
| 185 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 186 | } |
|---|
| 187 | break; |
|---|
| 188 | } |
|---|
| 189 | case DVB_TID_TIME_OFFSET: |
|---|
| 190 | { |
|---|
| 191 | tot_map_t *tmp_map = (tot_map_t *)entry; |
|---|
| 192 | if (desc_tag == TS_PSI_DT_DVB_LocalTimeOffset) { |
|---|
| 193 | time_offset_desc_t desc; |
|---|
| 194 | dvb_parse_descriptor(&buf[bs.bindex/8], (desc_hdr_t *)&desc); |
|---|
| 195 | BDBG_MSG(("time_offset : %d", desc.num_offset)); |
|---|
| 196 | if (desc.num_offset > 0) { |
|---|
| 197 | tmp_map->num_tot = desc.num_offset; |
|---|
| 198 | for (i=0; i<tmp_map->num_tot; i++) { |
|---|
| 199 | BKNI_Memcpy(tmp_map->tot[i].country, desc.offsets[i].country, 3); |
|---|
| 200 | tmp_map->tot[i].region_id = desc.offsets[i].region_id; |
|---|
| 201 | tmp_map->tot[i].polarity = desc.offsets[i].polarity; |
|---|
| 202 | tmp_map->tot[i].offset = desc.offsets[i].offset; |
|---|
| 203 | tmp_map->tot[i].toc = desc.offsets[i].toc; |
|---|
| 204 | tmp_map->tot[i].next_offset = desc.offsets[i].next_offset; |
|---|
| 205 | BDBG_MSG(("[%d] %c%c%c region:0x%x %d %d %d %d", |
|---|
| 206 | i, desc.offsets[i].country[0], desc.offsets[i].country[1], desc.offsets[i].country[2], |
|---|
| 207 | desc.offsets[i].region_id, desc.offsets[i].polarity, desc.offsets[i].offset, |
|---|
| 208 | desc.offsets[i].toc, desc.offsets[i].next_offset)); |
|---|
| 209 | } |
|---|
| 210 | } |
|---|
| 211 | } |
|---|
| 212 | break; |
|---|
| 213 | } |
|---|
| 214 | default: |
|---|
| 215 | break; |
|---|
| 216 | } |
|---|
| 217 | |
|---|
| 218 | get_bits(8, &bs); /* tag */ |
|---|
| 219 | len = get_bits(8, &bs); |
|---|
| 220 | parsed += len + 2; |
|---|
| 221 | bs.bindex = bs.bindex + len*8; |
|---|
| 222 | } |
|---|
| 223 | } |
|---|
| 224 | |
|---|
| 225 | static uint32_t calc_frequency(uint8_t coding_type, uint32_t freq) |
|---|
| 226 | { |
|---|
| 227 | uint32_t out_freq = 0; |
|---|
| 228 | int i, mul = 1; |
|---|
| 229 | uint8_t buf[4] ; |
|---|
| 230 | |
|---|
| 231 | switch (coding_type) { |
|---|
| 232 | case 2: /* cable */ |
|---|
| 233 | buf[0] = (freq>>24)&0xFF; |
|---|
| 234 | buf[1] = (freq>>16)&0xFF; |
|---|
| 235 | buf[2] = (freq>>8)&0xFF; |
|---|
| 236 | buf[3] = freq&0xFF; |
|---|
| 237 | mul = 1000000; |
|---|
| 238 | for (out_freq = 0, i=0; i<4; i++) { |
|---|
| 239 | out_freq += (buf[i]>>4)*mul; mul /= 10; |
|---|
| 240 | out_freq += (buf[i]&0x0F)*mul; mul/=10; |
|---|
| 241 | } |
|---|
| 242 | break; |
|---|
| 243 | case 3: /* terrestrial */ |
|---|
| 244 | out_freq = freq/100; |
|---|
| 245 | break; |
|---|
| 246 | case 1: /* satellite */ |
|---|
| 247 | default: |
|---|
| 248 | BDBG_WRN(("undefined.. coding type")); |
|---|
| 249 | break; |
|---|
| 250 | } |
|---|
| 251 | return out_freq; |
|---|
| 252 | } |
|---|
| 253 | |
|---|
| 254 | static void dvb_parse_descriptor(uint8_t *buf, desc_hdr_t *hdr) |
|---|
| 255 | { |
|---|
| 256 | uint8_t tag, len; |
|---|
| 257 | uint16_t idx; |
|---|
| 258 | int i, mul = 1; |
|---|
| 259 | struct bit_state_t bs; |
|---|
| 260 | |
|---|
| 261 | if (hdr == NULL) { |
|---|
| 262 | BDBG_MSG(("don't need process : 0x%02x", hdr->tag)); |
|---|
| 263 | return; |
|---|
| 264 | } |
|---|
| 265 | |
|---|
| 266 | bs.bindex = 0; |
|---|
| 267 | bs.data = (unsigned char *)buf; |
|---|
| 268 | |
|---|
| 269 | tag = get_bits(8, &bs); |
|---|
| 270 | |
|---|
| 271 | switch (tag) |
|---|
| 272 | { |
|---|
| 273 | case TS_PSI_DT_DVB_NetworkName: |
|---|
| 274 | { |
|---|
| 275 | network_name_desc_t *desc = (network_name_desc_t *)hdr; |
|---|
| 276 | |
|---|
| 277 | BKNI_Memset(desc, 0, sizeof(network_name_desc_t)); |
|---|
| 278 | len = get_bits(8, &bs); |
|---|
| 279 | desc->hdr.tag = tag; |
|---|
| 280 | if (len) |
|---|
| 281 | BKNI_Memcpy(desc->name, &buf[bs.bindex/8], (len>MAX_NAME_LEN)?MAX_NAME_LEN:len); |
|---|
| 282 | BDBG_WRN(("network name : %s", desc->name)); |
|---|
| 283 | break; |
|---|
| 284 | } |
|---|
| 285 | case TS_PSI_DT_DVB_CableDelivery: |
|---|
| 286 | { |
|---|
| 287 | cable_delivery_desc_t *desc = (cable_delivery_desc_t *)hdr; |
|---|
| 288 | BKNI_Memset(desc, 0, sizeof(cable_delivery_desc_t)); |
|---|
| 289 | desc->hdr.tag = tag; |
|---|
| 290 | len = get_bits(8, &bs); |
|---|
| 291 | desc->frequency = calc_frequency(2, get_bits_aligned(32, &bs)); |
|---|
| 292 | get_bits(16, &bs); /* skip reserved_future_use, FEC_outer */ |
|---|
| 293 | desc->modulation = get_bits(8, &bs); |
|---|
| 294 | |
|---|
| 295 | mul = 100000; |
|---|
| 296 | for (desc->symbol_rate=0, i=0; i<6; i++) { /* k symbols */ |
|---|
| 297 | desc->symbol_rate += get_bits(4, &bs)*mul; |
|---|
| 298 | mul /= 10; |
|---|
| 299 | } |
|---|
| 300 | get_bits(4, &bs); /* discard under khz */ |
|---|
| 301 | desc->code_rate = get_bits(4, &bs); |
|---|
| 302 | break; |
|---|
| 303 | } |
|---|
| 304 | case TS_PSI_DT_DVB_Service: |
|---|
| 305 | { |
|---|
| 306 | service_desc_t *desc = (service_desc_t *)hdr; |
|---|
| 307 | BKNI_Memset(desc, 0, sizeof(service_desc_t)); |
|---|
| 308 | desc->hdr.tag = tag; |
|---|
| 309 | get_bits(8, &bs); |
|---|
| 310 | desc->service_type = get_bits(8, &bs); |
|---|
| 311 | len = get_bits(8, &bs); |
|---|
| 312 | if (len) |
|---|
| 313 | BKNI_Memcpy(desc->provider_name, &buf[bs.bindex/8], (len>MAX_NAME_LEN)?MAX_NAME_LEN:len); |
|---|
| 314 | bs.bindex = bs.bindex + len*8; |
|---|
| 315 | len = get_bits(8, &bs); |
|---|
| 316 | if (len) |
|---|
| 317 | BKNI_Memcpy(desc->service_name, &buf[bs.bindex/8], (len>MAX_NAME_LEN)?MAX_NAME_LEN:len); |
|---|
| 318 | BDBG_MSG(("service: type:%d provider-%s, service-%s", |
|---|
| 319 | desc->service_type, desc->provider_name, desc->service_name)); |
|---|
| 320 | break; |
|---|
| 321 | } |
|---|
| 322 | case TS_PSI_DT_DVB_ShortEvent: |
|---|
| 323 | { |
|---|
| 324 | short_event_desc_t *desc = (short_event_desc_t *)hdr; |
|---|
| 325 | BKNI_Memset(desc, 0, sizeof(short_event_desc_t)); |
|---|
| 326 | desc->hdr.tag = tag; |
|---|
| 327 | len = get_bits(8, &bs); |
|---|
| 328 | for (i=0; i<3; i++) |
|---|
| 329 | desc->lang_code[i] = get_bits(8, &bs); |
|---|
| 330 | len = get_bits(8, &bs); |
|---|
| 331 | if (len) |
|---|
| 332 | BKNI_Memcpy(desc->event_name, &buf[bs.bindex/8], (len>MAX_EVENT_NAME)?MAX_EVENT_NAME:len); |
|---|
| 333 | bs.bindex = bs.bindex + len*8; |
|---|
| 334 | |
|---|
| 335 | len = get_bits(8, &bs); |
|---|
| 336 | if (len) |
|---|
| 337 | BKNI_Memcpy(desc->event_text, &buf[bs.bindex/8], len); |
|---|
| 338 | BDBG_MSG(("short event: %s, %s", desc->event_name, desc->event_text)); |
|---|
| 339 | break; |
|---|
| 340 | } |
|---|
| 341 | case TS_PSI_DT_DVB_ExtendedEvent: |
|---|
| 342 | { |
|---|
| 343 | extend_event_desc_t *desc = (extend_event_desc_t *)hdr; |
|---|
| 344 | uint8_t desc_num, last_num, parsed, item_len; |
|---|
| 345 | |
|---|
| 346 | BKNI_Memset(desc, 0, sizeof(extend_event_desc_t)); |
|---|
| 347 | desc->hdr.tag = tag; |
|---|
| 348 | len = get_bits(8, &bs); |
|---|
| 349 | desc_num = get_bits(4, &bs); |
|---|
| 350 | last_num = get_bits(4, &bs); |
|---|
| 351 | |
|---|
| 352 | for (i=0; i<3; i++) |
|---|
| 353 | desc->lang_code[i] = get_bits(8, &bs); |
|---|
| 354 | |
|---|
| 355 | len = get_bits(8, &bs); |
|---|
| 356 | parsed = 0; |
|---|
| 357 | |
|---|
| 358 | while (parsed<len) { |
|---|
| 359 | item_len = get_bits(8, &bs); |
|---|
| 360 | if (item_len) |
|---|
| 361 | BKNI_Memcpy(desc->item_desc, &buf[bs.bindex/8], (item_len>MAX_EVENT_NAME)?MAX_EVENT_NAME:item_len); |
|---|
| 362 | |
|---|
| 363 | bs.bindex = bs.bindex + item_len*8; |
|---|
| 364 | parsed += 1+item_len; |
|---|
| 365 | item_len = get_bits(8, &bs); |
|---|
| 366 | if (item_len) |
|---|
| 367 | BKNI_Memcpy(desc->item_char, &buf[bs.bindex/8], item_len); |
|---|
| 368 | bs.bindex = bs.bindex + item_len*8; |
|---|
| 369 | parsed += 1+item_len; |
|---|
| 370 | } |
|---|
| 371 | len = get_bits(8, &bs); |
|---|
| 372 | if (len) |
|---|
| 373 | BKNI_Memcpy(desc->text_char, &buf[bs.bindex/8], len); |
|---|
| 374 | BDBG_MSG(("extended event: %c%c%c, %s, %s, %s:", |
|---|
| 375 | desc->lang_code[0], desc->lang_code[1], desc->lang_code[2], |
|---|
| 376 | desc->item_desc, desc->item_char, desc->text_char)); |
|---|
| 377 | break; |
|---|
| 378 | } |
|---|
| 379 | case TS_PSI_DT_DVB_ParentalRating: |
|---|
| 380 | { |
|---|
| 381 | rating_desc_t *desc = (rating_desc_t *)hdr; |
|---|
| 382 | uint8_t parsed = 0; |
|---|
| 383 | |
|---|
| 384 | BKNI_Memset(desc, 0, sizeof(rating_desc_t)); |
|---|
| 385 | desc->hdr.tag = tag; |
|---|
| 386 | len = get_bits(8, &bs); |
|---|
| 387 | |
|---|
| 388 | while (parsed<len) { |
|---|
| 389 | for (i=0; i<3; i++) |
|---|
| 390 | desc->country_code[i] = get_bits(8, &bs); |
|---|
| 391 | |
|---|
| 392 | desc->rating = get_bits(8, &bs); |
|---|
| 393 | parsed += 4; |
|---|
| 394 | BDBG_MSG(("rating: %c%c%c year %d", desc->country_code[0], desc->country_code[1], desc->country_code[2], |
|---|
| 395 | (desc->rating>0&&desc->rating<0x10)?3+desc->rating:desc->rating)); |
|---|
| 396 | } |
|---|
| 397 | break; |
|---|
| 398 | } |
|---|
| 399 | case TS_PSI_DT_DVB_ServiceList: |
|---|
| 400 | { |
|---|
| 401 | service_list_desc_t *desc = (service_list_desc_t *)hdr; |
|---|
| 402 | |
|---|
| 403 | BKNI_Memset(desc, 0, sizeof(service_list_desc_t)); |
|---|
| 404 | desc->hdr.tag = tag; |
|---|
| 405 | |
|---|
| 406 | len = get_bits(8, &bs); |
|---|
| 407 | desc->num_list = len/3; |
|---|
| 408 | if (desc->num_list>MAX_SERVICE_LIST) |
|---|
| 409 | desc->num_list = MAX_SERVICE_LIST; |
|---|
| 410 | |
|---|
| 411 | BDBG_MSG(("service list")); |
|---|
| 412 | for (i=0; i<desc->num_list; i++) { |
|---|
| 413 | desc->service_id[i] = get_bits(16, &bs); |
|---|
| 414 | desc->service_type[i] = get_bits(8, &bs); |
|---|
| 415 | BDBG_MSG(("[%d] 0x%x type(%d)", i, desc->service_id[i], desc->service_type[i])); |
|---|
| 416 | } |
|---|
| 417 | break; |
|---|
| 418 | } |
|---|
| 419 | case TS_PSI_DT_DVB_Content: |
|---|
| 420 | { |
|---|
| 421 | content_desc_t *desc = (content_desc_t *)hdr; |
|---|
| 422 | BKNI_Memset(desc, 0, sizeof(content_desc_t)); |
|---|
| 423 | desc->hdr.tag = tag; |
|---|
| 424 | len = get_bits(8, &bs); |
|---|
| 425 | |
|---|
| 426 | for (i=0; i<len/2; i++) { |
|---|
| 427 | desc->content = get_bits(8, &bs); |
|---|
| 428 | desc->user = get_bits(8, &bs); |
|---|
| 429 | dump_dvb_content(desc->content); |
|---|
| 430 | } |
|---|
| 431 | break; |
|---|
| 432 | } |
|---|
| 433 | case TS_PSI_DT_DVB_PrivateDataSpecifier: |
|---|
| 434 | case TS_PSI_DT_DVB_Linkage: |
|---|
| 435 | { |
|---|
| 436 | len = get_bits(8, &bs); |
|---|
| 437 | BDBG_MSG(("linkage: length - %d", len)); |
|---|
| 438 | bs.bindex = bs.bindex + len*8; |
|---|
| 439 | break; |
|---|
| 440 | } |
|---|
| 441 | case TS_PSI_DT_DVB_PDC: |
|---|
| 442 | { |
|---|
| 443 | pdc_desc_t *desc = (pdc_desc_t *)hdr; |
|---|
| 444 | desc->hdr.tag = tag; |
|---|
| 445 | len = get_bits(8, &bs); |
|---|
| 446 | |
|---|
| 447 | get_bits(4, &bs); /* skip reserved_future_use */ |
|---|
| 448 | desc->day = get_bits(5, &bs); |
|---|
| 449 | desc->month = get_bits(4, &bs); |
|---|
| 450 | desc->hour = get_bits(5, &bs); |
|---|
| 451 | desc->minute = get_bits(6, &bs); |
|---|
| 452 | BDBG_MSG(("PDC : month(%d) day(%d) hour(%d) minute(%d)", desc->month, desc->day, desc->hour, desc->minute)); |
|---|
| 453 | break; |
|---|
| 454 | } |
|---|
| 455 | case TS_PSI_DT_DVB_Component: |
|---|
| 456 | { |
|---|
| 457 | component_desc_t *desc = (component_desc_t *)hdr; |
|---|
| 458 | int text_len ; |
|---|
| 459 | |
|---|
| 460 | BKNI_Memset(desc, 0, sizeof(component_desc_t)); |
|---|
| 461 | desc->hdr.tag = tag; |
|---|
| 462 | len = get_bits(8, &bs); |
|---|
| 463 | |
|---|
| 464 | get_bits(4, &bs); /* skip reserved_future_use */ |
|---|
| 465 | desc->content = get_bits(4, &bs); |
|---|
| 466 | desc->type = get_bits(8, &bs); |
|---|
| 467 | desc->tag = get_bits(8, &bs); |
|---|
| 468 | |
|---|
| 469 | for (i=0; i<3; i++) |
|---|
| 470 | desc->lang[i] = get_bits(8, &bs); |
|---|
| 471 | |
|---|
| 472 | text_len = len-6; |
|---|
| 473 | if (text_len > MAX_EVENT_TEXT) |
|---|
| 474 | text_len = MAX_EVENT_TEXT; |
|---|
| 475 | if (text_len) |
|---|
| 476 | BKNI_Memcpy(desc->text, &buf[bs.bindex/8], text_len); |
|---|
| 477 | BDBG_MSG(("component: c(%d), t(%d), tg(%d), (%c%c%c), %s)", |
|---|
| 478 | desc->content, desc->type, desc->tag, desc->lang[0], desc->lang[1], desc->lang[2], desc->text)); |
|---|
| 479 | break; |
|---|
| 480 | } |
|---|
| 481 | case TS_PSI_DT_DVB_TimeShiftedEvent: |
|---|
| 482 | { |
|---|
| 483 | timeshift_event_desc_t *desc = (timeshift_event_desc_t *)hdr; |
|---|
| 484 | len = get_bits(8, &bs); |
|---|
| 485 | desc->hdr.tag = tag; |
|---|
| 486 | |
|---|
| 487 | desc->service_id = get_bits(16, &bs); |
|---|
| 488 | desc->event_id = get_bits(16, &bs); |
|---|
| 489 | break; |
|---|
| 490 | } |
|---|
| 491 | case TS_PSI_DT_DVB_TerrestrialDeliverySystem: |
|---|
| 492 | { |
|---|
| 493 | terrestrial_delivery_desc_t *desc = (terrestrial_delivery_desc_t *)hdr; |
|---|
| 494 | |
|---|
| 495 | BKNI_Memset(desc, 0, sizeof(terrestrial_delivery_desc_t)); |
|---|
| 496 | len = get_bits(8, &bs); |
|---|
| 497 | desc->hdr.tag = tag; |
|---|
| 498 | |
|---|
| 499 | desc->frequency = get_bits_aligned(32, &bs)/100; /* khz unit. centre_frequency is in the 10Hz unit */ |
|---|
| 500 | desc->bandwidth = get_bits(3, &bs); |
|---|
| 501 | get_bits(5, &bs); /* skip reserved_future_use */ |
|---|
| 502 | desc->constellation = get_bits(2, &bs); |
|---|
| 503 | #if 0 |
|---|
| 504 | desc->hierarchy = get_bits(3, &bs); |
|---|
| 505 | desc->HP = get_bits(3, &bs); |
|---|
| 506 | desc->LP = get_bits(3, &bs); |
|---|
| 507 | desc->interval = get_bits(2, &bs); |
|---|
| 508 | desc->transmission = get_bits(2, &bs); |
|---|
| 509 | desc->flag = get_bits(1, &bs); |
|---|
| 510 | get_bits_aligned(32, &bs); /* skip reserved_future_use */ |
|---|
| 511 | #endif |
|---|
| 512 | break; |
|---|
| 513 | } |
|---|
| 514 | case TS_PSI_DT_DVB_CA_Indentifier: |
|---|
| 515 | { |
|---|
| 516 | ca_desc_t *desc = (ca_desc_t *)hdr; |
|---|
| 517 | BKNI_Memset(desc, 0, sizeof(ca_desc_t)); |
|---|
| 518 | len = get_bits(8, &bs); |
|---|
| 519 | desc->hdr.tag = tag; |
|---|
| 520 | |
|---|
| 521 | desc->ca_system_id = get_bits(16, &bs); /* TODO:: 1-n ca_system_id */ |
|---|
| 522 | BDBG_MSG(("ca_system_id : %x", desc->ca_system_id)); |
|---|
| 523 | break; |
|---|
| 524 | } |
|---|
| 525 | case TS_PSI_DT_DVB_FrequencyList: |
|---|
| 526 | { |
|---|
| 527 | freq_list_desc_t *desc = (freq_list_desc_t *)hdr; |
|---|
| 528 | BKNI_Memset(desc, 0, sizeof(freq_list_desc_t)); |
|---|
| 529 | len = get_bits(8, &bs); |
|---|
| 530 | desc->hdr.tag = tag; |
|---|
| 531 | |
|---|
| 532 | get_bits(6, &bs); /* skip reserved_future_use */ |
|---|
| 533 | desc->coding_type = get_bits(2, &bs); |
|---|
| 534 | |
|---|
| 535 | desc->num_freq = (len-1)/4; |
|---|
| 536 | BDBG_MSG(("frequency list : %d", desc->coding_type)); |
|---|
| 537 | for (i=0; i<desc->num_freq; i++) { |
|---|
| 538 | desc->frequency[i] = calc_frequency(desc->coding_type, get_bits_aligned(32, &bs)); |
|---|
| 539 | BDBG_MSG((" [%d] %d (%x)", i, desc->frequency[i], desc->frequency[i])); |
|---|
| 540 | } |
|---|
| 541 | break; |
|---|
| 542 | } |
|---|
| 543 | case TS_PSI_DT_DVB_LocalTimeOffset: |
|---|
| 544 | { |
|---|
| 545 | time_offset_desc_t *desc = (time_offset_desc_t *)hdr; |
|---|
| 546 | BKNI_Memset(desc, 0, sizeof(time_offset_desc_t)); |
|---|
| 547 | |
|---|
| 548 | len = get_bits(8, &bs); |
|---|
| 549 | desc->hdr.tag = tag; |
|---|
| 550 | |
|---|
| 551 | desc->num_offset = len/13; |
|---|
| 552 | if (desc->num_offset > MAX_TIMEOFFSET) |
|---|
| 553 | desc->num_offset = MAX_TIMEOFFSET; |
|---|
| 554 | |
|---|
| 555 | for (i=0; i<desc->num_offset; i++) { |
|---|
| 556 | desc->offsets[i].country[0] = get_bits(8, &bs); |
|---|
| 557 | desc->offsets[i].country[1] = get_bits(8, &bs); |
|---|
| 558 | desc->offsets[i].country[2] = get_bits(8, &bs); |
|---|
| 559 | |
|---|
| 560 | desc->offsets[i].region_id = get_bits(6, &bs); |
|---|
| 561 | get_bits(1, &bs); /* skip reserved */ |
|---|
| 562 | desc->offsets[i].polarity = get_bits(1, &bs); |
|---|
| 563 | idx = bs.bindex/8; |
|---|
| 564 | desc->offsets[i].offset = BCD_TO_MIN(buf[idx], buf[idx+1]); |
|---|
| 565 | desc->offsets[i].toc = MJD_TO_TIME(buf[idx+2], buf[idx+3]) + |
|---|
| 566 | BCD_TO_SEC(buf[idx+4], buf[idx+5], buf[idx+6]); |
|---|
| 567 | desc->offsets[i].next_offset = BCD_TO_MIN(buf[idx+7], buf[idx+8]); |
|---|
| 568 | bs.bindex += 72; |
|---|
| 569 | } |
|---|
| 570 | break; |
|---|
| 571 | } |
|---|
| 572 | case TS_PSI_DT_DVB_SatelliteDelivery: |
|---|
| 573 | { |
|---|
| 574 | satellite_delivery_desc_t *desc = (satellite_delivery_desc_t *)hdr; |
|---|
| 575 | BKNI_Memset(desc, 0, sizeof(satellite_delivery_desc_t)); |
|---|
| 576 | |
|---|
| 577 | desc->hdr.tag = tag; |
|---|
| 578 | len = get_bits(8, &bs); |
|---|
| 579 | idx = bs.bindex/8; |
|---|
| 580 | BDBG_WRN(("satellite : %x%x%x.%x%x%x%x%x", buf[idx], buf[idx+1], buf[idx+2], |
|---|
| 581 | buf[idx+3], buf[idx+4], buf[idx+5], buf[idx+6], buf[idx+7])); |
|---|
| 582 | break; |
|---|
| 583 | } |
|---|
| 584 | case TS_PSI_DT_DVB_BouquetName: |
|---|
| 585 | { |
|---|
| 586 | bouquet_name_desc_t *desc = (bouquet_name_desc_t *)hdr; |
|---|
| 587 | BKNI_Memset(desc, 0, sizeof(bouquet_name_desc_t)); |
|---|
| 588 | |
|---|
| 589 | desc->hdr.tag = tag; |
|---|
| 590 | len = get_bits(8, &bs); |
|---|
| 591 | if (len) { |
|---|
| 592 | BKNI_Memcpy(desc->bouquet_name, (uint8_t *)&buf[bs.bindex/8], (len>MAX_NAME_LEN)?MAX_NAME_LEN:len); |
|---|
| 593 | } |
|---|
| 594 | break; |
|---|
| 595 | } |
|---|
| 596 | case TS_PSI_DT_DVB_Teletext: |
|---|
| 597 | case TS_PSI_DT_DVB_VBI_Teletext: |
|---|
| 598 | { |
|---|
| 599 | teletext_desc_t *desc = (teletext_desc_t *)hdr; |
|---|
| 600 | BKNI_Memset(desc, 0, sizeof(teletext_desc_t)); |
|---|
| 601 | |
|---|
| 602 | desc->hdr.tag = tag; |
|---|
| 603 | len = get_bits(8, &bs); |
|---|
| 604 | for (i=0; i<3; i++) |
|---|
| 605 | desc->lang[i] = get_bits(8, &bs); |
|---|
| 606 | desc->type = get_bits(5, &bs); |
|---|
| 607 | desc->magazine = get_bits(3, &bs); |
|---|
| 608 | desc->page = get_bits(8, &bs); |
|---|
| 609 | break; |
|---|
| 610 | } |
|---|
| 611 | case TS_PSI_DT_DVB_Subtitling: |
|---|
| 612 | { |
|---|
| 613 | subtitling_desc_t *desc = (subtitling_desc_t *)hdr; |
|---|
| 614 | BKNI_Memset(desc, 0, sizeof(subtitling_desc_t)); |
|---|
| 615 | |
|---|
| 616 | desc->hdr.tag = tag; |
|---|
| 617 | len = get_bits(8, &bs); |
|---|
| 618 | for (i=0; i<3; i++) |
|---|
| 619 | desc->lang[i] = get_bits(8, &bs); |
|---|
| 620 | desc->type = get_bits(8, &bs); |
|---|
| 621 | desc->composition_page = get_bits(16, &bs); |
|---|
| 622 | desc->ancillary_page = get_bits(16, &bs); |
|---|
| 623 | break; |
|---|
| 624 | } |
|---|
| 625 | case TS_PSI_DT_DVB_DataBroadcast: |
|---|
| 626 | case TS_PSI_DT_DVB_Stuffing: |
|---|
| 627 | case TS_PSI_DT_DVB_VBI_Data: |
|---|
| 628 | case TS_PSI_DT_DVB_CountryAvailablity: |
|---|
| 629 | case TS_PSI_DT_DVB_NVOD_Reference: |
|---|
| 630 | case TS_PSI_DT_DVB_TimeShiftedService: |
|---|
| 631 | case TS_PSI_DT_DVB_Mosaic: |
|---|
| 632 | case TS_PSI_DT_DVB_StreamIdentifier: |
|---|
| 633 | case TS_PSI_DT_DVB_Telephone: |
|---|
| 634 | case TS_PSI_DT_DVB_MultilingualNetworkName: |
|---|
| 635 | case TS_PSI_DT_DVB_MultilingualBouquetName: |
|---|
| 636 | case TS_PSI_DT_DVB_MultilingualServiceName: |
|---|
| 637 | case TS_PSI_DT_DVB_MultilingualComponent: |
|---|
| 638 | case TS_PSI_DT_DVB_ServiceMove: |
|---|
| 639 | case TS_PSI_DT_DVB_ShortSmoothingBuffer: |
|---|
| 640 | case TS_PSI_DT_DVB_PartialTransportStream: |
|---|
| 641 | case TS_PSI_DT_DVB_Scrambling: |
|---|
| 642 | case TS_PSI_DT_DVB_DataBroadcastID: |
|---|
| 643 | case TS_PSI_DT_DVB_TransportStream: |
|---|
| 644 | case TS_PSI_DT_DVB_DSNG: |
|---|
| 645 | case TS_PSI_DT_DVB_AC3: |
|---|
| 646 | case TS_PSI_DT_DVB_AncillaryData: |
|---|
| 647 | case TS_PSI_DT_DVB_CellList: |
|---|
| 648 | case TS_PSI_DT_DVB_CellFrequencyLink: |
|---|
| 649 | case TS_PSI_DT_DVB_AnnouncementSupport: |
|---|
| 650 | case TS_PSI_DT_DVB_ApplicationSignalling: |
|---|
| 651 | case TS_PSI_DT_DVB_AdaptationFieldData: |
|---|
| 652 | case TS_PSI_DT_DVB_ServiceIdentifier: |
|---|
| 653 | case TS_PSI_DT_DVB_ServiceAvailability: |
|---|
| 654 | case TS_PSI_DT_DVB_DefaultAuthority: |
|---|
| 655 | case TS_PSI_DT_DVB_RelatedContent: |
|---|
| 656 | case TS_PSI_DT_DVB_TVA_ID: |
|---|
| 657 | case TS_PSI_DT_DVB_ContentIdentifier: |
|---|
| 658 | case TS_PSI_DT_DVB_TimeSliceFEC: |
|---|
| 659 | case TS_PSI_DT_DVB_ECMRepetitionRate: |
|---|
| 660 | case TS_PSI_DT_DVB_S2SatelliteDeliverySystem: |
|---|
| 661 | case TS_PSI_DT_DVB_EnhancedAC3: |
|---|
| 662 | case TS_PSI_DT_DVB_DTS: |
|---|
| 663 | case TS_PSI_DT_DVB_AAC: |
|---|
| 664 | case TS_PSI_DT_DVB_DRA: |
|---|
| 665 | default: |
|---|
| 666 | break; |
|---|
| 667 | } |
|---|
| 668 | } |
|---|
| 669 | |
|---|
| 670 | static void dump_dvb_content(uint8_t content) |
|---|
| 671 | { |
|---|
| 672 | switch (content&0xF0) |
|---|
| 673 | { |
|---|
| 674 | case 0x10: BDBG_MSG(("Movie/Drama (0x%x)", content&0x0F)); break; |
|---|
| 675 | case 0x20: BDBG_MSG(("News/Current affairs (0x%x)", content&0x0F)); break; |
|---|
| 676 | case 0x30: BDBG_MSG(("Show/Game show (0x%x)", content&0x0F)); break; |
|---|
| 677 | case 0x40: BDBG_MSG(("Sports (0x%x)", content&0x0F)); break; |
|---|
| 678 | case 0x50: BDBG_MSG(("Children's/Youth Programmes (0x%x)", content&0x0F)); break; |
|---|
| 679 | case 0x60: BDBG_MSG(("Music/Ballet/Dance (0x%x)", content&0x0F)); break; |
|---|
| 680 | case 0x70: BDBG_MSG(("Arts/Culture (0x%x)", content&0x0F)); break; |
|---|
| 681 | case 0x80: BDBG_MSG(("Social/Political Issues/Economics (0x%x)", content&0x0F)); break; |
|---|
| 682 | case 0x90: BDBG_MSG(("Education/Science/Factual topics (0x%x)", content&0x0F)); break; |
|---|
| 683 | case 0xA0: case 0xB0: BDBG_MSG(("Leisure hobbies (0x%x)", content&0x0F)); break; |
|---|
| 684 | default: break; |
|---|
| 685 | } |
|---|
| 686 | } |
|---|
| 687 | |
|---|