dvb_demux.c (32461B)
1// SPDX-License-Identifier: LGPL-2.1-or-later 2/* 3 * dvb_demux.c - DVB kernel demux API 4 * 5 * Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de> 6 * & Marcus Metzler <marcus@convergence.de> 7 * for convergence integrated media GmbH 8 */ 9 10#define pr_fmt(fmt) "dvb_demux: " fmt 11 12#include <linux/sched/signal.h> 13#include <linux/spinlock.h> 14#include <linux/slab.h> 15#include <linux/vmalloc.h> 16#include <linux/module.h> 17#include <linux/poll.h> 18#include <linux/string.h> 19#include <linux/crc32.h> 20#include <linux/uaccess.h> 21#include <asm/div64.h> 22 23#include <media/dvb_demux.h> 24 25static int dvb_demux_tscheck; 26module_param(dvb_demux_tscheck, int, 0644); 27MODULE_PARM_DESC(dvb_demux_tscheck, 28 "enable transport stream continuity and TEI check"); 29 30static int dvb_demux_speedcheck; 31module_param(dvb_demux_speedcheck, int, 0644); 32MODULE_PARM_DESC(dvb_demux_speedcheck, 33 "enable transport stream speed check"); 34 35static int dvb_demux_feed_err_pkts = 1; 36module_param(dvb_demux_feed_err_pkts, int, 0644); 37MODULE_PARM_DESC(dvb_demux_feed_err_pkts, 38 "when set to 0, drop packets with the TEI bit set (1 by default)"); 39 40#define dprintk(fmt, arg...) \ 41 printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg) 42 43#define dprintk_tscheck(x...) do { \ 44 if (dvb_demux_tscheck && printk_ratelimit()) \ 45 dprintk(x); \ 46} while (0) 47 48#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG 49# define dprintk_sect_loss(x...) dprintk(x) 50#else 51# define dprintk_sect_loss(x...) 52#endif 53 54#define set_buf_flags(__feed, __flag) \ 55 do { \ 56 (__feed)->buffer_flags |= (__flag); \ 57 } while (0) 58 59/****************************************************************************** 60 * static inlined helper functions 61 ******************************************************************************/ 62 63static inline u16 section_length(const u8 *buf) 64{ 65 return 3 + ((buf[1] & 0x0f) << 8) + buf[2]; 66} 67 68static inline u16 ts_pid(const u8 *buf) 69{ 70 return ((buf[1] & 0x1f) << 8) + buf[2]; 71} 72 73static inline u8 payload(const u8 *tsp) 74{ 75 if (!(tsp[3] & 0x10)) // no payload? 76 return 0; 77 78 if (tsp[3] & 0x20) { // adaptation field? 79 if (tsp[4] > 183) // corrupted data? 80 return 0; 81 else 82 return 184 - 1 - tsp[4]; 83 } 84 85 return 184; 86} 87 88static u32 dvb_dmx_crc32(struct dvb_demux_feed *f, const u8 *src, size_t len) 89{ 90 return (f->feed.sec.crc_val = crc32_be(f->feed.sec.crc_val, src, len)); 91} 92 93static void dvb_dmx_memcopy(struct dvb_demux_feed *f, u8 *d, const u8 *s, 94 size_t len) 95{ 96 memcpy(d, s, len); 97} 98 99/****************************************************************************** 100 * Software filter functions 101 ******************************************************************************/ 102 103static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed, 104 const u8 *buf) 105{ 106 int count = payload(buf); 107 int p; 108 int ccok; 109 u8 cc; 110 111 if (count == 0) 112 return -1; 113 114 p = 188 - count; 115 116 cc = buf[3] & 0x0f; 117 ccok = ((feed->cc + 1) & 0x0f) == cc; 118 feed->cc = cc; 119 if (!ccok) { 120 set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); 121 dprintk_sect_loss("missed packet: %d instead of %d!\n", 122 cc, (feed->cc + 1) & 0x0f); 123 } 124 125 if (buf[1] & 0x40) // PUSI ? 126 feed->peslen = 0xfffa; 127 128 feed->peslen += count; 129 130 return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, 131 &feed->buffer_flags); 132} 133 134static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed, 135 struct dvb_demux_filter *f) 136{ 137 u8 neq = 0; 138 int i; 139 140 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) { 141 u8 xor = f->filter.filter_value[i] ^ feed->feed.sec.secbuf[i]; 142 143 if (f->maskandmode[i] & xor) 144 return 0; 145 146 neq |= f->maskandnotmode[i] & xor; 147 } 148 149 if (f->doneq && !neq) 150 return 0; 151 152 return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen, 153 NULL, 0, &f->filter, &feed->buffer_flags); 154} 155 156static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed) 157{ 158 struct dvb_demux *demux = feed->demux; 159 struct dvb_demux_filter *f = feed->filter; 160 struct dmx_section_feed *sec = &feed->feed.sec; 161 int section_syntax_indicator; 162 163 if (!sec->is_filtering) 164 return 0; 165 166 if (!f) 167 return 0; 168 169 if (sec->check_crc) { 170 section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0); 171 if (section_syntax_indicator && 172 demux->check_crc32(feed, sec->secbuf, sec->seclen)) { 173 set_buf_flags(feed, DMX_BUFFER_FLAG_HAD_CRC32_DISCARD); 174 return -1; 175 } 176 } 177 178 do { 179 if (dvb_dmx_swfilter_sectionfilter(feed, f) < 0) 180 return -1; 181 } while ((f = f->next) && sec->is_filtering); 182 183 sec->seclen = 0; 184 185 return 0; 186} 187 188static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed) 189{ 190 struct dmx_section_feed *sec = &feed->feed.sec; 191 192 if (sec->secbufp < sec->tsfeedp) { 193 int n = sec->tsfeedp - sec->secbufp; 194 195 /* 196 * Section padding is done with 0xff bytes entirely. 197 * Due to speed reasons, we won't check all of them 198 * but just first and last. 199 */ 200 if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) { 201 set_buf_flags(feed, 202 DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); 203 dprintk_sect_loss("section ts padding loss: %d/%d\n", 204 n, sec->tsfeedp); 205 dprintk_sect_loss("pad data: %*ph\n", n, sec->secbuf); 206 } 207 } 208 209 sec->tsfeedp = sec->secbufp = sec->seclen = 0; 210 sec->secbuf = sec->secbuf_base; 211} 212 213/* 214 * Losless Section Demux 1.4.1 by Emard 215 * Valsecchi Patrick: 216 * - middle of section A (no PUSI) 217 * - end of section A and start of section B 218 * (with PUSI pointing to the start of the second section) 219 * 220 * In this case, without feed->pusi_seen you'll receive a garbage section 221 * consisting of the end of section A. Basically because tsfeedp 222 * is incemented and the use=0 condition is not raised 223 * when the second packet arrives. 224 * 225 * Fix: 226 * when demux is started, let feed->pusi_seen = false to 227 * prevent initial feeding of garbage from the end of 228 * previous section. When you for the first time see PUSI=1 229 * then set feed->pusi_seen = true 230 */ 231static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, 232 const u8 *buf, u8 len) 233{ 234 struct dvb_demux *demux = feed->demux; 235 struct dmx_section_feed *sec = &feed->feed.sec; 236 u16 limit, seclen, n; 237 238 if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE) 239 return 0; 240 241 if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) { 242 set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); 243 dprintk_sect_loss("section buffer full loss: %d/%d\n", 244 sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, 245 DMX_MAX_SECFEED_SIZE); 246 len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp; 247 } 248 249 if (len <= 0) 250 return 0; 251 252 demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len); 253 sec->tsfeedp += len; 254 255 /* 256 * Dump all the sections we can find in the data (Emard) 257 */ 258 limit = sec->tsfeedp; 259 if (limit > DMX_MAX_SECFEED_SIZE) 260 return -1; /* internal error should never happen */ 261 262 /* to be sure always set secbuf */ 263 sec->secbuf = sec->secbuf_base + sec->secbufp; 264 265 for (n = 0; sec->secbufp + 2 < limit; n++) { 266 seclen = section_length(sec->secbuf); 267 if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE 268 || seclen + sec->secbufp > limit) 269 return 0; 270 sec->seclen = seclen; 271 sec->crc_val = ~0; 272 /* dump [secbuf .. secbuf+seclen) */ 273 if (feed->pusi_seen) { 274 dvb_dmx_swfilter_section_feed(feed); 275 } else { 276 set_buf_flags(feed, 277 DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); 278 dprintk_sect_loss("pusi not seen, discarding section data\n"); 279 } 280 sec->secbufp += seclen; /* secbufp and secbuf moving together is */ 281 sec->secbuf += seclen; /* redundant but saves pointer arithmetic */ 282 } 283 284 return 0; 285} 286 287static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, 288 const u8 *buf) 289{ 290 u8 p, count; 291 int ccok, dc_i = 0; 292 u8 cc; 293 294 count = payload(buf); 295 296 if (count == 0) /* count == 0 if no payload or out of range */ 297 return -1; 298 299 p = 188 - count; /* payload start */ 300 301 cc = buf[3] & 0x0f; 302 ccok = ((feed->cc + 1) & 0x0f) == cc; 303 feed->cc = cc; 304 305 if (buf[3] & 0x20) { 306 /* adaption field present, check for discontinuity_indicator */ 307 if ((buf[4] > 0) && (buf[5] & 0x80)) 308 dc_i = 1; 309 } 310 311 if (!ccok || dc_i) { 312 if (dc_i) { 313 set_buf_flags(feed, 314 DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR); 315 dprintk_sect_loss("%d frame with disconnect indicator\n", 316 cc); 317 } else { 318 set_buf_flags(feed, 319 DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); 320 dprintk_sect_loss("discontinuity: %d instead of %d. %d bytes lost\n", 321 cc, (feed->cc + 1) & 0x0f, count + 4); 322 } 323 /* 324 * those bytes under some circumstances will again be reported 325 * in the following dvb_dmx_swfilter_section_new 326 */ 327 328 /* 329 * Discontinuity detected. Reset pusi_seen to 330 * stop feeding of suspicious data until next PUSI=1 arrives 331 * 332 * FIXME: does it make sense if the MPEG-TS is the one 333 * reporting discontinuity? 334 */ 335 336 feed->pusi_seen = false; 337 dvb_dmx_swfilter_section_new(feed); 338 } 339 340 if (buf[1] & 0x40) { 341 /* PUSI=1 (is set), section boundary is here */ 342 if (count > 1 && buf[p] < count) { 343 const u8 *before = &buf[p + 1]; 344 u8 before_len = buf[p]; 345 const u8 *after = &before[before_len]; 346 u8 after_len = count - 1 - before_len; 347 348 dvb_dmx_swfilter_section_copy_dump(feed, before, 349 before_len); 350 /* before start of new section, set pusi_seen */ 351 feed->pusi_seen = true; 352 dvb_dmx_swfilter_section_new(feed); 353 dvb_dmx_swfilter_section_copy_dump(feed, after, 354 after_len); 355 } else if (count > 0) { 356 set_buf_flags(feed, 357 DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); 358 dprintk_sect_loss("PUSI=1 but %d bytes lost\n", count); 359 } 360 } else { 361 /* PUSI=0 (is not set), no section boundary */ 362 dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count); 363 } 364 365 return 0; 366} 367 368static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, 369 const u8 *buf) 370{ 371 switch (feed->type) { 372 case DMX_TYPE_TS: 373 if (!feed->feed.ts.is_filtering) 374 break; 375 if (feed->ts_type & TS_PACKET) { 376 if (feed->ts_type & TS_PAYLOAD_ONLY) 377 dvb_dmx_swfilter_payload(feed, buf); 378 else 379 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, 380 &feed->buffer_flags); 381 } 382 /* Used only on full-featured devices */ 383 if (feed->ts_type & TS_DECODER) 384 if (feed->demux->write_to_decoder) 385 feed->demux->write_to_decoder(feed, buf, 188); 386 break; 387 388 case DMX_TYPE_SEC: 389 if (!feed->feed.sec.is_filtering) 390 break; 391 if (dvb_dmx_swfilter_section_packet(feed, buf) < 0) 392 feed->feed.sec.seclen = feed->feed.sec.secbufp = 0; 393 break; 394 395 default: 396 break; 397 } 398} 399 400#define DVR_FEED(f) \ 401 (((f)->type == DMX_TYPE_TS) && \ 402 ((f)->feed.ts.is_filtering) && \ 403 (((f)->ts_type & (TS_PACKET | TS_DEMUX)) == TS_PACKET)) 404 405static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) 406{ 407 struct dvb_demux_feed *feed; 408 u16 pid = ts_pid(buf); 409 int dvr_done = 0; 410 411 if (dvb_demux_speedcheck) { 412 ktime_t cur_time; 413 u64 speed_bytes, speed_timedelta; 414 415 demux->speed_pkts_cnt++; 416 417 /* show speed every SPEED_PKTS_INTERVAL packets */ 418 if (!(demux->speed_pkts_cnt % SPEED_PKTS_INTERVAL)) { 419 cur_time = ktime_get(); 420 421 if (ktime_to_ns(demux->speed_last_time) != 0) { 422 speed_bytes = (u64)demux->speed_pkts_cnt 423 * 188 * 8; 424 /* convert to 1024 basis */ 425 speed_bytes = 1000 * div64_u64(speed_bytes, 426 1024); 427 speed_timedelta = ktime_ms_delta(cur_time, 428 demux->speed_last_time); 429 if (speed_timedelta) 430 dprintk("TS speed %llu Kbits/sec \n", 431 div64_u64(speed_bytes, 432 speed_timedelta)); 433 } 434 435 demux->speed_last_time = cur_time; 436 demux->speed_pkts_cnt = 0; 437 } 438 } 439 440 if (buf[1] & 0x80) { 441 list_for_each_entry(feed, &demux->feed_list, list_head) { 442 if ((feed->pid != pid) && (feed->pid != 0x2000)) 443 continue; 444 set_buf_flags(feed, DMX_BUFFER_FLAG_TEI); 445 } 446 dprintk_tscheck("TEI detected. PID=0x%x data1=0x%x\n", 447 pid, buf[1]); 448 /* data in this packet can't be trusted - drop it unless 449 * module option dvb_demux_feed_err_pkts is set */ 450 if (!dvb_demux_feed_err_pkts) 451 return; 452 } else /* if TEI bit is set, pid may be wrong- skip pkt counter */ 453 if (demux->cnt_storage && dvb_demux_tscheck) { 454 /* check pkt counter */ 455 if (pid < MAX_PID) { 456 if (buf[3] & 0x10) 457 demux->cnt_storage[pid] = 458 (demux->cnt_storage[pid] + 1) & 0xf; 459 460 if ((buf[3] & 0xf) != demux->cnt_storage[pid]) { 461 list_for_each_entry(feed, &demux->feed_list, list_head) { 462 if ((feed->pid != pid) && (feed->pid != 0x2000)) 463 continue; 464 set_buf_flags(feed, 465 DMX_BUFFER_PKT_COUNTER_MISMATCH); 466 } 467 468 dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n", 469 pid, demux->cnt_storage[pid], 470 buf[3] & 0xf); 471 demux->cnt_storage[pid] = buf[3] & 0xf; 472 } 473 } 474 /* end check */ 475 } 476 477 list_for_each_entry(feed, &demux->feed_list, list_head) { 478 if ((feed->pid != pid) && (feed->pid != 0x2000)) 479 continue; 480 481 /* copy each packet only once to the dvr device, even 482 * if a PID is in multiple filters (e.g. video + PCR) */ 483 if ((DVR_FEED(feed)) && (dvr_done++)) 484 continue; 485 486 if (feed->pid == pid) 487 dvb_dmx_swfilter_packet_type(feed, buf); 488 else if (feed->pid == 0x2000) 489 feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, 490 &feed->buffer_flags); 491 } 492} 493 494void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, 495 size_t count) 496{ 497 unsigned long flags; 498 499 spin_lock_irqsave(&demux->lock, flags); 500 501 while (count--) { 502 if (buf[0] == 0x47) 503 dvb_dmx_swfilter_packet(demux, buf); 504 buf += 188; 505 } 506 507 spin_unlock_irqrestore(&demux->lock, flags); 508} 509 510EXPORT_SYMBOL(dvb_dmx_swfilter_packets); 511 512static inline int find_next_packet(const u8 *buf, int pos, size_t count, 513 const int pktsize) 514{ 515 int start = pos, lost; 516 517 while (pos < count) { 518 if (buf[pos] == 0x47 || 519 (pktsize == 204 && buf[pos] == 0xB8)) 520 break; 521 pos++; 522 } 523 524 lost = pos - start; 525 if (lost) { 526 /* This garbage is part of a valid packet? */ 527 int backtrack = pos - pktsize; 528 if (backtrack >= 0 && (buf[backtrack] == 0x47 || 529 (pktsize == 204 && buf[backtrack] == 0xB8))) 530 return backtrack; 531 } 532 533 return pos; 534} 535 536/* Filter all pktsize= 188 or 204 sized packets and skip garbage. */ 537static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, 538 size_t count, const int pktsize) 539{ 540 int p = 0, i, j; 541 const u8 *q; 542 unsigned long flags; 543 544 spin_lock_irqsave(&demux->lock, flags); 545 546 if (demux->tsbufp) { /* tsbuf[0] is now 0x47. */ 547 i = demux->tsbufp; 548 j = pktsize - i; 549 if (count < j) { 550 memcpy(&demux->tsbuf[i], buf, count); 551 demux->tsbufp += count; 552 goto bailout; 553 } 554 memcpy(&demux->tsbuf[i], buf, j); 555 if (demux->tsbuf[0] == 0x47) /* double check */ 556 dvb_dmx_swfilter_packet(demux, demux->tsbuf); 557 demux->tsbufp = 0; 558 p += j; 559 } 560 561 while (1) { 562 p = find_next_packet(buf, p, count, pktsize); 563 if (p >= count) 564 break; 565 if (count - p < pktsize) 566 break; 567 568 q = &buf[p]; 569 570 if (pktsize == 204 && (*q == 0xB8)) { 571 memcpy(demux->tsbuf, q, 188); 572 demux->tsbuf[0] = 0x47; 573 q = demux->tsbuf; 574 } 575 dvb_dmx_swfilter_packet(demux, q); 576 p += pktsize; 577 } 578 579 i = count - p; 580 if (i) { 581 memcpy(demux->tsbuf, &buf[p], i); 582 demux->tsbufp = i; 583 if (pktsize == 204 && demux->tsbuf[0] == 0xB8) 584 demux->tsbuf[0] = 0x47; 585 } 586 587bailout: 588 spin_unlock_irqrestore(&demux->lock, flags); 589} 590 591void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) 592{ 593 _dvb_dmx_swfilter(demux, buf, count, 188); 594} 595EXPORT_SYMBOL(dvb_dmx_swfilter); 596 597void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) 598{ 599 _dvb_dmx_swfilter(demux, buf, count, 204); 600} 601EXPORT_SYMBOL(dvb_dmx_swfilter_204); 602 603void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count) 604{ 605 unsigned long flags; 606 607 spin_lock_irqsave(&demux->lock, flags); 608 609 demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts, 610 &demux->feed->buffer_flags); 611 612 spin_unlock_irqrestore(&demux->lock, flags); 613} 614EXPORT_SYMBOL(dvb_dmx_swfilter_raw); 615 616static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux) 617{ 618 int i; 619 620 for (i = 0; i < demux->filternum; i++) 621 if (demux->filter[i].state == DMX_STATE_FREE) 622 break; 623 624 if (i == demux->filternum) 625 return NULL; 626 627 demux->filter[i].state = DMX_STATE_ALLOCATED; 628 629 return &demux->filter[i]; 630} 631 632static struct dvb_demux_feed *dvb_dmx_feed_alloc(struct dvb_demux *demux) 633{ 634 int i; 635 636 for (i = 0; i < demux->feednum; i++) 637 if (demux->feed[i].state == DMX_STATE_FREE) 638 break; 639 640 if (i == demux->feednum) 641 return NULL; 642 643 demux->feed[i].state = DMX_STATE_ALLOCATED; 644 645 return &demux->feed[i]; 646} 647 648static int dvb_demux_feed_find(struct dvb_demux_feed *feed) 649{ 650 struct dvb_demux_feed *entry; 651 652 list_for_each_entry(entry, &feed->demux->feed_list, list_head) 653 if (entry == feed) 654 return 1; 655 656 return 0; 657} 658 659static void dvb_demux_feed_add(struct dvb_demux_feed *feed) 660{ 661 spin_lock_irq(&feed->demux->lock); 662 if (dvb_demux_feed_find(feed)) { 663 pr_err("%s: feed already in list (type=%x state=%x pid=%x)\n", 664 __func__, feed->type, feed->state, feed->pid); 665 goto out; 666 } 667 668 list_add(&feed->list_head, &feed->demux->feed_list); 669out: 670 spin_unlock_irq(&feed->demux->lock); 671} 672 673static void dvb_demux_feed_del(struct dvb_demux_feed *feed) 674{ 675 spin_lock_irq(&feed->demux->lock); 676 if (!(dvb_demux_feed_find(feed))) { 677 pr_err("%s: feed not in list (type=%x state=%x pid=%x)\n", 678 __func__, feed->type, feed->state, feed->pid); 679 goto out; 680 } 681 682 list_del(&feed->list_head); 683out: 684 spin_unlock_irq(&feed->demux->lock); 685} 686 687static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type, 688 enum dmx_ts_pes pes_type, ktime_t timeout) 689{ 690 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; 691 struct dvb_demux *demux = feed->demux; 692 693 if (pid > DMX_MAX_PID) 694 return -EINVAL; 695 696 if (mutex_lock_interruptible(&demux->mutex)) 697 return -ERESTARTSYS; 698 699 if (ts_type & TS_DECODER) { 700 if (pes_type >= DMX_PES_OTHER) { 701 mutex_unlock(&demux->mutex); 702 return -EINVAL; 703 } 704 705 if (demux->pesfilter[pes_type] && 706 demux->pesfilter[pes_type] != feed) { 707 mutex_unlock(&demux->mutex); 708 return -EINVAL; 709 } 710 711 demux->pesfilter[pes_type] = feed; 712 demux->pids[pes_type] = pid; 713 } 714 715 dvb_demux_feed_add(feed); 716 717 feed->pid = pid; 718 feed->timeout = timeout; 719 feed->ts_type = ts_type; 720 feed->pes_type = pes_type; 721 722 feed->state = DMX_STATE_READY; 723 mutex_unlock(&demux->mutex); 724 725 return 0; 726} 727 728static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed) 729{ 730 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; 731 struct dvb_demux *demux = feed->demux; 732 int ret; 733 734 if (mutex_lock_interruptible(&demux->mutex)) 735 return -ERESTARTSYS; 736 737 if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) { 738 mutex_unlock(&demux->mutex); 739 return -EINVAL; 740 } 741 742 if (!demux->start_feed) { 743 mutex_unlock(&demux->mutex); 744 return -ENODEV; 745 } 746 747 if ((ret = demux->start_feed(feed)) < 0) { 748 mutex_unlock(&demux->mutex); 749 return ret; 750 } 751 752 spin_lock_irq(&demux->lock); 753 ts_feed->is_filtering = 1; 754 feed->state = DMX_STATE_GO; 755 spin_unlock_irq(&demux->lock); 756 mutex_unlock(&demux->mutex); 757 758 return 0; 759} 760 761static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed) 762{ 763 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; 764 struct dvb_demux *demux = feed->demux; 765 int ret; 766 767 mutex_lock(&demux->mutex); 768 769 if (feed->state < DMX_STATE_GO) { 770 mutex_unlock(&demux->mutex); 771 return -EINVAL; 772 } 773 774 if (!demux->stop_feed) { 775 mutex_unlock(&demux->mutex); 776 return -ENODEV; 777 } 778 779 ret = demux->stop_feed(feed); 780 781 spin_lock_irq(&demux->lock); 782 ts_feed->is_filtering = 0; 783 feed->state = DMX_STATE_ALLOCATED; 784 spin_unlock_irq(&demux->lock); 785 mutex_unlock(&demux->mutex); 786 787 return ret; 788} 789 790static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx, 791 struct dmx_ts_feed **ts_feed, 792 dmx_ts_cb callback) 793{ 794 struct dvb_demux *demux = (struct dvb_demux *)dmx; 795 struct dvb_demux_feed *feed; 796 797 if (mutex_lock_interruptible(&demux->mutex)) 798 return -ERESTARTSYS; 799 800 if (!(feed = dvb_dmx_feed_alloc(demux))) { 801 mutex_unlock(&demux->mutex); 802 return -EBUSY; 803 } 804 805 feed->type = DMX_TYPE_TS; 806 feed->cb.ts = callback; 807 feed->demux = demux; 808 feed->pid = 0xffff; 809 feed->peslen = 0xfffa; 810 feed->buffer_flags = 0; 811 812 (*ts_feed) = &feed->feed.ts; 813 (*ts_feed)->parent = dmx; 814 (*ts_feed)->priv = NULL; 815 (*ts_feed)->is_filtering = 0; 816 (*ts_feed)->start_filtering = dmx_ts_feed_start_filtering; 817 (*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering; 818 (*ts_feed)->set = dmx_ts_feed_set; 819 820 if (!(feed->filter = dvb_dmx_filter_alloc(demux))) { 821 feed->state = DMX_STATE_FREE; 822 mutex_unlock(&demux->mutex); 823 return -EBUSY; 824 } 825 826 feed->filter->type = DMX_TYPE_TS; 827 feed->filter->feed = feed; 828 feed->filter->state = DMX_STATE_READY; 829 830 mutex_unlock(&demux->mutex); 831 832 return 0; 833} 834 835static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, 836 struct dmx_ts_feed *ts_feed) 837{ 838 struct dvb_demux *demux = (struct dvb_demux *)dmx; 839 struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; 840 841 mutex_lock(&demux->mutex); 842 843 if (feed->state == DMX_STATE_FREE) { 844 mutex_unlock(&demux->mutex); 845 return -EINVAL; 846 } 847 848 feed->state = DMX_STATE_FREE; 849 feed->filter->state = DMX_STATE_FREE; 850 851 dvb_demux_feed_del(feed); 852 853 feed->pid = 0xffff; 854 855 if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_PES_OTHER) 856 demux->pesfilter[feed->pes_type] = NULL; 857 858 mutex_unlock(&demux->mutex); 859 return 0; 860} 861 862/****************************************************************************** 863 * dmx_section_feed API calls 864 ******************************************************************************/ 865 866static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed, 867 struct dmx_section_filter **filter) 868{ 869 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; 870 struct dvb_demux *dvbdemux = dvbdmxfeed->demux; 871 struct dvb_demux_filter *dvbdmxfilter; 872 873 if (mutex_lock_interruptible(&dvbdemux->mutex)) 874 return -ERESTARTSYS; 875 876 dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux); 877 if (!dvbdmxfilter) { 878 mutex_unlock(&dvbdemux->mutex); 879 return -EBUSY; 880 } 881 882 spin_lock_irq(&dvbdemux->lock); 883 *filter = &dvbdmxfilter->filter; 884 (*filter)->parent = feed; 885 (*filter)->priv = NULL; 886 dvbdmxfilter->feed = dvbdmxfeed; 887 dvbdmxfilter->type = DMX_TYPE_SEC; 888 dvbdmxfilter->state = DMX_STATE_READY; 889 dvbdmxfilter->next = dvbdmxfeed->filter; 890 dvbdmxfeed->filter = dvbdmxfilter; 891 spin_unlock_irq(&dvbdemux->lock); 892 893 mutex_unlock(&dvbdemux->mutex); 894 return 0; 895} 896 897static int dmx_section_feed_set(struct dmx_section_feed *feed, 898 u16 pid, int check_crc) 899{ 900 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; 901 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 902 903 if (pid > 0x1fff) 904 return -EINVAL; 905 906 if (mutex_lock_interruptible(&dvbdmx->mutex)) 907 return -ERESTARTSYS; 908 909 dvb_demux_feed_add(dvbdmxfeed); 910 911 dvbdmxfeed->pid = pid; 912 dvbdmxfeed->feed.sec.check_crc = check_crc; 913 914 dvbdmxfeed->state = DMX_STATE_READY; 915 mutex_unlock(&dvbdmx->mutex); 916 return 0; 917} 918 919static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed) 920{ 921 int i; 922 struct dvb_demux_filter *f; 923 struct dmx_section_filter *sf; 924 u8 mask, mode, doneq; 925 926 if (!(f = dvbdmxfeed->filter)) 927 return; 928 do { 929 sf = &f->filter; 930 doneq = false; 931 for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) { 932 mode = sf->filter_mode[i]; 933 mask = sf->filter_mask[i]; 934 f->maskandmode[i] = mask & mode; 935 doneq |= f->maskandnotmode[i] = mask & ~mode; 936 } 937 f->doneq = doneq ? true : false; 938 } while ((f = f->next)); 939} 940 941static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed) 942{ 943 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; 944 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 945 int ret; 946 947 if (mutex_lock_interruptible(&dvbdmx->mutex)) 948 return -ERESTARTSYS; 949 950 if (feed->is_filtering) { 951 mutex_unlock(&dvbdmx->mutex); 952 return -EBUSY; 953 } 954 955 if (!dvbdmxfeed->filter) { 956 mutex_unlock(&dvbdmx->mutex); 957 return -EINVAL; 958 } 959 960 dvbdmxfeed->feed.sec.tsfeedp = 0; 961 dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base; 962 dvbdmxfeed->feed.sec.secbufp = 0; 963 dvbdmxfeed->feed.sec.seclen = 0; 964 dvbdmxfeed->pusi_seen = false; 965 966 if (!dvbdmx->start_feed) { 967 mutex_unlock(&dvbdmx->mutex); 968 return -ENODEV; 969 } 970 971 prepare_secfilters(dvbdmxfeed); 972 973 if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) { 974 mutex_unlock(&dvbdmx->mutex); 975 return ret; 976 } 977 978 spin_lock_irq(&dvbdmx->lock); 979 feed->is_filtering = 1; 980 dvbdmxfeed->state = DMX_STATE_GO; 981 spin_unlock_irq(&dvbdmx->lock); 982 983 mutex_unlock(&dvbdmx->mutex); 984 return 0; 985} 986 987static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed) 988{ 989 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; 990 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 991 int ret; 992 993 mutex_lock(&dvbdmx->mutex); 994 995 if (!dvbdmx->stop_feed) { 996 mutex_unlock(&dvbdmx->mutex); 997 return -ENODEV; 998 } 999 1000 ret = dvbdmx->stop_feed(dvbdmxfeed); 1001 1002 spin_lock_irq(&dvbdmx->lock); 1003 dvbdmxfeed->state = DMX_STATE_READY; 1004 feed->is_filtering = 0; 1005 spin_unlock_irq(&dvbdmx->lock); 1006 1007 mutex_unlock(&dvbdmx->mutex); 1008 return ret; 1009} 1010 1011static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, 1012 struct dmx_section_filter *filter) 1013{ 1014 struct dvb_demux_filter *dvbdmxfilter = (struct dvb_demux_filter *)filter, *f; 1015 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; 1016 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 1017 1018 mutex_lock(&dvbdmx->mutex); 1019 1020 if (dvbdmxfilter->feed != dvbdmxfeed) { 1021 mutex_unlock(&dvbdmx->mutex); 1022 return -EINVAL; 1023 } 1024 1025 if (feed->is_filtering) { 1026 /* release dvbdmx->mutex as far as it is 1027 acquired by stop_filtering() itself */ 1028 mutex_unlock(&dvbdmx->mutex); 1029 feed->stop_filtering(feed); 1030 mutex_lock(&dvbdmx->mutex); 1031 } 1032 1033 spin_lock_irq(&dvbdmx->lock); 1034 f = dvbdmxfeed->filter; 1035 1036 if (f == dvbdmxfilter) { 1037 dvbdmxfeed->filter = dvbdmxfilter->next; 1038 } else { 1039 while (f->next != dvbdmxfilter) 1040 f = f->next; 1041 f->next = f->next->next; 1042 } 1043 1044 dvbdmxfilter->state = DMX_STATE_FREE; 1045 spin_unlock_irq(&dvbdmx->lock); 1046 mutex_unlock(&dvbdmx->mutex); 1047 return 0; 1048} 1049 1050static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, 1051 struct dmx_section_feed **feed, 1052 dmx_section_cb callback) 1053{ 1054 struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; 1055 struct dvb_demux_feed *dvbdmxfeed; 1056 1057 if (mutex_lock_interruptible(&dvbdmx->mutex)) 1058 return -ERESTARTSYS; 1059 1060 if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) { 1061 mutex_unlock(&dvbdmx->mutex); 1062 return -EBUSY; 1063 } 1064 1065 dvbdmxfeed->type = DMX_TYPE_SEC; 1066 dvbdmxfeed->cb.sec = callback; 1067 dvbdmxfeed->demux = dvbdmx; 1068 dvbdmxfeed->pid = 0xffff; 1069 dvbdmxfeed->buffer_flags = 0; 1070 dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base; 1071 dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0; 1072 dvbdmxfeed->feed.sec.tsfeedp = 0; 1073 dvbdmxfeed->filter = NULL; 1074 1075 (*feed) = &dvbdmxfeed->feed.sec; 1076 (*feed)->is_filtering = 0; 1077 (*feed)->parent = demux; 1078 (*feed)->priv = NULL; 1079 1080 (*feed)->set = dmx_section_feed_set; 1081 (*feed)->allocate_filter = dmx_section_feed_allocate_filter; 1082 (*feed)->start_filtering = dmx_section_feed_start_filtering; 1083 (*feed)->stop_filtering = dmx_section_feed_stop_filtering; 1084 (*feed)->release_filter = dmx_section_feed_release_filter; 1085 1086 mutex_unlock(&dvbdmx->mutex); 1087 return 0; 1088} 1089 1090static int dvbdmx_release_section_feed(struct dmx_demux *demux, 1091 struct dmx_section_feed *feed) 1092{ 1093 struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; 1094 struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; 1095 1096 mutex_lock(&dvbdmx->mutex); 1097 1098 if (dvbdmxfeed->state == DMX_STATE_FREE) { 1099 mutex_unlock(&dvbdmx->mutex); 1100 return -EINVAL; 1101 } 1102 dvbdmxfeed->state = DMX_STATE_FREE; 1103 1104 dvb_demux_feed_del(dvbdmxfeed); 1105 1106 dvbdmxfeed->pid = 0xffff; 1107 1108 mutex_unlock(&dvbdmx->mutex); 1109 return 0; 1110} 1111 1112/****************************************************************************** 1113 * dvb_demux kernel data API calls 1114 ******************************************************************************/ 1115 1116static int dvbdmx_open(struct dmx_demux *demux) 1117{ 1118 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; 1119 1120 if (dvbdemux->users >= MAX_DVB_DEMUX_USERS) 1121 return -EUSERS; 1122 1123 dvbdemux->users++; 1124 return 0; 1125} 1126 1127static int dvbdmx_close(struct dmx_demux *demux) 1128{ 1129 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; 1130 1131 if (dvbdemux->users == 0) 1132 return -ENODEV; 1133 1134 dvbdemux->users--; 1135 //FIXME: release any unneeded resources if users==0 1136 return 0; 1137} 1138 1139static int dvbdmx_write(struct dmx_demux *demux, const char __user *buf, size_t count) 1140{ 1141 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; 1142 void *p; 1143 1144 if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) 1145 return -EINVAL; 1146 1147 p = memdup_user(buf, count); 1148 if (IS_ERR(p)) 1149 return PTR_ERR(p); 1150 if (mutex_lock_interruptible(&dvbdemux->mutex)) { 1151 kfree(p); 1152 return -ERESTARTSYS; 1153 } 1154 dvb_dmx_swfilter(dvbdemux, p, count); 1155 kfree(p); 1156 mutex_unlock(&dvbdemux->mutex); 1157 1158 if (signal_pending(current)) 1159 return -EINTR; 1160 return count; 1161} 1162 1163static int dvbdmx_add_frontend(struct dmx_demux *demux, 1164 struct dmx_frontend *frontend) 1165{ 1166 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; 1167 struct list_head *head = &dvbdemux->frontend_list; 1168 1169 list_add(&(frontend->connectivity_list), head); 1170 1171 return 0; 1172} 1173 1174static int dvbdmx_remove_frontend(struct dmx_demux *demux, 1175 struct dmx_frontend *frontend) 1176{ 1177 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; 1178 struct list_head *pos, *n, *head = &dvbdemux->frontend_list; 1179 1180 list_for_each_safe(pos, n, head) { 1181 if (DMX_FE_ENTRY(pos) == frontend) { 1182 list_del(pos); 1183 return 0; 1184 } 1185 } 1186 1187 return -ENODEV; 1188} 1189 1190static struct list_head *dvbdmx_get_frontends(struct dmx_demux *demux) 1191{ 1192 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; 1193 1194 if (list_empty(&dvbdemux->frontend_list)) 1195 return NULL; 1196 1197 return &dvbdemux->frontend_list; 1198} 1199 1200static int dvbdmx_connect_frontend(struct dmx_demux *demux, 1201 struct dmx_frontend *frontend) 1202{ 1203 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; 1204 1205 if (demux->frontend) 1206 return -EINVAL; 1207 1208 mutex_lock(&dvbdemux->mutex); 1209 1210 demux->frontend = frontend; 1211 mutex_unlock(&dvbdemux->mutex); 1212 return 0; 1213} 1214 1215static int dvbdmx_disconnect_frontend(struct dmx_demux *demux) 1216{ 1217 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; 1218 1219 mutex_lock(&dvbdemux->mutex); 1220 1221 demux->frontend = NULL; 1222 mutex_unlock(&dvbdemux->mutex); 1223 return 0; 1224} 1225 1226static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 * pids) 1227{ 1228 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; 1229 1230 memcpy(pids, dvbdemux->pids, 5 * sizeof(u16)); 1231 return 0; 1232} 1233 1234int dvb_dmx_init(struct dvb_demux *dvbdemux) 1235{ 1236 int i; 1237 struct dmx_demux *dmx = &dvbdemux->dmx; 1238 1239 dvbdemux->cnt_storage = NULL; 1240 dvbdemux->users = 0; 1241 dvbdemux->filter = vmalloc(array_size(sizeof(struct dvb_demux_filter), 1242 dvbdemux->filternum)); 1243 1244 if (!dvbdemux->filter) 1245 return -ENOMEM; 1246 1247 dvbdemux->feed = vmalloc(array_size(sizeof(struct dvb_demux_feed), 1248 dvbdemux->feednum)); 1249 if (!dvbdemux->feed) { 1250 vfree(dvbdemux->filter); 1251 dvbdemux->filter = NULL; 1252 return -ENOMEM; 1253 } 1254 for (i = 0; i < dvbdemux->filternum; i++) { 1255 dvbdemux->filter[i].state = DMX_STATE_FREE; 1256 dvbdemux->filter[i].index = i; 1257 } 1258 for (i = 0; i < dvbdemux->feednum; i++) { 1259 dvbdemux->feed[i].state = DMX_STATE_FREE; 1260 dvbdemux->feed[i].index = i; 1261 } 1262 1263 dvbdemux->cnt_storage = vmalloc(MAX_PID + 1); 1264 if (!dvbdemux->cnt_storage) 1265 pr_warn("Couldn't allocate memory for TS/TEI check. Disabling it\n"); 1266 1267 INIT_LIST_HEAD(&dvbdemux->frontend_list); 1268 1269 for (i = 0; i < DMX_PES_OTHER; i++) { 1270 dvbdemux->pesfilter[i] = NULL; 1271 dvbdemux->pids[i] = 0xffff; 1272 } 1273 1274 INIT_LIST_HEAD(&dvbdemux->feed_list); 1275 1276 dvbdemux->playing = 0; 1277 dvbdemux->recording = 0; 1278 dvbdemux->tsbufp = 0; 1279 1280 if (!dvbdemux->check_crc32) 1281 dvbdemux->check_crc32 = dvb_dmx_crc32; 1282 1283 if (!dvbdemux->memcopy) 1284 dvbdemux->memcopy = dvb_dmx_memcopy; 1285 1286 dmx->frontend = NULL; 1287 dmx->priv = dvbdemux; 1288 dmx->open = dvbdmx_open; 1289 dmx->close = dvbdmx_close; 1290 dmx->write = dvbdmx_write; 1291 dmx->allocate_ts_feed = dvbdmx_allocate_ts_feed; 1292 dmx->release_ts_feed = dvbdmx_release_ts_feed; 1293 dmx->allocate_section_feed = dvbdmx_allocate_section_feed; 1294 dmx->release_section_feed = dvbdmx_release_section_feed; 1295 1296 dmx->add_frontend = dvbdmx_add_frontend; 1297 dmx->remove_frontend = dvbdmx_remove_frontend; 1298 dmx->get_frontends = dvbdmx_get_frontends; 1299 dmx->connect_frontend = dvbdmx_connect_frontend; 1300 dmx->disconnect_frontend = dvbdmx_disconnect_frontend; 1301 dmx->get_pes_pids = dvbdmx_get_pes_pids; 1302 1303 mutex_init(&dvbdemux->mutex); 1304 spin_lock_init(&dvbdemux->lock); 1305 1306 return 0; 1307} 1308 1309EXPORT_SYMBOL(dvb_dmx_init); 1310 1311void dvb_dmx_release(struct dvb_demux *dvbdemux) 1312{ 1313 vfree(dvbdemux->cnt_storage); 1314 vfree(dvbdemux->filter); 1315 vfree(dvbdemux->feed); 1316} 1317 1318EXPORT_SYMBOL(dvb_dmx_release);